summaryrefslogtreecommitdiffstats
path: root/crypto/cms
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
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')
-rw-r--r--crypto/cms/cms.h29
-rw-r--r--crypto/cms/cms_dd.c2
-rw-r--r--crypto/cms/cms_enc.c13
-rw-r--r--crypto/cms/cms_env.c92
-rw-r--r--crypto/cms/cms_err.c12
-rw-r--r--crypto/cms/cms_lcl.h12
-rw-r--r--crypto/cms/cms_lib.c4
-rw-r--r--crypto/cms/cms_sd.c2
-rw-r--r--crypto/cms/cms_smime.c102
9 files changed, 201 insertions, 67 deletions
diff --git a/crypto/cms/cms.h b/crypto/cms/cms.h
index c9801cf293..41f0e8687d 100644
--- a/crypto/cms/cms.h
+++ b/crypto/cms/cms.h
@@ -70,6 +70,7 @@ typedef struct CMS_ContentInfo_st CMS_ContentInfo;
typedef struct CMS_SignerInfo_st CMS_SignerInfo;
typedef struct CMS_CertificateChoices CMS_CertificateChoices;
typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
DECLARE_STACK_OF(CMS_SignerInfo)
DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
@@ -78,6 +79,12 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
#define CMS_SIGNERINFO_ISSUER_SERIAL 0
#define CMS_SIGNERINFO_KEYIDENTIFIER 1
+#define CMS_RECIPINFO_TRANS 0
+#define CMS_RECIPINFO_AGREE 1
+#define CMS_RECIPINFO_KEK 2
+#define CMS_RECIPINFO_PASS 3
+#define CMS_RECIPINFO_OTHER 4
+
/* S/MIME related flags */
#define CMS_TEXT 0x1
@@ -157,9 +164,23 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags);
-int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *data,
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+ BIO *data, BIO *dcont,
unsigned int flags);
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+ EVP_PKEY **pk, X509 **recip,
+ X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+ ASN1_OCTET_STRING **keyid,
+ X509_NAME **issuer, ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+ EVP_PKEY *pkey);
+
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
unsigned int flags);
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
@@ -249,6 +270,7 @@ void ERR_load_CMS_strings(void);
/* Error codes for the CMS functions. */
/* Function codes. */
+#define CMS_F_CHECK_CONTENT 151
#define CMS_F_CMS_ADD1_RECIPIENT_CERT 99
#define CMS_F_CMS_ADD1_SIGNER 100
#define CMS_F_CMS_ADD1_SIGNINGTIME 101
@@ -262,6 +284,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_DATA 107
#define CMS_F_CMS_DATAFINAL 108
#define CMS_F_CMS_DATAINIT 109
+#define CMS_F_CMS_DECRYPT 152
#define CMS_F_CMS_DECRYPTEDCONTENT_DECRYPT_BIO 145
#define CMS_F_CMS_DECRYPTEDCONTENT_ENCRYPT_BIO 143
#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 110
@@ -285,6 +308,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_GET0_ENVELOPED 119
#define CMS_F_CMS_GET0_REVOCATION_CHOICES 120
#define CMS_F_CMS_GET0_SIGNED 121
+#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 150
#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 122
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 123
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 124
@@ -307,6 +331,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_CIPHER_INITIALISATION_ERROR 138
#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 139
#define CMS_R_CMS_DATAFINAL_ERROR 101
+#define CMS_R_CMS_LIB 145
#define CMS_R_CONTENT_NOT_FOUND 102
#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 103
#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 104
@@ -328,6 +353,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_NO_DEFAULT_DIGEST 117
#define CMS_R_NO_DIGEST_SET 118
#define CMS_R_NO_MATCHING_DIGEST 119
+#define CMS_R_NO_MATCHING_RECIPIENT 147
#define CMS_R_NO_PRIVATE_KEY 120
#define CMS_R_NO_PUBLIC_KEY 121
#define CMS_R_NO_SIGNERS 122
@@ -340,6 +366,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_TYPE_NOT_DATA 129
#define CMS_R_TYPE_NOT_DIGESTED_DATA 130
#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 142
+#define CMS_R_TYPE_NOT_ENVELOPED_DATA 146
#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 131
#define CMS_R_UNKNOWN_CIPHER 141
#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 132
diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c
index ec7689d001..a927caad8e 100644
--- a/crypto/cms/cms_dd.c
+++ b/crypto/cms/cms_dd.c
@@ -98,8 +98,6 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
{
CMS_DigestedData *dd;
- if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_digest)
- return NULL;
dd = cms->d.digestedData;
return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
}
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
index fbf87b6735..a99ce1b5f2 100644
--- a/crypto/cms/cms_enc.c
+++ b/crypto/cms/cms_enc.c
@@ -227,13 +227,8 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
{
- CMS_EncryptedContentInfo *ec;
- if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
- {
- CMSerr(CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO,
- CMS_R_NOT_ENCRYPTED_DATA);
- return NULL;
- }
- ec = cms->d.encryptedData->encryptedContentInfo;
- return cms_EncryptedContent_init_bio(ec);
+ CMS_EncryptedData *enc = cms->d.encryptedData;
+ if (enc->unprotectedAttrs)
+ enc->version = 2;
+ return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
}
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);
}
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index 0d142681b4..3baa40e525 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -70,6 +70,7 @@
static ERR_STRING_DATA CMS_str_functs[]=
{
+{ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"},
{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_ADD1_RECIPIENT_CERT"},
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"},
@@ -83,6 +84,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"},
{ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"},
{ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
{ERR_FUNC(CMS_F_CMS_DECRYPTEDCONTENT_DECRYPT_BIO), "CMS_DECRYPTEDCONTENT_DECRYPT_BIO"},
{ERR_FUNC(CMS_F_CMS_DECRYPTEDCONTENT_ENCRYPT_BIO), "CMS_DECRYPTEDCONTENT_ENCRYPT_BIO"},
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), "CMS_DIGESTALGORITHM_FIND_CTX"},
@@ -106,9 +108,10 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "CMS_GET0_ENVELOPED"},
{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), "CMS_GET0_REVOCATION_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RECIPIENTINFO_KTRI_CERT_CMP"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), "CMS_RECIPIENTINFO_KTRI_GET0_ALGS"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), "CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), "CMS_RecipientInfo_ktri_get0_algs"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), "CMS_RecipientInfo_ktri_get0_signer_id"},
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "CMS_SET1_SIGNERIDENTIFIER"},
{ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
{ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
@@ -131,6 +134,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"},
+{ERR_REASON(CMS_R_CMS_LIB) ,"cms lib"},
{ERR_REASON(CMS_R_CONTENT_NOT_FOUND) ,"content not found"},
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
@@ -152,6 +156,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST) ,"no default digest"},
{ERR_REASON(CMS_R_NO_DIGEST_SET) ,"no digest set"},
{ERR_REASON(CMS_R_NO_MATCHING_DIGEST) ,"no matching digest"},
+{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
{ERR_REASON(CMS_R_NO_PRIVATE_KEY) ,"no private key"},
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"},
{ERR_REASON(CMS_R_NO_SIGNERS) ,"no signers"},
@@ -164,6 +169,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"},
{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
{ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"},
{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
index 06eeea7eeb..774ec103f7 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -91,7 +91,6 @@ typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
-typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
struct CMS_ContentInfo_st
{
@@ -187,12 +186,6 @@ struct CMS_RecipientInfo_st
} d;
};
-#define CMS_RECIPINFO_TRANS 0
-#define CMS_RECIPINFO_AGREE 1
-#define CMS_RECIPINFO_KEK 2
-#define CMS_RECIPINFO_PASS 3
-#define CMS_RECIPINFO_OTHER 4
-
typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
struct CMS_KeyTransRecipientInfo_st
@@ -416,9 +409,10 @@ BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
X509_ALGOR *mdalg);
-BIO *cms_EncryptedContent_encrypt_bio(CMS_EncryptedContentInfo *ec);
-BIO *cms_EncryptedContent_decrypt_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
#ifdef __cplusplus
}
diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c
index e691ca3a7c..7b118b8d98 100644
--- a/crypto/cms/cms_lib.c
+++ b/crypto/cms/cms_lib.c
@@ -137,6 +137,10 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
cmsbio = cms_EncryptedData_init_bio(cms);
break;
+ case NID_pkcs7_enveloped:
+ cmsbio = cms_EnvelopedData_init_bio(cms);
+ break;
+
default:
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
return NULL;
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 52860975f6..dc8e896e71 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -798,9 +798,9 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
CMS_SignedData *sd;
BIO *chain = NULL;
sd = cms_get0_signed(cms);
- cms_sd_set_version(sd);
if (!sd)
return NULL;
+ cms_sd_set_version(sd);
for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
{
X509_ALGOR *digestAlgorithm;
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)