Fix leak with ASN.1 combine.

When parsing a combined structure pass a flag to the decode routine
so on error a pointer to the parent structure is not zeroed as
this will leak any additional components in the parent.

This can leak memory in any application parsing PKCS#7 or CMS structures.

CVE-2015-3195.

Thanks to Adam Langley (Google/BoringSSL) for discovering this bug using
libFuzzer.

PR#4131

(Imported from upstream's cc598f321fbac9c04da5766243ed55d55948637d, with test
from our original report. Verified ASan trips up on the test without the fix.)

Change-Id: I007d93f172b2f16bf6845d685d72717ed840276c
Reviewed-on: https://boringssl-review.googlesource.com/6615
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index d852ad7..7c81753 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -170,6 +170,7 @@
 	int otag;
 	int ret = 0;
 	ASN1_VALUE **pchptr, *ptmpval;
+	int combine = aclass & ASN1_TFLG_COMBINE;
 	if (!pval)
 		return 0;
 	if (aux && aux->asn1_cb)
@@ -526,7 +527,8 @@
 	auxerr:
 	OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
 	err:
-	ASN1_item_ex_free(pval, it);
+	if (combine == 0)
+		ASN1_item_ex_free(pval, it);
 	if (errtt)
 		ERR_add_error_data(4, "Field=", errtt->field_name,
 					", Type=", it->sname);
@@ -742,7 +744,7 @@
 		{
 		/* Nothing special */
 		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-							-1, 0, opt, ctx);
+							-1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
 		if (!ret)
 			{
 			OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index 86476fc..07cb782 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -342,6 +342,22 @@
     0x07,
 };
 
+// kInvalidPrivateKey is an invalid private key. See
+// https://rt.openssl.org/Ticket/Display.html?id=4131.
+static const uint8_t kInvalidPrivateKey[] = {
+    0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08,
+    0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8,
+    0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08,
+    0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80,
+    0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b,
+    0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3,
+    0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04,
+    0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29,
+    0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8,
+    0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
+};
+
 static ScopedEVP_PKEY LoadExampleRSAKey() {
   ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
                                            sizeof(kExampleRSAKeyDER)));
@@ -519,8 +535,8 @@
   return true;
 }
 
-static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
-                                   int expected_id) {
+static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
+                                int expected_id) {
   const uint8_t *p = input;
   ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
   if (!pkey || p != input + input_len) {
@@ -536,6 +552,42 @@
   return true;
 }
 
+static bool Testd2i_AutoPrivateKey() {
+  if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
+                           EVP_PKEY_RSA)) {
+    fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
+    return false;
+  }
+
+  if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
+                           EVP_PKEY_RSA)) {
+    fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+    return false;
+  }
+
+  if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
+                           EVP_PKEY_EC)) {
+    fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
+    return false;
+  }
+
+  if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
+                           EVP_PKEY_DSA)) {
+    fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+    return false;
+  }
+
+  const uint8_t *p = kInvalidPrivateKey;
+  ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
+  if (pkey) {
+    fprintf(stderr, "Parsed invalid private key\n");
+    return false;
+  }
+  ERR_clear_error();
+
+  return true;
+}
+
 // TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
 static bool TestEVP_PKCS82PKEY(void) {
   const uint8_t *derp = kExampleBadECKeyDER;
@@ -641,30 +693,8 @@
     return 1;
   }
 
-  if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
-                              EVP_PKEY_RSA)) {
-    fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
-    ERR_print_errors_fp(stderr);
-    return 1;
-  }
-
-  if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
-                              EVP_PKEY_RSA)) {
-    fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
-    ERR_print_errors_fp(stderr);
-    return 1;
-  }
-
-  if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
-                              EVP_PKEY_EC)) {
-    fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
-    ERR_print_errors_fp(stderr);
-    return 1;
-  }
-
-  if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
-                              EVP_PKEY_DSA)) {
-    fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+  if (!Testd2i_AutoPrivateKey()) {
+    fprintf(stderr, "Testd2i_AutoPrivateKey failed\n");
     ERR_print_errors_fp(stderr);
     return 1;
   }