Skip to content

Commit dfba364

Browse files
committed
Fix a number of CVEs in OpenSSL
CVE-2025-68160 - Heap out-of-bounds write in BIO_f_linebuffer on short writes CVE-2025-69418 - Unauthenticated/unencrypted trailing bytes with low-level OCB function calls CVE-2025-69419 - Out of bounds write in PKCS12_get_friendlyname() UTF-8 conversion CVE-2025-69420 - Missing ASN1_TYPE validation in TS_RESP_verify_response() function CVE-2025-69421 - NULL Pointer Dereference in PKCS12_item_decrypt_d2i_ex function CVE-2026-22795 - Missing ASN1_TYPE validation in PKCS#12 parsing CVE-2026-22796 - ASN1_TYPE Type Confusion in the PKCS7_digest_from_attributes() function
1 parent f947e72 commit dfba364

File tree

9 files changed

+63
-15
lines changed

9 files changed

+63
-15
lines changed

crypto/openssl/apps/s_client.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2698,8 +2698,9 @@ int s_client_main(int argc, char **argv)
26982698
goto end;
26992699
}
27002700
atyp = ASN1_generate_nconf(genstr, cnf);
2701-
if (atyp == NULL) {
2701+
if (atyp == NULL || atyp->type != V_ASN1_SEQUENCE) {
27022702
NCONF_free(cnf);
2703+
ASN1_TYPE_free(atyp);
27032704
BIO_printf(bio_err, "ASN1_generate_nconf failed\n");
27042705
goto end;
27052706
}

crypto/openssl/crypto/asn1/a_strex.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,10 @@ static int do_buf(unsigned char *buf, int buflen,
203203
orflags = CHARTYPE_LAST_ESC_2253;
204204
if (type & BUF_TYPE_CONVUTF8) {
205205
unsigned char utfbuf[6];
206-
int utflen;
207-
utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c);
206+
int utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c);
207+
208+
if (utflen < 0)
209+
return -1; /* error happened with UTF8 */
208210
for (i = 0; i < utflen; i++) {
209211
/*
210212
* We don't need to worry about setting orflags correctly

crypto/openssl/crypto/bio/bf_lbuf.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,34 @@ static int linebuffer_write(BIO *b, const char *in, int inl)
191191
while (foundnl && inl > 0);
192192
/*
193193
* We've written as much as we can. The rest of the input buffer, if
194-
* any, is text that doesn't and with a NL and therefore needs to be
195-
* saved for the next trip.
194+
* any, is text that doesn't end with a NL and therefore we need to try
195+
* free up some space in our obuf so we can make forward progress.
196196
*/
197-
if (inl > 0) {
198-
memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
199-
ctx->obuf_len += inl;
200-
num += inl;
197+
while (inl > 0) {
198+
size_t avail = (size_t)ctx->obuf_size - (size_t)ctx->obuf_len;
199+
size_t to_copy;
200+
201+
if (avail == 0) {
202+
/* Flush buffered data to make room */
203+
i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
204+
if (i <= 0) {
205+
BIO_copy_next_retry(b);
206+
return num > 0 ? num : i;
207+
}
208+
if (i < ctx->obuf_len)
209+
memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
210+
ctx->obuf_len -= i;
211+
continue;
212+
}
213+
214+
to_copy = inl > (int)avail ? avail : (size_t)inl;
215+
memcpy(&(ctx->obuf[ctx->obuf_len]), in, to_copy);
216+
ctx->obuf_len += (int)to_copy;
217+
in += to_copy;
218+
inl -= (int)to_copy;
219+
num += (int)to_copy;
201220
}
221+
202222
return num;
203223
}
204224

crypto/openssl/crypto/modes/ocb128.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
342342

343343
if (num_blocks && all_num_blocks == (size_t)all_num_blocks
344344
&& ctx->stream != NULL) {
345-
size_t max_idx = 0, top = (size_t)all_num_blocks;
345+
size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0;
346346

347347
/*
348348
* See how many L_{i} entries we need to process data at hand
@@ -356,6 +356,9 @@ int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
356356
ctx->stream(in, out, num_blocks, ctx->keyenc,
357357
(size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
358358
(const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
359+
processed_bytes = num_blocks * 16;
360+
in += processed_bytes;
361+
out += processed_bytes;
359362
} else {
360363
/* Loop through all full blocks to be encrypted */
361364
for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {
@@ -434,7 +437,7 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
434437

435438
if (num_blocks && all_num_blocks == (size_t)all_num_blocks
436439
&& ctx->stream != NULL) {
437-
size_t max_idx = 0, top = (size_t)all_num_blocks;
440+
size_t max_idx = 0, top = (size_t)all_num_blocks, processed_bytes = 0;
438441

439442
/*
440443
* See how many L_{i} entries we need to process data at hand
@@ -448,6 +451,9 @@ int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
448451
ctx->stream(in, out, num_blocks, ctx->keydec,
449452
(size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,
450453
(const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);
454+
processed_bytes = num_blocks * 16;
455+
in += processed_bytes;
456+
out += processed_bytes;
451457
} else {
452458
OCB_BLOCK tmp;
453459

crypto/openssl/crypto/pkcs12/p12_decr.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
8888
void *ret;
8989
int outlen;
9090

91+
if (oct == NULL) {
92+
PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
93+
PKCS12_R_INVALID_NULL_ARGUMENT);
94+
return NULL;
95+
}
96+
9197
if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
9298
&out, &outlen, 0)) {
9399
PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,

crypto/openssl/crypto/pkcs12/p12_kiss.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
183183
ASN1_BMPSTRING *fname = NULL;
184184
ASN1_OCTET_STRING *lkid = NULL;
185185

186-
if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)))
186+
if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) {
187+
if (attrib->type != V_ASN1_BMPSTRING)
188+
return 0;
187189
fname = attrib->value.bmpstring;
190+
}
188191

189-
if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)))
192+
if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID))) {
193+
if (attrib->type != V_ASN1_OCTET_STRING)
194+
return 0;
190195
lkid = attrib->value.octet_string;
196+
}
191197

192198
switch (PKCS12_SAFEBAG_get_nid(bag)) {
193199
case NID_keyBag:

crypto/openssl/crypto/pkcs12/p12_utl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen)
207207
/* re-run the loop emitting UTF-8 string */
208208
for (asclen = 0, i = 0; i < unilen; ) {
209209
j = bmp_to_utf8(asctmp+asclen, uni+i, unilen-i);
210+
/* when UTF8_putc fails */
211+
if (j < 0) {
212+
OPENSSL_free(asctmp);
213+
return NULL;
214+
}
210215
if (j == 4) i += 4;
211216
else i += 2;
212217
asclen += j;

crypto/openssl/crypto/pkcs7/pk7_doit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,8 @@ ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
10921092
ASN1_TYPE *astype;
10931093
if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
10941094
return NULL;
1095+
if (astype->type != V_ASN1_OCTET_STRING)
1096+
return NULL;
10951097
return astype->value.octet_string;
10961098
}
10971099

crypto/openssl/crypto/ts/ts_rsp_verify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si)
262262
ASN1_TYPE *attr;
263263
const unsigned char *p;
264264
attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
265-
if (!attr)
265+
if (attr == NULL || attr->type != V_ASN1_SEQUENCE)
266266
return NULL;
267267
p = attr->value.sequence->data;
268268
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)
274274
const unsigned char *p;
275275

276276
attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2);
277-
if (attr == NULL)
277+
if (attr == NULL || attr->type != V_ASN1_SEQUENCE)
278278
return NULL;
279279
p = attr->value.sequence->data;
280280
return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length);

0 commit comments

Comments
 (0)