summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
authortedu <>2015-03-19 14:00:22 +0000
committertedu <>2015-03-19 14:00:22 +0000
commit325847dec91a0775a2c9806147ab783c0737cc84 (patch)
treee1849327a9d18d917e7698c775d31f7ae7c4e34f /src/lib/libcrypto/pkcs7
parent5018b21486fe3d91084c0d32a86d1240d832e25e (diff)
downloadopenbsd-325847dec91a0775a2c9806147ab783c0737cc84.tar.gz
openbsd-325847dec91a0775a2c9806147ab783c0737cc84.tar.bz2
openbsd-325847dec91a0775a2c9806147ab783c0737cc84.zip
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 'src/lib/libcrypto/pkcs7')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c98
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c4
2 files changed, 86 insertions, 16 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
index 252fab04d7..d0cf84df80 100644
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/src/lib/libcrypto/pkcs7/pk7_doit.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pk7_doit.c,v 1.31 2015/02/07 13:19:15 doug Exp $ */ 1/* $OpenBSD: pk7_doit.c,v 1.32 2015/03/19 14:00:22 tedu Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -261,6 +261,28 @@ PKCS7_dataInit(PKCS7 *p7, BIO *bio)
261 PKCS7_RECIP_INFO *ri = NULL; 261 PKCS7_RECIP_INFO *ri = NULL;
262 ASN1_OCTET_STRING *os = NULL; 262 ASN1_OCTET_STRING *os = NULL;
263 263
264 if (p7 == NULL) {
265 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
266 return NULL;
267 }
268
269 /*
270 * The content field in the PKCS7 ContentInfo is optional,
271 * but that really only applies to inner content (precisely,
272 * detached signatures).
273 *
274 * When reading content, missing outer content is therefore
275 * treated as an error.
276 *
277 * When creating content, PKCS7_content_new() must be called
278 * before calling this method, so a NULL p7->d is always
279 * an error.
280 */
281 if (p7->d.ptr == NULL) {
282 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
283 return NULL;
284 }
285
264 i = OBJ_obj2nid(p7->type); 286 i = OBJ_obj2nid(p7->type);
265 p7->state = PKCS7_S_HEADER; 287 p7->state = PKCS7_S_HEADER;
266 288
@@ -417,6 +439,17 @@ PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
417 unsigned char *ek = NULL, *tkey = NULL; 439 unsigned char *ek = NULL, *tkey = NULL;
418 int eklen = 0, tkeylen = 0; 440 int eklen = 0, tkeylen = 0;
419 441
442 if (p7 == NULL) {
443 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
444 PKCS7_R_INVALID_NULL_POINTER);
445 return NULL;
446 }
447
448 if (p7->d.ptr == NULL) {
449 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
450 return NULL;
451 }
452
420 i = OBJ_obj2nid(p7->type); 453 i = OBJ_obj2nid(p7->type);
421 p7->state = PKCS7_S_HEADER; 454 p7->state = PKCS7_S_HEADER;
422 455
@@ -691,6 +724,17 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
691 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; 724 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
692 ASN1_OCTET_STRING *os = NULL; 725 ASN1_OCTET_STRING *os = NULL;
693 726
727 if (p7 == NULL) {
728 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
729 PKCS7_R_INVALID_NULL_POINTER);
730 return 0;
731 }
732
733 if (p7->d.ptr == NULL) {
734 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
735 return 0;
736 }
737
694 EVP_MD_CTX_init(&ctx_tmp); 738 EVP_MD_CTX_init(&ctx_tmp);
695 i = OBJ_obj2nid(p7->type); 739 i = OBJ_obj2nid(p7->type);
696 p7->state = PKCS7_S_HEADER; 740 p7->state = PKCS7_S_HEADER;
@@ -736,6 +780,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
736 /* If detached data then the content is excluded */ 780 /* If detached data then the content is excluded */
737 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 781 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
738 M_ASN1_OCTET_STRING_free(os); 782 M_ASN1_OCTET_STRING_free(os);
783 os = NULL;
739 p7->d.sign->contents->d.data = NULL; 784 p7->d.sign->contents->d.data = NULL;
740 } 785 }
741 break; 786 break;
@@ -750,6 +795,7 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
750 if (PKCS7_type_is_data(p7->d.digest->contents) && 795 if (PKCS7_type_is_data(p7->d.digest->contents) &&
751 p7->detached) { 796 p7->detached) {
752 M_ASN1_OCTET_STRING_free(os); 797 M_ASN1_OCTET_STRING_free(os);
798 os = NULL;
753 p7->d.digest->contents->d.data = NULL; 799 p7->d.digest->contents->d.data = NULL;
754 } 800 }
755 break; 801 break;
@@ -815,22 +861,32 @@ PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
815 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 861 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
816 } 862 }
817 863
818 if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) { 864 if (!PKCS7_is_detached(p7)) {
819 char *cont; 865 /*
820 long contlen; 866 * NOTE: only reach os == NULL here because detached
821 btmp = BIO_find_type(bio, BIO_TYPE_MEM); 867 * digested data support is broken?
822 if (btmp == NULL) { 868 */
823 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 869 if (os == NULL)
824 PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
825 goto err; 870 goto err;
871 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
872 char *cont;
873 long contlen;
874
875 btmp = BIO_find_type(bio, BIO_TYPE_MEM);
876 if (btmp == NULL) {
877 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
878 PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
879 goto err;
880 }
881 contlen = BIO_get_mem_data(btmp, &cont);
882 /*
883 * Mark the BIO read only then we can use its copy
884 * of the data instead of making an extra copy.
885 */
886 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
887 BIO_set_mem_eof_return(btmp, 0);
888 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
826 } 889 }
827 contlen = BIO_get_mem_data(btmp, &cont);
828 /* Mark the BIO read only then we can use its copy of the data
829 * instead of making an extra copy.
830 */
831 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
832 BIO_set_mem_eof_return(btmp, 0);
833 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
834 } 890 }
835 ret = 1; 891 ret = 1;
836err: 892err:
@@ -905,6 +961,17 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
905 STACK_OF(X509) *cert; 961 STACK_OF(X509) *cert;
906 X509 *x509; 962 X509 *x509;
907 963
964 if (p7 == NULL) {
965 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
966 PKCS7_R_INVALID_NULL_POINTER);
967 return 0;
968 }
969
970 if (p7->d.ptr == NULL) {
971 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
972 return 0;
973 }
974
908 if (PKCS7_type_is_signed(p7)) { 975 if (PKCS7_type_is_signed(p7)) {
909 cert = p7->d.sign->cert; 976 cert = p7->d.sign->cert;
910 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 977 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
@@ -941,6 +1008,7 @@ PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
941 1008
942 return PKCS7_signatureVerify(bio, p7, si, x509); 1009 return PKCS7_signatureVerify(bio, p7, si, x509);
943err: 1010err:
1011
944 return ret; 1012 return ret;
945} 1013}
946 1014
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
index 27370800c9..3eec92e29b 100644
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/src/lib/libcrypto/pkcs7/pk7_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pk7_lib.c,v 1.14 2014/07/12 16:03:37 miod Exp $ */ 1/* $OpenBSD: pk7_lib.c,v 1.15 2015/03/19 14:00:22 tedu Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -460,6 +460,8 @@ PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
460STACK_OF(PKCS7_SIGNER_INFO) * 460STACK_OF(PKCS7_SIGNER_INFO) *
461PKCS7_get_signer_info(PKCS7 *p7) 461PKCS7_get_signer_info(PKCS7 *p7)
462{ 462{
463 if (p7 == NULL || p7->d.ptr == NULL)
464 return (NULL);
463 if (PKCS7_type_is_signed(p7)) { 465 if (PKCS7_type_is_signed(p7)) {
464 return (p7->d.sign->signer_info); 466 return (p7->d.sign->signer_info);
465 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 467 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {