summaryrefslogtreecommitdiff
path: root/crypto/cms
diff options
context:
space:
mode:
authorMichael Baentsch <info@baentsch.ch>2022-02-18 14:10:04 +0100
committerTomas Mraz <tomas@openssl.org>2022-03-03 13:30:45 +0100
commitd15d561844d8989e50896724d89681ae7ba81a74 (patch)
tree1dcd82903c4fb4e85d36d3929a41dc8a77207c16 /crypto/cms
parent13ba91cb02479a91b0743d2bf5f5ec7ce42860d0 (diff)
downloadopenssl-new-d15d561844d8989e50896724d89681ae7ba81a74.tar.gz
enable CMS sign/verify for provider-implemented PKEYs
We need to handle signatures with and without digest algs and we generalize the ossl_cms_ecdsa_dsa_sign() function to other algorithms that are handled in the same way. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17733)
Diffstat (limited to 'crypto/cms')
-rw-r--r--crypto/cms/cms_ec.c23
-rw-r--r--crypto/cms/cms_local.h1
-rw-r--r--crypto/cms/cms_sd.c37
3 files changed, 34 insertions, 27 deletions
diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c
index fd6c5d7077..e8d942a812 100644
--- a/crypto/cms/cms_ec.c
+++ b/crypto/cms/cms_ec.c
@@ -388,26 +388,3 @@ int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt)
ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
return 0;
}
-
-/* ECDSA and DSA implementation is the same */
-int ossl_cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify)
-{
- assert(verify == 0 || verify == 1);
-
- if (!verify) {
- 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_get_id(pkey)))
- return -1;
- return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
- }
- return 1;
-}
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
index 15b4a29ce0..e9fb43715a 100644
--- a/crypto/cms/cms_local.h
+++ b/crypto/cms/cms_local.h
@@ -479,7 +479,6 @@ int ossl_cms_check_signing_certs(const CMS_SignerInfo *si,
int ossl_cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt);
int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt);
int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt);
-int ossl_cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify);
int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify);
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 8985be4fb4..d1e5ec8b4e 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -227,19 +227,50 @@ int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
return -1;
}
+/* Method to map any, incl. provider-implemented PKEY types to OIDs */
+/* ECDSA and DSA and all provider-delivered signatures implementation is the same */
+static int cms_generic_sign(CMS_SignerInfo *si, int verify)
+{
+ if (!ossl_assert(verify == 0 || verify == 1))
+ return -1;
+
+ if (!verify) {
+ int snid, hnid, pknid;
+ X509_ALGOR *alg1, *alg2;
+ EVP_PKEY *pkey = si->pkey;
+ pknid = EVP_PKEY_get_id(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 (pknid <= 0) { /* check whether a provider registered a NID */
+ const char *typename = EVP_PKEY_get0_type_name(pkey);
+ if (typename != NULL)
+ pknid = OBJ_txt2nid(typename);
+ }
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
+ return -1;
+ return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
+ }
+ return 1;
+}
+
static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
{
EVP_PKEY *pkey = si->pkey;
int i;
if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC"))
- return ossl_cms_ecdsa_dsa_sign(si, cmd);
+ return cms_generic_sign(si, cmd);
else if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS"))
return ossl_cms_rsa_sign(si, cmd);
- /* Something else? We'll give engines etc a chance to handle this */
+ /* Now give engines, providers, etc a chance to handle this */
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
- return 1;
+ return cms_generic_sign(si, cmd);
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
if (i == -2) {
ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);