cookie ready
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user