diff options
| author | tb <> | 2026-04-07 13:15:29 +0000 |
|---|---|---|
| committer | tb <> | 2026-04-07 13:15:29 +0000 |
| commit | e783182e57d664df5859c6b6cbd65563cdc26528 (patch) | |
| tree | 74e40050fa87c5fc08859ab1090ca3949b48d15e /src | |
| parent | bd035cb5927e4f4359c2ecd94226a2536b0d7773 (diff) | |
| download | openbsd-e783182e57d664df5859c6b6cbd65563cdc26528.tar.gz openbsd-e783182e57d664df5859c6b6cbd65563cdc26528.tar.bz2 openbsd-e783182e57d664df5859c6b6cbd65563cdc26528.zip | |
Fix NULL deref for malformed OAEP parameters in CMS decryption
This converts rsa_cms_decrypt() to use X509_ALGOR_get0() and fixes a
NULL deref when a parameter is (invalidly) omitted similar to the fix
in ec/ec_ameth.c r1.66 from a couple years back. There is currently
an XXX annotating a hairy leak due to trying to be smart and stealing
the parameters from the oaep object. Instead, just make a copy of the
label string and free it in the exit path.
The diff adds an error for labellen == 0 since that is an invalid
encoding of pSpecifiedEmpty (see RFC 8017) -- per the DER the default
must be omitted. This way we avoid a malloc(0) implementation-defined
behavior.
This minor issue was assigned CVE-2026-28390 by OpenSSL and was reported
by too many to list. The fix is my own. It is similar to OpenSSL's fix
only because I rewiewed theirs and suggested an improvement or two.
This is the last of the "security fixes" in today's OpenSSL release that
"affect" LibreSSL. All the other bugs were already fixed a few years back
or we didn't have the code/bugs in the first place.
ok beck jsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/rsa/rsa_ameth.c | 29 | ||||
| -rw-r--r-- | src/lib/libcrypto/rsa/rsa_pmeth.c | 4 |
2 files changed, 22 insertions, 11 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c index 00fa6afb3d..2aea9c4848 100644 --- a/src/lib/libcrypto/rsa/rsa_ameth.c +++ b/src/lib/libcrypto/rsa/rsa_ameth.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: rsa_ameth.c,v 1.63 2025/05/10 05:54:38 tb Exp $ */ | 1 | /* $OpenBSD: rsa_ameth.c,v 1.64 2026/04/07 13:15:29 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -59,6 +59,7 @@ | |||
| 59 | #include <stdint.h> | 59 | #include <stdint.h> |
| 60 | #include <stdio.h> | 60 | #include <stdio.h> |
| 61 | #include <stdlib.h> | 61 | #include <stdlib.h> |
| 62 | #include <string.h> | ||
| 62 | 63 | ||
| 63 | #include <openssl/opensslconf.h> | 64 | #include <openssl/opensslconf.h> |
| 64 | 65 | ||
| @@ -1148,23 +1149,29 @@ rsa_cms_decrypt(CMS_RecipientInfo *ri) | |||
| 1148 | goto err; | 1149 | goto err; |
| 1149 | 1150 | ||
| 1150 | if (oaep->pSourceFunc != NULL) { | 1151 | if (oaep->pSourceFunc != NULL) { |
| 1151 | X509_ALGOR *plab = oaep->pSourceFunc; | 1152 | const ASN1_OBJECT *aobj; |
| 1153 | const void *parameter; | ||
| 1154 | int parameter_type; | ||
| 1152 | 1155 | ||
| 1153 | if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { | 1156 | X509_ALGOR_get0(&aobj, ¶meter_type, ¶meter, |
| 1157 | oaep->pSourceFunc); | ||
| 1158 | if (OBJ_obj2nid(aobj) != NID_pSpecified) { | ||
| 1154 | RSAerror(RSA_R_UNSUPPORTED_LABEL_SOURCE); | 1159 | RSAerror(RSA_R_UNSUPPORTED_LABEL_SOURCE); |
| 1155 | goto err; | 1160 | goto err; |
| 1156 | } | 1161 | } |
| 1157 | if (plab->parameter->type != V_ASN1_OCTET_STRING) { | 1162 | if (parameter_type != V_ASN1_OCTET_STRING) { |
| 1158 | RSAerror(RSA_R_INVALID_LABEL); | 1163 | RSAerror(RSA_R_INVALID_LABEL); |
| 1159 | goto err; | 1164 | goto err; |
| 1160 | } | 1165 | } |
| 1161 | 1166 | ||
| 1162 | label = plab->parameter->value.octet_string->data; | 1167 | if ((labellen = ASN1_STRING_length(parameter)) == 0) { |
| 1168 | RSAerror(RSA_R_INVALID_LABEL); | ||
| 1169 | goto err; | ||
| 1170 | } | ||
| 1163 | 1171 | ||
| 1164 | /* Stop label being freed when OAEP parameters are freed */ | 1172 | if ((label = calloc(1, labellen)) == NULL) |
| 1165 | /* XXX - this leaks label on error... */ | 1173 | goto err; |
| 1166 | plab->parameter->value.octet_string->data = NULL; | 1174 | memcpy(label, ASN1_STRING_get0_data(parameter), labellen); |
| 1167 | labellen = plab->parameter->value.octet_string->length; | ||
| 1168 | } | 1175 | } |
| 1169 | 1176 | ||
| 1170 | if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) | 1177 | if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) |
| @@ -1175,11 +1182,15 @@ rsa_cms_decrypt(CMS_RecipientInfo *ri) | |||
| 1175 | goto err; | 1182 | goto err; |
| 1176 | if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) | 1183 | if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) |
| 1177 | goto err; | 1184 | goto err; |
| 1185 | label = NULL; | ||
| 1186 | labellen = 0; | ||
| 1178 | 1187 | ||
| 1179 | rv = 1; | 1188 | rv = 1; |
| 1180 | 1189 | ||
| 1181 | err: | 1190 | err: |
| 1182 | RSA_OAEP_PARAMS_free(oaep); | 1191 | RSA_OAEP_PARAMS_free(oaep); |
| 1192 | freezero(label, labellen); | ||
| 1193 | |||
| 1183 | return rv; | 1194 | return rv; |
| 1184 | } | 1195 | } |
| 1185 | 1196 | ||
diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c index 518b077dbc..b1b8e8c675 100644 --- a/src/lib/libcrypto/rsa/rsa_pmeth.c +++ b/src/lib/libcrypto/rsa/rsa_pmeth.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: rsa_pmeth.c,v 1.44 2025/05/10 05:54:38 tb Exp $ */ | 1 | /* $OpenBSD: rsa_pmeth.c,v 1.45 2026/04/07 13:15:29 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -583,7 +583,7 @@ pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | |||
| 583 | RSAerror(RSA_R_INVALID_PADDING_MODE); | 583 | RSAerror(RSA_R_INVALID_PADDING_MODE); |
| 584 | return -2; | 584 | return -2; |
| 585 | } | 585 | } |
| 586 | free(rctx->oaep_label); | 586 | freezero(rctx->oaep_label, rctx->oaep_labellen); |
| 587 | if (p2 != NULL && p1 > 0) { | 587 | if (p2 != NULL && p1 > 0) { |
| 588 | rctx->oaep_label = p2; | 588 | rctx->oaep_label = p2; |
| 589 | rctx->oaep_labellen = p1; | 589 | rctx->oaep_labellen = p1; |
