Hi,

devel/cjose (0.6.1pl20260427) is affected by two real security
issues, both already fixed upstream and both already backported
for Debian's LTS branch:

CVE-2026-53938: _cjose_jwe_decrypt_ek_aes_kw() passes the
attacker-controlled encrypted_key straight to AES_unwrap_key()
without checking its length against the fixed-size jwe->cek
buffer it unwraps into. A crafted JWE with an oversized
encrypted_key segment for an AES key wrap algorithm triggers an
out-of-bounds heap write - at minimum a remote, unauthenticated
DoS. Fix adds the length check RFC 3394 already implies (wrapped
key length is always the plaintext CEK length plus 8 bytes)
before unwrapping.

CVE-2026-53939: _cjose_jwe_set_cek_aes_cbc() passes the wrong
boolean to _cjose_jwe_malloc()'s "zero" parameter (inverted), so
a freshly generated CEK for AES-CBC-HMAC content encryption is
always zero-filled instead of randomly generated. Every JWE
produced with an AES-CBC-HMAC enc algorithm ends up encrypted
and authenticated under the same fixed, publicly known key.

Both confirmed against the actual upstream fix commits
(OpenIDC/cjose@8c51d2452, OpenIDC/cjose@2a6e5bd96) and verified
against this port's own snapshot - the vulnerable functions are
identical between OpenIDC's and cisco's forks. Built and tested
clean on 7.9, full regression suite passes (1/1).

Index: patches/patch-src_jwe_c
--- /dev/null
+++ patches/patch-src_jwe_c
@@ -0,0 +1,49 @@
+Fix two security issues in JWE handling.
+
+CVE-2026-53938: _cjose_jwe_decrypt_ek_aes_kw() passed the
+attacker-controlled encrypted_key straight to AES_unwrap_key()
+without checking its length against the fixed-size jwe->cek buffer
+it unwraps into. A crafted JWE with an oversized encrypted_key
+segment for an AES key wrap algorithm (A128KW/A192KW/A256KW)
+triggers an out-of-bounds heap write, which is at minimum a remote,
+unauthenticated denial of service. Add the length check RFC 3394
+already implies (wrapped key length is always the plaintext CEK
+length plus 8 bytes) before unwrapping.
+https://github.com/OpenIDC/cjose/commit/8c51d2452
+
+CVE-2026-53939: _cjose_jwe_set_cek_aes_cbc() passed the wrong boolean
+to _cjose_jwe_malloc()'s "zero" parameter (inverted), so a freshly
+generated CEK for AES-CBC-HMAC content encryption was always
+zero-filled instead of randomly generated. Every JWE produced with
+an AES-CBC-HMAC enc algorithm was therefore encrypted and
+authenticated under the same fixed, publicly known key.
+https://github.com/OpenIDC/cjose/commit/2a6e5bd96
+
+Index: src/jwe.c
+--- src/jwe.c.orig
++++ src/jwe.c
+@@ -459,7 +459,7 @@
+     {
+         // allocate memory for the CEK and fill with random bytes or 0's
+         _cjose_release_cek(&jwe->cek, jwe->cek_len);
+-        if (!_cjose_jwe_malloc(keysize, !random, &jwe->cek, err))
++        if (!_cjose_jwe_malloc(keysize, random, &jwe->cek, err))
+         {
+             return false;
+         }
+@@ -588,6 +588,15 @@
+         return false;
+     }
+
++    // the wrapped key (RFC 3394) is always the plaintext CEK length
plus 8 bytes;
++    // enforce this before calling AES_unwrap_key, which would
otherwise copy the
++    // attacker-controlled encrypted_key into the fixed-size jwe->cek buffer
++    if (recipient->enc_key.raw_len != jwe->cek_len + 8)
++    {
++        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
++        return false;
++    }
++
+     // AES unwrap the CEK in to jwe->cek
+     int len = AES_unwrap_key(&akey, (const unsigned char *)NULL,
jwe->cek, (const unsigned char *)recipient->enc_key.raw,
+                              recipient->enc_key.raw_len);

OK?

Ivo

Reply via email to