Module Name:    src
Committed By:   riz
Date:           Thu Mar 19 16:40:07 UTC 2015

Modified Files:
        src/crypto/dist/openssl/crypto/asn1 [netbsd-5-1]: a_type.c tasn_dec.c
        src/crypto/dist/openssl/crypto/pkcs7 [netbsd-5-1]: pk7_doit.c pk7_lib.c
        src/crypto/dist/openssl/doc/crypto [netbsd-5-1]: d2i_X509.pod
        src/crypto/dist/openssl/ssl [netbsd-5-1]: s2_lib.c s2_srvr.c

Log Message:
Pull up following revision(s) (requested by spz in ticket #1954):
        crypto/external/bsd/openssl/dist/ssl/s2_lib.c: revision 1.3
        crypto/external/bsd/openssl/dist/crypto/asn1/a_type.c: revision 1.2
        crypto/external/bsd/openssl/dist/doc/crypto/d2i_X509.pod: revision 1.2
        crypto/external/bsd/openssl/dist/crypto/pkcs7/pk7_doit.c: revision 1.2
        crypto/external/bsd/openssl/dist/crypto/pkcs7/pk7_lib.c: revision 1.2
        crypto/external/bsd/openssl/dist/ssl/s2_srvr.c: revision 1.2
        crypto/external/bsd/openssl/dist/crypto/asn1/tasn_dec.c: revision 1.2
patches for todays' OpenSSL security advisory from OpenSSL, as relevant
to NetBSD base:
OpenSSL Security Advisory [19 Mar 2015]
=======================================
Reclassified: RSA silently downgrades to EXPORT_RSA [Client] (CVE-2015-0204)
============================================================================
Severity: High
This security issue was previously announced by the OpenSSL project and
classified as "low" severity. This severity rating has now been changed to
"high".
This was classified low because it was originally thought that server RSA
export ciphersuite support was rare: a client was only vulnerable to a MITM
attack against a server which supports an RSA export ciphersuite. Recent
studies have shown that RSA export ciphersuites support is far more common.
This issue affects OpenSSL versions: 1.0.1, 1.0.0 and 0.9.8.
** issue already committed see last release **
OpenSSL 1.0.1 users should upgrade to 1.0.1k.
OpenSSL 1.0.0 users should upgrade to 1.0.0p.
OpenSSL 0.9.8 users should upgrade to 0.9.8zd.
This issue was reported to OpenSSL on 22nd October 2014 by Karthikeyan
Bhargavan of the PROSECCO team at INRIA. The fix was developed by Stephen
Henson of the OpenSSL core team. It was previously announced in the OpenSSL
security advisory on 8th January 2015.
Segmentation fault in ASN1_TYPE_cmp (CVE-2015-0286)
===================================================
Severity: Moderate
The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is
made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check
certificate signature algorithm consistency this can be used to crash any
certificate verification operation and exploited in a DoS attack. Any
application which performs certificate verification is vulnerable including
OpenSSL clients and servers which enable client authentication.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0 and 0.9.8.
OpenSSL 1.0.2 users should upgrade to 1.0.2a
commit 1b8ac2b07d02207f2b88e0b009b0bff4ef7eda96
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
commit ee5a1253285e5c9f406c8b57b0686319b70c07d8
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
commit 1e3ca524cb38ec92deea37629718e98aba43bc5d
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
commit 7058bd1712828a78d34457b1cfc32bdc1e6d3d33
This issue was discovered and fixed by Stephen Henson of the OpenSSL
development team.
ASN.1 structure reuse memory corruption (CVE-2015-0287)
=======================================================
Severity: Moderate
Reusing a structure in ASN.1 parsing may allow an attacker to cause
memory corruption via an invalid write. Such reuse is and has been
strongly discouraged and is believed to be rare.
Applications that parse structures containing CHOICE or ANY DEFINED BY
components may be affected. Certificate parsing (d2i_X509 and related
functions) are however not affected. OpenSSL clients and servers are
not affected.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0
and 0.9.8.
OpenSSL 1.0.2 users should upgrade to 1.0.2a
commit 0ca8edbe6ec402e39c9e095f8ae11dba8fa93fc1
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
commit a9f34a7aac5fd89f33a34fb71e954b85fbf35875
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
commit d96692c933fe02829c3e922bf7f239e0bd003759
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
commit 5722767d5dc1a3b5505058fe27877fc993fe9a5a
This issue was discovered by Emilia K�sper and a fix developed by
Stephen Henson of the OpenSSL development team.
PKCS7 NULL pointer dereferences (CVE-2015-0289)
===============================================
Severity: Moderate
The PKCS#7 parsing code does not handle missing outer ContentInfo correctly.
An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with
missing content and trigger a NULL pointer dereference on parsing.
Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or
otherwise parse PKCS#7 structures from untrusted sources are
affected. OpenSSL clients and servers are not affected.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0
and 0.9.8.
OpenSSL 1.0.2 users should upgrade to 1.0.2a
commit e0d6a791c53b64da64277c5565eb89b1cb149fc3
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
commit d3d52c73544bba800c2a8f5ef3376358158cf2ca
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
commit 1f858109d0556b5864bb6a0aa3e2d177b1cc4552
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
commit f20caf7f66cb1eb9ba9562e6097bc7b64d207cb9
This issue was reported to OpenSSL on February 16th 2015 by Michal
Zalewski (Google) and a fix developed by Emilia K�sper of the OpenSSL
development team.
Base64 decode (CVE-2015-0292)
=============================
Severity: Moderate
A vulnerability existed in previous versions of OpenSSL related to the
processing of base64 encoded data. Any code path that reads base64 data from an
untrusted source could be affected (such as the PEM processing routines).
Maliciously crafted base 64 data could trigger a segmenation fault or memory
corruption. This was addressed in previous versions of OpenSSL but has not been
included in any security advisory until now.
This issue affects OpenSSL versions: 1.0.1, 1.0.0 and 0.9.8.
OpenSSL 1.0.1 users should upgrade to 1.0.1h.
OpenSSL 1.0.0 users should upgrade to 1.0.0m.
OpenSSL 0.9.8 users should upgrade to 0.9.8za.
The fix for this issue can be identified by commits d0666f289a (1.0.1),
84fe686173 (1.0.0) and 9febee0272 (0.9.8). This issue was originally reported by
Robert Dugal and subsequently by David Ramos.
DoS via reachable assert in SSLv2 servers (CVE-2015-0293)
=========================================================
Severity: Moderate
A malicious client can trigger an OPENSSL_assert (i.e., an abort) in
servers that both support SSLv2 and enable export cipher suites by sending
a specially crafted SSLv2 CLIENT-MASTER-KEY message.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0
and 0.9.8.
OpenSSL 1.0.2 users should upgrade to 1.0.2a
commit b29d57f20d4821a9d3f4e19673a89615e4c6fcf0
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
commit a40c1bcb8c37fbad24d8f28f0fb0204d76f0fee2
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
commit ee4435e5b587879e7bd66df10d4d9ec274e2b163
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
commit ab646ee5a6a7b8cace425a617a053ad6d7977086
This issue was discovered by Sean Burford (Google) and Emilia K�sper
(OpenSSL development team) in March 2015 and the fix was developed by
Emilia K�sper.
Use After Free following d2i_ECPrivatekey error (CVE-2015-0209)
===============================================================
Severity: Low
A malformed EC private key file consumed via the d2i_ECPrivateKey function could
cause a use after free condition. This, in turn, could cause a double
free in several private key parsing functions (such as d2i_PrivateKey
or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption
for applications that receive EC private keys from untrusted
sources. This scenario is considered rare.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0 and 0.9.8.
** issue already committed **
OpenSSL 1.0.2 users should upgrade to 1.0.2a
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
https://github.com/openssl/openssl/commit/1b4a8df38fc9ab3c089ca5765075ee53ec5bd66a
This issue was discovered by the BoringSSL project and fixed in their commit
517073cd4b. The OpenSSL fix was developed by Matt Caswell of the OpenSSL
development team.
X509_to_X509_REQ NULL pointer deref (CVE-2015-0288)
===================================================
Severity: Low
The function X509_to_X509_REQ will crash with a NULL pointer dereference if
the certificate key is invalid. This function is rarely used in practice.
This issue affects all current OpenSSL versions: 1.0.2, 1.0.1, 1.0.0
and 0.9.8.
** issue already committed **
OpenSSL 1.0.2 users should upgrade to 1.0.2a
OpenSSL 1.0.1 users should upgrade to 1.0.1m.
OpenSSL 1.0.0 users should upgrade to 1.0.0r.
OpenSSL 0.9.8 users should upgrade to 0.9.8zf.
https://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=28a00bcd8e318da18031b2ac8778c64147cd54f9
This issue was discovered by Brian Carpenter and a fix developed by Stephen
Henson of the OpenSSL development team.
References
==========
URL for this Security Advisory:
https://www.openssl.org/news/secadv_20150319.txt
Note: the online version of the advisory may be updated with additional
details over time.
For details of OpenSSL severity classifications please see:
https://www.openssl.org/about/secpolicy.html


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.7.12.1 -r1.1.1.7.12.2 \
    src/crypto/dist/openssl/crypto/asn1/a_type.c
cvs rdiff -u -r1.8.4.1.6.1 -r1.8.4.1.6.2 \
    src/crypto/dist/openssl/crypto/asn1/tasn_dec.c
cvs rdiff -u -r1.6 -r1.6.12.1 src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c
cvs rdiff -u -r1.1.1.8 -r1.1.1.8.12.1 \
    src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c
cvs rdiff -u -r1.1.1.2 -r1.1.1.2.34.1 \
    src/crypto/dist/openssl/doc/crypto/d2i_X509.pod
cvs rdiff -u -r1.12.12.1 -r1.12.12.2 src/crypto/dist/openssl/ssl/s2_lib.c
cvs rdiff -u -r1.9.4.1.6.1 -r1.9.4.1.6.2 \
    src/crypto/dist/openssl/ssl/s2_srvr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/dist/openssl/crypto/asn1/a_type.c
diff -u src/crypto/dist/openssl/crypto/asn1/a_type.c:1.1.1.7.12.1 src/crypto/dist/openssl/crypto/asn1/a_type.c:1.1.1.7.12.2
--- src/crypto/dist/openssl/crypto/asn1/a_type.c:1.1.1.7.12.1	Mon Jan 26 11:47:23 2015
+++ src/crypto/dist/openssl/crypto/asn1/a_type.c	Thu Mar 19 16:40:07 2015
@@ -124,6 +124,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, AS
 	case V_ASN1_OBJECT:
 		result = OBJ_cmp(a->value.object, b->value.object);
 		break;
+	case V_ASN1_BOOLEAN:
+		result = a->value.boolean - b->value.boolean;
+		break;
 	case V_ASN1_NULL:
 		result = 0;	/* They do not have content. */
 		break;

Index: src/crypto/dist/openssl/crypto/asn1/tasn_dec.c
diff -u src/crypto/dist/openssl/crypto/asn1/tasn_dec.c:1.8.4.1.6.1 src/crypto/dist/openssl/crypto/asn1/tasn_dec.c:1.8.4.1.6.2
--- src/crypto/dist/openssl/crypto/asn1/tasn_dec.c:1.8.4.1.6.1	Mon Jan 26 11:47:23 2015
+++ src/crypto/dist/openssl/crypto/asn1/tasn_dec.c	Thu Mar 19 16:40:07 2015
@@ -130,11 +130,17 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **p
 	{
 	ASN1_TLC c;
 	ASN1_VALUE *ptmpval = NULL;
-	if (!pval)
-		pval = &ptmpval;
 	asn1_tlc_clear_nc(&c);
-	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
-		return *pval;
+	if (pval && *pval && it->itype == ASN1_ITYPE_PRIMITIVE)
+		ptmpval = *pval;
+	if (ASN1_item_ex_d2i(&ptmpval, in, len, it, -1, 0, 0, &c) > 0) {
+		if (pval && it->itype != ASN1_ITYPE_PRIMITIVE) {
+			if (*pval)
+				ASN1_item_free(*pval, it);
+			*pval = ptmpval;
+		}
+		return ptmpval;
+	}
 	return NULL;
 	}
 
@@ -311,9 +317,16 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, 
 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
 				goto auxerr;
 
-		/* Allocate structure */
-		if (!*pval && !ASN1_item_ex_new(pval, it))
-			{
+		if (*pval) {
+			/* Free up and zero CHOICE value if initialised */
+			i = asn1_get_choice_selector(pval, it);
+			if ((i >= 0) && (i < it->tcount)) {
+				tt = it->templates + i;
+				pchptr = asn1_get_field_ptr(pval, tt);
+				ASN1_template_free(pchptr, tt);
+				asn1_set_choice_selector(pval, -1, it);
+			}
+		} else if (!ASN1_item_ex_new(pval, it)) {
 			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
 						ERR_R_NESTED_ASN1_ERROR);
 			goto err;
@@ -408,6 +421,17 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, 
 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
 				goto auxerr;
 
+		/* Free up and zero any ADB found */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+			if (tt->flags & ASN1_TFLG_ADB_MASK) {
+				const ASN1_TEMPLATE *seqtt;
+				ASN1_VALUE **pseqval;
+				seqtt = asn1_do_adb(pval, tt, 1);
+				pseqval = asn1_get_field_ptr(pval, seqtt);
+				ASN1_template_free(pseqval, seqtt);
+			}
+		}
+
 		/* Get each field entry */
 		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
 			{

Index: src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c
diff -u src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c:1.6 src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c:1.6.12.1
--- src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c:1.6	Fri May  9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/pkcs7/pk7_doit.c	Thu Mar 19 16:40:07 2015
@@ -265,6 +265,25 @@ BIO *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;
 
@@ -424,6 +443,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
 	X509_ALGOR *xalg=NULL;
 	PKCS7_RECIP_INFO *ri=NULL;
+	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;
@@ -749,6 +780,7 @@ int 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;
@@ -759,6 +791,7 @@ int 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;
@@ -829,24 +862,29 @@ int 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(emilia): I think we 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:
 	EVP_MD_CTX_cleanup(&ctx_tmp);
@@ -921,6 +959,16 @@ int PKCS7_dataVerify(X509_STORE *cert_st
 	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;

Index: src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c
diff -u src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c:1.1.1.8 src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c:1.1.1.8.12.1
--- src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c:1.1.1.8	Fri May  9 21:34:33 2008
+++ src/crypto/dist/openssl/crypto/pkcs7/pk7_lib.c	Thu Mar 19 16:40:07 2015
@@ -71,6 +71,7 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long
 
 	switch (cmd)
 		{
+	/* NOTE(emilia): does not support detached digested data. */
 	case PKCS7_OP_SET_DETACHED_SIGNATURE:
 		if (nid == NID_pkcs7_signed)
 			{
@@ -459,6 +460,8 @@ int PKCS7_set_digest(PKCS7 *p7, const EV
 
 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);

Index: src/crypto/dist/openssl/doc/crypto/d2i_X509.pod
diff -u src/crypto/dist/openssl/doc/crypto/d2i_X509.pod:1.1.1.2 src/crypto/dist/openssl/doc/crypto/d2i_X509.pod:1.1.1.2.34.1
--- src/crypto/dist/openssl/doc/crypto/d2i_X509.pod:1.1.1.2	Fri Nov 25 03:08:19 2005
+++ src/crypto/dist/openssl/doc/crypto/d2i_X509.pod	Thu Mar 19 16:40:07 2015
@@ -199,6 +199,12 @@ B<*px> is valid is broken and some parts
 persist if they are not present in the new one. As a result the use
 of this "reuse" behaviour is strongly discouraged.
 
+Current versions of OpenSSL will not modify B<*px> if an error occurs.
+If parsing succeeds then B<*px> is freed (if it is not NULL) and then
+set to the value of the newly decoded structure. As a result B<*px>
+B<must not> be allocated on the stack or an attempt will be made to
+free an invalid pointer.
+
 i2d_X509() will not return an error in many versions of OpenSSL,
 if mandatory fields are not initialized due to a programming error
 then the encoded structure may contain invalid data or omit the
@@ -210,7 +216,9 @@ always succeed.
 
 d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
 or B<NULL> if an error occurs. The error code that can be obtained by
-L<ERR_get_error(3)|ERR_get_error(3)>. 
+L<ERR_get_error(3)|ERR_get_error(3)>. If the "reuse" capability has been used
+with a valid X509 structure being passed in via B<px> then the object is not
+modified in the event of error.
 
 i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes
 successfully encoded or a negative value if an error occurs. The error code

Index: src/crypto/dist/openssl/ssl/s2_lib.c
diff -u src/crypto/dist/openssl/ssl/s2_lib.c:1.12.12.1 src/crypto/dist/openssl/ssl/s2_lib.c:1.12.12.2
--- src/crypto/dist/openssl/ssl/s2_lib.c:1.12.12.1	Sun Oct 19 20:10:11 2014
+++ src/crypto/dist/openssl/ssl/s2_lib.c	Thu Mar 19 16:40:07 2015
@@ -487,7 +487,7 @@ int ssl2_generate_key_material(SSL *s)
 
 		OPENSSL_assert(s->session->master_key_length >= 0
 		    && s->session->master_key_length
-		    < (int)sizeof(s->session->master_key));
+		    <= (int)sizeof(s->session->master_key));
 		EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
 		EVP_DigestUpdate(&ctx,&c,1);
 		c++;

Index: src/crypto/dist/openssl/ssl/s2_srvr.c
diff -u src/crypto/dist/openssl/ssl/s2_srvr.c:1.9.4.1.6.1 src/crypto/dist/openssl/ssl/s2_srvr.c:1.9.4.1.6.2
--- src/crypto/dist/openssl/ssl/s2_srvr.c:1.9.4.1.6.1	Mon Jan 26 11:47:24 2015
+++ src/crypto/dist/openssl/ssl/s2_srvr.c	Thu Mar 19 16:40:07 2015
@@ -453,10 +453,6 @@ static int get_client_master_key(SSL *s)
 		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
 		return(-1);
 		}
-	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
-		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
-		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
-
 	is_export=SSL_C_IS_EXPORT(s->session->cipher);
 	
 	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
@@ -474,21 +470,59 @@ static int get_client_master_key(SSL *s)
 	else
 		ek=5;
 
+	/*
+	 * The format of the CLIENT-MASTER-KEY message is
+	 * 1 byte message type
+	 * 3 bytes cipher
+	 * 2-byte clear key length (stored in s->s2->tmp.clear)
+	 * 2-byte encrypted key length (stored in s->s2->tmp.enc)
+	 * 2-byte key args length (IV etc)
+	 * clear key
+	 * encrypted key
+	 * key args
+	 *
+	 * If the cipher is an export cipher, then the encrypted key bytes
+	 * are a fixed portion of the total key (5 or 8 bytes). The size of
+	 * this portion is in |ek|. If the cipher is not an export cipher,
+	 * then the entire key material is encrypted (i.e., clear key length
+	 * must be zero).
+	 */
+	if ((!is_export && s->s2->tmp.clear != 0) ||
+	    (is_export && s->s2->tmp.clear + ek != EVP_CIPHER_key_length(c))) {
+		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
+		return -1;
+	}
+	/*
+	 * The encrypted blob must decrypt to the encrypted portion of the key.
+	 * Decryption can't be expanding, so if we don't have enough encrypted
+	 * bytes to fit the key in the buffer, stop now.
+	 */
+	if ((is_export && s->s2->tmp.enc < ek) ||
+	    (!is_export && s->s2->tmp.enc < EVP_CIPHER_key_length(c))) {
+		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
+		return -1;
+	}
+
+	i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
+	                            &(p[s->s2->tmp.clear]),
+	                            &(p[s->s2->tmp.clear]),
+	                            (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING :
+	                            RSA_PKCS1_PADDING);
+
 	/* bad decrypt */
 #if 1
 	/* If a bad decrypt, continue with protocol but with a
 	 * random master secret (Bleichenbacher attack) */
-	if ((i < 0) ||
-		((!is_export && (i != EVP_CIPHER_key_length(c)))
-		|| (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
-			(unsigned int)EVP_CIPHER_key_length(c))))))
-		{
+	if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c))
+	                || (is_export && i != ek))) {
 		ERR_clear_error();
 		if (is_export)
 			i=ek;
 		else
 			i=EVP_CIPHER_key_length(c);
-		if (RAND_pseudo_bytes(p,i) <= 0)
+		if (RAND_pseudo_bytes(&p[s->s2->tmp.clear], i) <= 0)
 			return 0;
 		}
 #else
@@ -512,7 +546,8 @@ static int get_client_master_key(SSL *s)
 		}
 #endif
 
-	if (is_export) i+=s->s2->tmp.clear;
+	if (is_export)
+		i = EVP_CIPHER_key_length(c);
 
 	if (i > SSL_MAX_MASTER_KEY_LENGTH)
 		{

Reply via email to