From 9ab7fe483629704b09dc43c1998e0e489615390f Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 7 Oct 2020 14:45:22 +0100 Subject: [PATCH] Move CMS signing code out of the algorithms and into CMS There is a large amount of CMS sepcific code in the algorithms. This is in the wrong place and breaks layering. This code should be in the CMS layer. Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/13088) --- crypto/asn1/x_algor.c | 2 +- crypto/cms/build.info | 6 +- crypto/cms/cms_dh.c | 32 +++++------ crypto/cms/{cms_ecdh.c => cms_ec.c} | 67 +++++++++++++++------- crypto/cms/cms_env.c | 10 +++- crypto/cms/cms_local.h | 2 + crypto/cms/cms_rsa.c | 79 ++++++++++++++++++++++++-- crypto/cms/cms_sd.c | 9 +++ crypto/dsa/dsa_ameth.c | 16 ------ crypto/ec/ec_ameth.c | 16 ------ crypto/rsa/rsa_ameth.c | 86 +++-------------------------- include/crypto/asn1.h | 2 +- include/crypto/rsa.h | 4 ++ 13 files changed, 175 insertions(+), 156 deletions(-) rename crypto/cms/{cms_ecdh.c => cms_ec.c} (89%) diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c index c5453f9fd8..7e198a558c 100644 --- a/crypto/asn1/x_algor.c +++ b/crypto/asn1/x_algor.c @@ -184,7 +184,7 @@ int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) err: ASN1_STRING_free(stmp); X509_ALGOR_free(algtmp); - if (*palg) + if (*palg != NULL) return 1; return 0; } diff --git a/crypto/cms/build.info b/crypto/cms/build.info index 2f5b653382..c7579f78c1 100644 --- a/crypto/cms/build.info +++ b/crypto/cms/build.info @@ -7,6 +7,6 @@ SOURCE[../../libcrypto]= \ IF[{- !$disabled{dh} -}] SOURCE[../../libcrypto]=cms_dh.c ENDIF -IF[{- !$disabled{ed} -}] - SOURCE[../../libcrypto]=cms_ecdh.c -ENDIF \ No newline at end of file +IF[{- !$disabled{ec} || !$disabled{dsa}-}] + SOURCE[../../libcrypto]=cms_ec.c +ENDIF diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c index aca609653c..0d9eac50b3 100644 --- a/crypto/cms/cms_dh.c +++ b/crypto/cms/cms_dh.c @@ -7,7 +7,9 @@ * https://www.openssl.org/source/license.html */ +#include #include +#include #include #include #include "cms_local.h" @@ -32,9 +34,7 @@ static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, goto err; pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (pk == NULL) - goto err; - if (!EVP_PKEY_is_a(pk, "DHX")) + if (pk == NULL || !EVP_PKEY_is_a(pk, "DHX")) goto err; /* Get public key */ @@ -85,10 +85,8 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) goto err; } - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0 + || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) goto err; if (alg->parameter->type != V_ASN1_SEQUENCE) @@ -139,9 +137,7 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) static int dh_cms_decrypt(CMS_RecipientInfo *ri) { - EVP_PKEY_CTX *pctx; - - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (pctx == NULL) return 0; @@ -194,8 +190,9 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, NULL, NULL, NULL)) goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); + /* Is everything uninitialised? */ + X509_ALGOR_get0(&aoid, NULL, NULL, talg); if (aoid == OBJ_nid2obj(NID_undef)) { BIGNUM *bn_pub_key = NULL; ASN1_INTEGER *pubk; @@ -207,8 +204,8 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) BN_free(bn_pub_key); if (pubk == NULL) goto err; - /* Set the key */ + /* Set the key */ penclen = i2d_ASN1_INTEGER(pubk, &penc); ASN1_INTEGER_free(pubk); if (penclen <= 0) @@ -224,9 +221,7 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) /* See if custom parameters set */ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) + if (kdf_type <= 0 || !EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) goto err; if (kdf_type == EVP_PKEY_DH_KDF_NONE) { @@ -312,11 +307,14 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt) { + assert(decrypt == 0 || decrypt == 1); + if (decrypt == 1) return dh_cms_decrypt(ri); - else if (decrypt == 0) + + if (decrypt == 0) return dh_cms_encrypt(ri); CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); return 0; -} \ No newline at end of file +} diff --git a/crypto/cms/cms_ecdh.c b/crypto/cms/cms_ec.c similarity index 89% rename from crypto/cms/cms_ecdh.c rename to crypto/cms/cms_ec.c index b88be91211..394c8b4dc3 100644 --- a/crypto/cms/cms_ecdh.c +++ b/crypto/cms/cms_ec.c @@ -7,13 +7,14 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include #include "cms_local.h" #include "crypto/evp.h" - +#ifndef OPENSSL_NO_EC static EVP_PKEY *pkey_type2param(int ptype, const void *pval, OPENSSL_CTX *libctx, const char *propq) { @@ -30,7 +31,14 @@ static EVP_PKEY *pkey_type2param(int ptype, const void *pval, /* TODO(3.0): Need to be able to specify here that only params will do */ ctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, "DER", "EC", libctx, propq); + if (ctx == NULL) + goto err; + membio = BIO_new_mem_buf(pm, pmlen); + if (membio == NULL) { + OSSL_DECODER_CTX_free(ctx); + goto err; + } OSSL_DECODER_from_bio(ctx, membio); BIO_free(membio); OSSL_DECODER_CTX_free(ctx); @@ -38,15 +46,9 @@ static EVP_PKEY *pkey_type2param(int ptype, const void *pval, const ASN1_OBJECT *poid = pval; const char *groupname; - /* - * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID - */ - + /* type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */ pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq); - - if (pctx == NULL) - goto err; - if (EVP_PKEY_paramgen_init(pctx) <= 0) + if (pctx == NULL || EVP_PKEY_paramgen_init(pctx) <= 0) goto err; groupname = OBJ_nid2sn(OBJ_obj2nid(poid)); if (groupname == NULL @@ -54,10 +56,8 @@ static EVP_PKEY *pkey_type2param(int ptype, const void *pval, CMSerr(0, CMS_R_DECODE_ERROR); goto err; } - if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { - EVP_PKEY_free(pkey); - pkey = NULL; - } + if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) + goto err; } else { CMSerr(0, CMS_R_DECODE_ERROR); goto err; @@ -85,9 +85,11 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) goto err; + /* If absent parameters get group from main key */ if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { EVP_PKEY *pk; + pk = EVP_PKEY_CTX_get0_pkey(pctx); if (pk == NULL) goto err; @@ -127,6 +129,7 @@ static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) { int kdf_nid, kdfmd_nid, cofactor; const EVP_MD *kdf_md; + if (eckdf_nid == NID_undef) return 0; @@ -159,7 +162,6 @@ static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) { int rv = 0; - X509_ALGOR *alg, *kekalg = NULL; ASN1_OCTET_STRING *ukm; const unsigned char *p; @@ -233,7 +235,7 @@ static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, NULL, NULL, NULL)) return 0; - if (!alg || !pubkey) + if (alg == NULL || pubkey == NULL) return 0; if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { CMSerr(0, CMS_R_PEER_KEY_ERROR); @@ -350,7 +352,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); - if (!penclen) + if (penclen == 0) goto err; if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) @@ -362,7 +364,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) * of another AlgorithmIdentifier. */ penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) + if (penc == NULL || penclen == 0) goto err; wrap_str = ASN1_STRING_new(); if (wrap_str == NULL) @@ -381,11 +383,38 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt) { + assert(decrypt == 0 || decrypt == 1); + if (decrypt == 1) return ecdh_cms_decrypt(ri); - else if (decrypt == 0) + + if (decrypt == 0) return ecdh_cms_encrypt(ri); CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); return 0; -} \ No newline at end of file +} +#endif + +/* ECDSA and DSA implementation is the same */ +int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + EVP_PKEY *pkey = si->pkey; + + CMS_SignerInfo_get0_algs(si, NULL, 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; +} diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index 395e05ce55..84d9e5b948 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -116,11 +116,17 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) } else return 0; +#ifndef OPENSSL_NO_DH if (EVP_PKEY_is_a(pkey, "DHX")) return cms_dh_envelope(ri, cmd); - else if (EVP_PKEY_is_a(pkey, "EC")) + else +#endif +#ifndef OPENSSL_NO_EC + if (EVP_PKEY_is_a(pkey, "EC")) return cms_ecdh_envelope(ri, cmd); - else if (EVP_PKEY_is_a(pkey, "RSA")) + else +#endif + if (EVP_PKEY_is_a(pkey, "RSA")) return cms_rsa_envelope(ri, cmd); /* Something else? We'll give engines etc a chance to handle this */ diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index e162ea13ad..0b663a9e88 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -474,6 +474,8 @@ int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain); int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt); int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt); int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt); +int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify); +int cms_rsa_sign(CMS_SignerInfo *si, int verify); DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_DigestedData) diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c index 82d36d9b1f..88201d7b44 100644 --- a/crypto/cms/cms_rsa.c +++ b/crypto/cms/cms_rsa.c @@ -7,12 +7,13 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include "crypto/asn1.h" +#include "crypto/rsa.h" #include "cms_local.h" - static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) { RSA_OAEP_PARAMS *oaep; @@ -118,7 +119,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) return 0; - if (pkctx) { + if (pkctx != NULL) { if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; } @@ -145,6 +146,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) goto err; if (labellen > 0) { ASN1_OCTET_STRING *los; + oaep->pSourceFunc = X509_ALGOR_new(); if (oaep->pSourceFunc == NULL) goto err; @@ -172,11 +174,80 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt) { + assert(decrypt == 0 || decrypt == 1); + if (decrypt == 1) return rsa_cms_decrypt(ri); - else if (decrypt == 0) + + if (decrypt == 0) return rsa_cms_encrypt(ri); CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); return 0; -} \ No newline at end of file +} + +static int rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + ASN1_STRING *os = NULL; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx != NULL) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + os = ossl_rsa_ctx_to_pss_string(pkctx); + if (os == NULL) + return 0; + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); + return 1; +} + +static int rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx); + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == EVP_PKEY_RSA_PSS) + return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL); + /* Only PSS allowed for PSS keys */ + if (EVP_PKEY_is_a(pkey, "RSA-PSS")) { + RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if (nid == NID_rsaEncryption) + return 1; + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} + +int cms_rsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 1) + return rsa_cms_verify(si); + + if (verify == 0) + return rsa_cms_sign(si); + + CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index 1338211072..377fac5917 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -233,6 +233,15 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) EVP_PKEY *pkey = si->pkey; int i; +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) + if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC")) + return cms_ecdsa_dsa_sign(si, cmd); + else +#endif + if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS")) + return cms_rsa_sign(si, cmd); + + /* Something else? We'll give engines etc a chance to handle this */ if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return 1; i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 7619c05b5e..d9b4a3fae7 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -482,22 +482,6 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) } return 1; #ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, 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_CMS_RI_TYPE: *(int *)arg2 = CMS_RECIPINFO_NONE; return 1; diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index 25644577cd..864402ab18 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -490,22 +490,6 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) } return 1; #ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, 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_CMS_RI_TYPE: *(int *)arg2 = CMS_RECIPINFO_AGREE; return 1; diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 562f307bcb..fc76a0e103 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -26,11 +26,6 @@ #include "crypto/rsa.h" #include "rsa_local.h" -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si); -static int rsa_cms_verify(CMS_SignerInfo *si); -#endif - static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); static int rsa_sync_to_pss_params_30(RSA *rsa); @@ -511,13 +506,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) PKCS7_RECIP_INFO_get0_alg(arg2, &alg); break; #ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) - return rsa_cms_sign(arg2); - else if (arg1 == 1) - return rsa_cms_verify(arg2); - break; - case ASN1_PKEY_CTRL_CMS_RI_TYPE: if (pkey_is_pss(pkey)) return -2; @@ -560,7 +548,6 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); - RSA *rsa = EVP_PKEY_get0_RSA(pk); int saltlen; if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) @@ -572,7 +559,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2 || saltlen == -3) { - saltlen = RSA_size(rsa) - EVP_MD_size(sigmd) - 2; + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if ((EVP_PKEY_bits(pk) & 0x7) == 1) saltlen--; if (saltlen < 0) @@ -610,7 +597,7 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, return NULL; } -static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) +ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) { RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); ASN1_STRING *os; @@ -629,8 +616,8 @@ static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) * passed to pkctx instead. */ -static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, - const X509_ALGOR *sigalg, EVP_PKEY *pkey) +int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + const X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; @@ -639,14 +626,14 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + RSAerr(0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg); if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); + RSAerr(0, RSA_R_INVALID_PSS_PARAMETERS); goto err; } @@ -659,7 +646,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); + RSAerr(0, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } @@ -780,33 +767,6 @@ static int rsa_sync_to_pss_params_30(RSA *rsa) return 1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_verify(CMS_SignerInfo *si) -{ - int nid, nid2; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - nid = OBJ_obj2nid(alg->algorithm); - if (nid == EVP_PKEY_RSA_PSS) - return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); - /* Only PSS allowed for PSS keys */ - if (pkey_ctx_is_pss(pkctx)) { - RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return 0; - } - if (nid == NID_rsaEncryption) - return 1; - /* Workaround for some implementation that use a signature OID */ - if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { - if (nid2 == NID_rsaEncryption) - return 1; - } - return 0; -} -#endif - /* * Customised RSA item verification routine. This is called when a signature * is encountered requiring special handling. We currently only handle PSS. @@ -821,41 +781,13 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } - if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + if (ossl_rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { /* Carry on */ return 2; } return -1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si) -{ - int pad_mode = RSA_PKCS1_PADDING; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - ASN1_STRING *os = NULL; - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* We don't support it */ - if (pad_mode != RSA_PKCS1_PSS_PADDING) - return 0; - os = rsa_ctx_to_pss_string(pkctx); - if (!os) - return 0; - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); - return 1; -} -#endif - static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) @@ -869,7 +801,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { ASN1_STRING *os1 = NULL; - os1 = rsa_ctx_to_pss_string(pkctx); + os1 = ossl_rsa_ctx_to_pss_string(pkctx); if (!os1) return 0; /* Duplicate parameters if we have to */ diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index 72e105276f..08018e4cf1 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -137,4 +137,4 @@ int asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, int x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md); const EVP_MD *x509_algor_get_md(X509_ALGOR *alg); X509_ALGOR *x509_algor_mgf1_decode(X509_ALGOR *alg); -int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md); \ No newline at end of file +int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md); diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 85682aa55d..7ec745766f 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -93,6 +93,10 @@ extern const char *ossl_rsa_mp_factor_names[]; extern const char *ossl_rsa_mp_exp_names[]; extern const char *ossl_rsa_mp_coeff_names[]; +ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx); +int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + const X509_ALGOR *sigalg, EVP_PKEY *pkey); + # if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]); void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst); -- 2.34.1