Index: openssl/crypto/cms/cms_env.c |
=================================================================== |
--- openssl/crypto/cms/cms_env.c (revision 105093) |
+++ openssl/crypto/cms/cms_env.c (working copy) |
@@ -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_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 @@ |
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) |
+ if (pk->ameth && pk->ameth->pkey_ctrl) |
{ |
- X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, |
- OBJ_nid2obj(NID_rsaEncryption), |
- V_ASN1_NULL, 0); |
- } |
- else |
- { |
- 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 @@ |
{ |
CMS_KeyTransRecipientInfo *ktri; |
CMS_EncryptedContentInfo *ec; |
+ EVP_PKEY_CTX *pctx = NULL; |
unsigned char *ek = NULL; |
- int eklen; |
+ size_t eklen; |
int ret = 0; |
@@ -315,8 +318,23 @@ |
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); |
if (ek == NULL) |
@@ -326,9 +344,7 @@ |
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 @@ |
ret = 1; |
err: |
+ if (pctx) |
+ EVP_PKEY_CTX_free(pctx); |
if (ek) |
OPENSSL_free(ek); |
return ret; |
@@ -349,8 +367,9 @@ |
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,8 +379,25 @@ |
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); |
if (ek == NULL) |
@@ -371,10 +407,9 @@ |
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 @@ |
cms->d.envelopedData->encryptedContentInfo->keylen = eklen; |
err: |
+ if (pctx) |
+ EVP_PKEY_CTX_free(pctx); |
if (!ret && ek) |
OPENSSL_free(ek); |