Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Mar 2015 17:48:02 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org
Subject:   svn commit: r46358 - in head/share: security/advisories security/patches/SA-15:06 xml
Message-ID:  <201503191748.t2JHm2Yq076705@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Thu Mar 19 17:48:01 2015
New Revision: 46358
URL: https://svnweb.freebsd.org/changeset/doc/46358

Log:
  Add SA-15:06.openssl.

Added:
  head/share/security/advisories/FreeBSD-SA-15:06.openssl.asc   (contents, props changed)
  head/share/security/patches/SA-15:06/
  head/share/security/patches/SA-15:06/openssl-0.9.8.patch   (contents, props changed)
  head/share/security/patches/SA-15:06/openssl-0.9.8.patch.asc   (contents, props changed)
  head/share/security/patches/SA-15:06/openssl-1.0.1.patch   (contents, props changed)
  head/share/security/patches/SA-15:06/openssl-1.0.1.patch.asc   (contents, props changed)
Modified:
  head/share/xml/advisories.xml

Added: head/share/security/advisories/FreeBSD-SA-15:06.openssl.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-SA-15:06.openssl.asc	Thu Mar 19 17:48:01 2015	(r46358)
@@ -0,0 +1,197 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-15:06.openssl                                    Security Advisory
+                                                          The FreeBSD Project
+
+Topic:          Multiple OpenSSL vulnerabilities
+
+Category:       contrib
+Module:         openssl
+Announced:      2015-03-19
+Affects:        All supported versions of FreeBSD.
+Corrected:      2015-03-19 17:40:43 UTC (stable/10, 10.1-STABLE)
+                2015-03-19 17:42:38 UTC (releng/10.1, 10.1-RELEASE-p7)
+                2015-03-19 17:40:43 UTC (stable/9, 9.3-STABLE)
+                2015-03-19 17:42:38 UTC (releng/9.3, 9.3-RELEASE-p11)
+                2015-03-19 17:40:43 UTC (stable/8, 8.4-STABLE)
+                2015-03-19 17:42:38 UTC (releng/8.4, 8.4-RELEASE-p25)
+CVE Name:       CVE-2015-0209, CVE-2015-0286, CVE-2015-0287, CVE-2015-0288,
+                CVE-2015-0289, CVE-2015-0293
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+FreeBSD includes software from the OpenSSL Project.  The OpenSSL Project is
+a collaborative effort to develop a robust, commercial-grade, full-featured
+Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
+and Transport Layer Security (TLS v1) protocols as well as a full-strength
+general purpose cryptography library.
+
+Abstract Syntax Notation One (ASN.1) is a standard and notation that
+describes rules and structures for representing, encoding, transmitting,
+and decoding data in telecommunications and computer networking, which
+enables representation of objects that are independent of machine-specific
+encoding technique.
+
+II.  Problem Description
+
+A malformed elliptic curve private key file could cause a use-after-free
+condition in the d2i_ECPrivateKey function.  [CVE-2015-0209]
+
+An attempt to compare ASN.1 boolean types will cause the ASN1_TYPE_cmp
+function to crash with an invalid read.  [CVE-2015-0286]
+
+Reusing a structure in ASN.1 parsing may allow an attacker to cause memory
+corruption via an invalid write. [CVE-2015-0287]
+
+The function X509_to_X509_REQ will crash with a NULL pointer dereference if
+the certificate key is invalid.  [CVE-2015-0288]
+
+The PKCS#7 parsing code does not handle missing outer ContentInfo correctly.
+[CVE-2015-0289]
+
+A malicious client can trigger an OPENSSL_assert in servers that both support
+SSLv2 and enable export cipher suites by sending a specially crafted SSLv2
+CLIENT-MASTER-KEY message.  [CVE-2015-0293]
+
+III. Impact
+
+A malformed elliptic curve private key file can cause server daemons using
+OpenSSL to crash, resulting in a Denial of Service.  [CVE-2015-0209]
+
+A remote attacker who is able to send specifically crafted certificates
+may be able to crash an OpenSSL client or server.  [CVE-2015-0286]
+
+An attacker who can cause invalid writes with applications that parse
+structures containing CHOICE or ANY DEFINED BY components and reusing
+the structures may be able to cause them to crash.  Such reuse is believed
+to be rare.  OpenSSL clients and servers are not affected. [CVE-2015-0287]
+
+An attacker may be able to crash applications that create a new certificate
+request with subject name the same as in an existing, specifically crafted
+certificate.  This usage is rare in practice.  [CVE-2015-0288]
+
+An attacker may be able to crash applications that verify PKCS#7 signatures,
+decrypt PKCS#7 data or otherwise parse PKCS#7 structures with specifically
+crafted certificates.  [CVE-2015-0289]
+
+A malicious client can trigger an OPENSSL_assert in servers that both support
+SSLv2 and enable export cipher suites by sending a carefully crafted SSLv2
+CLIENT-MASTER-KEY message, resulting in a Denial of Service.  [CVE-2015-0293]
+
+Note that two issues in the original OpenSSL advisory, CVE-2015-0204 and
+CVE-2015-0292, were already addressed by FreeBSD-SA-15:01.openssl and
+FreeBSD-EN-15:02.openssl.
+
+IV.  Workaround
+
+No workaround is available.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 8.4 and FreeBSD 9.3]
+# fetch https://security.FreeBSD.org/patches/SA-15:06/openssl-0.9.8.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:06/openssl-0.9.8.patch.asc
+# gpg --verify openssl-0.9.8.patch.asc
+
+[FreeBSD 10.1]
+# fetch https://security.FreeBSD.org/patches/SA-15:06/openssl-1.0.1.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:06/openssl-1.0.1.patch.asc
+# gpg --verify openssl-1.0.1.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all deamons using the library, or reboot the system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/8/                                                         r280266
+releng/8.4/                                                       r280268
+stable/9/                                                         r280266
+releng/9.3/                                                       r280268
+stable/10/                                                        r280266
+releng/10.1/                                                      r280268
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>;
+
+VII. References
+
+<URL:https://www.openssl.org/news/secadv_20150319.txt>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0209>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0286>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0287>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0288>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0289>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0293>;
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:06.openssl.asc>;
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.2 (FreeBSD)
+
+iQIcBAEBCgAGBQJVCwr1AAoJEO1n7NZdz2rnayEP/0w3Pba5k/1G0mJ1T9APNAns
+hhXm0YuR/rNJ1XBooWEOctrijlsVChcIt8KvJCU9apOZWjDvm/nvaQ077GCi5RSp
+jhQBs8MLVfXzwMbJ0/uBpp6ChF8uafk5O+gr8ulb2jG6VIaLkGOWPYv61aRYSGxy
+R7+6FxD8M0lLbGOQGETy1HxKzeWztA2p0ILORNAsi+bF8GSJpxGhSxqDDi4+ic/C
+3oEw0zT/E6DhxJovOPebKq0eGcRbv7ETqDmtNQdqbOddV+0FY1E+nHtrAo6B/Kln
+rL+meBJHmLeEREROFk4OvCynuROUJGmXJGKwjN3uOVM05qcEZS4NkVhFNrxt6S5H
+t3wQ02SesbA3pbmce5OuXmlJgdL57DVlMb5sQjkqPeoJ6pn6Rz7VLSgLNfXDUSxs
+x/Lgx0+qLQUubMud7zT97UIvZmDqFTWXfJu5S/0Qt8BPFunmoNJttJ5Cr+brzEtu
+5RLjcvkC1giVCpSXS96QbeT67uqSkMZa8gtII8bA77HBGA0Ky8AOwTAXbCiUovuH
+sLwsI8KUC3lsKUh7eyLsSm2+wRHn0e6dZ1PE0JRazCnCRboTvMWK2d4R7ANdrwsq
+CgtCWLRz6vbB9J4XTNupcEoZGhIA4RuOBqx43eQmaRw1HoV3vn85QP94oL5jzXBd
+UQg3YfrXHDlxCsqEzN7o
+=wi0T
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/SA-15:06/openssl-0.9.8.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-15:06/openssl-0.9.8.patch	Thu Mar 19 17:48:01 2015	(r46358)
@@ -0,0 +1,387 @@
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c	(revision 280181)
++++ crypto/openssl/crypto/asn1/a_type.c	(working copy)
+@@ -121,6 +121,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_T
+ 	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: crypto/openssl/crypto/asn1/tasn_dec.c
+===================================================================
+--- crypto/openssl/crypto/asn1/tasn_dec.c	(revision 280181)
++++ crypto/openssl/crypto/asn1/tasn_dec.c	(working copy)
+@@ -125,16 +125,23 @@ unsigned long ASN1_tag2bit(int tag)
+ 
+ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+ 		const unsigned char **in, long len, const ASN1_ITEM *it)
+-	{
++{
+ 	ASN1_TLC c;
+ 	ASN1_VALUE *ptmpval = NULL;
+-	if (!pval)
+-		pval = &ptmpval;
+ 	c.valid = 0;
+-	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;
+-	}
++}
+ 
+ int ASN1_template_d2i(ASN1_VALUE **pval,
+ 		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
+@@ -309,13 +316,20 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
+ 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+ 				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;
+-			}
++		}
+ 		/* CHOICE type, try each possibility in turn */
+ 		p = *in;
+ 		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
+@@ -405,6 +419,17 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
+ 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+ 				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: crypto/openssl/crypto/pkcs7/pk7_doit.c
+===================================================================
+--- crypto/openssl/crypto/pkcs7/pk7_doit.c	(revision 280181)
++++ crypto/openssl/crypto/pkcs7/pk7_doit.c	(working copy)
+@@ -151,6 +151,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
+ 	EVP_PKEY *pkey;
+ 	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;
+ 
+@@ -344,6 +363,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
+ 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
+ 	PKCS7_RECIP_INFO *ri=NULL;
+ 
++	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;
+ 
+@@ -637,6 +666,16 @@ int 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;
+@@ -668,6 +707,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;
+@@ -678,6 +718,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;
+@@ -813,8 +854,13 @@ 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))
+-		{
++	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;
+ 		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
+ 		if (btmp == NULL)
+ 			{
+@@ -849,6 +895,16 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_
+ 	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: crypto/openssl/crypto/pkcs7/pk7_lib.c
+===================================================================
+--- crypto/openssl/crypto/pkcs7/pk7_lib.c	(revision 280181)
++++ crypto/openssl/crypto/pkcs7/pk7_lib.c	(working copy)
+@@ -70,6 +70,7 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, cha
+ 
+ 	switch (cmd)
+ 		{
++	/* NOTE(emilia): does not support detached digested data. */
+ 	case PKCS7_OP_SET_DETACHED_SIGNATURE:
+ 		if (nid == NID_pkcs7_signed)
+ 			{
+@@ -473,6 +474,8 @@ int 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);
+Index: crypto/openssl/doc/crypto/d2i_X509.pod
+===================================================================
+--- crypto/openssl/doc/crypto/d2i_X509.pod	(revision 280181)
++++ crypto/openssl/doc/crypto/d2i_X509.pod	(working copy)
+@@ -199,6 +199,12 @@ B<*px> is valid is broken and some parts of the re
+ 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() returns the number of bytes successfully encoded or a negative
+ value if an error occurs. The error code can be obtained by
+Index: crypto/openssl/ssl/s2_lib.c
+===================================================================
+--- crypto/openssl/ssl/s2_lib.c	(revision 280181)
++++ crypto/openssl/ssl/s2_lib.c	(working copy)
+@@ -410,7 +410,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: crypto/openssl/ssl/s2_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s2_srvr.c	(revision 280181)
++++ crypto/openssl/ssl/s2_srvr.c	(working copy)
+@@ -446,9 +446,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);
+ 	
+@@ -467,23 +464,61 @@ 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
+ 	if (i < 0)
+ 		{
+@@ -505,7 +540,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)
+ 		{
+Index: secure/lib/libcrypto/man/d2i_X509.3
+===================================================================
+--- secure/lib/libcrypto/man/d2i_X509.3	(revision 280181)
++++ secure/lib/libcrypto/man/d2i_X509.3	(working copy)
+@@ -342,6 +342,12 @@ In some versions of OpenSSL the \*(L"reuse\*(R" be
+ persist if they are not present in the new one. As a result the use
+ of this \*(L"reuse\*(R" behaviour is strongly discouraged.
+ .PP
++Current versions of OpenSSL will not modify \fB*px\fR if an error occurs.
++If parsing succeeds then \fB*px\fR is freed (if it is not \s-1NULL\s0) and then
++set to the value of the newly decoded structure. As a result \fB*px\fR
++\&\fBmust not\fR be allocated on the stack or an attempt will be made to
++free an invalid pointer.
++.PP
+ \&\fIi2d_X509()\fR 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
+@@ -352,7 +358,9 @@ always succeed.
+ .IX Header "RETURN VALUES"
+ \&\fId2i_X509()\fR, \fId2i_X509_bio()\fR and \fId2i_X509_fp()\fR return a valid \fBX509\fR structure
+ or \fB\s-1NULL\s0\fR if an error occurs. The error code that can be obtained by
+-\&\fIERR_get_error\fR\|(3).
++\&\fIERR_get_error\fR\|(3). If the \*(L"reuse\*(R" capability has been used
++with a valid X509 structure being passed in via \fBpx\fR then the object is not
++modified in the event of error.
+ .PP
+ \&\fIi2d_X509()\fR returns the number of bytes successfully encoded or a negative
+ value if an error occurs. The error code can be obtained by

Added: head/share/security/patches/SA-15:06/openssl-0.9.8.patch.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-15:06/openssl-0.9.8.patch.asc	Thu Mar 19 17:48:01 2015	(r46358)
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.2 (FreeBSD)
+
+iQIcBAABCgAGBQJVCwsCAAoJEO1n7NZdz2rnWy4P+QGq5XsN4+SQb4B66MJeemw8
+5ogrKICDpYb5QciOxqaF/99XxheKvIFRQkc8Av/VMJrMrx7JJ2HKdMUD+ZrzlNYs
+kAMEKBsgS4wj8bACWYCRN8zhztOVLNwzKSNPjjFQZOiQ7cDYI9U27Jj/uPb27/KJ
+fSPQCoYCN47xrbWBuxbeJFqdSk3f9xSp3ZVMRkCUfMvme6LDdenqcZkGm6vE0128
+T3b9KHmk2RgwHklkrhiuR8u+27TjkgqL3KGgF2iKR28rkplgoupGpo/grp0kQQZU
+u9AQQOQV7QrDkVdOVVEpo76z+qaZX8x/z3JPuxDcMxACa1SqKdGXYXlrEcn8e7xD
+IAFAQRBMUnlr3WzxSGAFd2B2m8F0/7t2FPCKoqI2QzLmnte2zLUlpk5s5Ystx5ea
+Y2sxgMC+19PfJZg+nlG5fj4sWRZVQqZ98Nob7e7naZySbC/G7W9VqhhwQm7f0yXI
+dLjzBilVwJ7/6/EeXhms6N4IExULBx5sNKMyXJAWT7yhP2L9DOxffiyLLDM/WQV1
+IBWeDFTZs0rJtwurafU82zO1RWSLp8MmnAI3v8AeqUFzXUyWK6HhBQtXjBAOK+6j
+6v49GPC4DKUUXVPu5K72pXQDv0KcCkRBS80EML+wHBe0NaMPWhwDf1KNL4p1uTOT
+ueRwW6tDMa+DWPjUMqxN
+=0rs2
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/SA-15:06/openssl-1.0.1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-15:06/openssl-1.0.1.patch	Thu Mar 19 17:48:01 2015	(r46358)
@@ -0,0 +1,428 @@
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c	(revision 280181)
++++ crypto/openssl/crypto/asn1/a_type.c	(working copy)
+@@ -124,6 +124,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_T
+ 	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: crypto/openssl/crypto/asn1/tasn_dec.c
+===================================================================
+--- crypto/openssl/crypto/asn1/tasn_dec.c	(revision 280181)
++++ crypto/openssl/crypto/asn1/tasn_dec.c	(working copy)
+@@ -127,16 +127,22 @@ unsigned long ASN1_tag2bit(int tag)
+ 
+ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+ 		const unsigned char **in, long len, const ASN1_ITEM *it)
+-	{
++{
+ 	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;
+-	}
++}
+ 
+ int ASN1_template_d2i(ASN1_VALUE **pval,
+ 		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
+@@ -311,13 +317,20 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
+ 		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;
+-			}
++		}
+ 		/* CHOICE type, try each possibility in turn */
+ 		p = *in;
+ 		for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
+@@ -407,6 +420,17 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsi
+ 		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: crypto/openssl/crypto/pkcs7/pk7_doit.c
+===================================================================
+--- crypto/openssl/crypto/pkcs7/pk7_doit.c	(revision 280181)
++++ crypto/openssl/crypto/pkcs7/pk7_doit.c	(working copy)
+@@ -272,6 +272,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;
+ 
+@@ -433,6 +452,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
+        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;
+ 
+@@ -752,6 +781,16 @@ int 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;
+@@ -796,6 +835,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;
+@@ -806,6 +846,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;
+@@ -866,8 +907,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
+ 				}
+ 			}
+ 		}
+-	else if (i == NID_pkcs7_digest)
+-		{
++	else if (i == NID_pkcs7_digest) {
+ 		unsigned char md_data[EVP_MAX_MD_SIZE];
+ 		unsigned int md_len;
+ 		if (!PKCS7_find_digest(&mdc, bio,
+@@ -878,24 +918,31 @@ 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);
+-			goto err;
++		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);
+@@ -971,6 +1018,16 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_
+ 	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: crypto/openssl/crypto/pkcs7/pk7_lib.c
+===================================================================
+--- crypto/openssl/crypto/pkcs7/pk7_lib.c	(revision 280181)
++++ crypto/openssl/crypto/pkcs7/pk7_lib.c	(working copy)
+@@ -71,6 +71,7 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, cha
+ 
+ 	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 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);
+Index: crypto/openssl/doc/crypto/d2i_X509.pod
+===================================================================
+--- crypto/openssl/doc/crypto/d2i_X509.pod	(revision 280181)
++++ crypto/openssl/doc/crypto/d2i_X509.pod	(working copy)
+@@ -199,6 +199,12 @@ B<*px> is valid is broken and some parts of the re
+ 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() returns the number of bytes successfully encoded or a negative
+ value if an error occurs. The error code can be obtained by
+Index: crypto/openssl/ssl/s2_lib.c
+===================================================================
+--- crypto/openssl/ssl/s2_lib.c	(revision 280181)
++++ crypto/openssl/ssl/s2_lib.c	(working copy)
+@@ -488,7 +488,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: crypto/openssl/ssl/s2_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s2_srvr.c	(revision 280181)
++++ crypto/openssl/ssl/s2_srvr.c	(working copy)
+@@ -454,9 +454,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);
+ 	
+@@ -475,23 +472,61 @@ 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;
+-		}
++	}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503191748.t2JHm2Yq076705>