summaryrefslogtreecommitdiff
path: root/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2015-03-19 14:00:23 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2015-03-19 14:00:23 +0000
commit836b495106f594955b58752d134d1fdfdc8973b1 (patch)
tree7822387262a7d3bef9e0cd5e3fe209b4f0b5c5c6 /lib/libcrypto/pkcs7
parent5ee002f51cf23a40109eb29a0600077fe8edc54b (diff)
Fix several crash causing defects from OpenSSL.
These include: CVE-2015-0209 - Use After Free following d2i_ECPrivatekey error CVE-2015-0286 - Segmentation fault in ASN1_TYPE_cmp CVE-2015-0287 - ASN.1 structure reuse memory corruption CVE-2015-0289 - PKCS7 NULL pointer dereferences Several other issues did not apply or were already fixed. Refer to https://www.openssl.org/news/secadv_20150319.txt joint work with beck, doug, guenther, jsing, miod
Diffstat (limited to 'lib/libcrypto/pkcs7')
-rw-r--r--lib/libcrypto/pkcs7/pk7_doit.c98
-rw-r--r--lib/libcrypto/pkcs7/pk7_lib.c4
2 files changed, 86 insertions, 16 deletions
diff --git a/lib/libcrypto/pkcs7/pk7_doit.c b/lib/libcrypto/pkcs7/pk7_doit.c
index 252fab04d7c..d0cf84df80b 100644
--- a/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/lib/libcrypto/pkcs7/pk7_doit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pk7_doit.c,v 1.31 2015/02/07 13:19:15 doug Exp $ */
+/* $OpenBSD: pk7_doit.c,v 1.32 2015/03/19 14:00:22 tedu Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -261,6 +261,28 @@ PKCS7_dataInit(PKCS7 *p7, BIO *bio)
PKCS7_RECIP_INFO *ri = NULL;
ASN1_OCTET_STRING *os = NULL;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+
+ /*
+ * The content field in the PKCS7 ContentInfo is optional,
+ * but that really only applies to inner content (precisely,
+ * detached signatures).
+ *
+ * When reading content, missing outer content is therefore
+ * treated as an error.
+ *
+ * When creating content, PKCS7_content_new() must be called
+ * before calling this method, so a NULL p7->d is always
+ * an error.
+ */
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
i = OBJ_obj2nid(p7->type);
p7->state = PKCS7_S_HEADER;
@@ -417,6 +439,17 @@ PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
unsigned char *ek = NULL, *tkey = NULL;
int eklen = 0, tkeylen = 0;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_INVALID_NULL_POINTER);
+ return NULL;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ return NULL;
+ }
+
i = OBJ_obj2nid(p7->type);
p7->state = PKCS7_S_HEADER;
@@ -691,6 +724,17 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
ASN1_OCTET_STRING *os = NULL;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+ PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
EVP_MD_CTX_init(&ctx_tmp);
i = OBJ_obj2nid(p7->type);
p7->state = PKCS7_S_HEADER;
@@ -736,6 +780,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
/* If detached data then the content is excluded */
if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
p7->d.sign->contents->d.data = NULL;
}
break;
@@ -750,6 +795,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
if (PKCS7_type_is_data(p7->d.digest->contents) &&
p7->detached) {
M_ASN1_OCTET_STRING_free(os);
+ os = NULL;
p7->d.digest->contents->d.data = NULL;
}
break;
@@ -815,22 +861,32 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
}
- if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) {
- char *cont;
- long contlen;
- btmp = BIO_find_type(bio, BIO_TYPE_MEM);
- if (btmp == NULL) {
- PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
- PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+ if (!PKCS7_is_detached(p7)) {
+ /*
+ * NOTE: only reach os == NULL here because detached
+ * digested data support is broken?
+ */
+ if (os == NULL)
goto err;
+ if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
+ char *cont;
+ long contlen;
+
+ btmp = BIO_find_type(bio, BIO_TYPE_MEM);
+ if (btmp == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+ PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+ goto err;
+ }
+ contlen = BIO_get_mem_data(btmp, &cont);
+ /*
+ * Mark the BIO read only then we can use its copy
+ * of the data instead of making an extra copy.
+ */
+ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
+ BIO_set_mem_eof_return(btmp, 0);
+ ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
}
- contlen = BIO_get_mem_data(btmp, &cont);
- /* Mark the BIO read only then we can use its copy of the data
- * instead of making an extra copy.
- */
- BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
- BIO_set_mem_eof_return(btmp, 0);
- ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
}
ret = 1;
err:
@@ -905,6 +961,17 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
STACK_OF(X509) *cert;
X509 *x509;
+ if (p7 == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
+ PKCS7_R_INVALID_NULL_POINTER);
+ return 0;
+ }
+
+ if (p7->d.ptr == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+ return 0;
+ }
+
if (PKCS7_type_is_signed(p7)) {
cert = p7->d.sign->cert;
} else if (PKCS7_type_is_signedAndEnveloped(p7)) {
@@ -941,6 +1008,7 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
return PKCS7_signatureVerify(bio, p7, si, x509);
err:
+
return ret;
}
diff --git a/lib/libcrypto/pkcs7/pk7_lib.c b/lib/libcrypto/pkcs7/pk7_lib.c
index 27370800c97..3eec92e29b4 100644
--- a/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/lib/libcrypto/pkcs7/pk7_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pk7_lib.c,v 1.14 2014/07/12 16:03:37 miod Exp $ */
+/* $OpenBSD: pk7_lib.c,v 1.15 2015/03/19 14:00:22 tedu Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -460,6 +460,8 @@ PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
STACK_OF(PKCS7_SIGNER_INFO) *
PKCS7_get_signer_info(PKCS7 *p7)
{
+ if (p7 == NULL || p7->d.ptr == NULL)
+ return (NULL);
if (PKCS7_type_is_signed(p7)) {
return (p7->d.sign->signer_info);
} else if (PKCS7_type_is_signedAndEnveloped(p7)) {