summaryrefslogtreecommitdiffstats
path: root/crypto/cms/cms_env.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2008-03-15 23:21:33 +0000
committerDr. Stephen Henson <steve@openssl.org>2008-03-15 23:21:33 +0000
commit4f1aa191b33f0bbda29c3289d50fee2991b77df0 (patch)
tree10c7eb9e8d1fcf55e78d6d2ad05d2fcefb835aab /crypto/cms/cms_env.c
parente540d1cd77d4cf0edea74212a5e598d073ce2e67 (diff)
Initial support for enveloped data decrypt. Extent runex.pl to cover these
examples. All RFC4134 examples can not be processed.
Diffstat (limited to 'crypto/cms/cms_env.c')
-rw-r--r--crypto/cms/cms_env.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index 3a5991e016..39ebe5a0f1 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -101,6 +101,20 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
return cms_get0_enveloped(cms);
}
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+ {
+ CMS_EnvelopedData *env;
+ env = cms_enveloped_data_init(cms);
+ if (!env)
+ return NULL;
+ return env->recipientInfos;
+ }
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+ {
+ return ri->type;
+ }
+
/* Add a recipient certificate. For now only handle key transport.
* If we ever handle key agreement will need updating.
*/
@@ -229,6 +243,7 @@ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
CMS_R_NOT_KEY_TRANSPORT);
return 0;
}
+ ktri = ri->d.ktri;
return cms_SignerIdentifier_get0_signer_id(ktri->rid,
keyid, issuer, sno);
@@ -236,13 +251,86 @@ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
{
- CMS_KeyTransRecipientInfo *ktri;
if (ri->type != CMS_RECIPINFO_TRANS)
{
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
CMS_R_NOT_KEY_TRANSPORT);
+ return -2;
+ }
+
+ return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+ }
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+ EVP_PKEY *pkey)
+ {
+ CMS_KeyTransRecipientInfo *ktri;
+ EVP_PKEY_CTX *pctx = NULL;
+ unsigned char *ek = NULL;
+ size_t eklen;
+
+ int ret = 0;
+
+ if (ri->type != CMS_RECIPINFO_TRANS)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+ CMS_R_NOT_KEY_TRANSPORT);
+ return 0;
+ }
+ ktri = ri->d.ktri;
+
+ pctx = EVP_PKEY_CTX_new(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_DECRYPT, CMS_R_CTRL_ERROR);
+ goto err;
}
- return cms_SignerIdentifier_cert_cmp(ktri->rid, cert);
+ if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+ ktri->encryptedKey->data,
+ ktri->encryptedKey->length) <= 0)
+ goto err;
+
+ ek = OPENSSL_malloc(eklen);
+
+ if (ek == NULL)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+ ktri->encryptedKey->data,
+ ktri->encryptedKey->length) <= 0)
+ {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, CMS_R_CMS_LIB);
+ goto err;
+ }
+
+ ret = 1;
+
+ cms->d.envelopedData->encryptedContentInfo->key = ek;
+ cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
+
+ err:
+ if (pctx)
+ EVP_PKEY_CTX_free(pctx);
+ if (!ret && ek)
+ OPENSSL_free(ek);
+
+ return ret;
+ }
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+ {
+ CMS_EncryptedContentInfo *ec;
+ ec = cms->d.envelopedData->encryptedContentInfo;
+ return cms_EncryptedContent_init_bio(ec);
}