svn commit: r46817 - in head/share: security/advisories security/patches/SA-15:10 xml

Xin LI <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.doc
Message-ID <[email protected]>
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 ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-doc-all
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.