Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Jun 2015 07:33:56 +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: r46817 - in head/share: security/advisories security/patches/SA-15:10 xml
Message-ID:  <201506120733.t5C7XuXj018873@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Fri Jun 12 07:33:55 2015
New Revision: 46817
URL: https://svnweb.freebsd.org/changeset/doc/46817

Log:
  Add advisory for SA-15:10.openssl.

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

Added: head/share/security/advisories/FreeBSD-SA-15:10.openssl.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-SA-15:10.openssl.asc	Fri Jun 12 07:33:55 2015	(r46817)
@@ -0,0 +1,202 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-15:10.openssl                                    Security Advisory
+                                                          The FreeBSD Project
+
+Topic:          Multiple OpenSSL vulnerabilities
+
+Category:       contrib
+Module:         openssl
+Announced:      2015-06-12
+Affects:        All supported versions of FreeBSD.
+Corrected:      2015-06-11 19:07:45 UTC (stable/10, 10.1-STABLE)
+                2015-06-12 07:23:55 UTC (releng/10.1, 10.1-RELEASE-p12)
+                2015-06-11 19:39:27 UTC (stable/9, 9.3-STABLE)
+                2015-06-12 07:23:55 UTC (releng/9.3, 9.3-RELEASE-p16)
+                2015-06-11 19:39:27 UTC (stable/8, 8.4-STABLE)
+                2015-06-12 07:23:55 UTC (releng/8.4, 8.4-RELEASE-p30)
+CVE Name:       CVE-2015-1788, CVE-2015-1789, CVE-2015-1790, CVE-2015-1791
+                CVE-2015-1792, CVE-2015-4000
+
+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.
+
+II.  Problem Description
+
+A vulnerability in the TLS protocol would allow a man-in-the-middle
+attacker to downgrade vulnerable TLS connections using ephemeral
+Diffie-Hellman key exchange to 512-bit export-grade cryptography.
+This vulnerability is also known as Logjam [CVE-2015-4000].
+
+When processing an ECParameters structure OpenSSL enters an infinite
+loop if the curve specified is over a specially malformed binary
+polynomial field. [CVE-2015-1788]
+
+X509_cmp_time does not properly check the length of the ASN1_TIME
+string and can read a few bytes out of bounds. In addition,
+X509_cmp_time accepts an arbitrary number of fractional seconds in
+the time string. [CVE-2015-1789]
+
+The PKCS#7 parsing code does not handle missing inner EncryptedContent
+correctly.  [CVE-2015-1790]
+
+When verifying a signedData message the CMS code can enter an infinite
+loop if presented with an unknown hash function OID. [CVE-2015-1792]
+
+If a NewSessionTicket is received by a multi-threaded client when
+attempting to reuse a previous ticket then a race condition can occur,
+potentially leading to a double free of the ticket data. [CVE-2015-1791]
+
+The OpenSSL advisory also describes a problem that is identified as
+CVE-2014-8176, which is already fixed by an earlier FreeBSD Errata
+Notice, FreeBSD-EN-15:02.openssl.
+
+III. Impact
+
+A man-in-the-middle attacker may be able to downgrade vulnerable TLS
+connections using ephemeral Diffie-Hellman key exchange to 512-bit
+export-grade cryptography. [CVE-2015-4000].  On FreeBSD 10.1, the
+patch contains a countermeasure for clients by rejecting handshakes
+with DH parameters shorter than 768 bits.
+
+An attacker who is able to use a certificate to authenticate with
+a remote system perform denial of service against any system which
+processes public keys, certificate requests or certificates.
+[CVE-2015-1788].  This affects FreeBSD 10.1 only, as the problem
+was no longer exist in OpenSSL 0.9.8 series since July 2012.
+
+An attacker can use the CVE-2015-1789 issue by using specifically
+crafted certificates and CRLs of various sizes and potentially
+cause a segmentation fault, resulting in a DoS on applications that
+verify certificates or CRLs.
+
+An attacker who can create specifically crafted malformed ASN.1-encoded
+PKCS#7 blobs with missing content and trigger a NULL pointer dereference
+on parsing. [CVE-2015-1790].  Applications that decrypt PKCS#7 data
+or otherwise parse PKCS#7 structures from untrusted sources are
+affected. OpenSSL clients and servers are not affected.
+
+An attacker can perform denial of service against any system which
+verifies signedData messages using the CMS code. [CVE-2015-1792]
+
+An attacker may be able to crash multi-thread applications that
+supports resumed TLS handshakes. [CVE-2015-1791]
+
+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 10.1]
+# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch.asc
+# gpg --verify openssl-10.1.patch.asc
+
+[FreeBSD 9.3 and 8.4]
+# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch.asc
+# gpg --verify openssl-8.4.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/                                                         r284286
+releng/8.4/                                                       r284295
+stable/9/                                                         r284286
+releng/9.3/                                                       r284295
+stable/10/                                                        r284285
+releng/10.1/                                                      r284295
+- -------------------------------------------------------------------------
+
+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_20150611.txt>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1788>; 
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1789>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1790>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1791>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1792>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4000>;
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:10.openssl.asc>;
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.4 (FreeBSD)
+
+iQIcBAEBCgAGBQJVeopGAAoJEO1n7NZdz2rnzhQP/Ak6el188Y+7QbEYVfCZ7eG8
+BQLj5TMGHV5swSKVlPcEuBlMwTjpgB5Gqhc8luDS0eIAuJGdcMPSrZDdXxWQFtPf
+pbfIwp/ElFc7d6ut0Y8t6fFLJbhTOoHJpzTGkFRfJkjinGOx7OZQPeLJsxSubbnL
+JKugZ3diH6yk6IPMf9SvhO/kYXUF1VbXQvHNTnqgdhFVkgF6tK22Pkl2XoJ9EHbh
+vBXft1yJwiYlZ//DxZuScTUj1pHYzK3bOpg//REJMWCMj1RVwQr2EyDa0Q2cT02d
+eRnSZykXD69eybyzEck+BvwnUYYJICimnHuE5t78UIr0D/NWyOAZTQ99z5TID5aV
+HXkcil+1E/Q+xBB4+5UOOnESf6cmiWwewQOVvD26ZY39E6oJXvsrWnyxIuCG6DL9
+sLtxB6iTYlTX5Civ/VJX8H7rFiw4UwMembthvGzck22026iHjplWM3GCWz0E8O3R
+PrXBHjAzNFawK3owNMxFSUFTuFw/qY7EEwJ3SKCEC+hoxcLOl26NMxrQKRIAUk+I
+MMOaZfvOh2uM19y9SJZz8+sqU8gIm7ihDm5fuSkO8kY0jdvLwyS9bXAejN/lZ6oJ
+TyfTDDyXDOdaPpnpQehh6vQV0NiaJ+WXfGhfiE8/G/t6b1E0LlCaaGJTpYkildGe
+vVCM4Nyx4S9WDFOi76ug
+=dyhg
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/SA-15:10/openssl-10.1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-15:10/openssl-10.1.patch	Fri Jun 12 07:33:55 2015	(r46817)
@@ -0,0 +1,1897 @@
+Index: crypto/openssl/apps/dhparam.c
+===================================================================
+--- crypto/openssl/apps/dhparam.c	(revision 284286)
++++ crypto/openssl/apps/dhparam.c	(working copy)
+@@ -130,7 +130,7 @@
+ #undef PROG
+ #define PROG	dhparam_main
+ 
+-#define DEFBITS	512
++#define DEFBITS	2048
+ 
+ /* -inform arg	- input format - default PEM (DER or PEM)
+  * -outform arg - output format - default PEM
+@@ -253,7 +253,7 @@ bad:
+ 		BIO_printf(bio_err," -C            Output C code\n");
+ 		BIO_printf(bio_err," -2            generate parameters using  2 as the generator value\n");
+ 		BIO_printf(bio_err," -5            generate parameters using  5 as the generator value\n");
+-		BIO_printf(bio_err," numbits       number of bits in to generate (default 512)\n");
++		BIO_printf(bio_err," numbits       number of bits in to generate (default 2048)\n");
+ #ifndef OPENSSL_NO_ENGINE
+ 		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
+ #endif
+Index: crypto/openssl/apps/gendh.c
+===================================================================
+--- crypto/openssl/apps/gendh.c	(revision 284286)
++++ crypto/openssl/apps/gendh.c	(working copy)
+@@ -78,7 +78,7 @@
+ #include <openssl/x509.h>
+ #include <openssl/pem.h>
+ 
+-#define DEFBITS	512
++#define DEFBITS	2048
+ #undef PROG
+ #define PROG gendh_main
+ 
+Index: crypto/openssl/apps/s_server.c
+===================================================================
+--- crypto/openssl/apps/s_server.c	(revision 284286)
++++ crypto/openssl/apps/s_server.c	(working copy)
+@@ -214,7 +214,7 @@ static int generate_session_id(const SSL *ssl, uns
+ 				unsigned int *id_len);
+ #ifndef OPENSSL_NO_DH
+ static DH *load_dh_param(const char *dhfile);
+-static DH *get_dh512(void);
++static DH *get_dh2048(void);
+ #endif
+ 
+ #ifdef MONOLITH
+@@ -222,29 +222,49 @@ static void s_server_init(void);
+ #endif
+ 
+ #ifndef OPENSSL_NO_DH
+-static unsigned char dh512_p[]={
+-	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+-	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+-	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+-	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+-	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+-	0x47,0x74,0xE8,0x33,
+-	};
+-static unsigned char dh512_g[]={
++static unsigned char dh2048_p[] = {
++    0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
++    0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
++    0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
++    0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
++    0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
++    0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
++    0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
++    0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
++    0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
++    0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
++    0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
++    0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
++    0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
++    0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
++    0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
++    0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
++    0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
++    0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
++    0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
++    0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
++    0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
++    0xE9,0x32,0x0B,0x3B,
++};
++
++static unsigned char dh2048_g[] = {
+ 	0x02,
+-	};
++};
+ 
+-static DH *get_dh512(void)
+-	{
+-	DH *dh=NULL;
++DH *get_dh2048()
++{
++    DH *dh;
+ 
+-	if ((dh=DH_new()) == NULL) return(NULL);
+-	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+-	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+-	if ((dh->p == NULL) || (dh->g == NULL))
+-		return(NULL);
+-	return(dh);
++    if ((dh = DH_new()) == NULL)
++        return NULL;
++    dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
++    dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
++    if (dh->p == NULL || dh->g == NULL) {
++        DH_free(dh);
++        return NULL;
+ 	}
++    return dh;
++}
+ #endif
+ 
+ 
+@@ -1661,9 +1681,8 @@ bad:
+ #endif 
+ 
+ #ifndef OPENSSL_NO_DH
+-	if (!no_dhe)
+-		{
+-		DH *dh=NULL;
++    if (!no_dhe) {
++        DH *dh = NULL;
+ 
+ 		if (dhfile)
+ 			dh = load_dh_param(dhfile);
+@@ -1670,27 +1689,25 @@ bad:
+ 		else if (s_cert_file)
+ 			dh = load_dh_param(s_cert_file);
+ 
+-		if (dh != NULL)
+-			{
+-			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
++        if (dh != NULL) {
++            BIO_printf(bio_s_out, "Setting temp DH parameters\n");
++        } else {
++            BIO_printf(bio_s_out, "Using default temp DH parameters\n");
++            dh = get_dh2048();
++            if (dh == NULL) {
++                ERR_print_errors(bio_err);
++                goto end;
+ 			}
+-		else
+-			{
+-			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
+-			dh=get_dh512();
+ 			}
+ 		(void)BIO_flush(bio_s_out);
+ 
+-		SSL_CTX_set_tmp_dh(ctx,dh);
+-#ifndef OPENSSL_NO_TLSEXT
+-		if (ctx2)
+-			{
+-			if (!dhfile)
+-				{ 
+-				DH *dh2=load_dh_param(s_cert_file2);
+-				if (dh2 != NULL)
+-					{
+-					BIO_printf(bio_s_out,"Setting temp DH parameters\n");
++        SSL_CTX_set_tmp_dh(ctx, dh);
++# ifndef OPENSSL_NO_TLSEXT
++        if (ctx2) {
++            if (!dhfile) {
++                DH *dh2 = load_dh_param(s_cert_file2);
++                if (dh2 != NULL) {
++                    BIO_printf(bio_s_out, "Setting temp DH parameters\n");
+ 					(void)BIO_flush(bio_s_out);
+ 
+ 					DH_free(dh);
+@@ -1697,9 +1714,9 @@ bad:
+ 					dh = dh2;
+ 					}
+ 				}
+-			SSL_CTX_set_tmp_dh(ctx2,dh);
++            SSL_CTX_set_tmp_dh(ctx2, dh);
+ 			}
+-#endif
++# endif
+ 		DH_free(dh);
+ 		}
+ #endif
+Index: crypto/openssl/crypto/bio/bio_lib.c
+===================================================================
+--- crypto/openssl/crypto/bio/bio_lib.c	(revision 284286)
++++ crypto/openssl/crypto/bio/bio_lib.c	(working copy)
+@@ -543,8 +543,10 @@ BIO *BIO_dup_chain(BIO *in)
+ 
+ 		/* copy app data */
+ 		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
+-					&bio->ex_data))
++                                &bio->ex_data)) {
++            BIO_free(new_bio);
+ 			goto err;
++        }
+ 
+ 		if (ret == NULL)
+ 			{
+@@ -559,8 +561,8 @@ BIO *BIO_dup_chain(BIO *in)
+ 		}
+ 	return(ret);
+ err:
+-	if (ret != NULL)
+-		BIO_free(ret);
++	BIO_free_all(ret);
++
+ 	return(NULL);	
+ 	}
+ 
+Index: crypto/openssl/crypto/bn/bn_gf2m.c
+===================================================================
+--- crypto/openssl/crypto/bn/bn_gf2m.c	(revision 284286)
++++ crypto/openssl/crypto/bn/bn_gf2m.c	(working copy)
+@@ -568,10 +568,11 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co
+ 		}
+ #else
+ 	{
+-	int i,	ubits = BN_num_bits(u),
+-		vbits = BN_num_bits(v),	/* v is copy of p */
+-		top = p->top;
+-	BN_ULONG *udp,*bdp,*vdp,*cdp;
++        int i;
++        int ubits = BN_num_bits(u);
++        int vbits = BN_num_bits(v); /* v is copy of p */
++        int top = p->top;
++        BN_ULONG *udp, *bdp, *vdp, *cdp;
+ 
+ 	bn_wexpand(u,top);	udp = u->d;
+ 				for (i=u->top;i<top;i++) udp[i] = 0;
+@@ -611,7 +612,12 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co
+ 			ubits--;
+ 			}
+ 
+-		if (ubits<=BN_BITS2 && udp[0]==1) break;
++            if (ubits <= BN_BITS2) {
++                if (udp[0] == 0) /* poly was reducible */
++                    goto err;
++                if (udp[0] == 1)
++                    break;
++            }
+ 
+ 		if (ubits<vbits)
+ 			{
+Index: crypto/openssl/crypto/bn/bn_print.c
+===================================================================
+--- crypto/openssl/crypto/bn/bn_print.c	(revision 284286)
++++ crypto/openssl/crypto/bn/bn_print.c	(working copy)
+@@ -71,7 +71,12 @@ char *BN_bn2hex(const BIGNUM *a)
+ 	char *buf;
+ 	char *p;
+ 
+-	buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
++	if (a->neg && BN_is_zero(a)) {
++	    /* "-0" == 3 bytes including NULL terminator */
++	    buf = OPENSSL_malloc(3);
++	} else {
++	    buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
++	}
+ 	if (buf == NULL)
+ 		{
+ 		BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
+Index: crypto/openssl/crypto/buffer/buffer.c
+===================================================================
+--- crypto/openssl/crypto/buffer/buffer.c	(revision 284286)
++++ crypto/openssl/crypto/buffer/buffer.c	(working copy)
+@@ -88,7 +88,7 @@ void BUF_MEM_free(BUF_MEM *a)
+ 
+ 	if (a->data != NULL)
+ 		{
+-		memset(a->data,0,(unsigned int)a->max);
++		OPENSSL_cleanse(a->data, a->max);
+ 		OPENSSL_free(a->data);
+ 		}
+ 	OPENSSL_free(a);
+Index: crypto/openssl/crypto/cms/cms_smime.c
+===================================================================
+--- crypto/openssl/crypto/cms/cms_smime.c	(revision 284286)
++++ crypto/openssl/crypto/cms/cms_smime.c	(working copy)
+@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *upto)
+ 			BIO_free(f);
+ 			f = tbio;
+ 			}
+-		while (f != upto);
++		while (f && f != upto);
+ 		}
+ 	else
+ 		BIO_free_all(f);
+Index: crypto/openssl/crypto/ec/ec2_oct.c
+===================================================================
+--- crypto/openssl/crypto/ec/ec2_oct.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ec2_oct.c	(working copy)
+@@ -390,7 +390,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group
+ 		if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+ 		}
+ 	
+-	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
++	/* test required by X9.62 */
++	if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
+ 		{
+ 		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ 		goto err;
+Index: crypto/openssl/crypto/ec/ec_check.c
+===================================================================
+--- crypto/openssl/crypto/ec/ec_check.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ec_check.c	(working copy)
+@@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *
+ 		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+ 		goto err;
+ 		}
+-	if (!EC_POINT_is_on_curve(group, group->generator, ctx))
++	if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0)
+ 		{
+ 		ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+ 		goto err;
+Index: crypto/openssl/crypto/ec/ec_key.c
+===================================================================
+--- crypto/openssl/crypto/ec/ec_key.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ec_key.c	(working copy)
+@@ -326,7 +326,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
+ 		goto err;
+ 
+ 	/* testing whether the pub_key is on the elliptic curve */
+-	if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
++	if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0)
+ 		{
+ 		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+ 		goto err;
+Index: crypto/openssl/crypto/ec/ec_lib.c
+===================================================================
+--- crypto/openssl/crypto/ec/ec_lib.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ec_lib.c	(working copy)
+@@ -972,7 +972,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group,
+ 	}
+ 
+ 
+-int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
++/*
++ * Check whether an EC_POINT is on the curve or not. Note that the return
++ * value for this function should NOT be treated as a boolean. Return values:
++ *  1: The point is on the curve
++ *  0: The point is not on the curve
++ * -1: An error occurred
++ */
++int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
++                         BN_CTX *ctx)
+ 	{
+ 	if (group->meth->is_on_curve == 0)
+ 		{
+Index: crypto/openssl/crypto/ec/ecp_oct.c
+===================================================================
+--- crypto/openssl/crypto/ec/ecp_oct.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ecp_oct.c	(working copy)
+@@ -416,7 +416,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group,
+ 		if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+ 		}
+ 	
+-	if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
++	/* test required by X9.62 */
++	if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
+ 		{
+ 		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ 		goto err;
+Index: crypto/openssl/crypto/ec/ectest.c
+===================================================================
+--- crypto/openssl/crypto/ec/ectest.c	(revision 284286)
++++ crypto/openssl/crypto/ec/ectest.c	(working copy)
+@@ -343,7 +343,7 @@ static void prime_field_tests(void)
+ 
+ 	if (!BN_hex2bn(&x, "D")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, Q, ctx))
++	if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
+ 		{
+ 		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
+ 		fprintf(stderr, "Point is not on curve: x = 0x");
+@@ -439,7 +439,7 @@ static void prime_field_tests(void)
+ 	if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
+ 	if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
+ 	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
+ 	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+ 
+@@ -473,7 +473,7 @@ static void prime_field_tests(void)
+ 
+ 	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
+ 	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+ 
+@@ -507,7 +507,7 @@ static void prime_field_tests(void)
+ 
+ 	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
+ 	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+ 
+@@ -541,7 +541,7 @@ static void prime_field_tests(void)
+ 
+ 	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
+ 		"84F3B9CAC2FC632551")) ABORT;
+ 	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+@@ -580,7 +580,7 @@ static void prime_field_tests(void)
+ 	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
+ 		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ 		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
+ 	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
+@@ -624,7 +624,7 @@ static void prime_field_tests(void)
+ 		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
+ 		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
+ 	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ 		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
+ 		"C9B8899C47AEBB6FB71E91386409")) ABORT;
+@@ -657,7 +657,7 @@ static void prime_field_tests(void)
+ 	if (!EC_POINT_copy(Q, P)) ABORT;
+ 	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ 	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+ 
+ 	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+@@ -771,7 +771,7 @@ static void prime_field_tests(void)
+ #define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ 	if (!BN_hex2bn(&x, _x)) ABORT; \
+ 	if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
+ 	if (!BN_hex2bn(&z, _order)) ABORT; \
+ 	if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ 	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+@@ -789,7 +789,7 @@ static void prime_field_tests(void)
+ 	if (!BN_hex2bn(&x, _x)) ABORT; \
+ 	if (!BN_hex2bn(&y, _y)) ABORT; \
+ 	if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
+ 	if (!BN_hex2bn(&z, _order)) ABORT; \
+ 	if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ 	if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+@@ -894,7 +894,7 @@ static void char2_field_tests(void)
+ 	if (!BN_hex2bn(&y, "8")) ABORT;
+ 	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
+ #endif
+-	if (!EC_POINT_is_on_curve(group, Q, ctx))
++	if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
+ 		{
+ /* Change test based on whether binary point compression is enabled or not. */
+ #ifdef OPENSSL_EC_BIN_PT_COMP
+@@ -1133,7 +1133,7 @@ static void char2_field_tests(void)
+ 	if (!EC_POINT_copy(Q, P)) ABORT;
+ 	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
+ 	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
+-	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
++	if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
+ 	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
+ 
+ 	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
+Index: crypto/openssl/crypto/evp/e_aes.c
+===================================================================
+--- crypto/openssl/crypto/evp/e_aes.c	(revision 284286)
++++ crypto/openssl/crypto/evp/e_aes.c	(working copy)
+@@ -50,6 +50,7 @@
+ 
+ #include <openssl/opensslconf.h>
+ #ifndef OPENSSL_NO_AES
++#include <openssl/crypto.h>
+ #include <openssl/evp.h>
+ #include <openssl/err.h>
+ #include <string.h>
+@@ -967,7 +968,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx,
+ 		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
+ 					EVP_GCM_TLS_TAG_LEN);
+ 		/* If tag mismatch wipe buffer */
+-		if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
++		if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
+ 			{
+ 			OPENSSL_cleanse(out, len);
+ 			goto err;
+@@ -1351,7 +1352,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, uns
+ 			unsigned char tag[16];
+ 			if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
+ 				{
+-				if (!memcmp(tag, ctx->buf, cctx->M))
++				if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M))
+ 					rv = len;
+ 				}
+ 			}
+Index: crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
+===================================================================
+--- crypto/openssl/crypto/evp/e_rc4_hmac_md5.c	(revision 284286)
++++ crypto/openssl/crypto/evp/e_rc4_hmac_md5.c	(working copy)
+@@ -54,6 +54,7 @@
+ 
+ #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+ 
++#include <openssl/crypto.h>
+ #include <openssl/evp.h>
+ #include <openssl/objects.h>
+ #include <openssl/rc4.h>
+@@ -205,7 +206,7 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx
+ 			MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH);
+ 			MD5_Final(mac,&key->md);
+ 
+-			if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH))
++			if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+ 				return 0;
+ 		} else {
+ 			MD5_Update(&key->md,out+md5_off,len-md5_off);
+Index: crypto/openssl/crypto/evp/evp.h
+===================================================================
+--- crypto/openssl/crypto/evp/evp.h	(revision 284286)
++++ crypto/openssl/crypto/evp/evp.h	(working copy)
+@@ -103,7 +103,6 @@
+ #define EVP_PKS_RSA	0x0100
+ #define EVP_PKS_DSA	0x0200
+ #define EVP_PKS_EC	0x0400
+-#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
+ 
+ #define EVP_PKEY_NONE	NID_undef
+ #define EVP_PKEY_RSA	NID_rsaEncryption
+Index: crypto/openssl/crypto/hmac/hmac.c
+===================================================================
+--- crypto/openssl/crypto/hmac/hmac.c	(revision 284286)
++++ crypto/openssl/crypto/hmac/hmac.c	(working copy)
+@@ -240,6 +240,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const vo
+ 	HMAC_CTX_cleanup(&c);
+ 	return md;
+ 	err:
++    HMAC_CTX_cleanup(&c);
+ 	return NULL;
+ 	}
+ 
+Index: crypto/openssl/crypto/modes/gcm128.c
+===================================================================
+--- crypto/openssl/crypto/modes/gcm128.c	(revision 284286)
++++ crypto/openssl/crypto/modes/gcm128.c	(working copy)
+@@ -1525,7 +1525,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const
+ 	ctx->Xi.u[1] ^= ctx->EK0.u[1];
+ 
+ 	if (tag && len<=sizeof(ctx->Xi))
+-		return memcmp(ctx->Xi.c,tag,len);
++		return CRYPTO_memcmp(ctx->Xi.c, tag, len);
+ 	else
+ 		return -1;
+ }
+Index: crypto/openssl/crypto/objects/obj_dat.c
+===================================================================
+--- crypto/openssl/crypto/objects/obj_dat.c	(revision 284286)
++++ crypto/openssl/crypto/objects/obj_dat.c	(working copy)
+@@ -405,6 +405,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a)
+ 	if (a->nid != 0)
+ 		return(a->nid);
+ 
++	if (a->length == 0)
++		return NID_undef;
++
+ 	if (added != NULL)
+ 		{
+ 		ad.type=ADDED_DATA;
+Index: crypto/openssl/crypto/pkcs12/p12_mutl.c
+===================================================================
+--- crypto/openssl/crypto/pkcs12/p12_mutl.c	(revision 284286)
++++ crypto/openssl/crypto/pkcs12/p12_mutl.c	(working copy)
+@@ -59,6 +59,7 @@
+ #ifndef OPENSSL_NO_HMAC
+ #include <stdio.h>
+ #include "cryptlib.h"
++#include <openssl/crypto.h>
+ #include <openssl/hmac.h>
+ #include <openssl/rand.h>
+ #include <openssl/pkcs12.h>
+@@ -123,7 +124,8 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pas
+ 		return 0;
+ 	}
+ 	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
+-	|| memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
++        || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen))
++		return 0;
+ 	return 1;
+ }
+ 
+Index: crypto/openssl/crypto/pkcs7/pk7_doit.c
+===================================================================
+--- crypto/openssl/crypto/pkcs7/pk7_doit.c	(revision 284286)
++++ crypto/openssl/crypto/pkcs7/pk7_doit.c	(working copy)
+@@ -504,6 +504,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
+ 	        goto err;
+ 		}
+ 
++    /* Detached content must be supplied via in_bio instead. */
++    if (data_body == NULL && in_bio == NULL) {
++        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
++        goto err;
++    }
++
+ 	/* We will be checking the signature */
+ 	if (md_sk != NULL)
+ 		{
+@@ -660,7 +666,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
+ 		}
+ 
+ #if 1
+-	if (PKCS7_is_detached(p7) || (in_bio != NULL))
++	if (in_bio != NULL)
+ 		{
+ 		bio=in_bio;
+ 		}
+Index: crypto/openssl/crypto/x509/x509_vfy.c
+===================================================================
+--- crypto/openssl/crypto/x509/x509_vfy.c	(revision 284286)
++++ crypto/openssl/crypto/x509/x509_vfy.c	(working copy)
+@@ -1679,83 +1679,121 @@ int X509_cmp_current_time(const ASN1_TIME *ctm)
+ }
+ 
+ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
+-	{
++{
+ 	char *str;
+ 	ASN1_TIME atm;
+ 	long offset;
+-	char buff1[24],buff2[24],*p;
+-	int i,j;
++    char buff1[24], buff2[24], *p;
++    int i, j, remaining;
+ 
+-	p=buff1;
+-	i=ctm->length;
+-	str=(char *)ctm->data;
+-	if (ctm->type == V_ASN1_UTCTIME)
+-		{
+-		if ((i < 11) || (i > 17)) return 0;
+-		memcpy(p,str,10);
+-		p+=10;
+-		str+=10;
++    p = buff1;
++    remaining = ctm->length;
++    str = (char *)ctm->data;
++    /*
++     * Note that the following (historical) code allows much more slack in the
++     * time format than RFC5280. In RFC5280, the representation is fixed:
++     * UTCTime: YYMMDDHHMMSSZ
++     * GeneralizedTime: YYYYMMDDHHMMSSZ
++     */
++    if (ctm->type == V_ASN1_UTCTIME) {
++        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
++        int min_length = sizeof("YYMMDDHHMMZ") - 1;
++        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
++        if (remaining < min_length || remaining > max_length)
++            return 0;
++        memcpy(p, str, 10);
++        p += 10;
++        str += 10;
++        remaining -= 10;
++    } else {
++        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
++        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
++        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
++        if (remaining < min_length || remaining > max_length)
++            return 0;
++        memcpy(p, str, 12);
++        p += 12;
++        str += 12;
++        remaining -= 12;
+ 		}
+-	else
+-		{
+-		if (i < 13) return 0;
+-		memcpy(p,str,12);
+-		p+=12;
+-		str+=12;
+-		}
+ 
+-	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
+-		{ *(p++)='0'; *(p++)='0'; }
+-	else
+-		{ 
+-		*(p++)= *(str++);
+-		*(p++)= *(str++);
+-		/* Skip any fractional seconds... */
+-		if (*str == '.')
+-			{
++    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
++        *(p++) = '0';
++        *(p++) = '0';
++    } else {
++        /* SS (seconds) */
++        if (remaining < 2)
++            return 0;
++        *(p++) = *(str++);
++        *(p++) = *(str++);
++        remaining -= 2;
++        /*
++         * Skip any (up to three) fractional seconds...
++         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
++         * Can we just kill them altogether?
++         */
++        if (remaining && *str == '.') {
+ 			str++;
+-			while ((*str >= '0') && (*str <= '9')) str++;
++            remaining--;
++            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
++                if (*str < '0' || *str > '9')
++                    break;
+ 			}
+-		
+ 		}
+-	*(p++)='Z';
+-	*(p++)='\0';
+ 
+-	if (*str == 'Z')
+-		offset=0;
+-	else
+-		{
++    }
++    *(p++) = 'Z';
++    *(p++) = '\0';
++
++    /* We now need either a terminating 'Z' or an offset. */
++    if (!remaining)
++        return 0;
++    if (*str == 'Z') {
++        if (remaining != 1)
++            return 0;
++        offset = 0;
++    } else {
++        /* (+-)HHMM */
+ 		if ((*str != '+') && (*str != '-'))
+ 			return 0;
+-		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
+-		offset+=(str[3]-'0')*10+(str[4]-'0');
++        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
++        if (remaining != 5)
++            return 0;
++        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
++            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
++            return 0;
++        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
++        offset += (str[3] - '0') * 10 + (str[4] - '0');
+ 		if (*str == '-')
+-			offset= -offset;
++            offset = -offset;
+ 		}
+-	atm.type=ctm->type;
++    atm.type = ctm->type;
+ 	atm.flags = 0;
+-	atm.length=sizeof(buff2);
+-	atm.data=(unsigned char *)buff2;
++    atm.length = sizeof(buff2);
++    atm.data = (unsigned char *)buff2;
+ 
+-	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
++    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
+ 		return 0;
+ 
+-	if (ctm->type == V_ASN1_UTCTIME)
+-		{
+-		i=(buff1[0]-'0')*10+(buff1[1]-'0');
+-		if (i < 50) i+=100; /* cf. RFC 2459 */
+-		j=(buff2[0]-'0')*10+(buff2[1]-'0');
+-		if (j < 50) j+=100;
++    if (ctm->type == V_ASN1_UTCTIME) {
++        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
++        if (i < 50)
++            i += 100;           /* cf. RFC 2459 */
++        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
++        if (j < 50)
++            j += 100;
+ 
+-		if (i < j) return -1;
+-		if (i > j) return 1;
++        if (i < j)
++            return -1;
++        if (i > j)

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



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