aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Belyavskiy <beldmit@gmail.com>2020-08-28 16:39:16 +0300
committerDmitry Belyavskiy <beldmit@gmail.com>2020-08-29 19:36:36 +0300
commit835b2900168bfd1cc471bf1d798d3b5b7219cd4d (patch)
tree10d1c0ea7aed1de72d894cda83e594c98a0c719a
parentbd1bbbfe516de5d0a6f2a2494c0dd386f2f178da (diff)
downloadopenssl-835b2900168bfd1cc471bf1d798d3b5b7219cd4d.zip
openssl-835b2900168bfd1cc471bf1d798d3b5b7219cd4d.tar.gz
openssl-835b2900168bfd1cc471bf1d798d3b5b7219cd4d.tar.bz2
Fix PKCS#7 so that it still works with non fetchable cipher algorithms.
Fixes #12697 Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12740)
-rw-r--r--crypto/pkcs7/pk7_doit.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 573e9eb..6a7af78 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -219,6 +219,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
BIO *out = NULL, *btmp = NULL;
X509_ALGOR *xa = NULL;
EVP_CIPHER *fetched_cipher = NULL;
+ const EVP_CIPHER *cipher;
const EVP_CIPHER *evp_cipher = NULL;
STACK_OF(X509_ALGOR) *md_sk = NULL;
STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
@@ -311,13 +312,22 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
if (RAND_bytes_ex(p7_ctx->libctx, iv, ivlen) <= 0)
goto err;
+ (void)ERR_set_mark();
fetched_cipher = EVP_CIPHER_fetch(p7_ctx->libctx,
EVP_CIPHER_name(evp_cipher),
p7_ctx->propq);
- if (fetched_cipher == NULL)
+ if (fetched_cipher != NULL)
+ cipher = fetched_cipher;
+ else
+ cipher = evp_cipher;
+
+ if (cipher == NULL) {
+ (void)ERR_clear_last_mark();
goto err;
+ }
+ (void)ERR_pop_to_mark();
- if (EVP_CipherInit_ex(ctx, fetched_cipher, NULL, NULL, NULL, 1) <= 0)
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0)
goto err;
EVP_CIPHER_free(fetched_cipher);
@@ -401,6 +411,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
EVP_MD *evp_md = NULL;
const EVP_MD *md;
EVP_CIPHER *evp_cipher = NULL;
+ const EVP_CIPHER *cipher = NULL;
EVP_CIPHER_CTX *evp_ctx = NULL;
X509_ALGOR *enc_alg = NULL;
STACK_OF(X509_ALGOR) *md_sk = NULL;
@@ -450,12 +461,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
+
+ (void)ERR_set_mark();
evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
- if (evp_cipher == NULL) {
+ if (evp_cipher != NULL)
+ cipher = evp_cipher;
+ else
+ cipher = EVP_get_cipherbyname(name);
+
+ if (cipher == NULL) {
+ (void)ERR_clear_last_mark();
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
+ (void)ERR_pop_to_mark();
break;
case NID_pkcs7_enveloped:
rsk = p7->d.enveloped->recipientinfo;
@@ -463,12 +483,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
/* data_body is NULL if the optional EncryptedContent is missing. */
data_body = p7->d.enveloped->enc_data->enc_data;
name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
+
+ (void)ERR_set_mark();
evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
- if (evp_cipher == NULL) {
+ if (evp_cipher != NULL)
+ cipher = evp_cipher;
+ else
+ cipher = EVP_get_cipherbyname(name);
+
+ if (cipher == NULL) {
+ (void)ERR_clear_last_mark();
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
+ (void)ERR_pop_to_mark();
break;
default:
PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
@@ -517,7 +546,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
}
}
- if (evp_cipher != NULL) {
+ if (cipher != NULL) {
if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
goto err;
@@ -557,7 +586,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
ri->ctx = p7_ctx;
if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
- EVP_CIPHER_key_length(evp_cipher)) < 0)
+ EVP_CIPHER_key_length(cipher)) < 0)
goto err;
ERR_clear_error();
}
@@ -571,7 +600,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
evp_ctx = NULL;
BIO_get_cipher_ctx(etmp, &evp_ctx);
- if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
+ if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0)
goto err;
if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
goto err;