From 01ca0bbbe65215f6ae72bba7d63ea67fb53c4f9a Mon Sep 17 00:00:00 2001 From: Ken Zalewski Date: Sat, 13 Jul 2024 11:00:49 -0400 Subject: [PATCH] Patch to openssl-1.1.1x. This version addresses two vulnerabilities: CVE-2023-5678 and CVE-2024-0727 --- crypto/dh/dh_check.c | 13 +++++++++++++ crypto/dh/dh_err.c | 2 ++ crypto/dh/dh_key.c | 10 ++++++++++ crypto/err/openssl.txt | 2 ++ crypto/pkcs12/p12_add.c | 18 ++++++++++++++++++ crypto/pkcs12/p12_mutl.c | 5 +++++ crypto/pkcs12/p12_npas.c | 5 +++-- crypto/pkcs12/pk12err.c | 2 ++ crypto/pkcs7/pk7_mime.c | 9 +++++++-- include/openssl/dh.h | 6 ++++-- include/openssl/dherr.h | 2 ++ include/openssl/opensslv.h | 4 ++-- include/openssl/pkcs12err.h | 1 + 13 files changed, 71 insertions(+), 8 deletions(-) diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index ae1b03b..40dfc57 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -198,6 +198,19 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) BN_CTX *ctx = NULL; *ret = 0; + + /* Don't do any checks at all with an excessively large modulus */ + if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { + DHerr(DH_F_DH_CHECK_PUB_KEY, DH_R_MODULUS_TOO_LARGE); + *ret = DH_CHECK_P_NOT_PRIME | DH_CHECK_PUBKEY_INVALID; + return 0; + } + + if (dh->q != NULL && BN_ucmp(dh->p, dh->q) < 0) { + *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; + return 1; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index 92800d3..048ba66 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -21,6 +21,7 @@ static const ERR_STRING_DATA DH_str_functs[] = { {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK, 0), "DH_check"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY, 0), "DH_check_pub_key"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_DECRYPT, 0), "dh_cms_decrypt"}, {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_PEERKEY, 0), "dh_cms_set_peerkey"}, @@ -82,6 +83,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR), "unable to check generator"}, diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 117f2fa..9f5e6f6 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -114,6 +114,11 @@ static int generate_key(DH *dh) return 0; } + if (dh->q != NULL && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_Q_TOO_LARGE); + return 0; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -207,6 +212,11 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; } + if (dh->q != NULL && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_Q_TOO_LARGE); + goto err; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index c0a3cd7..ec3823e 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -969,6 +969,7 @@ PKCS12_F_PKCS12_SETUP_MAC:122:PKCS12_setup_mac PKCS12_F_PKCS12_SET_MAC:123:PKCS12_set_mac PKCS12_F_PKCS12_UNPACK_AUTHSAFES:130:PKCS12_unpack_authsafes PKCS12_F_PKCS12_UNPACK_P7DATA:131:PKCS12_unpack_p7data +PKCS12_F_PKCS12_UNPACK_P7ENCDATA:134:PKCS12_unpack_p7encdata PKCS12_F_PKCS12_VERIFY_MAC:126:PKCS12_verify_mac PKCS12_F_PKCS8_ENCRYPT:125:PKCS8_encrypt PKCS12_F_PKCS8_SET0_PBE:132:PKCS8_set0_pbe @@ -2106,6 +2107,7 @@ DH_R_NO_PARAMETERS_SET:107:no parameters set DH_R_NO_PRIVATE_VALUE:100:no private value DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error +DH_R_Q_TOO_LARGE:130:q too large DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator DSA_R_BAD_Q_VALUE:102:bad q value diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c index af184c8..6549691 100644 --- a/crypto/pkcs12/p12_add.c +++ b/crypto/pkcs12/p12_add.c @@ -76,6 +76,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } + + if (p7->d.data == NULL) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, PKCS12_R_DECODE_ERROR); + return NULL; + } + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); } @@ -132,6 +138,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, { if (!PKCS7_type_is_encrypted(p7)) return NULL; + + if (p7->d.encrypted == NULL) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_P7ENCDATA, PKCS12_R_DECODE_ERROR); + return NULL; + } + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen, @@ -159,6 +171,12 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } + + if (p12->authsafes->d.data == NULL) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, PKCS12_R_DECODE_ERROR); + return NULL; + } + return ASN1_item_unpack(p12->authsafes->d.data, ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); } diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index 3658003..766c9c1 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -93,6 +93,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, return 0; } + if (p12->authsafes->d.data == NULL) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_DECODE_ERROR); + return 0; + } + salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (!p12->mac->iter) diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c index 0334289..1303376 100644 --- a/crypto/pkcs12/p12_npas.c +++ b/crypto/pkcs12/p12_npas.c @@ -78,8 +78,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); - if (!alg_get(p7->d.encrypted->enc_data->algorithm, - &pbe_nid, &pbe_iter, &pbe_saltlen)) + if (p7->d.encrypted == NULL + || !alg_get(p7->d.encrypted->enc_data->algorithm, + &pbe_nid, &pbe_iter, &pbe_saltlen)) goto err; } else { continue; diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index 38ce519..3eb7f2f 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -58,6 +58,8 @@ static const ERR_STRING_DATA PKCS12_str_functs[] = { "PKCS12_unpack_authsafes"}, {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_P7DATA, 0), "PKCS12_unpack_p7data"}, + {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_P7ENCDATA, 0), + "PKCS12_unpack_p7encdata"}, {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_VERIFY_MAC, 0), "PKCS12_verify_mac"}, {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS8_ENCRYPT, 0), "PKCS8_encrypt"}, diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c index 19e6868..635af10 100644 --- a/crypto/pkcs7/pk7_mime.c +++ b/crypto/pkcs7/pk7_mime.c @@ -30,10 +30,15 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) { STACK_OF(X509_ALGOR) *mdalgs; int ctype_nid = OBJ_obj2nid(p7->type); - if (ctype_nid == NID_pkcs7_signed) + if (ctype_nid == NID_pkcs7_signed) { + if (p7->d.sign == NULL) { + return 0; + } mdalgs = p7->d.sign->md_algs; - else + } + else { mdalgs = NULL; + } flags ^= SMIME_OLDMIME; diff --git a/include/openssl/dh.h b/include/openssl/dh.h index 6c6ff36..d2a9c0d 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -71,14 +71,16 @@ DECLARE_ASN1_ITEM(DHparams) /* #define DH_GENERATOR_3 3 */ # define DH_GENERATOR_5 5 -/* DH_check error codes */ +/* DH_check error codes, some of them shared with DH_check_pub_key */ # define DH_CHECK_P_NOT_PRIME 0x01 # define DH_CHECK_P_NOT_SAFE_PRIME 0x02 # define DH_UNABLE_TO_CHECK_GENERATOR 0x04 # define DH_NOT_SUITABLE_GENERATOR 0x08 # define DH_CHECK_Q_NOT_PRIME 0x10 -# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */ # define DH_CHECK_INVALID_J_VALUE 0x40 +# define DH_MODULUS_TOO_SMALL 0x80 +# define DH_MODULUS_TOO_LARGE 0x100 /* +DH_check_pub_key */ /* DH_check_pub_key error codes */ # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h index 528c819..a98bb1e 100644 --- a/include/openssl/dherr.h +++ b/include/openssl/dherr.h @@ -33,6 +33,7 @@ int ERR_load_DH_strings(void); # define DH_F_DH_CHECK 126 # define DH_F_DH_CHECK_EX 121 # define DH_F_DH_CHECK_PARAMS_EX 122 +# define DH_F_DH_CHECK_PUB_KEY 127 # define DH_F_DH_CHECK_PUB_KEY_EX 123 # define DH_F_DH_CMS_DECRYPT 114 # define DH_F_DH_CMS_SET_PEERKEY 115 @@ -82,6 +83,7 @@ int ERR_load_DH_strings(void); # define DH_R_NO_PRIVATE_VALUE 100 # define DH_R_PARAMETER_ENCODING_ERROR 105 # define DH_R_PEER_KEY_ERROR 111 +# define DH_R_Q_TOO_LARGE 130 # define DH_R_SHARED_INFO_ERROR 113 # define DH_R_UNABLE_TO_CHECK_GENERATOR 121 diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index 5667d47..c16eafd 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 0x1010117fL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1w 11 Sep 2023" +# define OPENSSL_VERSION_NUMBER 0x1010118fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1x 25 Jan 2024" /*- * The macros below are to be used for shared library (.so, .dll, ...) diff --git a/include/openssl/pkcs12err.h b/include/openssl/pkcs12err.h index eff5eb2..0d2f15a 100644 --- a/include/openssl/pkcs12err.h +++ b/include/openssl/pkcs12err.h @@ -49,6 +49,7 @@ int ERR_load_PKCS12_strings(void); # define PKCS12_F_PKCS12_SET_MAC 123 # define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 # define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_UNPACK_P7ENCDATA 134 # define PKCS12_F_PKCS12_VERIFY_MAC 126 # define PKCS12_F_PKCS8_ENCRYPT 125 # define PKCS12_F_PKCS8_SET0_PBE 132