mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-27 11:52:34 -04:00
BUG/MINOR: jwe: enforce GCM tag length to 128 bits
Two fixes addressing cryptographic and parsing correctness issues: 1. Enforce 16-byte GCM authentication tag in decrypt_ciphertext() The base64url-decoded 5th JWE component (authentication tag) was passed directly to EVP_CTRL_AEAD_SET_TAG with its attacker-controlled length. OpenSSL accepts 1-16 byte GCM tags and only verifies that many bytes, so a 1-byte tag reduces forgery work factor to ~256. RFC 7518 mandates 128-bit (16 byte) tags for A*GCM. The CBC-HMAC path already enforced correct length, confirming this was an oversight. Fix: Add (*aead_tag)->data != 16 check before the GCM branch in decrypt_ciphertext(), rejecting any non-16-byte tag. Introduced by416b87d5db(JWE A*GCM support). 2. Enforce 16-byte GCMKW tag in parse_jose() decode_jose_field() The $.tag field from the attacker-supplied protected header in A*GCMKW key-wrap was similarly decoded without length enforcement. Fix: Add a size != 16 check for fields named ".tag" in decode_jose_field() when called from the GCMKW path. Introduced by026652a7eb(GCMKW tag field parsing).
This commit is contained in:
parent
ce9371a768
commit
4e7518ed21
1 changed files with 10 additions and 2 deletions
12
src/jwe.c
12
src/jwe.c
|
|
@ -266,8 +266,10 @@ static int parse_jose(struct buffer *decoded_jose, int *alg, int *enc, struct jo
|
|||
|
||||
|
||||
if (gcm) {
|
||||
/* Look for "tag" field (used by aes gcm encryption) */
|
||||
if (decode_jose_field(decoded_jose, "$.tag", &jose_fields->tag, 1))
|
||||
/* Look for "tag" field (used by aes gcm encryption).
|
||||
* GCMKW tag must be exactly 16 bytes per RFC 7518 */
|
||||
if (decode_jose_field(decoded_jose, "$.tag", &jose_fields->tag, 1) ||
|
||||
b_data(jose_fields->tag) != 16)
|
||||
goto end;
|
||||
|
||||
/* Look for "iv" field (used by aes gcm encryption) */
|
||||
|
|
@ -556,6 +558,12 @@ static int decrypt_ciphertext(jwe_enc enc, struct jwt_item items[JWE_ELT_MAX],
|
|||
(*aead_tag)->data = size;
|
||||
|
||||
if (gcm) {
|
||||
/* RFC 7518 mandates a 128-bit (16 byte) authentication tag for A*GCM.
|
||||
* OpenSSL accepts 1-16 bytes but only verifies that many bytes, so a
|
||||
* truncated tag reduces forgery work factor to ~256 per byte short. */
|
||||
if ((*aead_tag)->data != 16)
|
||||
goto end;
|
||||
|
||||
aad = alloc_trash_chunk();
|
||||
if (!aad)
|
||||
goto end;
|
||||
|
|
|
|||
Loading…
Reference in a new issue