summaryrefslogtreecommitdiffstats
path: root/crypto/cms
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2008-03-14 13:21:48 +0000
committerDr. Stephen Henson <steve@openssl.org>2008-03-14 13:21:48 +0000
commitb820455c6e0aa38e7bdf121ec971f72e0eb097d0 (patch)
tree0f10ad6bfc453e02a18feeb398d99f0aff256433 /crypto/cms
parent5c4436c97759a98794cd84dc37c937fa637aad61 (diff)
Encrypted Data type processing. Add options to cms utility and run section 7
tests in RFC4134.
Diffstat (limited to 'crypto/cms')
-rw-r--r--crypto/cms/cms.h10
-rw-r--r--crypto/cms/cms_enc.c23
-rw-r--r--crypto/cms/cms_err.c3
-rw-r--r--crypto/cms/cms_lcl.h6
-rw-r--r--crypto/cms/cms_lib.c6
-rw-r--r--crypto/cms/cms_smime.c34
6 files changed, 70 insertions, 12 deletions
diff --git a/crypto/cms/cms.h b/crypto/cms/cms.h
index 0df4b0f4cf..a95dda906e 100644
--- a/crypto/cms/cms.h
+++ b/crypto/cms/cms.h
@@ -138,6 +138,13 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
unsigned int flags);
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+ const unsigned char *key, size_t keylen,
+ BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_EncryptedData_set1_key(BIO *b, CMS_ContentInfo *cms,
+ const unsigned char *key, size_t keylen);
+
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
@@ -255,6 +262,8 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 112
#define CMS_F_CMS_DIGEST_VERIFY 113
#define CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO 138
+#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 140
+#define CMS_F_CMS_ENCRYPTED_DATA_DECRYPT 139
#define CMS_F_CMS_ENVELOPED_DATA_INIT 114
#define CMS_F_CMS_FINAL 115
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 116
@@ -315,6 +324,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_TYPE_NOT_COMPRESSED_DATA 128
#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_UNABLE_TO_FINALIZE_CONTEXT 131
#define CMS_R_UNKNOWN_CIPHER 141
#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 132
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
index 084bc12466..b395bc499b 100644
--- a/crypto/cms/cms_enc.c
+++ b/crypto/cms/cms_enc.c
@@ -132,18 +132,11 @@ int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec,
/* Return BIO based on EncryptedContentInfo and key */
-BIO *cms_EncryptedContent_to_bio(CMS_EncryptedContentInfo *ec,
+int cms_EncryptedContent_to_bio(BIO *b, CMS_EncryptedContentInfo *ec,
const unsigned char *key, int keylen)
{
- BIO *b;
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *ciph;
- b = BIO_new(BIO_f_cipher());
- if (!b)
- {
- CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
BIO_get_cipher_ctx(b, &ctx);
ciph = EVP_get_cipherbyobj(ec->contentEncryptionAlgorithm->algorithm);
@@ -187,10 +180,18 @@ BIO *cms_EncryptedContent_to_bio(CMS_EncryptedContentInfo *ec,
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
goto err;
}
- return b;
+ return 1;
err:
- BIO_free(b);
- return NULL;
+ return 0;
}
+int CMS_EncryptedData_set1_key(BIO *b, CMS_ContentInfo *cms,
+ const unsigned char *key, size_t keylen)
+ {
+ CMS_EncryptedContentInfo *ec;
+ if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
+ return 0;
+ ec = cms->d.encryptedData->encryptedContentInfo;
+ return cms_EncryptedContent_to_bio(b, ec, key, keylen);
+ }
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index 8a45c059a8..6fb6939b93 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -87,6 +87,8 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"},
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO), "CMS_ENCRYPTEDCONTENT_TO_BIO"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTED_DATA_DECRYPT), "CMS_ENCRYPTED_DATA_DECRYPT"},
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
@@ -150,6 +152,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
{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_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 e33c274a10..cc22e00d53 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -411,6 +411,12 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
X509_ALGOR *mdalg);
+
+int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec,
+ const unsigned char *key, int keylen,
+ BIO *b);
+int cms_EncryptedContent_to_bio(BIO *b, CMS_EncryptedContentInfo *ec,
+ const unsigned char *key, int keylen);
#ifdef __cplusplus
}
diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c
index 24ab0e7ba5..f2169e138b 100644
--- a/crypto/cms/cms_lib.c
+++ b/crypto/cms/cms_lib.c
@@ -139,6 +139,10 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
break;
#endif
+ case NID_pkcs7_encrypted:
+ cmsbio = BIO_new(BIO_f_cipher());
+ break;
+
default:
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
return NULL;
@@ -152,7 +156,7 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
return NULL;
}
-
+
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
{
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index 0a67c78694..a1ee0f24e2 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -188,6 +188,40 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
return NULL;
}
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+ const unsigned char *key, size_t keylen,
+ BIO *dcont, BIO *out, unsigned int flags)
+ {
+ BIO *cont;
+ int r;
+ if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
+ {
+ CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
+ CMS_R_TYPE_NOT_ENCRYPTED_DATA);
+ 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;
+ }
+ }
+
+ cont = CMS_dataInit(cms, dcont);
+ if (!cont)
+ return 0;
+ r = CMS_EncryptedData_set1_key(cont, cms, key, keylen);
+ if (r)
+ r = cms_copy_content(out, cont, flags);
+ BIO_free_all(cont);
+ return r;
+ }
+
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
X509_STORE *store,
STACK_OF(X509) *certs,