diff options
Diffstat (limited to 'openssl/crypto/cms/cms_env.c')
-rw-r--r-- | openssl/crypto/cms/cms_env.c | 85 |
1 files changed, 61 insertions, 24 deletions
diff --git a/openssl/crypto/cms/cms_env.c b/openssl/crypto/cms/cms_env.c index d499ae85b..b3237d4b9 100644 --- a/openssl/crypto/cms/cms_env.c +++ b/openssl/crypto/cms/cms_env.c @@ -60,6 +60,7 @@ #include <openssl/rand.h> #include <openssl/aes.h> #include "cms_lcl.h" +#include "asn1_locl.h" /* CMS EnvelopedData Utilities */ @@ -151,7 +152,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, CMS_KeyTransRecipientInfo *ktri; CMS_EnvelopedData *env; EVP_PKEY *pk = NULL; - int type; + int i, type; env = cms_get0_enveloped(cms); if (!env) goto err; @@ -200,21 +201,22 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) goto err; - /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, - * hard code algorithm parameters. - */ - - if (pk->type == EVP_PKEY_RSA) - { - X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, - OBJ_nid2obj(NID_rsaEncryption), - V_ASN1_NULL, 0); - } - else + if (pk->ameth && pk->ameth->pkey_ctrl) { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + 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); - goto err; + goto err; + } + if (i <= 0) + { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + CMS_R_CTRL_FAILURE); + goto err; + } } if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) @@ -301,8 +303,9 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, { CMS_KeyTransRecipientInfo *ktri; CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; - int eklen; + size_t eklen; int ret = 0; @@ -315,7 +318,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, ktri = ri->d.ktri; ec = cms->d.envelopedData->encryptedContentInfo; - eklen = EVP_PKEY_size(ktri->pkey); + 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) + { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) + goto err; ek = OPENSSL_malloc(eklen); @@ -326,9 +344,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, goto err; } - eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); - - if (eklen <= 0) + if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) goto err; ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); @@ -337,6 +353,8 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, ret = 1; err: + if (pctx) + EVP_PKEY_CTX_free(pctx); if (ek) OPENSSL_free(ek); return ret; @@ -349,8 +367,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; - int eklen; + size_t eklen; int ret = 0; if (ktri->pkey == NULL) @@ -360,7 +379,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, return 0; } - eklen = EVP_PKEY_size(ktri->pkey); + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(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, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) + goto err; ek = OPENSSL_malloc(eklen); @@ -371,10 +407,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, goto err; } - eklen = EVP_PKEY_decrypt(ek, + if (EVP_PKEY_decrypt(pctx, ek, &eklen, ktri->encryptedKey->data, - ktri->encryptedKey->length, ktri->pkey); - if (eklen <= 0) + ktri->encryptedKey->length) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); goto err; @@ -386,6 +421,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, cms->d.envelopedData->encryptedContentInfo->keylen = eklen; err: + if (pctx) + EVP_PKEY_CTX_free(pctx); if (!ret && ek) OPENSSL_free(ek); |