cookie ready

This commit is contained in:
2026-05-13 22:34:11 +02:00
parent 8c4e664ca8
commit 1b53c1c199
16 changed files with 798 additions and 146 deletions
+37 -7
View File
@@ -74,6 +74,9 @@ func (c *nativeCodec) Decode(raw string) (*SessionContext, error) {
if err != nil {
return nil, err
}
if err := validatePlaintextChecksum(string(plaintext), c.cfg.CookieIV); err != nil {
return nil, err
}
values, orderedKeys := parsePlaintext(string(plaintext))
return &SessionContext{
@@ -129,12 +132,10 @@ func (c *nativeCodec) decryptInternal(ciphertextHex string) ([]byte, error) {
return nil, err
}
message := append(append(append([]byte{}, salt...), iv...), encrypted...)
if len(expectedHMAC) == macSize && !verifyHMAC(expectedHMAC, message, keys.akey) {
// Some existing shop cookies decrypt correctly but fail MAC verification with
// the same behavior observed in the reference implementation this codec ports.
// Keep decryption permissive for compatibility, but still compute the MAC so
// the encode path emits a complete payload.
message := append(append(append([]byte{}, header...), salt...), iv...)
message = append(message, encrypted...)
if len(expectedHMAC) != macSize || !verifyHMAC(expectedHMAC, message, keys.akey) {
return nil, errors.New("integrity check failed")
}
return aesCTR(encrypted, keys.ekey, iv)
@@ -161,7 +162,8 @@ func (c *nativeCodec) encryptInternal(plaintext string) (string, error) {
return "", err
}
message := append(append(append([]byte{}, salt...), iv...), encrypted...)
message := append(append(append([]byte{}, []byte(currentVersion)...), salt...), iv...)
message = append(message, encrypted...)
h := hmac.New(sha256.New, keys.akey)
h.Write(message)
mac := h.Sum(nil)
@@ -269,6 +271,34 @@ func verifyHMAC(expected, message, key []byte) bool {
return hmac.Equal(h.Sum(nil), expected)
}
func validatePlaintextChecksum(plaintext, cookieIV string) error {
pairs := strings.Split(plaintext, fieldSeparator)
if len(pairs) == 0 {
return errors.New("missing cookie checksum")
}
bodyPairs := pairs[:len(pairs)-1]
body := strings.Join(bodyPairs, fieldSeparator)
if body != "" {
body += fieldSeparator
}
lastPair := pairs[len(pairs)-1]
checksumParts := strings.SplitN(lastPair, pairSeparator, 2)
if len(checksumParts) != 2 || checksumParts[0] != "checksum" {
return errors.New("missing cookie checksum")
}
if cookieIV == "" {
return errors.New("cookie iv is required for checksum validation")
}
want := fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(cookieIV+body)))
if checksumParts[1] != want {
return errors.New("cookie checksum mismatch")
}
return nil
}
func decodeHex(input string) ([]byte, error) {
if len(input)%2 != 0 {
return nil, errors.New("odd length hex")