CVE-2015-1790: Other (NVD-CWE-Other)
value: The PKCS7_dataDecodefunction in crypto/pkcs7/pk7_doit.c in OpenSSL before 0.9.8zg, 1.0.0 before 1.0.0s, 1.0.1 before 1.0.1n, and 1.0.2 before 1.0.2b allows remote attackers to cause a denial of service (NULL pointer dereference and application crash) via a PKCS#7 blob that uses ASN.1 encoding and lacks inner EncryptedContent data.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Published: 2015-06-12T19:59Z
Repository: https://github.com/openssl/openssl
Language: C
Files changed: crypto/pkcs7/pk7_doit.c
Commit date: 2015-06-11 11:06:31 +0100
Commit message: PKCS#7: Fix NULL dereference with missing EncryptedContent.

CVE-2015-1790

Reviewed-by: Rich Salz <rsalz@openssl.org>

Diff: diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 2c8dd87136..cc2f3be554 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -430,10 +430,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
     i = OBJ_obj2nid(p7->type);
     p7->state = PKCS7_S_HEADER;
 
     switch (i) {
     case NID_pkcs7_signed:
+        /*
+         * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+         * field and optional content.
+         * data_body is NULL if that structure has no (=detached) content
+         * or if the contentType is wrong (i.e., not "data").
+         */
         data_body = PKCS7_get_octet_string(p7->d.sign->contents);
         if (!PKCS7_is_detached(p7) && data_body == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                      PKCS7_R_INVALID_SIGNED_DATA_TYPE);
             goto err;
@@ -441,10 +447,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
         md_sk = p7->d.sign->md_algs;
         break;
     case NID_pkcs7_signedAndEnveloped:
         rsk = p7->d.signed_and_enveloped->recipientinfo;
         md_sk = p7->d.signed_and_enveloped->md_algs;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
         enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
@@ -453,10 +460,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
         }
         break;
     case NID_pkcs7_enveloped:
         rsk = p7->d.enveloped->recipientinfo;
         enc_alg = p7->d.enveloped->enc_data->algorithm;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.enveloped->enc_data->enc_data;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                      PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
@@ -466,10 +474,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
     default:
         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
         goto err;
     }
 
+    /* Detached content must be supplied via in_bio instead. */
+    if (data_body == NULL && in_bio == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+        goto err;
+    }
+
     /* We will be checking the signature */
     if (md_sk != NULL) {
         for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
             xa = sk_X509_ALGOR_value(md_sk, i);
             if ((btmp = BIO_new(BIO_f_md())) == NULL) {
@@ -591,11 +605,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
             out = etmp;
         else
             BIO_push(out, etmp);
         etmp = NULL;
     }
-    if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
+    if (in_bio != NULL) {
         bio = in_bio;
     } else {
         if (data_body->length > 0)
             bio = BIO_new_mem_buf(data_body->data, data_body->length);
         else {

Vulnerable code:     if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
Fixed code:         /*
         * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
         * field and optional content.
         * data_body is NULL if that structure has no (=detached) content
         * or if the contentType is wrong (i.e., not "data").
         */
        /* data_body is NULL if the optional EncryptedContent is missing. */
        /* data_body is NULL if the optional EncryptedContent is missing. */
    /* Detached content must be supplied via in_bio instead. */
    if (data_body == NULL && in_bio == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
        goto err;
    }

    if (in_bio != NULL) {