summaryrefslogtreecommitdiffstats
path: root/crypto/cms
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2013-06-19 18:17:14 +0100
committerDr. Stephen Henson <steve@openssl.org>2013-06-21 21:33:00 +0100
commite365352d6a6368039392fed14a328f8c0bf955c3 (patch)
treeaf89ba59ce03204b352c2df246fb07b800bea9e4 /crypto/cms
parent211a14f6279f127f7a5a59948819bd939131b0b6 (diff)
CMS public key parameter support.
Add support for customisation of CMS handling of signed and enveloped data from custom public key parameters. This will provide support for RSA-PSS and RSA-OAEP but could also be applied to other algorithms.
Diffstat (limited to 'crypto/cms')
-rw-r--r--crypto/cms/cms.h6
-rw-r--r--crypto/cms/cms_asn1.c4
-rw-r--r--crypto/cms/cms_env.c100
-rw-r--r--crypto/cms/cms_err.c2
-rw-r--r--crypto/cms/cms_lcl.h5
-rw-r--r--crypto/cms/cms_sd.c170
6 files changed, 212 insertions, 75 deletions
diff --git a/crypto/cms/cms.h b/crypto/cms/cms.h
index 198688e53a..1624b79ebc 100644
--- a/crypto/cms/cms.h
+++ b/crypto/cms/cms.h
@@ -112,6 +112,7 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
#define CMS_REUSE_DIGEST 0x8000
#define CMS_USE_KEYID 0x10000
#define CMS_DEBUG_DECRYPT 0x20000
+#define CMS_KEY_PARAM 0x40000
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
@@ -190,6 +191,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
X509 *recip, unsigned int flags);
@@ -256,6 +258,8 @@ int CMS_SignedData_init(CMS_ContentInfo *cms);
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
unsigned int flags);
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
@@ -374,6 +378,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_ENVELOPEDDATA_CREATE 124
#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125
#define CMS_F_CMS_ENVELOPED_DATA_INIT 126
+#define CMS_F_CMS_ENV_ASN1_CTRL 171
#define CMS_F_CMS_FINAL 127
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128
#define CMS_F_CMS_GET0_CONTENT 129
@@ -399,6 +404,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144
#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145
+#define CMS_F_CMS_SD_ASN1_CTRL 170
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146
#define CMS_F_CMS_SET_DETACHED 147
#define CMS_F_CMS_SIGN 148
diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c
index cfe67fb6c1..6a692cdb1d 100644
--- a/crypto/cms/cms_asn1.c
+++ b/crypto/cms/cms_asn1.c
@@ -97,6 +97,8 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
EVP_PKEY_free(si->pkey);
if (si->signer)
X509_free(si->signer);
+ if (si->pctx)
+ EVP_MD_CTX_cleanup(&si->mctx);
}
return 1;
}
@@ -227,6 +229,8 @@ static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
EVP_PKEY_free(ktri->pkey);
if (ktri->recip)
X509_free(ktri->recip);
+ if (ktri->pctx)
+ EVP_PKEY_CTX_free(ktri->pctx);
}
else if (ri->type == CMS_RECIPINFO_KEK)
{
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index 632dbae760..c26dd59738 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -103,6 +103,27 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
return cms_get0_enveloped(cms);
}
+static int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
+ {
+ EVP_PKEY *pkey = ri->d.ktri->pkey;
+ int i;
+ if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+ return 1;
+ i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
+ if (i == -2)
+ {
+ CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
+ CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+ }
+ if (i <= 0)
+ {
+ CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+ return 0;
+ }
+ return 1;
+ }
+
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
{
CMS_EnvelopedData *env;
@@ -117,6 +138,13 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
return ri->type;
}
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
+ {
+ if (ri->type == CMS_RECIPINFO_TRANS)
+ return ri->d.ktri->pctx;
+ return NULL;
+ }
+
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
{
CMS_ContentInfo *cms;
@@ -151,7 +179,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
CMS_KeyTransRecipientInfo *ktri;
CMS_EnvelopedData *env;
EVP_PKEY *pk = NULL;
- int i, type;
+ int type;
env = cms_get0_enveloped(cms);
if (!env)
goto err;
@@ -200,23 +228,16 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
goto err;
- if (pk->ameth && pk->ameth->pkey_ctrl)
+ if (flags & CMS_KEY_PARAM)
{
- i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
- 0, ri);
- if (i == -2)
- {
- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+ if (!ktri->pctx)
+ return 0;
+ if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
goto err;
- }
- if (i <= 0)
- {
- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
- CMS_R_CTRL_FAILURE);
- goto err;
- }
}
+ else if (!cms_env_asn1_ctrl(ri, 0))
+ goto err;
if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
goto merr;
@@ -302,7 +323,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
{
CMS_KeyTransRecipientInfo *ktri;
CMS_EncryptedContentInfo *ec;
- EVP_PKEY_CTX *pctx = NULL;
+ EVP_PKEY_CTX *pctx;
unsigned char *ek = NULL;
size_t eklen;
@@ -317,12 +338,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
ktri = ri->d.ktri;
ec = cms->d.envelopedData->encryptedContentInfo;
- pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
- if (!pctx)
- return 0;
+ pctx = ktri->pctx;
- if (EVP_PKEY_encrypt_init(pctx) <= 0)
- goto err;
+ if (pctx)
+ {
+ if (!cms_env_asn1_ctrl(ri, 0))
+ goto err;
+ }
+ else
+ {
+ pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+ if (!pctx)
+ return 0;
+
+ if (EVP_PKEY_encrypt_init(pctx) <= 0)
+ goto err;
+ }
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
@@ -353,7 +384,10 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
err:
if (pctx)
+ {
EVP_PKEY_CTX_free(pctx);
+ ktri->pctx = NULL;
+ }
if (ek)
OPENSSL_free(ek);
return ret;
@@ -366,7 +400,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
CMS_RecipientInfo *ri)
{
CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
- EVP_PKEY_CTX *pctx = NULL;
+ EVP_PKEY *pkey = ktri->pkey;
unsigned char *ek = NULL;
size_t eklen;
int ret = 0;
@@ -380,21 +414,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
return 0;
}
- pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
- if (!pctx)
+ ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!ktri->pctx)
return 0;
- if (EVP_PKEY_decrypt_init(pctx) <= 0)
+ if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
+ goto err;
+
+ if (!cms_env_asn1_ctrl(ri, 1))
goto err;
- if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+ if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
{
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
goto err;
}
- if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+ if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
ktri->encryptedKey->data,
ktri->encryptedKey->length) <= 0)
goto err;
@@ -408,7 +445,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
goto err;
}
- if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+ if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
ktri->encryptedKey->data,
ktri->encryptedKey->length) <= 0)
{
@@ -428,8 +465,11 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
ec->keylen = eklen;
err:
- if (pctx)
- EVP_PKEY_CTX_free(pctx);
+ if (ktri->pctx)
+ {
+ EVP_PKEY_CTX_free(ktri->pctx);
+ ktri->pctx = NULL;
+ }
if (!ret && ek)
OPENSSL_free(ek);
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index cc58ea5f96..35aca59335 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -103,6 +103,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), "cms_EnvelopedData_init_bio"},
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
+{ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "CMS_ENV_ASN1_CTRL"},
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
@@ -128,6 +129,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), "CMS_RecipientInfo_set0_key"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), "CMS_RecipientInfo_set0_password"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), "CMS_RecipientInfo_set0_pkey"},
+{ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "CMS_SD_ASN1_CTRL"},
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
{ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
{ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
index d5a70b4665..b62dc72f2f 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -140,6 +140,9 @@ struct CMS_SignerInfo_st
/* Signing certificate and key */
X509 *signer;
EVP_PKEY *pkey;
+ /* Digest and public key context for alternative parameters */
+ EVP_MD_CTX mctx;
+ EVP_PKEY_CTX *pctx;
};
struct CMS_SignerIdentifier_st
@@ -202,6 +205,8 @@ struct CMS_KeyTransRecipientInfo_st
/* Recipient Key and cert */
X509 *recip;
EVP_PKEY *pkey;
+ /* Public key context for this operation */
+ EVP_PKEY_CTX *pctx;
};
struct CMS_KeyAgreeRecipientInfo_st
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index f448a35066..b7dbf52ab1 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -297,6 +297,27 @@ int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
return -1;
}
+static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
+ {
+ EVP_PKEY *pkey = si->pkey;
+ int i;
+ if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+ return 1;
+ i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
+ if (i == -2)
+ {
+ CMSerr(CMS_F_CMS_SD_ASN1_CTRL,
+ CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ return 0;
+ }
+ if (i <= 0)
+ {
+ CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+ return 0;
+ }
+ return 1;
+ }
+
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
unsigned int flags)
@@ -324,6 +345,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
si->pkey = pk;
si->signer = signer;
+ EVP_MD_CTX_init(&si->mctx);
+ si->pctx = NULL;
if (flags & CMS_USE_KEYID)
{
@@ -385,23 +408,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
}
}
- if (pk->ameth && pk->ameth->pkey_ctrl)
- {
- i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
- 0, si);
- if (i == -2)
- {
- CMSerr(CMS_F_CMS_ADD1_SIGNER,
- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
- goto err;
- }
- if (i <= 0)
- {
- CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
- goto err;
- }
- }
-
+ if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
+ goto err;
if (!(flags & CMS_NOATTR))
{
/* Initialialize signed attributes strutucture so other
@@ -429,7 +437,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
{
if (!cms_copy_messageDigest(cms, si))
goto err;
- if (!(flags & CMS_PARTIAL) &&
+ if (!(flags & (CMS_PARTIAL|CMS_KEY_PARAM)) &&
!CMS_SignerInfo_sign(si))
goto err;
}
@@ -442,6 +450,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
goto merr;
}
+ if (flags & CMS_KEY_PARAM)
+ {
+ if (flags & CMS_NOATTR)
+ {
+ si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+ if (!si->pctx)
+ goto err;
+ if (EVP_PKEY_sign_init(si->pctx) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
+ goto err;
+ }
+ else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <= 0)
+ goto err;
+ }
+
if (!sd->signerInfos)
sd->signerInfos = sk_CMS_SignerInfo_new_null();
if (!sd->signerInfos ||
@@ -489,6 +513,16 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
}
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
+ {
+ return si->pctx;
+ }
+
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
+ {
+ return &si->mctx;
+ }
+
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
{
CMS_SignedData *sd;
@@ -621,9 +655,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
{
EVP_MD_CTX mctx;
int r = 0;
+ EVP_PKEY_CTX *pctx = NULL;
EVP_MD_CTX_init(&mctx);
-
if (!si->pkey)
{
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
@@ -632,6 +666,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
goto err;
+ /* Set SignerInfo algortihm details if we used custom parametsr */
+ if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
+ goto err;
/* If any signed attributes calculate and add messageDigest attribute */
@@ -654,6 +691,26 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
if (!CMS_SignerInfo_sign(si))
goto err;
}
+ else if (si->pctx)
+ {
+ unsigned char *sig;
+ size_t siglen;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int mdlen;
+ pctx = si->pctx;
+ if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+ goto err;
+ sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
+ if (!sig)
+ {
+ CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0)
+ goto err;
+ ASN1_STRING_set0(si->signature, sig, siglen);
+ }
else
{
unsigned char *sig;
@@ -679,6 +736,8 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
err:
EVP_MD_CTX_cleanup(&mctx);
+ if (pctx)
+ EVP_PKEY_CTX_free(pctx);
return r;
}
@@ -701,7 +760,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
int CMS_SignerInfo_sign(CMS_SignerInfo *si)
{
- EVP_MD_CTX mctx;
+ EVP_MD_CTX *mctx = &si->mctx;
EVP_PKEY_CTX *pctx;
unsigned char *abuf = NULL;
int alen;
@@ -712,7 +771,6 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
if (md == NULL)
return 0;
- EVP_MD_CTX_init(&mctx);
if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
{
@@ -720,8 +778,14 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
goto err;
}
- if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
- goto err;
+ if (si->pctx)
+ pctx = si->pctx;
+ else
+ {
+ EVP_MD_CTX_init(mctx);
+ if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
+ goto err;
+ }
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
@@ -734,15 +798,15 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
ASN1_ITEM_rptr(CMS_Attributes_Sign));
if(!abuf)
goto err;
- if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
+ if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
goto err;
- if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+ if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
goto err;
OPENSSL_free(abuf);
abuf = OPENSSL_malloc(siglen);
if(!abuf)
goto err;
- if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+ if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
goto err;
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
@@ -752,7 +816,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
goto err;
}
- EVP_MD_CTX_cleanup(&mctx);
+ EVP_MD_CTX_cleanup(mctx);
ASN1_STRING_set0(si->signature, abuf, siglen);
@@ -761,15 +825,14 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
err:
if (abuf)
OPENSSL_free(abuf);
- EVP_MD_CTX_cleanup(&mctx);
+ EVP_MD_CTX_cleanup(mctx);
return 0;
}
int CMS_SignerInfo_verify(CMS_SignerInfo *si)
{
- EVP_MD_CTX mctx;
- EVP_PKEY_CTX *pctx;
+ EVP_MD_CTX *mctx = &si->mctx;
unsigned char *abuf = NULL;
int alen, r = -1;
const EVP_MD *md = NULL;
@@ -783,27 +846,30 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
if (md == NULL)
return -1;
- EVP_MD_CTX_init(&mctx);
- if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+ EVP_MD_CTX_init(mctx);
+ if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
+ goto err;
+
+ if (!cms_sd_asn1_ctrl(si, 1))
goto err;
alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
ASN1_ITEM_rptr(CMS_Attributes_Verify));
if(!abuf)
goto err;
- r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
+ r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
OPENSSL_free(abuf);
if (r <= 0)
{
r = -1;
goto err;
}
- r = EVP_DigestVerifyFinal(&mctx,
+ r = EVP_DigestVerifyFinal(mctx,
si->signature->data, si->signature->length);
if (r <= 0)
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
err:
- EVP_MD_CTX_cleanup(&mctx);
+ EVP_MD_CTX_cleanup(mctx);
return r;
}
@@ -843,7 +909,10 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
{
ASN1_OCTET_STRING *os = NULL;
EVP_MD_CTX mctx;
+ EVP_PKEY_CTX *pkctx = NULL;
int r = -1;
+ unsigned char mval[EVP_MAX_MD_SIZE];
+ unsigned int mlen;
EVP_MD_CTX_init(&mctx);
/* If we have any signed attributes look for messageDigest value */
if (CMS_signed_get_attr_count(si) >= 0)
@@ -862,18 +931,17 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
goto err;
+ if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
+ {
+ CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+ CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
+ goto err;
+ }
+
/* If messageDigest found compare it */
if (os)
{
- unsigned char mval[EVP_MAX_MD_SIZE];
- unsigned int mlen;
- if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
- {
- CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
- CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
- goto err;
- }
if (mlen != (unsigned int)os->length)
{
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
@@ -892,8 +960,18 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
}
else
{
- r = EVP_VerifyFinal(&mctx, si->signature->data,
- si->signature->length, si->pkey);
+ const EVP_MD *md = EVP_MD_CTX_md(&mctx);
+ pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+ if (EVP_PKEY_verify_init(pkctx) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
+ goto err;
+ si->pctx = pkctx;
+ if (!cms_sd_asn1_ctrl(si, 1))
+ goto err;
+ r = EVP_PKEY_verify(pkctx, si->signature->data,
+ si->signature->length,
+ mval, mlen);
if (r <= 0)
{
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
@@ -903,6 +981,8 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
}
err:
+ if (pkctx)
+ EVP_PKEY_CTX_free(pkctx);
EVP_MD_CTX_cleanup(&mctx);
return r;