summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto/asn1/asn1_item_list.h1
-rw-r--r--crypto/cms/cms_env.c37
-rw-r--r--crypto/cms/cms_local.h1
-rw-r--r--doc/man3/CMS_EncryptedData_decrypt.pod27
-rw-r--r--doc/man3/CMS_EnvelopedData_create.pod12
-rw-r--r--doc/man3/CMS_decrypt.pod49
-rw-r--r--doc/man3/X509_dup.pod1
-rw-r--r--include/openssl/cms.h.in23
-rw-r--r--util/libcrypto.num2
-rw-r--r--util/missingcrypto.txt1
10 files changed, 113 insertions, 41 deletions
diff --git a/crypto/asn1/asn1_item_list.h b/crypto/asn1/asn1_item_list.h
index 1432012b7c..72299a7b6b 100644
--- a/crypto/asn1/asn1_item_list.h
+++ b/crypto/asn1/asn1_item_list.h
@@ -52,6 +52,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = {
ASN1_ITEM_ref(CERTIFICATEPOLICIES),
#ifndef OPENSSL_NO_CMS
ASN1_ITEM_ref(CMS_ContentInfo),
+ ASN1_ITEM_ref(CMS_EnvelopedData),
ASN1_ITEM_ref(CMS_ReceiptRequest),
#endif
ASN1_ITEM_ref(CRL_DIST_POINTS),
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index 24632fa9c1..471676d2f5 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -242,6 +242,43 @@ CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
return CMS_EnvelopedData_create_ex(cipher, NULL, NULL);
}
+BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data,
+ EVP_PKEY *pkey, X509 *cert,
+ ASN1_OCTET_STRING *secret, unsigned int flags,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ CMS_ContentInfo *ci;
+ BIO *bio = NULL;
+ int res = 0;
+
+ if (env == NULL) {
+ ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL
+ || (bio = BIO_new(BIO_s_mem())) == NULL)
+ goto end;
+ ci->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+ ci->d.envelopedData = env;
+ if (secret != NULL
+ && CMS_decrypt_set1_password(ci, (unsigned char *)
+ ASN1_STRING_get0_data(secret),
+ ASN1_STRING_length(secret)) != 1)
+ goto end;
+ res = CMS_decrypt(ci, pkey, cert, detached_data, bio, flags);
+
+ end:
+ if (ci != NULL)
+ ci->d.envelopedData = NULL;
+ CMS_ContentInfo_free(ci);
+ if (!res) {
+ BIO_free(bio);
+ bio = NULL;
+ }
+ return bio;
+}
+
CMS_ContentInfo *
CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
const char *propq)
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
index 096235c0fa..d16ca95176 100644
--- a/crypto/cms/cms_local.h
+++ b/crypto/cms/cms_local.h
@@ -25,7 +25,6 @@ typedef struct CMS_SignedData_st CMS_SignedData;
typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
-typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
typedef struct CMS_DigestedData_st CMS_DigestedData;
typedef struct CMS_EncryptedData_st CMS_EncryptedData;
typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
diff --git a/doc/man3/CMS_EncryptedData_decrypt.pod b/doc/man3/CMS_EncryptedData_decrypt.pod
index 17850a98af..930ac3340b 100644
--- a/doc/man3/CMS_EncryptedData_decrypt.pod
+++ b/doc/man3/CMS_EncryptedData_decrypt.pod
@@ -2,8 +2,8 @@
=head1 NAME
-CMS_EncryptedData_decrypt
-- Decrypt CMS EncryptedData
+CMS_EncryptedData_decrypt, CMS_EnvelopedData_decrypt
+- Decrypt CMS EncryptedData or EnvelopedData
=head1 SYNOPSIS
@@ -13,6 +13,11 @@ CMS_EncryptedData_decrypt
const unsigned char *key, size_t keylen,
BIO *dcont, BIO *out, unsigned int flags);
+ BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data,
+ EVP_PKEY *pkey, X509 *cert,
+ ASN1_OCTET_STRING *secret, unsigned int flags,
+ OSSL_LIB_CTX *libctx, const char *propq);
+
=head1 DESCRIPTION
CMS_EncryptedData_decrypt() decrypts a I<cms> EncryptedData object using the
@@ -27,15 +32,27 @@ If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
from the content. If the content is not of type B<text/plain> then an error is
returned.
+CMS_EnvelopedData_decrypt() decrypts, similarly to CMS_decrypt(3),
+a CMS EnvelopedData object I<env> using the symmetric key I<secret> or
+the private key of the recipient B<pkey> and its associated certificate B<cert>.
+The optional parameters I<flags> and I<dcont> are used as described above.
+The optional parameters library context I<libctx> and property query I<propq>
+are used when retrieving algorithms from providers.
+
=head1 RETURN VALUES
-CMS_EncryptedData_decrypt() returns 0 if an error occurred otherwise it
-returns 1.
+CMS_EncryptedData_decrypt() returns 0 if an error occurred otherwise returns 1.
+
+CMS_EnvelopedData_decrypt() returns NULL if an error occurred,
+otherwise a BIO containing the decypted content.
=head1 SEE ALSO
-L<ERR_get_error(3)>, L<CMS_EncryptedData_encrypt(3)>
+L<ERR_get_error(3)>, L<CMS_EncryptedData_encrypt(3)>, L<CMS_decrypt(3)>
+
+=head1 HISTORY
+CMS_EnvelopedData_decrypt() was added in OpenSSL 3.1.
=head1 COPYRIGHT
diff --git a/doc/man3/CMS_EnvelopedData_create.pod b/doc/man3/CMS_EnvelopedData_create.pod
index e5ff269e47..9dfd0ad77d 100644
--- a/doc/man3/CMS_EnvelopedData_create.pod
+++ b/doc/man3/CMS_EnvelopedData_create.pod
@@ -42,20 +42,22 @@ L<CMS_add0_recipient_key(3)>.
The B<CMS_ContentInfo> structure needs to be finalized using L<CMS_final(3)>
and then freed using L<CMS_ContentInfo_free(3)>.
-CMS_EnvelopedData_create() and CMS_AuthEnvelopedData_create are similar to
-CMS_EnvelopedData_create_ex() and
-CMS_AuthEnvelopedData_create_ex() but use default values of NULL for
+CMS_EnvelopedData_create() and CMS_AuthEnvelopedData_create() are similar to
+CMS_EnvelopedData_create_ex() and CMS_AuthEnvelopedData_create_ex()
+but use default values of NULL for
the library context I<libctx> and the property query I<propq>.
=head1 NOTES
-Although CMS_EnvelopedData_create() and CMS_AuthEnvelopedData_create() allocate
+Although CMS_EnvelopedData_create_ex(), and CMS_EnvelopedData_create(),
+CMS_AuthEnvelopedData_create_ex(), and CMS_AuthEnvelopedData_create() allocate
a new B<CMS_ContentInfo> structure, they are not usually used in applications.
The wrappers L<CMS_encrypt(3)> and L<CMS_decrypt(3)> are often used instead.
=head1 RETURN VALUES
-If the allocation fails, CMS_EnvelopedData_create() and
+If the allocation fails, CMS_EnvelopedData_create_ex(),
+CMS_EnvelopedData_create(), CMS_AuthEnvelopedData_create_ex(), and
CMS_AuthEnvelopedData_create() return NULL and set an error code that can be
obtained by L<ERR_get_error(3)>. Otherwise they return a pointer to the newly
allocated structure.
diff --git a/doc/man3/CMS_decrypt.pod b/doc/man3/CMS_decrypt.pod
index 4f8d32fbbb..3d3a4e0693 100644
--- a/doc/man3/CMS_decrypt.pod
+++ b/doc/man3/CMS_decrypt.pod
@@ -2,8 +2,9 @@
=head1 NAME
-CMS_decrypt, CMS_decrypt_set1_pkey_and_peer, CMS_decrypt_set1_pkey - decrypt
-content from a CMS envelopedData structure
+CMS_decrypt, CMS_decrypt_set1_pkey_and_peer,
+CMS_decrypt_set1_pkey, CMS_decrypt_set1_password
+- decrypt content from a CMS envelopedData structure
=head1 SYNOPSIS
@@ -14,23 +15,28 @@ content from a CMS envelopedData structure
int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms,
EVP_PKEY *pk, X509 *cert, X509 *peer);
int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+ int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+ unsigned char *pass, ossl_ssize_t passlen);
=head1 DESCRIPTION
CMS_decrypt() extracts and decrypts the content from a CMS EnvelopedData
-or AuthEnvelopedData structure. B<pkey> is the private key of the recipient,
-B<cert> is the recipient's certificate, B<out> is a BIO to write the content to
-and B<flags> is an optional set of flags.
+or AuthEnvelopedData structure. I<pkey> is the private key of the recipient,
+I<cert> is the recipient's certificate, I<out> is a BIO to write the content to
+and I<flags> is an optional set of flags.
-The B<dcont> parameter is used in the rare case where the encrypted content
+The I<dcont> parameter is used in the rare case where the encrypted content
is detached. It will normally be set to NULL.
-CMS_decrypt_set1_pkey_and_peer() associates the private key B<pkey>, the
-corresponding certificate B<cert> and the originator certificate B<peer> with
-the CMS_ContentInfo structure B<cms>.
+CMS_decrypt_set1_pkey_and_peer() associates the private key I<pkey>, the
+corresponding certificate I<cert> and the originator certificate I<peer> with
+the CMS_ContentInfo structure I<cms>.
-CMS_decrypt_set1_pkey() associates the private key B<pkey>, corresponding
-certificate B<cert> with the CMS_ContentInfo structure B<cms>.
+CMS_decrypt_set1_pkey() associates the private key I<pkey> and the corresponding
+certificate I<cert> with the CMS_ContentInfo structure I<cms>.
+
+CMS_decrypt_set1_password() associates the secret I<pass> of length I<passlen>
+with the CMS_ContentInfo structure I<cms>.
=head1 NOTES
@@ -38,7 +44,7 @@ Although the recipients certificate is not needed to decrypt the data it is
needed to locate the appropriate (of possible several) recipients in the CMS
structure.
-If B<cert> is set to NULL all possible recipients are tried. This case however
+If I<cert> is set to NULL all possible recipients are tried. This case however
is problematic. To thwart the MMA attack (Bleichenbacher's attack on
PKCS #1 v1.5 RSA padding) all recipients are tried whether they succeed or
not. If no recipient succeeds then a random symmetric key is used to decrypt
@@ -55,22 +61,24 @@ open to attack.
It is possible to determine the correct recipient key by other means (for
example looking them up in a database) and setting them in the CMS structure
in advance using the CMS utility functions such as CMS_set1_pkey(). In this
-case both B<cert> and B<pkey> should be set to NULL.
+case both I<cert> and I<pkey> should be set to NULL.
To process KEKRecipientInfo types CMS_set1_key() or CMS_RecipientInfo_set0_key()
and CMS_RecipientInfo_decrypt() should be called before CMS_decrypt() and
-B<cert> and B<pkey> set to NULL.
+I<cert> and I<pkey> set to NULL.
-The following flags can be passed in the B<flags> parameter.
+The following flags can be passed in the I<flags> parameter.
-If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are deleted
-from the content. If the content is not of type B<text/plain> then an error is
+If the B<CMS_TEXT> flag is set MIME headers for type C<text/plain> are deleted
+from the content. If the content is not of type C<text/plain> then an error is
returned.
=head1 RETURN VALUES
-CMS_decrypt() returns either 1 for success or 0 for failure.
-The error can be obtained from ERR_get_error(3)
+CMS_decrypt(), CMS_decrypt_set1_pkey_and_peer(),
+CMS_decrypt_set1_pkey(), and CMS_decrypt_set1_password()
+return either 1 for success or 0 for failure.
+The error can be obtained from ERR_get_error(3).
=head1 BUGS
@@ -83,7 +91,8 @@ L<ERR_get_error(3)>, L<CMS_encrypt(3)>
=head1 HISTORY
-B<CMS_decrypt_set1_pkey_and_peer> was added in OpenSSL 3.0.
+CMS_decrypt_set1_pkey_and_peer() and CMS_decrypt_set1_password()
+were added in OpenSSL 3.0.
=head1 COPYRIGHT
diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod
index bc80caa51c..e24922bcf1 100644
--- a/doc/man3/X509_dup.pod
+++ b/doc/man3/X509_dup.pod
@@ -31,6 +31,7 @@ CMS_ContentInfo_free,
CMS_ContentInfo_new,
CMS_ContentInfo_new_ex,
CMS_ContentInfo_print_ctx,
+CMS_EnvelopedData_it,
CMS_ReceiptRequest_free,
CMS_ReceiptRequest_new,
CRL_DIST_POINTS_free,
diff --git a/include/openssl/cms.h.in b/include/openssl/cms.h.in
index 749b92cbcf..4be44b4bac 100644
--- a/include/openssl/cms.h.in
+++ b/include/openssl/cms.h.in
@@ -32,6 +32,7 @@ use OpenSSL::stackhash qw(generate_stack_macros);
extern "C" {
# endif
+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
typedef struct CMS_ContentInfo_st CMS_ContentInfo;
typedef struct CMS_SignerInfo_st CMS_SignerInfo;
typedef struct CMS_CertificateChoices CMS_CertificateChoices;
@@ -49,6 +50,7 @@ typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
.generate_stack_macros("CMS_RevocationInfoChoice");
-}
+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
@@ -128,7 +130,7 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
unsigned int flags);
CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey,
STACK_OF(X509) *certs, BIO *data,
- unsigned int flags, OSSL_LIB_CTX *ctx,
+ unsigned int flags, OSSL_LIB_CTX *libctx,
const char *propq);
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
@@ -138,27 +140,26 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags,
- OSSL_LIB_CTX *ctx, const char *propq);
+ OSSL_LIB_CTX *libctx, const char *propq);
int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
unsigned int flags);
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
unsigned int flags);
CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md,
- unsigned int flags, OSSL_LIB_CTX *ctx,
+ unsigned int flags, OSSL_LIB_CTX *libctx,
const char *propq);
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
const unsigned char *key, size_t keylen,
BIO *dcont, BIO *out, unsigned int flags);
-
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
const unsigned char *key,
size_t keylen, unsigned int flags);
CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher,
const unsigned char *key,
size_t keylen, unsigned int flags,
- OSSL_LIB_CTX *ctx,
+ OSSL_LIB_CTX *libctx,
const char *propq);
int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
@@ -177,7 +178,7 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags);
CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags,
- OSSL_LIB_CTX *ctx, const char *propq);
+ OSSL_LIB_CTX *libctx, const char *propq);
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
BIO *dcont, BIO *out, unsigned int flags);
@@ -196,12 +197,16 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher);
CMS_ContentInfo *
-CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *ctx,
+CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
const char *propq);
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher,
- OSSL_LIB_CTX *ctx,
+ OSSL_LIB_CTX *libctx,
const char *propq);
+BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data,
+ EVP_PKEY *pkey, X509 *cert,
+ ASN1_OCTET_STRING *secret, unsigned int flags,
+ OSSL_LIB_CTX *libctx, const char *propq);
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
X509 *recip, unsigned int flags);
@@ -346,7 +351,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex(
unsigned char *id, int idlen, int allorfirst,
STACK_OF(GENERAL_NAMES) *receiptList,
STACK_OF(GENERAL_NAMES) *receiptsTo,
- OSSL_LIB_CTX *ctx);
+ OSSL_LIB_CTX *libctx);
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
diff --git a/util/libcrypto.num b/util/libcrypto.num
index dcd9d02924..cb0d48cfca 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5438,5 +5438,7 @@ ASYNC_set_mem_functions ? 3_1_0 EXIST::FUNCTION:
ASYNC_get_mem_functions ? 3_1_0 EXIST::FUNCTION:
BIO_ADDR_dup ? 3_1_0 EXIST::FUNCTION:SOCK
CMS_final_digest ? 3_1_0 EXIST::FUNCTION:CMS
+CMS_EnvelopedData_it ? 3_1_0 EXIST::FUNCTION:CMS
+CMS_EnvelopedData_decrypt ? 3_1_0 EXIST::FUNCTION:CMS
OPENSSL_strcasecmp ? 3_0_3 EXIST::FUNCTION:
OPENSSL_strncasecmp ? 3_0_3 EXIST::FUNCTION:
diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt
index b93a081f6d..a0937d4d98 100644
--- a/util/missingcrypto.txt
+++ b/util/missingcrypto.txt
@@ -328,7 +328,6 @@ CMS_data(3)
CMS_dataFinal(3)
CMS_dataInit(3)
CMS_decrypt_set1_key(3)
-CMS_decrypt_set1_password(3)
CMS_digest_verify(3)
CMS_is_detached(3)
CMS_set1_signers_certs(3)