From 3e878d924f138f4a71c04628b57be75f1d45ef8e Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Wed, 18 Nov 2020 16:56:29 +1000 Subject: [PATCH] Remove pkey_downgrade from PKCS7 code Fixes #12991 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/13435) --- apps/smime.c | 15 -------- crypto/dsa/dsa_ameth.c | 18 ---------- crypto/ec/ec_ameth.c | 19 ---------- crypto/pkcs7/pk7_lib.c | 78 ++++++++++++++++++++++++++++++++++-------- crypto/rsa/rsa_ameth.c | 13 ------- 5 files changed, 64 insertions(+), 79 deletions(-) diff --git a/apps/smime.c b/apps/smime.c index b8451d8403..07abcbf8c9 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -478,14 +478,6 @@ int smime_main(int argc, char **argv) key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; - - /* - * TODO: Remove this when CMS has full support for provider-native - * EVP_PKEYs - */ - if (EVP_PKEY_get0(key) == NULL) - goto end; - } in = bio_open_default(infile, 'r', informat); @@ -579,13 +571,6 @@ int smime_main(int argc, char **argv) if (key == NULL) goto end; - /* - * TODO: Remove this when CMS has full support for provider-native - * EVP_PKEYs - */ - if (EVP_PKEY_get0(key) == NULL) - goto end; - if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) goto end; X509_free(signer); diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index ff4904952d..60ef9812e1 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -464,31 +464,13 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha256; return 1; default: return -2; - } - } static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index c137a72614..3e4bc8454a 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -472,23 +472,6 @@ static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) { /* For SM2, the only valid digest-alg is SM3 */ @@ -507,9 +490,7 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) default: return -2; - } - } static int ec_pkey_check(const EVP_PKEY *pkey) diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index 35a757062b..ad59417529 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include +#include #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/x509.h" /* for sk_X509_add1_cert() */ @@ -292,6 +293,39 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) return 1; } +static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, + int verify) +{ + if (verify == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + EVP_PKEY *pkey = si->pkey; + + PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +} + +static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify) +{ + if (verify == 0) { + X509_ALGOR *alg = NULL; + + PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg); + if (alg != NULL) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + } + return 1; +} + int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) { @@ -313,17 +347,6 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) goto err; - /* - * TODO(3.0) Adapt for provider-native keys - * Meanwhile, we downgrade the key. - * #legacy - */ - if (!evp_pkey_downgrade(pkey)) { - ERR_raise(ERR_LIB_PKCS7, - PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - } - /* lets keep the pkey around for a while */ EVP_PKEY_up_ref(pkey); p7i->pkey = pkey; @@ -333,7 +356,12 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), V_ASN1_NULL, NULL); - if (pkey->ameth && pkey->ameth->pkey_ctrl) { + if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA")) + return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0); + if (EVP_PKEY_is_a(pkey, "RSA")) + return pkcs7_rsa_sign_verify_setup(p7i, 0); + + if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) { ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); if (ret > 0) return 1; @@ -526,6 +554,18 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) return 1; } +static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt) +{ + X509_ALGOR *alg = NULL; + + if (decrypt == 0) { + PKCS7_RECIP_INFO_get0_alg(ri, &alg); + if (alg != NULL) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + } + return 1; +} + int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) { int ret; @@ -542,8 +582,18 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) return 0; pkey = X509_get0_pubkey(x509); + if (pkey == NULL) + return 0; - if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { + if (EVP_PKEY_is_a(pkey, "RSA-PSS")) + return -2; + if (EVP_PKEY_is_a(pkey, "RSA")) { + if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0) + goto err; + goto finished; + } + + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; @@ -559,7 +609,7 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE); goto err; } - +finished: X509_up_ref(x509); p7i->cert = x509; diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 3988024082..1e494f9044 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -492,19 +492,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) int min_saltlen; switch (op) { - - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); - break; - - case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - PKCS7_RECIP_INFO_get0_alg(arg2, &alg); - break; - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: if (pkey->pkey.rsa->pss != NULL) { if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md,