From 6cc1dfca88c565ddacd9ea9aa8261ef9c0c37335 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 30 Jul 2020 10:14:27 +0200 Subject: [PATCH] PROV: Fix DSA and DH private key serializers If those private key serializer were given a key structure with just the public key material, they crashed, because they tried to de-reference NULL. This adds better checking. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/12679) --- crypto/err/openssl.txt | 2 ++ .../common/include/prov/providercommonerr.h | 2 ++ providers/common/provider_err.c | 2 ++ .../serializers/serializer_dh.c | 18 ++++++++++++++---- .../serializers/serializer_dsa.c | 18 ++++++++++++++---- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index b42abcc137..7431248d8f 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2916,6 +2916,8 @@ PROV_R_MISSING_SESSION_ID:133:missing session id PROV_R_MISSING_TYPE:134:missing type PROV_R_MISSING_XCGHASH:135:missing xcghash PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure +PROV_R_NOT_A_PRIVATE_KEY:221:not a private key +PROV_R_NOT_A_PUBLIC_KEY:220:not a public key PROV_R_NOT_INSTANTIATED:193:not instantiated PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 3f3c39ba52..4c356fc5c6 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -128,6 +128,8 @@ int ERR_load_PROV_strings(void); # define PROV_R_MISSING_TYPE 134 # define PROV_R_MISSING_XCGHASH 135 # define PROV_R_MODULE_INTEGRITY_FAILURE 214 +# define PROV_R_NOT_A_PRIVATE_KEY 221 +# define PROV_R_NOT_A_PUBLIC_KEY 220 # define PROV_R_NOT_INSTANTIATED 193 # define PROV_R_NOT_SUPPORTED 136 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index ad7ae57157..3ea41f3c25 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -133,6 +133,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_XCGHASH), "missing xcghash"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MODULE_INTEGRITY_FAILURE), "module integrity failure"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH), diff --git a/providers/implementations/serializers/serializer_dh.c b/providers/implementations/serializers/serializer_dh.c index d63c8402f9..d1b1d27cf6 100644 --- a/providers/implementations/serializers/serializer_dh.c +++ b/providers/implementations/serializers/serializer_dh.c @@ -119,10 +119,15 @@ int ossl_prov_prepare_dh_params(const void *dh, int nid, int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder) { - ASN1_INTEGER *pub_key = BN_to_ASN1_INTEGER(DH_get0_pub_key(dh), NULL); + const BIGNUM *bn = NULL; + ASN1_INTEGER *pub_key = NULL; int ret; - if (pub_key == NULL) { + if ((bn = DH_get0_pub_key(dh)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); return 0; } @@ -135,10 +140,15 @@ int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder) int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder) { - ASN1_INTEGER *priv_key = BN_to_ASN1_INTEGER(DH_get0_priv_key(dh), NULL); + const BIGNUM *bn = NULL; + ASN1_INTEGER *priv_key = NULL; int ret; - if (priv_key == NULL) { + if ((bn = DH_get0_priv_key(dh)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); return 0; } diff --git a/providers/implementations/serializers/serializer_dsa.c b/providers/implementations/serializers/serializer_dsa.c index 4389bded99..1f986b62d5 100644 --- a/providers/implementations/serializers/serializer_dsa.c +++ b/providers/implementations/serializers/serializer_dsa.c @@ -132,10 +132,15 @@ int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid, int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder) { - ASN1_INTEGER *pub_key = BN_to_ASN1_INTEGER(DSA_get0_pub_key(dsa), NULL); + const BIGNUM *bn = NULL; + ASN1_INTEGER *pub_key = NULL; int ret; - if (pub_key == NULL) { + if ((bn = DSA_get0_pub_key(dsa)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); return 0; } @@ -148,10 +153,15 @@ int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder) int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder) { - ASN1_INTEGER *priv_key = BN_to_ASN1_INTEGER(DSA_get0_priv_key(dsa), NULL); + const BIGNUM *bn = NULL; + ASN1_INTEGER *priv_key = NULL; int ret; - if (priv_key == NULL) { + if ((bn = DSA_get0_priv_key(dsa)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); return 0; } -- 2.39.2