diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2008-03-15 23:21:33 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2008-03-15 23:21:33 +0000 |
commit | 4f1aa191b33f0bbda29c3289d50fee2991b77df0 (patch) | |
tree | 10c7eb9e8d1fcf55e78d6d2ad05d2fcefb835aab /crypto/cms/cms_smime.c | |
parent | e540d1cd77d4cf0edea74212a5e598d073ce2e67 (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_smime.c')
-rw-r--r-- | crypto/cms/cms_smime.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index d1a16808e9..7a2498d735 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -113,6 +113,17 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) } +static int check_content(CMS_ContentInfo *cms) + { + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos || !*pos) + { + CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); + return 0; + } + return 1; + } + int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) { BIO *cont; @@ -156,15 +167,8 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, return 0; } - if (!dcont) - { - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) - { - CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_NO_CONTENT); - return 0; - } - } + if (!dcont && !check_content(cms)) + return 0; cont = CMS_dataInit(cms, dcont); if (!cont) @@ -209,16 +213,8 @@ int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, return 0; } - if (!dcont) - { - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) - { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, - CMS_R_NO_CONTENT); - return 0; - } - } + if (!dcont && !check_content(cms)) + return 0; if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) return 0; @@ -304,15 +300,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, int i, scount = 0, ret = 0; BIO *cmsbio = NULL, *tmpin = NULL; - if (!dcont) - { - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) - { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_CONTENT); - return 0; - } - } + if (!dcont && !check_content(cms)) + return 0; /* Attempt to find all signer certificates */ @@ -470,7 +459,7 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, return NULL; } -/* Placeholders for now... */ +/* Placeholder for now... */ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags) @@ -478,10 +467,50 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, return NULL; } -int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *data, +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags) { - return 0; + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + BIO *cont; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) + { + CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); + return 0; + } + if (!dcont && !check_content(cms)) + return 0; + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) + { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS) + continue; + if (cert) + { + if (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0) + { + if (CMS_RecipientInfo_decrypt(cms, ri, pk) <=0) + return 0; + else + break; + } + } + } + + if (i == sk_CMS_RecipientInfo_num(ris)) + { + CMSerr(CMS_F_CMS_DECRYPT, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + } + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + BIO_free_all(cont); + return r; } int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags) @@ -528,15 +557,8 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, return 0; } - if (!dcont) - { - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) - { - CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_NO_CONTENT); - return 0; - } - } + if (!dcont && !check_content(cms)) + return 0; cont = CMS_dataInit(cms, dcont); if (!cont) |