From 6fb25be77b1228e40e202a6b5141865b8a30d4d7 Mon Sep 17 00:00:00 2001 From: Ken Zalewski Date: Fri, 6 Feb 2026 01:39:02 -0500 Subject: [PATCH] Patch to openssl-1.1.1ze. This version addresses seven vulnerabilities: CVE-2025-68160, CVE-2025-69418, CVE-2025-69419, CVE-2025-69420, CVE-2025-69421, CVE-2026-22795, and CVE-2026-22796 --- CHANGES | 127 +++++++++++++++++++++++++++++++++++++ NEWS | 16 +++++ README | 4 +- apps/s_client.c | 3 +- crypto/asn1/a_strex.c | 6 +- crypto/bio/bf_lbuf.c | 32 ++++++++-- crypto/modes/ocb128.c | 10 ++- crypto/pkcs12/p12_decr.c | 5 ++ crypto/pkcs12/p12_kiss.c | 10 ++- crypto/pkcs12/p12_utl.c | 13 +++- crypto/pkcs7/pk7_doit.c | 2 + crypto/ts/ts_rsp_verify.c | 4 +- include/openssl/opensslv.h | 4 +- 13 files changed, 214 insertions(+), 22 deletions(-) diff --git a/CHANGES b/CHANGES index b9e5e61..1abcd76 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,133 @@ https://github.com/openssl/openssl/commits/ and pick the appropriate release branch. + Changes between 1.1.1zd and 1.1.1ze [27 Jan 2026] + + *) Fixed Heap out-of-bounds write in BIO_f_linebuffer on short writes. + + Severity: Low + + Issue summary: Writing large, newline-free data into a BIO chain using the + line-buffering filter where the next BIO performs short writes can trigger + a heap-based out-of-bounds write. + + Impact summary: This out-of-bounds write can cause memory corruption + which typically results in a crash, leading to Denial of Service for + an application. + + Reported by: Petr Simecek (Aisle Research) and Stanislav Fort (Aisle + Research) + + (CVE-2025-68160) + [Stanislav Fort] + [Neil Horman] + + *) Fixed Unauthenticated/unencrypted trailing bytes with low-level OCB + function calls. + + Severity: Low + + Issue summary: When using the low-level OCB API directly with AES-NI or + other hardware-accelerated code paths, inputs whose length is not a multiple + of 16 bytes can leave the final partial block unencrypted and + unauthenticated. + + Impact summary: The trailing 1-15 bytes of a message may be exposed in + cleartext on encryption and are not covered by the authentication tag, + allowing an attacker to read or tamper with those bytes without detection. + + Reported by: Stanislav Fort (Aisle Research) + + (CVE-2025-69418) + [Stanislav Fort] + + *) Fixed Out of bounds write in PKCS12_get_friendlyname() UTF-8 conversion. + + Severity: Low + + Issue summary: Calling PKCS12_get_friendlyname() function on a maliciously + crafted PKCS#12 file with a BMPString (UTF-16BE) friendly name containing + non-ASCII BMP code point can trigger a one byte write before the allocated + buffer. + + Impact summary: The out-of-bounds write can cause a memory corruption + which can have various consequences including a Denial of Service. + + Reported by: Stanislav Fort (Aisle Research) + + (CVE-2025-69419) + [Norbert Pócs] + + *) Fixed Missing ASN1_TYPE validation in TS_RESP_verify_response() function. + + Severity: Low + + Issue summary: A type confusion vulnerability exists in the TimeStamp + Response verification code where an ASN1_TYPE union member is accessed + without first validating the type, causing an invalid or NULL pointer + dereference when processing a malformed TimeStamp Response file. + + Impact summary: An application calling TS_RESP_verify_response() + with a malformed TimeStamp Response can be caused to dereference an invalid + or NULL pointer when reading, resulting in a Denial of Service. + + Reported by: Luigino Camastra (Aisle Research) + + (CVE-2025-69420) + [Bob Beck] + + *) Fixed NULL Pointer Dereference in PKCS12_item_decrypt_d2i_ex() function. + + Severity: Low + + Issue summary: Processing a malformed PKCS#12 file can trigger a NULL + pointer dereference in the PKCS12_item_decrypt_d2i_ex() function. + + Impact summary: A NULL pointer dereference can trigger a crash which leads + to Denial of Service for an application processing PKCS#12 files. + + Reported by: Luigino Camastra (Aisle Research) + + (CVE-2025-69421) + [Luigino Camastra] + + *) Fixed Missing ASN1_TYPE validation in PKCS#12 parsing. + + Severity: Low + + Issue summary: An invalid or NULL pointer dereference can happen in + an application processing a malformed PKCS#12 file. + + Impact summary: An application processing a malformed PKCS#12 file can be + caused to dereference an invalid or NULL pointer on memory read, resulting + in a Denial of Service. + + Reported by: Luigino Camastra (Aisle Research) + + (CVE-2026-22795) + [Bob Beck] + + *) Fixed ASN1_TYPE Type Confusion in the PKCS7_digest_from_attributes() + function. + + Severity: Low + + Issue summary: A type confusion vulnerability exists in the signature + verification of signed PKCS#7 data where an ASN1_TYPE union member + is accessed without first validating the type, causing an invalid or NULL + pointer dereference when processing malformed PKCS#7 data. + + Impact summary: An application performing signature verification of PKCS#7 + data or calling directly the PKCS7_digest_from_attributes() function can be + caused to dereference an invalid or NULL pointer when reading, resulting in + a Denial of Service. + + Reported by: Luigino Camastra (Aisle Research) + + (CVE-2026-22796) + [Bob Beck] + + Changes between 1.1.1zb_p2 and 1.1.1zd [30 Sep 2025] *) Fix incorrect check of unwrapped key size in kek_unwrap_key() diff --git a/NEWS b/NEWS index 19b7aa3..c9d06c5 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,22 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between 1.1.1zd and 1.1.1ze [27 Jan 2026] + + o Fixed Heap out-of-bounds write in BIO_f_linebuffer on short writes. + (CVE-2025-68160) + o Fixed Unauthenticated/unencrypted trailing bytes with low-level OCB + function calls. (CVE-2025-69418) + o Fixed Out of bounds write in PKCS12_get_friendlyname() UTF-8 conversion. + (CVE-2025-69419) + o Fixed Missing ASN1_TYPE validation in TS_RESP_verify_response() + function. (CVE-2025-69420) + o Fixed NULL Pointer Dereference in PKCS12_item_decrypt_d2i_ex() function. + (CVE-2025-69421) + o Fixed Missing ASN1_TYPE validation in PKCS#12 parsing. (CVE-2026-22795) + o Fixed ASN1_TYPE Type Confusion in the PKCS7_digest_from_attributes() + function. (CVE-2026-22796) + Major changes between 1.1.1zb_p2 and 1.1.1zd [30 Sep 2025] o Fix out-of-bounds read & write in RFC 3211 KEK Unwrap (CVE-2025-9230) diff --git a/README b/README index 6eaa1e0..f388077 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ - OpenSSL 1.1.1zd 30 Sep 2025 + OpenSSL 1.1.1ze 27 Jan 2026 - Copyright (c) 1998-2023 The OpenSSL Project + Copyright (c) 1998-2026 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson All rights reserved. diff --git a/apps/s_client.c b/apps/s_client.c index 00effc8..39df178 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -2698,8 +2698,9 @@ int s_client_main(int argc, char **argv) goto end; } atyp = ASN1_generate_nconf(genstr, cnf); - if (atyp == NULL) { + if (atyp == NULL || atyp->type != V_ASN1_SEQUENCE) { NCONF_free(cnf); + ASN1_TYPE_free(atyp); BIO_printf(bio_err, "ASN1_generate_nconf failed\n"); goto end; } diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index 284dde2..60b8395 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -203,8 +203,10 @@ static int do_buf(unsigned char *buf, int buflen, orflags = CHARTYPE_LAST_ESC_2253; if (type & BUF_TYPE_CONVUTF8) { unsigned char utfbuf[6]; - int utflen; - utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c); + int utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c); + if (utflen < 0) + return -1; /* error happened with UTF8 */ + for (i = 0; i < utflen; i++) { /* * We don't need to worry about setting orflags correctly diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c index 72f9901..34dd035 100644 --- a/crypto/bio/bf_lbuf.c +++ b/crypto/bio/bf_lbuf.c @@ -191,14 +191,34 @@ static int linebuffer_write(BIO *b, const char *in, int inl) while (foundnl && inl > 0); /* * We've written as much as we can. The rest of the input buffer, if - * any, is text that doesn't and with a NL and therefore needs to be - * saved for the next trip. + * any, is text that doesn't end with a NL and therefore we need to try + * free up some space in our obuf so we can make forward progress. */ - if (inl > 0) { - memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); - ctx->obuf_len += inl; - num += inl; + while (inl > 0) { + size_t avail = (size_t)ctx->obuf_size - (size_t)ctx->obuf_len; + size_t to_copy; + + if (avail == 0) { + /* Flush buffered data to make room */ + i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); + if (i <= 0) { + BIO_copy_next_retry(b); + return num > 0 ? num : i; + } + if (i < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i); + ctx->obuf_len -= i; + continue; + } + + to_copy = inl > (int)avail ? avail : (size_t)inl; + memcpy(&(ctx->obuf[ctx->obuf_len]), in, to_copy); + ctx->obuf_len += (int)to_copy; + in += to_copy; + inl -= (int)to_copy; + num += (int)to_copy; } + return num; } diff --git a/crypto/modes/ocb128.c b/crypto/modes/ocb128.c index b39a55a..2ef3982 100644 --- a/crypto/modes/ocb128.c +++ b/crypto/modes/ocb128.c @@ -342,7 +342,7 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, if (num_blocks && all_num_blocks == (size_t)all_num_blocks && ctx->stream != NULL) { - size_t max_idx = 0, top = (size_t)all_num_blocks; + size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0; /* * See how many L_{i} entries we need to process data at hand @@ -356,6 +356,9 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, ctx->stream(in, out, num_blocks, ctx->keyenc, (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c, (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c); + processed_bytes = num_blocks * 16; + in += processed_bytes; + out += processed_bytes; } else { /* Loop through all full blocks to be encrypted */ for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) { @@ -434,7 +437,7 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, if (num_blocks && all_num_blocks == (size_t)all_num_blocks && ctx->stream != NULL) { - size_t max_idx = 0, top = (size_t)all_num_blocks; + size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0; /* * See how many L_{i} entries we need to process data at hand @@ -448,6 +451,9 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, ctx->stream(in, out, num_blocks, ctx->keydec, (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c, (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c); + processed_bytes = num_blocks * 16; + in += processed_bytes; + out += processed_bytes; } else { OCB_BLOCK tmp; diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c index 3c86058..e3d1b8b 100644 --- a/crypto/pkcs12/p12_decr.c +++ b/crypto/pkcs12/p12_decr.c @@ -88,6 +88,11 @@ void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, void *ret; int outlen; + if (oct == NULL) { + PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, &out, &outlen, 0)) { PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c index 7ab9838..d90404d 100644 --- a/crypto/pkcs12/p12_kiss.c +++ b/crypto/pkcs12/p12_kiss.c @@ -183,11 +183,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, ASN1_BMPSTRING *fname = NULL; ASN1_OCTET_STRING *lkid = NULL; - if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) + if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) { + if (attrib->type != V_ASN1_BMPSTRING) + return 0; fname = attrib->value.bmpstring; + } - if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID))) + if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID))) { + if (attrib->type != V_ASN1_OCTET_STRING) + return 0; lkid = attrib->value.octet_string; + } switch (PKCS12_SAFEBAG_get_nid(bag)) { case NID_keyBag: diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c index 43b9e3a..b71e9b1 100644 --- a/crypto/pkcs12/p12_utl.c +++ b/crypto/pkcs12/p12_utl.c @@ -206,9 +206,16 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen) /* re-run the loop emitting UTF-8 string */ for (asclen = 0, i = 0; i < unilen; ) { - j = bmp_to_utf8(asctmp+asclen, uni+i, unilen-i); - if (j == 4) i += 4; - else i += 2; + j = bmp_to_utf8(asctmp + asclen, uni + i, unilen - i); + /* when UTF8_putc fails */ + if (j < 0) { + OPENSSL_free(asctmp); + return NULL; + } + if (j == 4) + i += 4; + else + i += 2; asclen += j; } diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index f63fbc5..4e0eb1e 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -1092,6 +1092,8 @@ ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) ASN1_TYPE *astype; if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL) return NULL; + if (astype->type != V_ASN1_OCTET_STRING) + return NULL; return astype->value.octet_string; } diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index 7fe3d27..5d452d2 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -262,7 +262,7 @@ static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si) ASN1_TYPE *attr; const unsigned char *p; attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); - if (!attr) + if (attr == NULL || attr->type != V_ASN1_SEQUENCE) return NULL; p = attr->value.sequence->data; return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); @@ -274,7 +274,7 @@ static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si) const unsigned char *p; attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2); - if (attr == NULL) + if (attr == NULL || attr->type != V_ASN1_SEQUENCE) return NULL; p = attr->value.sequence->data; return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length); diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index af85ab0..7ea9cd7 100644 --- a/include/openssl/opensslv.h +++ b/include/openssl/opensslv.h @@ -39,8 +39,8 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x101011bfL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1zd 30 Sep 2025" +# define OPENSSL_VERSION_NUMBER 0x101011efL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1ze 27 Jan 2026" /*- * The macros below are to be used for shared library (.so, .dll, ...)