diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2013-06-19 18:17:14 +0100 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2013-10-01 14:01:17 +0100 |
commit | f2edf3181e30413c99864e7106125be7da905678 (patch) | |
tree | 0f9e64b7398a01aa7252171828c31fa8813389e7 /crypto/cms/cms_env.c | |
parent | d6dc5c506a049e3f09acca57dea4b33bc8cfb2be (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.
(cherry picked from commit e365352d6a6368039392fed14a328f8c0bf955c3)
Diffstat (limited to 'crypto/cms/cms_env.c')
-rw-r--r-- | crypto/cms/cms_env.c | 100 |
1 files changed, 70 insertions, 30 deletions
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); |