[Pkg-openssl-changes] r702 - in openssl/trunk/debian: . patches

Kurt Roeckx kroeckx at moszumanska.debian.org
Thu Nov 6 23:39:56 UTC 2014


Author: kroeckx
Date: 2014-11-06 23:39:56 +0000 (Thu, 06 Nov 2014)
New Revision: 702

Added:
   openssl/trunk/debian/patches/git_snapshot.patch
Modified:
   openssl/trunk/debian/changelog
   openssl/trunk/debian/patches/series
Log:
Add git snapshot.


Modified: openssl/trunk/debian/changelog
===================================================================
--- openssl/trunk/debian/changelog	2014-11-06 23:38:23 UTC (rev 701)
+++ openssl/trunk/debian/changelog	2014-11-06 23:39:56 UTC (rev 702)
@@ -1,6 +1,7 @@
 openssl (1.0.2~beta3-1) experimental; urgency=low
 
   * New usptream beta version
+  * Add git snapshot
   * Merge changes between 1.0.1h-3 and 1.0.1j-1:
     - Disables SSLv3 because of CVE-2014-3566
   * Drop patch rehash-crt.patch: partially applied upstream.
@@ -16,7 +17,7 @@
   * Update symbols files to require beta3
   * Enable unit tests
 
- -- Kurt Roeckx <kurt at roeckx.be>  Sat, 01 Nov 2014 18:34:42 +0100
+ -- Kurt Roeckx <kurt at roeckx.be>  Fri, 07 Nov 2014 00:20:10 +0100
 
 openssl (1.0.2~beta2-1) experimental; urgency=medium
 

Added: openssl/trunk/debian/patches/git_snapshot.patch
===================================================================
--- openssl/trunk/debian/patches/git_snapshot.patch	                        (rev 0)
+++ openssl/trunk/debian/patches/git_snapshot.patch	2014-11-06 23:39:56 UTC (rev 702)
@@ -0,0 +1,1900 @@
+diff --git a/CHANGES b/CHANGES
+index 9d3e458..caee934 100644
+--- a/CHANGES
++++ b/CHANGES
+@@ -2,11 +2,57 @@
+  OpenSSL CHANGES
+  _______________
+ 
+- Changes between 1.0.1i and 1.0.2 [xx XXX xxxx]
++ Changes between 1.0.1j and 1.0.2 [xx XXX xxxx]
++
++  *) SRTP Memory Leak.
++
++     A flaw in the DTLS SRTP extension parsing code allows an attacker, who
++     sends a carefully crafted handshake message, to cause OpenSSL to fail
++     to free up to 64k of memory causing a memory leak. This could be
++     exploited in a Denial Of Service attack. This issue affects OpenSSL
++     1.0.1 server implementations for both SSL/TLS and DTLS regardless of
++     whether SRTP is used or configured. Implementations of OpenSSL that
++     have been compiled with OPENSSL_NO_SRTP defined are not affected.
++
++     The fix was developed by the OpenSSL team.
++     (CVE-2014-3513)
++     [OpenSSL team]
++
++  *) Session Ticket Memory Leak.
++
++     When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
++     integrity of that ticket is first verified. In the event of a session
++     ticket integrity check failing, OpenSSL will fail to free memory
++     causing a memory leak. By sending a large number of invalid session
++     tickets an attacker could exploit this issue in a Denial Of Service
++     attack.
++     (CVE-2014-3567)
++     [Steve Henson]
++
++  *) Build option no-ssl3 is incomplete.
++
++     When OpenSSL is configured with "no-ssl3" as a build option, servers
++     could accept and complete a SSL 3.0 handshake, and clients could be
++     configured to send them.
++     (CVE-2014-3568)
++     [Akamai and the OpenSSL team]
++
++  *) Add support for TLS_FALLBACK_SCSV.
++     Client applications doing fallback retries should call
++     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
++     (CVE-2014-3566)
++     [Adam Langley, Bodo Moeller]
++
++   *) Tighten client-side session ticket handling during renegotiation:
++      ensure that the client only accepts a session ticket if the server sends
++      the extension anew in the ServerHello. Previously, a TLS client would
++      reuse the old extension state and thus accept a session ticket if one was
++      announced in the initial ServerHello.
++      [Emilia Käsper]
+ 
+   *) Accelerated NIST P-256 elliptic curve implementation for x86_64
+      (other platforms pending).
+-     [Shay Gueron (Intel Corp), Andy Polyakov]
++     [Shay Gueron & Vlad Krasnov (Intel Corp), Andy Polyakov]
+ 
+   *) Add support for the SignedCertificateTimestampList certificate and
+      OCSP response extensions from RFC6962.
+@@ -42,7 +88,7 @@
+ 
+   *) Accelerated modular exponentiation for Intel processors, a.k.a.
+      RSAZ.
+-     [Shay Gueron (Intel Corp)]
++     [Shay Gueron & Vlad Krasnov (Intel Corp)]
+ 
+   *) Support for new and upcoming Intel processors, including AVX2,
+      BMI and SHA ISA extensions. This includes additional "stitched"
+@@ -52,6 +98,11 @@
+      This work was sponsored by Intel Corp.
+      [Andy Polyakov]
+ 
++  *) Support for DTLS 1.2. This adds two sets of DTLS methods: DTLS_*_method()
++     supports both DTLS 1.2 and 1.0 and should use whatever version the peer
++     supports and DTLSv1_2_*_method() which supports DTLS 1.2 only.
++     [Steve Henson]
++
+   *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file():
+      this fixes a limiation in previous versions of OpenSSL.
+      [Steve Henson]
+@@ -319,6 +370,66 @@
+      X509_CINF_set_modified, X509_CINF_get_issuer, X509_CINF_get_extensions and
+      X509_CINF_get_signature were reverted post internal team review.
+ 
++ Changes between 1.0.1j and 1.0.1k [xx XXX xxxx]
++
++   *) Tighten client-side session ticket handling during renegotiation:
++      ensure that the client only accepts a session ticket if the server sends
++      the extension anew in the ServerHello. Previously, a TLS client would
++      reuse the old extension state and thus accept a session ticket if one was
++      announced in the initial ServerHello.
++      [Emilia Käsper]
++
++ Changes between 1.0.1i and 1.0.1j [15 Oct 2014]
++
++  *) SRTP Memory Leak.
++
++     A flaw in the DTLS SRTP extension parsing code allows an attacker, who
++     sends a carefully crafted handshake message, to cause OpenSSL to fail
++     to free up to 64k of memory causing a memory leak. This could be
++     exploited in a Denial Of Service attack. This issue affects OpenSSL
++     1.0.1 server implementations for both SSL/TLS and DTLS regardless of
++     whether SRTP is used or configured. Implementations of OpenSSL that
++     have been compiled with OPENSSL_NO_SRTP defined are not affected.
++
++     The fix was developed by the OpenSSL team.
++     (CVE-2014-3513)
++     [OpenSSL team]
++
++  *) Session Ticket Memory Leak.
++
++     When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
++     integrity of that ticket is first verified. In the event of a session
++     ticket integrity check failing, OpenSSL will fail to free memory
++     causing a memory leak. By sending a large number of invalid session
++     tickets an attacker could exploit this issue in a Denial Of Service
++     attack.
++     (CVE-2014-3567)
++     [Steve Henson]
++
++  *) Build option no-ssl3 is incomplete.
++
++     When OpenSSL is configured with "no-ssl3" as a build option, servers
++     could accept and complete a SSL 3.0 handshake, and clients could be
++     configured to send them.
++     (CVE-2014-3568)
++     [Akamai and the OpenSSL team]
++
++  *) Add support for TLS_FALLBACK_SCSV.
++     Client applications doing fallback retries should call
++     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
++     (CVE-2014-3566)
++     [Adam Langley, Bodo Moeller]
++
++  *) Add additional DigestInfo checks.
++ 
++     Reencode DigestInto in DER and check against the original when
++     verifying RSA signature: this will reject any improperly encoded
++     DigestInfo structures.
++
++     Note: this is a precautionary measure and no attacks are currently known.
++
++     [Steve Henson]
++
+  Changes between 1.0.1h and 1.0.1i [6 Aug 2014]
+ 
+   *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
+@@ -405,6 +516,18 @@
+      bogus results, with non-infinity inputs mapped to infinity too.)
+      [Bodo Moeller]
+ 
++ Changes between 1.0.1i and 1.0.1j [xx XXX xxxx]
++
++  *) Add additional DigestInfo checks.
++ 
++     Reencode DigestInto in DER and check against the original when
++     verifying RSA signature: this will reject any improperly encoded
++     DigestInfo structures.
++
++     Note: this is a precautionary measure and no attacks are currently known.
++
++     [Steve Henson]
++
+  Changes between 1.0.1g and 1.0.1h [5 Jun 2014]
+ 
+   *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted
+diff --git a/NEWS b/NEWS
+index ee7f35b..e9180ad 100644
+--- a/NEWS
++++ b/NEWS
+@@ -5,7 +5,7 @@
+   This file gives a brief overview of the major changes between each OpenSSL
+   release. For more details please read the CHANGES file.
+ 
+-  Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.2 [in beta]:
++  Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.2 [in beta]:
+ 
+       o Suite B support for TLS 1.2 and DTLS 1.2
+       o Support for DTLS 1.2
+@@ -16,6 +16,13 @@
+       o ALPN support.
+       o CMS support for RSA-PSS, RSA-OAEP, ECDH and X9.42 DH.
+ 
++  Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014]
++
++      o Fix for CVE-2014-3513
++      o Fix for CVE-2014-3567
++      o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
++      o Fix for CVE-2014-3568
++
+   Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014]
+ 
+       o Fix for CVE-2014-3512
+diff --git a/apps/s_client.c b/apps/s_client.c
+index ffd3a4b..151d9dc 100644
+--- a/apps/s_client.c
++++ b/apps/s_client.c
+@@ -343,6 +343,7 @@ static void sc_usage(void)
+ 	BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
+ 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
+ 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
++	BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
+ 	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
+ 	BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
+ 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
+@@ -649,6 +650,7 @@ int MAIN(int argc, char **argv)
+ 	char *sess_out = NULL;
+ 	struct sockaddr peer;
+ 	int peerlen = sizeof(peer);
++	int fallback_scsv = 0;
+ 	int enable_timeouts = 0 ;
+ 	long socket_mtu = 0;
+ #ifndef OPENSSL_NO_JPAKE
+@@ -933,6 +935,10 @@ static char *jpake_secret = NULL;
+ 			socket_mtu = atol(*(++argv));
+ 			}
+ #endif
++		else if (strcmp(*argv,"-fallback_scsv") == 0)
++			{
++			fallback_scsv = 1;
++			}
+ 		else if	(strcmp(*argv,"-keyform") == 0)
+ 			{
+ 			if (--argc < 1) goto bad;
+@@ -1415,6 +1421,10 @@ bad:
+ 		SSL_set_session(con, sess);
+ 		SSL_SESSION_free(sess);
+ 		}
++
++	if (fallback_scsv)
++		SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
++
+ #ifndef OPENSSL_NO_TLSEXT
+ 	if (servername != NULL)
+ 		{
+diff --git a/crypto/aes/asm/aesni-x86_64.pl b/crypto/aes/asm/aesni-x86_64.pl
+index 31c80ae..5f61746 100644
+--- a/crypto/aes/asm/aesni-x86_64.pl
++++ b/crypto/aes/asm/aesni-x86_64.pl
+@@ -584,6 +584,16 @@ $code.=<<___;
+ .type	aesni_ecb_encrypt,\@function,5
+ .align	16
+ aesni_ecb_encrypt:
++___
++$code.=<<___ if ($win64);
++	lea	-0x58(%rsp),%rsp
++	movaps	%xmm6,(%rsp)
++	movaps	%xmm7,0x10(%rsp)
++	movaps	%xmm8,0x20(%rsp)
++	movaps	%xmm9,0x30(%rsp)
++.Lecb_enc_body:
++___
++$code.=<<___;
+ 	and	\$-16,$len
+ 	jz	.Lecb_ret
+ 
+@@ -862,6 +872,16 @@ $code.=<<___;
+ 	movups	$inout5,0x50($out)
+ 
+ .Lecb_ret:
++___
++$code.=<<___ if ($win64);
++	movaps	(%rsp),%xmm6
++	movaps	0x10(%rsp),%xmm7
++	movaps	0x20(%rsp),%xmm8
++	movaps	0x30(%rsp),%xmm9
++	lea	0x58(%rsp),%rsp
++.Lecb_enc_ret:
++___
++$code.=<<___;
+ 	ret
+ .size	aesni_ecb_encrypt,.-aesni_ecb_encrypt
+ ___
+@@ -3225,28 +3245,9 @@ $code.=<<___;
+ .extern	__imp_RtlVirtualUnwind
+ ___
+ $code.=<<___ if ($PREFIX eq "aesni");
+-.type	ecb_se_handler,\@abi-omnipotent
+-.align	16
+-ecb_se_handler:
+-	push	%rsi
+-	push	%rdi
+-	push	%rbx
+-	push	%rbp
+-	push	%r12
+-	push	%r13
+-	push	%r14
+-	push	%r15
+-	pushfq
+-	sub	\$64,%rsp
+-
+-	mov	152($context),%rax	# pull context->Rsp
+-
+-	jmp	.Lcommon_seh_tail
+-.size	ecb_se_handler,.-ecb_se_handler
+-
+-.type	ccm64_se_handler,\@abi-omnipotent
++.type	ecb_ccm64_se_handler,\@abi-omnipotent
+ .align	16
+-ccm64_se_handler:
++ecb_ccm64_se_handler:
+ 	push	%rsi
+ 	push	%rdi
+ 	push	%rbx
+@@ -3283,7 +3284,7 @@ ccm64_se_handler:
+ 	lea	0x58(%rax),%rax		# adjust stack pointer
+ 
+ 	jmp	.Lcommon_seh_tail
+-.size	ccm64_se_handler,.-ccm64_se_handler
++.size	ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
+ 
+ .type	ctr_xts_se_handler,\@abi-omnipotent
+ .align	16
+@@ -3457,14 +3458,15 @@ ___
+ $code.=<<___ if ($PREFIX eq "aesni");
+ .LSEH_info_ecb:
+ 	.byte	9,0,0,0
+-	.rva	ecb_se_handler
++	.rva	ecb_ccm64_se_handler
++	.rva	.Lecb_enc_body,.Lecb_enc_ret		# HandlerData[]
+ .LSEH_info_ccm64_enc:
+ 	.byte	9,0,0,0
+-	.rva	ccm64_se_handler
++	.rva	ecb_ccm64_se_handler
+ 	.rva	.Lccm64_enc_body,.Lccm64_enc_ret	# HandlerData[]
+ .LSEH_info_ccm64_dec:
+ 	.byte	9,0,0,0
+-	.rva	ccm64_se_handler
++	.rva	ecb_ccm64_se_handler
+ 	.rva	.Lccm64_dec_body,.Lccm64_dec_ret	# HandlerData[]
+ .LSEH_info_ctr32:
+ 	.byte	9,0,0,0
+diff --git a/crypto/constant_time_locl.h b/crypto/constant_time_locl.h
+index c048393..ccb6408 100644
+--- a/crypto/constant_time_locl.h
++++ b/crypto/constant_time_locl.h
+@@ -129,17 +129,12 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b);
+ 
+ static inline unsigned int constant_time_msb(unsigned int a)
+ 	{
+-	return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
++	return -(a >> (sizeof(unsigned int) * 8 - 1));
+ 	}
+ 
+ static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
+ 	{
+-	unsigned int lt;
+-	/* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
+-	lt = ~(a ^ b) & (a - b);
+-	/* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
+-	lt |= ~a & b;
+-	return constant_time_msb(lt);
++	return constant_time_msb(a^((a^b)|((a-b)^b)));
+ 	}
+ 
+ static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+@@ -149,12 +144,7 @@ static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+ 
+ static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
+ 	{
+-	unsigned int ge;
+-	/* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
+-	ge = ~((a ^ b) | (a - b));
+-	/* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
+-	ge |= a & ~b;
+-	return constant_time_msb(ge);
++	return ~constant_time_lt(a, b);
+ 	}
+ 
+ static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
+@@ -204,7 +194,7 @@ static inline unsigned char constant_time_select_8(unsigned char mask,
+ 	return (unsigned char)(constant_time_select(mask, a, b));
+ 	}
+ 
+-inline int constant_time_select_int(unsigned int mask, int a, int b)
++static inline int constant_time_select_int(unsigned int mask, int a, int b)
+ 	{
+ 	return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+ 	}
+diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
+index 4cb24df..139afe3 100644
+--- a/crypto/err/openssl.ec
++++ b/crypto/err/openssl.ec
+@@ -72,6 +72,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		1060
+ R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
+ R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
+ R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
++R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK	1086
+ R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
+ R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
+ R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
+diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
+index 04f6037..5d54c4a 100644
+--- a/crypto/pkcs7/pkcs7.h
++++ b/crypto/pkcs7/pkcs7.h
+@@ -233,10 +233,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
+ 		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+ #define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+ #define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+-#define PKCS7_type_is_encrypted(a) \
+-		(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+-
+-#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+ 
+ #define PKCS7_set_detached(p,v) \
+ 		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c
+index b6f6037..225bcfe 100644
+--- a/crypto/rsa/rsa_sign.c
++++ b/crypto/rsa/rsa_sign.c
+@@ -151,6 +151,25 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+ 	return(ret);
+ 	}
+ 
++/*
++ * Check DigestInfo structure does not contain extraneous data by reencoding
++ * using DER and checking encoding against original. 
++ */
++static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, int dinfolen)
++	{
++	unsigned char *der = NULL;
++	int derlen;
++	int ret = 0;
++	derlen = i2d_X509_SIG(sig, &der);
++	if (derlen <= 0)
++		return 0;
++	if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
++		ret = 1;
++	OPENSSL_cleanse(der, derlen);
++	OPENSSL_free(der);
++	return ret;
++	}
++
+ int int_rsa_verify(int dtype, const unsigned char *m,
+ 			  unsigned int m_len,
+ 			  unsigned char *rm, size_t *prm_len,
+@@ -228,7 +247,7 @@ int int_rsa_verify(int dtype, const unsigned char *m,
+ 		if (sig == NULL) goto err;
+ 
+ 		/* Excess data can be used to create forgeries */
+-		if(p != s+i)
++		if(p != s+i || !rsa_check_digestinfo(sig, s, i))
+ 			{
+ 			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ 			goto err;
+diff --git a/doc/apps/s_client.pod b/doc/apps/s_client.pod
+index 85a17e6..aad59b1 100644
+--- a/doc/apps/s_client.pod
++++ b/doc/apps/s_client.pod
+@@ -37,6 +37,9 @@ B<openssl> B<s_client>
+ [B<-no_ssl2>]
+ [B<-no_ssl3>]
+ [B<-no_tls1>]
++[B<-no_tls1_1>]
++[B<-no_tls1_2>]
++[B<-fallback_scsv>]
+ [B<-bugs>]
+ [B<-cipher cipherlist>]
+ [B<-serverpref>]
+@@ -197,16 +200,19 @@ Use the PSK key B<key> when using a PSK cipher suite. The key is
+ given as a hexadecimal number without leading 0x, for example -psk
+ 1a2b3c4d.
+ 
+-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>
++=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
+ 
+ these options disable the use of certain SSL or TLS protocols. By default
+ the initial handshake uses a method which should be compatible with all
+ servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
+ 
+-Unfortunately there are a lot of ancient and broken servers in use which
++Unfortunately there are still ancient and broken servers in use which
+ cannot handle this technique and will fail to connect. Some servers only
+-work if TLS is turned off with the B<-no_tls> option others will only
+-support SSL v2 and may need the B<-ssl2> option.
++work if TLS is turned off.
++
++=item B<-fallback_scsv>
++
++Send TLS_FALLBACK_SCSV in the ClientHello.
+ 
+ =item B<-bugs>
+ 
+diff --git a/doc/crypto/EVP_BytesToKey.pod b/doc/crypto/EVP_BytesToKey.pod
+index cd09b68..5d60595 100644
+--- a/doc/crypto/EVP_BytesToKey.pod
++++ b/doc/crypto/EVP_BytesToKey.pod
+@@ -55,7 +55,10 @@ the IV.
+ 
+ =head1 RETURN VALUES
+ 
+-EVP_BytesToKey() returns the size of the derived key in bytes, or 0 on error.
++If B<data> is NULL, then EVP_BytesToKey() returns the number of bytes
++needed to store the derived key.
++Otherwise, EVP_BytesToKey() returns the size of the derived key in bytes,
++or 0 on error.
+ 
+ =head1 SEE ALSO
+ 
+diff --git a/doc/crypto/OPENSSL_VERSION_NUMBER.pod b/doc/crypto/OPENSSL_VERSION_NUMBER.pod
+index c39ac35..f7ca7cb 100644
+--- a/doc/crypto/OPENSSL_VERSION_NUMBER.pod
++++ b/doc/crypto/OPENSSL_VERSION_NUMBER.pod
+@@ -17,7 +17,7 @@ OPENSSL_VERSION_NUMBER, SSLeay, SSLeay_version - get OpenSSL version number
+ 
+ OPENSSL_VERSION_NUMBER is a numeric release version identifier:
+ 
+- MMNNFFPPS: major minor fix patch status
++ MNNFFPPS: major minor fix patch status
+ 
+ The status nibble has one of the values 0 for development, 1 to e for betas
+ 1 to 14, and f for release.
+diff --git a/doc/ssl/SSL_CTX_set_mode.pod b/doc/ssl/SSL_CTX_set_mode.pod
+index 8cb669d..2a5aaa5 100644
+--- a/doc/ssl/SSL_CTX_set_mode.pod
++++ b/doc/ssl/SSL_CTX_set_mode.pod
+@@ -71,6 +71,16 @@ SSL_CTX->freelist_max_len, which defaults to 32.  Using this flag can
+ save around 34k per idle SSL connection.
+ This flag has no effect on SSL v2 connections, or on DTLS connections.
+ 
++=item SSL_MODE_SEND_FALLBACK_SCSV
++
++Send TLS_FALLBACK_SCSV in the ClientHello.
++To be set only by applications that reconnect with a downgraded protocol
++version; see draft-ietf-tls-downgrade-scsv-00 for details.
++
++DO NOT ENABLE THIS if your application attempts a normal handshake.
++Only use this in explicit fallback retries, following the guidance
++in draft-ietf-tls-downgrade-scsv-00.
++
+ =back
+ 
+ =head1 RETURN VALUES
+diff --git a/e_os.h b/e_os.h
+index 200df42..13694c4 100644
+--- a/e_os.h
++++ b/e_os.h
+@@ -293,7 +293,7 @@ extern "C" {
+ #    ifdef _WIN64
+ #      define strlen(s) _strlen31(s)
+ /* cut strings to 2GB */
+-static unsigned int _strlen31(const char *str)
++static __inline unsigned int _strlen31(const char *str)
+ 	{
+ 	unsigned int len=0;
+ 	while (*str && len<0x80000000U) str++, len++;
+@@ -742,8 +742,8 @@ struct servent *getservbyname(const char *name, const char *proto);
+ #if !defined(inline) && !defined(__cplusplus)
+ # if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+    /* do nothing, inline works */
+-# elif defined(__GNUC__) && __GNUC__>=3 && !defined(__NO_INLINE__)
+-   /* do nothing, inline works */
++# elif defined(__GNUC__) && __GNUC__>=2
++#  define inline __inline__
+ # elif defined(_MSC_VER)
+   /*
+    * Visual Studio: inline is available in C++ only, however
+diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
+index 7d9d91f..25c58a8 100644
+--- a/ssl/d1_lib.c
++++ b/ssl/d1_lib.c
+@@ -294,6 +294,25 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
+ 	case DTLS_CTRL_LISTEN:
+ 		ret = dtls1_listen(s, parg);
+ 		break;
++	case SSL_CTRL_CHECK_PROTO_VERSION:
++		/* For library-internal use; checks that the current protocol
++		 * is the highest enabled version (according to s->ctx->method,
++		 * as version negotiation may have changed s->method). */
++		if (s->version == s->ctx->method->version)
++			return 1;
++		/* Apparently we're using a version-flexible SSL_METHOD
++		 * (not at its highest protocol version). */
++		if (s->ctx->method->version == DTLS_method()->version)
++			{
++#if DTLS_MAX_VERSION != DTLS1_2_VERSION
++#  error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
++#endif
++			if (!(s->options & SSL_OP_NO_DTLSv1_2))
++				return s->version == DTLS1_2_VERSION;
++			if (!(s->options & SSL_OP_NO_DTLSv1))
++				return s->version == DTLS1_VERSION;
++			}
++		return 0; /* Unexpected state; fail closed. */
+ 
+ 	default:
+ 		ret = ssl3_ctrl(s, cmd, larg, parg);
+diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c
+index 928935b..ac1bef0 100644
+--- a/ssl/d1_srtp.c
++++ b/ssl/d1_srtp.c
+@@ -167,25 +167,6 @@ static int find_profile_by_name(char *profile_name,
+ 	return 1;
+ 	}
+ 
+-static int find_profile_by_num(unsigned profile_num,
+-			       SRTP_PROTECTION_PROFILE **pptr)
+-	{
+-	SRTP_PROTECTION_PROFILE *p;
+-
+-	p=srtp_known_profiles;
+-	while(p->name)
+-		{
+-		if(p->id == profile_num)
+-			{
+-			*pptr=p;
+-			return 0;
+-			}
+-		p++;
+-		}
+-
+-	return 1;
+-	}
+-
+ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+ 	{
+ 	STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+@@ -208,11 +189,19 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE
+ 		if(!find_profile_by_name(ptr,&p,
+ 					 col ? col-ptr : (int)strlen(ptr)))
+ 			{
++			if (sk_SRTP_PROTECTION_PROFILE_find(profiles,p) >= 0)
++				{
++				SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
++				sk_SRTP_PROTECTION_PROFILE_free(profiles);
++				return 1;
++				}
++
+ 			sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
+ 			}
+ 		else
+ 			{
+ 			SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
++			sk_SRTP_PROTECTION_PROFILE_free(profiles);
+ 			return 1;
+ 			}
+ 
+@@ -304,13 +293,12 @@ int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max
+ 
+ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+ 	{
+-	SRTP_PROTECTION_PROFILE *cprof,*sprof;
+-	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
++	SRTP_PROTECTION_PROFILE *sprof;
++	STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
+         int ct;
+         int mki_len;
+-	int i,j;
+-	int id;
+-	int ret;
++	int i, srtp_pref;
++	unsigned int id;
+ 
+          /* Length value + the MKI length */
+         if(len < 3)
+@@ -340,22 +328,32 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
+ 		return 1;
+ 		}
+ 
++	srvr=SSL_get_srtp_profiles(s);
++	s->srtp_profile = NULL;
++	/* Search all profiles for a match initially */
++	srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
+         
+-	clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
+-
+ 	while(ct)
+ 		{
+ 		n2s(d,id);
+ 		ct-=2;
+                 len-=2;
+ 
+-		if(!find_profile_by_num(id,&cprof))
++		/*
++		 * Only look for match in profiles of higher preference than
++		 * current match.
++		 * If no profiles have been have been configured then this
++		 * does nothing.
++		 */
++		for (i = 0; i < srtp_pref; i++)
+ 			{
+-			sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
+-			}
+-		else
+-			{
+-			; /* Ignore */
++			sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
++			if (sprof->id == id)
++				{
++				s->srtp_profile = sprof;
++				srtp_pref = i;
++				break;
++				}
+ 			}
+ 		}
+ 
+@@ -370,36 +368,7 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
+ 		return 1;
+ 		}
+ 
+-	srvr=SSL_get_srtp_profiles(s);
+-
+-	/* Pick our most preferred profile. If no profiles have been
+-	 configured then the outer loop doesn't run 
+-	 (sk_SRTP_PROTECTION_PROFILE_num() = -1)
+-	 and so we just return without doing anything */
+-	for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
+-		{
+-		sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
+-
+-		for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
+-			{
+-			cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
+-            
+-			if(cprof->id==sprof->id)
+-				{
+-				s->srtp_profile=sprof;
+-				*al=0;
+-				ret=0;
+-				goto done;
+-				}
+-			}
+-		}
+-
+-	ret=0;
+-    
+-done:
+-	if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
+-
+-	return ret;
++	return 0;
+ 	}
+ 
+ int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+diff --git a/ssl/dtls1.h b/ssl/dtls1.h
+index c6edbe3..5cb79f1 100644
+--- a/ssl/dtls1.h
++++ b/ssl/dtls1.h
+@@ -84,8 +84,11 @@ extern "C" {
+ #endif
+ 
+ #define DTLS1_VERSION			0xFEFF
+-#define DTLS1_BAD_VER			0x0100
+ #define DTLS1_2_VERSION			0xFEFD
++#define DTLS_MAX_VERSION		DTLS1_2_VERSION
++
++#define DTLS1_BAD_VER			0x0100
++
+ /* Special value for method supporting multiple versions */
+ #define DTLS_ANY_VERSION		0x1FFFF
+ 
+@@ -287,4 +290,3 @@ typedef struct dtls1_record_data_st
+ }
+ #endif
+ #endif
+-
+diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
+index 5177f06..56705c3 100644
+--- a/ssl/s23_clnt.c
++++ b/ssl/s23_clnt.c
+@@ -125,9 +125,11 @@ static const SSL_METHOD *ssl23_get_client_method(int ver)
+ 	if (ver == SSL2_VERSION)
+ 		return(SSLv2_client_method());
+ #endif
++#ifndef OPENSSL_NO_SSL3
+ 	if (ver == SSL3_VERSION)
+ 		return(SSLv3_client_method());
+-	else if (ver == TLS1_VERSION)
++#endif
++	if (ver == TLS1_VERSION)
+ 		return(TLSv1_client_method());
+ 	else if (ver == TLS1_1_VERSION)
+ 		return(TLSv1_1_client_method());
+@@ -710,6 +712,7 @@ static int ssl23_get_server_hello(SSL *s)
+ 		{
+ 		/* we have sslv3 or tls1 (server hello or alert) */
+ 
++#ifndef OPENSSL_NO_SSL3
+ 		if ((p[2] == SSL3_VERSION_MINOR) &&
+ 			!(s->options & SSL_OP_NO_SSLv3))
+ 			{
+@@ -724,7 +727,9 @@ static int ssl23_get_server_hello(SSL *s)
+ 			s->version=SSL3_VERSION;
+ 			s->method=SSLv3_client_method();
+ 			}
+-		else if ((p[2] == TLS1_VERSION_MINOR) &&
++		else
++#endif
++		if ((p[2] == TLS1_VERSION_MINOR) &&
+ 			!(s->options & SSL_OP_NO_TLSv1))
+ 			{
+ 			s->version=TLS1_VERSION;
+@@ -748,6 +753,9 @@ static int ssl23_get_server_hello(SSL *s)
+ 			goto err;
+ 			}
+ 
++		/* ensure that TLS_MAX_VERSION is up-to-date */
++		OPENSSL_assert(s->version <= TLS_MAX_VERSION);
++
+ 		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
+ 			{
+ 			/* fatal alert */
+diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
+index 75d8142..e656ac2 100644
+--- a/ssl/s23_srvr.c
++++ b/ssl/s23_srvr.c
+@@ -127,9 +127,11 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
+ 	if (ver == SSL2_VERSION)
+ 		return(SSLv2_server_method());
+ #endif
++#ifndef OPENSSL_NO_SSL3
+ 	if (ver == SSL3_VERSION)
+ 		return(SSLv3_server_method());
+-	else if (ver == TLS1_VERSION)
++#endif
++	if (ver == TLS1_VERSION)
+ 		return(TLSv1_server_method());
+ 	else if (ver == TLS1_1_VERSION)
+ 		return(TLSv1_1_server_method());
+@@ -421,6 +423,9 @@ int ssl23_get_client_hello(SSL *s)
+ 			}
+ 		}
+ 
++	/* ensure that TLS_MAX_VERSION is up-to-date */
++	OPENSSL_assert(s->version <= TLS_MAX_VERSION);
++
+ 	if (s->version < TLS1_2_VERSION && tls1_suiteb(s))
+ 		{
+ 		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
+@@ -604,6 +609,14 @@ int ssl23_get_client_hello(SSL *s)
+ 	if ((type == 2) || (type == 3))
+ 		{
+ 		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
++		const SSL_METHOD *new_method;
++		new_method = ssl23_get_server_method(s->version);
++		if (new_method == NULL)
++			{
++			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
++			goto err;
++			}
++		s->method = new_method;
+ 
+ 		if (!ssl_init_wbio_buffer(s,1)) goto err;
+ 
+@@ -631,14 +644,6 @@ int ssl23_get_client_hello(SSL *s)
+ 			s->s3->rbuf.left=0;
+ 			s->s3->rbuf.offset=0;
+ 			}
+-		if (s->version == TLS1_2_VERSION)
+-			s->method = TLSv1_2_server_method();
+-		else if (s->version == TLS1_1_VERSION)
+-			s->method = TLSv1_1_server_method();
+-		else if (s->version == TLS1_VERSION)
+-			s->method = TLSv1_server_method();
+-		else
+-			s->method = SSLv3_server_method();
+ #if 0 /* ssl3_get_client_hello does this */
+ 		s->client_version=(v[0]<<8)|v[1];
+ #endif
+diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
+index 41ae4e8..41818dc 100644
+--- a/ssl/s2_lib.c
++++ b/ssl/s2_lib.c
+@@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
+ 	case SSL_CTRL_GET_SESSION_REUSED:
+ 		ret=s->hit;
+ 		break;
++	case SSL_CTRL_CHECK_PROTO_VERSION:
++		return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
+ 	default:
+ 		break;
+ 		}
+@@ -434,7 +436,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
+ 	if (p != NULL)
+ 		{
+ 		l=c->id;
+-		if ((l & 0xff000000) != 0x02000000) return(0);
++		if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
+ 		p[0]=((unsigned char)(l>>16L))&0xFF;
+ 		p[1]=((unsigned char)(l>> 8L))&0xFF;
+ 		p[2]=((unsigned char)(l     ))&0xFF;
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 3e89e52..7d7af4b 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -225,6 +225,14 @@ int ssl3_connect(SSL *s)
+ 			s->renegotiate=1;
+ 			s->state=SSL_ST_CONNECT;
+ 			s->ctx->stats.sess_connect_renegotiate++;
++#ifndef OPENSSL_NO_TLSEXT
++			/*
++			 * If renegotiating, the server may choose to not issue
++			 * a new ticket, so reset the flag. It will be set to
++			 * the right value when parsing ServerHello extensions.
++			 */
++			s->tlsext_ticket_expected = 0;
++#endif
+ 			/* break */
+ 		case SSL_ST_BEFORE:
+ 		case SSL_ST_CONNECT:
+@@ -2168,12 +2176,18 @@ int ssl3_get_certificate_request(SSL *s)
+ 			s->cert->pkeys[i].digest = NULL;
+ 			s->cert->pkeys[i].valid_flags = 0;
+ 			}
+-		if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
++		if ((llen & 1) || !tls1_save_sigalgs(s, p, llen))
+ 			{
+ 			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+ 			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ 			goto err;
+ 			}
++		if (!tls1_process_sigalgs(s))
++			{
++			ssl3_send_alert(s,SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
++			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
++			goto err;
++			}
+ 		p += llen;
+ 		}
+ 
+@@ -2322,7 +2336,7 @@ int ssl3_get_new_session_ticket(SSL *s)
+ 		}
+ 	memcpy(s->session->tlsext_tick, p, ticklen);
+ 	s->session->tlsext_ticklen = ticklen;
+-	/* There are two ways to detect a resumed ticket sesion.
++	/* There are two ways to detect a resumed ticket session.
+ 	 * One is to set an appropriate session ID and then the server
+ 	 * must return a match in ServerHello. This allows the normal
+ 	 * client session ID matching to work and we know much 
+diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
+index 86f06d0..73f3e17 100644
+--- a/ssl/s3_enc.c
++++ b/ssl/s3_enc.c
+@@ -941,7 +941,7 @@ int ssl3_alert_code(int code)
+ 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
+ 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
+ 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
++	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
+ 	default:			return(-1);
+ 		}
+ 	}
+-
+diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
+index a15625b..361f295 100644
+--- a/ssl/s3_lib.c
++++ b/ssl/s3_lib.c
+@@ -3598,6 +3598,33 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
+ 		return (int)sess->tlsext_ecpointformatlist_length;
+ 		}
+ #endif
++
++	case SSL_CTRL_CHECK_PROTO_VERSION:
++		/* For library-internal use; checks that the current protocol
++		 * is the highest enabled version (according to s->ctx->method,
++		 * as version negotiation may have changed s->method). */
++		if (s->version == s->ctx->method->version)
++			return 1;
++		/* Apparently we're using a version-flexible SSL_METHOD
++		 * (not at its highest protocol version). */
++		if (s->ctx->method->version == SSLv23_method()->version)
++			{
++#if TLS_MAX_VERSION != TLS1_2_VERSION
++#  error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
++#endif
++			if (!(s->options & SSL_OP_NO_TLSv1_2))
++				return s->version == TLS1_2_VERSION;
++			if (!(s->options & SSL_OP_NO_TLSv1_1))
++				return s->version == TLS1_1_VERSION;
++			if (!(s->options & SSL_OP_NO_TLSv1))
++				return s->version == TLS1_VERSION;
++			if (!(s->options & SSL_OP_NO_SSLv3))
++				return s->version == SSL3_VERSION;
++			if (!(s->options & SSL_OP_NO_SSLv2))
++				return s->version == SSL2_VERSION;
++			}
++		return 0; /* Unexpected state; fail closed. */
++
+ 	default:
+ 		break;
+ 		}
+@@ -4519,4 +4546,3 @@ long ssl_get_algorithm2(SSL *s)
+ 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+ 	return alg2;
+ 	}
+-
+diff --git a/ssl/srtp.h b/ssl/srtp.h
+index ae364d0..dfdab0e 100644
+--- a/ssl/srtp.h
++++ b/ssl/srtp.h
+@@ -130,12 +130,16 @@ extern "C" {
+ #define SRTP_NULL_SHA1_80      0x0005
+ #define SRTP_NULL_SHA1_32      0x0006
+ 
++#ifndef OPENSSL_NO_SRTP
++
+ int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+ int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+ 
+ STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+ SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+ 
++#endif
++
+ #ifdef  __cplusplus
+ }
+ #endif
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index dc034d5..bbf3180 100644
+--- a/ssl/ssl.h
++++ b/ssl/ssl.h
+@@ -681,6 +681,15 @@ struct ssl_session_st
+  */
+ #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
+ #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
++/* Send TLS_FALLBACK_SCSV in the ClientHello.
++ * To be set only by applications that reconnect with a downgraded protocol
++ * version; see draft-ietf-tls-downgrade-scsv-00 for details.
++ *
++ * DO NOT ENABLE THIS if your application attempts a normal handshake.
++ * Only use this in explicit fallback retries, following the guidance
++ * in draft-ietf-tls-downgrade-scsv-00.
++ */
++#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
+ 
+ /* Cert related flags */
+ /* Many implementations ignore some aspects of the TLS standards such as
+@@ -1683,6 +1692,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+ #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+ #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+ #define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
++#define SSL_AD_INAPPROPRIATE_FALLBACK	TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */
+ 
+ #define SSL_ERROR_NONE			0
+ #define SSL_ERROR_SSL			1
+@@ -1821,6 +1831,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+ #define SSL_CTRL_SELECT_CURRENT_CERT		116
+ #define SSL_CTRL_SET_CURRENT_CERT		117
+ 
++#define SSL_CTRL_CHECK_PROTO_VERSION		119
++
++
+ #define SSL_CERT_SET_FIRST			1
+ #define SSL_CERT_SET_NEXT			2
+ #define SSL_CERT_SET_SERVER			3
+@@ -2569,6 +2582,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL_CERT_INST				 222
+ #define SSL_F_SSL_CERT_INSTANTIATE			 214
+ #define SSL_F_SSL_CERT_NEW				 162
++#define SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE		 335
+ #define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
+ #define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
+ #define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
+@@ -2765,6 +2779,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_HTTP_REQUEST				 156
+ #define SSL_R_ILLEGAL_PADDING				 283
+ #define SSL_R_ILLEGAL_SUITEB_DIGEST			 380
++#define SSL_R_INAPPROPRIATE_FALLBACK			 373
+ #define SSL_R_INCONSISTENT_COMPRESSION			 340
+ #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
+ #define SSL_R_INVALID_COMMAND				 280
+@@ -2921,6 +2936,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
+ #define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
+ #define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
++#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK	 1086
+ #define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
+ #define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
+ #define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
+diff --git a/ssl/ssl3.h b/ssl/ssl3.h
+index 7ba8f4c..a4823d3 100644
+--- a/ssl/ssl3.h
++++ b/ssl/ssl3.h
+@@ -128,9 +128,14 @@
+ extern "C" {
+ #endif
+ 
+-/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
++/* Signalling cipher suite value from RFC 5746
++ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
+ #define SSL3_CK_SCSV				0x030000FF
+ 
++/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
++ * (TLS_FALLBACK_SCSV) */
++#define SSL3_CK_FALLBACK_SCSV			0x03005600
++
+ #define SSL3_CK_RSA_NULL_MD5			0x03000001
+ #define SSL3_CK_RSA_NULL_SHA			0x03000002
+ #define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
+diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
+index 1eca037..bcd124e 100644
+--- a/ssl/ssl_err.c
++++ b/ssl/ssl_err.c
+@@ -199,6 +199,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
+ {ERR_FUNC(SSL_F_SSL_CERT_INST),	"ssl_cert_inst"},
+ {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE),	"SSL_CERT_INSTANTIATE"},
+ {ERR_FUNC(SSL_F_SSL_CERT_NEW),	"ssl_cert_new"},
++{ERR_FUNC(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE),	"ssl_check_clienthello_tlsext_late"},
+ {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_private_key"},
+ {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CHECK_SERVERHELLO_TLSEXT"},
+ {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),	"ssl_check_srvr_ecc_cert_and_alg"},
+@@ -398,6 +399,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
+ {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+ {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"},
++{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"},
+ {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
+ {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
+ {ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
+@@ -554,6 +556,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
+ {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
+ {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
++{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"},
+ {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
+ {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
+ {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index f779ce6..22a210e 100644
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -1464,12 +1464,14 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
+ 	SSL_CIPHER *c;
+ 	CERT *ct = s->cert;
+ 	unsigned char *q;
+-	int no_scsv = s->renegotiate;
++	int empty_reneg_info_scsv = !s->renegotiate;
+ 	/* Set disabled masks for this session */
+ 	ssl_set_client_disabled(s);
+ 
+ 	if (sk == NULL) return(0);
+ 	q=p;
++	if (put_cb == NULL)
++		put_cb = s->method->put_cipher_by_char;
+ 
+ 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
+ 		{
+@@ -1482,29 +1484,40 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
+ #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ 		if (c->id == SSL3_CK_SCSV)
+ 			{
+-			if (no_scsv)
++			if (!empty_reneg_info_scsv)
+ 				continue;
+ 			else
+-				no_scsv = 1;
++				empty_reneg_info_scsv = 0;
+ 			}
+ #endif
+-		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
++		j = put_cb(c,p);
+ 		p+=j;
+ 		}
+-	/* If p == q, no ciphers and caller indicates an error. Otherwise
+-	 * add SCSV if not renegotiating.
+-	 */
+-	if (p != q && !no_scsv)
++	/* If p == q, no ciphers; caller indicates an error.
++	 * Otherwise, add applicable SCSVs. */
++	if (p != q)
+ 		{
+-		static SSL_CIPHER scsv =
++		if (empty_reneg_info_scsv)
+ 			{
+-			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+-			};
+-		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
+-		p+=j;
++			static SSL_CIPHER scsv =
++				{
++				0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
++				};
++			j = put_cb(&scsv,p);
++			p+=j;
+ #ifdef OPENSSL_RI_DEBUG
+-		fprintf(stderr, "SCSV sent by client\n");
++			fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
+ #endif
++			}
++		if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
++			{
++			static SSL_CIPHER scsv =
++				{
++				0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
++				};
++			j = put_cb(&scsv,p);
++			p+=j;
++			}
+ 		}
+ 
+ 	return(p-q);
+@@ -1516,11 +1529,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
+ 	const SSL_CIPHER *c;
+ 	STACK_OF(SSL_CIPHER) *sk;
+ 	int i,n;
++
+ 	if (s->s3)
+ 		s->s3->send_connection_binding = 0;
+ 
+ 	n=ssl_put_cipher_by_char(s,NULL,NULL);
+-	if ((num%n) != 0)
++	if (n == 0 || (num%n) != 0)
+ 		{
+ 		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ 		return(NULL);
+@@ -1545,7 +1559,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
+ 
+ 	for (i=0; i<num; i+=n)
+ 		{
+-		/* Check for SCSV */
++		/* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+ 		if (s->s3 && (n != 3 || !p[0]) &&
+ 			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+ 			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
+@@ -1565,6 +1579,24 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
+ 			continue;
+ 			}
+ 
++		/* Check for TLS_FALLBACK_SCSV */
++		if ((n != 3 || !p[0]) &&
++			(p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
++			(p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff)))
++			{
++			/* The SCSV indicates that the client previously tried a higher version.
++			 * Fail if the current version is an unexpected downgrade. */
++			if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL))
++				{
++				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK);
++				if (s->s3)
++					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
++				goto err;
++				}
++			p += n;
++			continue;
++			}
++
+ 		c=ssl_get_cipher_by_char(s,p);
+ 		p+=n;
+ 		if (c != NULL)
+@@ -3152,15 +3184,28 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+ 
+ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
+ 	{
++	CERT *ocert = ssl->cert;
+ 	if (ssl->ctx == ctx)
+ 		return ssl->ctx;
+ #ifndef OPENSSL_NO_TLSEXT
+ 	if (ctx == NULL)
+ 		ctx = ssl->initial_ctx;
+ #endif
+-	if (ssl->cert != NULL)
+-		ssl_cert_free(ssl->cert);
+ 	ssl->cert = ssl_cert_dup(ctx->cert);
++	if (ocert)
++		{
++		/* Preserve any already negotiated parameters */
++		if (ssl->server)
++			{
++			ssl->cert->peer_sigalgs = ocert->peer_sigalgs;
++			ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen;
++			ocert->peer_sigalgs = NULL;
++			ssl->cert->ciphers_raw = ocert->ciphers_raw;
++			ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen;
++			ocert->ciphers_raw = NULL;
++			}
++		ssl_cert_free(ocert);
++		}
+ 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+ 	if (ssl->ctx != NULL)
+ 		SSL_CTX_free(ssl->ctx); /* decrement reference count */
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index ce5856a..6d8047c 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -1353,7 +1353,8 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
+ 					  int *al);
+ long ssl_get_algorithm2(SSL *s);
+-int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
++int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize);
++int tls1_process_sigalgs(SSL *s);
+ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
+ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
+ 				const unsigned char *sig, EVP_PKEY *pkey);
+diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
+index 73d87fd..3f9bad1 100644
+--- a/ssl/ssl_sess.c
++++ b/ssl/ssl_sess.c
+@@ -340,7 +340,21 @@ int ssl_get_new_session(SSL *s, int session)
+ 			return(0);
+ 			}
+ #ifndef OPENSSL_NO_TLSEXT
+-		/* If RFC4507 ticket use empty session ID */
++		/*
++		 * If RFC5077 ticket, use empty session ID (as server).
++		 * Note that:
++		 * (a) ssl_get_prev_session() does lookahead into the
++		 *     ClientHello extensions to find the session ticket.
++		 *     When ssl_get_prev_session() fails, s3_srvr.c calls
++		 *     ssl_get_new_session() in ssl3_get_client_hello().
++		 *     At that point, it has not yet parsed the extensions,
++		 *     however, because of the lookahead, it already knows
++		 *     whether a ticket is expected or not.
++		 *
++		 * (b) s3_clnt.c calls ssl_get_new_session() before parsing
++		 *     ServerHello extensions, and before recording the session
++		 *     ID received from the server, so this block is a noop.
++		 */
+ 		if (s->tlsext_ticket_expected)
+ 			{
+ 			ss->session_id_length = 0;
+diff --git a/ssl/ssltest.c b/ssl/ssltest.c
+index 7dffb94..406a801 100644
+--- a/ssl/ssltest.c
++++ b/ssl/ssltest.c
+@@ -724,7 +724,9 @@ static void sv_usage(void)
+ 	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
+ 	               "                 (default is sect163r2).\n");
+ #endif
+-	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
++	fprintf(stderr," -test_cipherlist - Verifies the order of the ssl cipher lists.\n"
++		       "                    When this option is requested, the cipherlist\n"
++		       "                    tests are run instead of handshake tests.\n");
+ 	fprintf(stderr," -serverinfo_file file - have server use this file\n");
+ 	fprintf(stderr," -serverinfo_sct  - have client offer and expect SCT\n");
+ 	fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n");
+@@ -912,6 +914,7 @@ int main(int argc, char *argv[])
+ #ifdef OPENSSL_FIPS
+ 	int fips_mode=0;
+ #endif
++        int no_protocol = 0;
+ 
+ 	verbose = 0;
+ 	debug = 0;
+@@ -1021,11 +1024,26 @@ int main(int argc, char *argv[])
+ 			}
+ #endif
+ 		else if	(strcmp(*argv,"-ssl2") == 0)
+-			ssl2=1;
++			{
++#ifdef OPENSSL_NO_SSL2
++			no_protocol = 1;
++#endif
++			ssl2 = 1;
++			}
+ 		else if	(strcmp(*argv,"-tls1") == 0)
+-			tls1=1;
++			{
++#ifdef OPENSSL_NO_TLS1
++			no_protocol = 1;
++#endif
++			tls1 = 1;
++			}
+ 		else if	(strcmp(*argv,"-ssl3") == 0)
+-			ssl3=1;
++			{
++#ifdef OPENSSL_NO_SSL3
++			no_protocol = 1;
++#endif
++			ssl3 = 1;
++			}
+ 		else if	(strncmp(*argv,"-num",4) == 0)
+ 			{
+ 			if (--argc < 1) goto bad;
+@@ -1178,15 +1196,41 @@ bad:
+ 		goto end;
+ 		}
+ 
++	/*
++	 * test_cipherlist prevails over protocol switch: we test the cipherlist
++	 * for all enabled protocols.
++	 */
+ 	if (test_cipherlist == 1)
+ 		{
+ 		/* ensure that the cipher list are correctly sorted and exit */
++		fprintf(stdout, "Testing cipherlist order only. Ignoring all "
++			"other options.\n");
+ 		if (do_test_cipherlist() == 0)
+ 			EXIT(1);
+ 		ret = 0;
+ 		goto end;
+ 		}
+ 
++	if (ssl2 + ssl3 + tls1 > 1)
++		{
++		fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should "
++			"be requested.\n");
++		EXIT(1);
++		}
++
++	/*
++	 * Testing was requested for a compiled-out protocol (e.g. SSLv2).
++         * Ideally, we would error out, but the generic test wrapper can't know
++	 * when to expect failure. So we do nothing and return success.
++	 */
++	if (no_protocol)
++		{
++		fprintf(stderr, "Testing was requested for a disabled protocol. "
++			"Skipping tests.\n");
++		ret = 0;
++		goto end;
++		}
++
+ 	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
+ 		{
+ 		fprintf(stderr, "This case cannot work.  Use -f to perform "
+@@ -1265,30 +1309,25 @@ bad:
+ 	}
+ #endif
+ 
+-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
++/* At this point, ssl2/ssl3/tls1 is only set if the protocol is available.
++ * (Otherwise we exit early.)
++ * However the compiler doesn't know this, so we ifdef. */
++#ifndef OPENSSL_NO_SSL2
+ 	if (ssl2)
+ 		meth=SSLv2_method();
+-	else 
+-	if (tls1)
+-		meth=TLSv1_method();
+ 	else
++#endif
++#ifndef OPENSSL_NO_SSL3
+ 	if (ssl3)
+ 		meth=SSLv3_method();
+ 	else
+-		meth=SSLv23_method();
+-#else
+-#ifdef OPENSSL_NO_SSL2
++#endif
++#ifndef OPENSSL_NO_TLS1
+ 	if (tls1)
+ 		meth=TLSv1_method();
+ 	else
+-	if (ssl3)
+-		meth=SSLv3_method();
+-	else
+-		meth=SSLv23_method();
+-#else
+-	meth=SSLv2_method();
+-#endif
+ #endif
++	meth=SSLv23_method();
+ 
+ 	c_ctx=SSL_CTX_new(meth);
+ 	s_ctx=SSL_CTX_new(meth);
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 10fc795..7974762 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -1286,6 +1286,7 @@ int tls1_alert_code(int code)
+ 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+ 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
+ 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
++	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
+ #if 0 /* not appropriate for TLS, not used for DTLS */
+ 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
+ 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
+index 5fed446..23aee07 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -1474,7 +1474,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
+ 		ret += s->alpn_client_proto_list_len;
+ 		}
+ 
+-        if(SSL_get_srtp_profiles(s))
++        if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s))
+                 {
+                 int el;
+ 
+@@ -1648,7 +1648,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
+ 		}
+ #endif
+ 
+-        if(s->srtp_profile)
++        if(SSL_IS_DTLS(s) && s->srtp_profile)
+                 {
+                 int el;
+ 
+@@ -1908,7 +1908,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 	unsigned short len;
+ 	unsigned char *data = *p;
+ 	int renegotiate_seen = 0;
+-	size_t i;
+ 
+ 	s->servername_done = 0;
+ 	s->tlsext_status_type = -1;
+@@ -1938,18 +1937,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 		OPENSSL_free(s->cert->peer_sigalgs);
+ 		s->cert->peer_sigalgs = NULL;
+ 		}
+-	/* Clear any shared sigtnature algorithms */
+-	if (s->cert->shared_sigalgs)
+-		{
+-		OPENSSL_free(s->cert->shared_sigalgs);
+-		s->cert->shared_sigalgs = NULL;
+-		}
+-	/* Clear certificate digests and validity flags */
+-	for (i = 0; i < SSL_PKEY_NUM; i++)
+-		{
+-		s->cert->pkeys[i].digest = NULL;
+-		s->cert->pkeys[i].valid_flags = 0;
+-		}
+ 
+ 	if (data >= (d+n-2))
+ 		goto ri_check;
+@@ -2236,21 +2223,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 				*al = SSL_AD_DECODE_ERROR;
+ 				return 0;
+ 				}
+-			if (!tls1_process_sigalgs(s, data, dsize))
++			if (!tls1_save_sigalgs(s, data, dsize))
+ 				{
+ 				*al = SSL_AD_DECODE_ERROR;
+ 				return 0;
+ 				}
+-			/* If sigalgs received and no shared algorithms fatal
+-			 * error.
+-			 */
+-			if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs)
+-				{
+-				SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
+-					SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
+-				*al = SSL_AD_ILLEGAL_PARAMETER;
+-				return 0;
+-				}
+ 			}
+ 		else if (type == TLSEXT_TYPE_status_request)
+ 			{
+@@ -2417,23 +2394,13 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 			}
+ 
+ 		/* session ticket processed earlier */
+-		else if (type == TLSEXT_TYPE_use_srtp)
++		else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
++				&& type == TLSEXT_TYPE_use_srtp)
+                         {
+ 			if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
+ 							      al))
+ 				return 0;
+                         }
+-		/* If this ClientHello extension was unhandled and this is 
+-		 * a nonresumed connection, check whether the extension is a 
+-		 * custom TLS Extension (has a custom_srv_ext_record), and if
+-		 * so call the callback and record the extension number so that
+-		 * an appropriate ServerHello may be later returned.
+-		 */
+-		else if (!s->hit)
+-			{
+-			if (custom_ext_parse(s, 1, type, data, size, al) <= 0)
+-				return 0;
+-			}
+ 
+ 		data+=size;
+ 		}
+@@ -2452,9 +2419,41 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 				SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ 		return 0;
+ 		}
+-	/* If no signature algorithms extension set default values */
+-	if (!s->cert->peer_sigalgs)
+-		ssl_cert_set_default_md(s->cert);
++
++	return 1;
++	}
++
++/*
++ * Parse any custom extensions found.  "data" is the start of the extension data
++ * and "limit" is the end of the record. TODO: add strict syntax checking.
++ */
++
++static int ssl_scan_clienthello_custom_tlsext(SSL *s, const unsigned char *data, const unsigned char *limit, int *al) 
++	{	
++	unsigned short type, size, len;
++	/* If resumed session or no custom extensions nothing to do */
++	if (s->hit || s->cert->srv_ext.meths_count == 0)
++		return 1;
++
++	if (data >= limit - 2)
++		return 1;
++	n2s(data, len);
++
++	if (data > limit - len) 
++		return 1;
++
++	while (data <= limit - 4)
++		{
++		n2s(data, type);
++		n2s(data, size);
++
++		if (data+size > limit)
++	   		return 1;
++		if (custom_ext_parse(s, 1 /* server */, type, data, size, al) <= 0)
++			return 0;
++
++		data+=size;
++		}
+ 
+ 	return 1;
+ 	}
+@@ -2462,7 +2461,13 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
+ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n) 
+ 	{
+ 	int al = -1;
+-	custom_ext_init(&s->cert->srv_ext);
++	unsigned char *ptmp = *p;
++	/*
++	 * Internally supported extensions are parsed first so SNI can be handled
++	 * before custom extensions. An application processing SNI will typically
++	 * switch the parent context using SSL_set_SSL_CTX and custom extensions
++	 * need to be handled by the new SSL_CTX structure.
++	 */
+ 	if (ssl_scan_clienthello_tlsext(s, p, d, n, &al) <= 0) 
+ 		{
+ 		ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+@@ -2474,6 +2479,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
+ 		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,SSL_R_CLIENTHELLO_TLSEXT);
+ 		return 0;
+ 		}
++
++	custom_ext_init(&s->cert->srv_ext);
++	if (ssl_scan_clienthello_custom_tlsext(s, ptmp, d + n, &al) <= 0) 
++		{
++		ssl3_send_alert(s,SSL3_AL_FATAL,al); 
++		return 0;
++		}
++
+ 	return 1;
+ }
+ 
+@@ -2750,7 +2763,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
+ 				}
+ 			}
+ #endif
+-		else if (type == TLSEXT_TYPE_use_srtp)
++		else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp)
+                         {
+                         if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
+ 							      al))
+@@ -2961,6 +2974,7 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
+ 	{
+ 	int ret = SSL_TLSEXT_ERR_OK;
+ 	int al;
++	size_t i;
+ 
+ 	/* If status request then ask callback what to do.
+  	 * Note: this must be called after servername callbacks in case
+@@ -3006,6 +3020,43 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
+ 	else
+ 		s->tlsext_status_expected = 0;
+ 
++	/* Clear any shared sigtnature algorithms */
++	if (s->cert->shared_sigalgs)
++		{
++		OPENSSL_free(s->cert->shared_sigalgs);
++		s->cert->shared_sigalgs = NULL;
++		}
++	/* Clear certificate digests and validity flags */
++	for (i = 0; i < SSL_PKEY_NUM; i++)
++		{
++		s->cert->pkeys[i].digest = NULL;
++		s->cert->pkeys[i].valid_flags = 0;
++		}
++
++	/* If sigalgs received process it. */
++	if (s->cert->peer_sigalgs)
++		{
++		if (!tls1_process_sigalgs(s))
++			{
++			SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
++					ERR_R_MALLOC_FAILURE);
++			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
++			al = SSL_AD_INTERNAL_ERROR;
++			goto err;
++			}
++		/* Fatal error is no shared signature algorithms */
++		if (!s->cert->shared_sigalgs)
++			{
++			SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
++					SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
++			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
++			al = SSL_AD_ILLEGAL_PARAMETER;
++			goto err;
++			}
++		}
++	else
++		ssl_cert_set_default_md(s->cert);
++
+  err:
+ 	switch (ret)
+ 		{
+@@ -3343,7 +3394,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
+ 	HMAC_Final(&hctx, tick_hmac, NULL);
+ 	HMAC_CTX_cleanup(&hctx);
+ 	if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
++		{
++		EVP_CIPHER_CTX_cleanup(&ctx);
+ 		return 2;
++		}
+ 	/* Attempt to decrypt session data */
+ 	/* Move p after IV to start of encrypted ticket, update length */
+ 	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+@@ -3635,13 +3689,9 @@ static int tls1_set_shared_sigalgs(SSL *s)
+ 
+ /* Set preferred digest for each key type */
+ 
+-int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
++int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
+ 	{
+-	int idx;
+-	size_t i;
+-	const EVP_MD *md;
+ 	CERT *c = s->cert;
+-	TLS_SIGALGS *sigptr;
+ 	/* Extension ignored for inappropriate versions */
+ 	if (!SSL_USE_SIGALGS(s))
+ 		return 1;
+@@ -3656,8 +3706,18 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
+ 		return 0;
+ 	c->peer_sigalgslen = dsize;
+ 	memcpy(c->peer_sigalgs, data, dsize);
++	return 1;
++	}
+ 
+-	tls1_set_shared_sigalgs(s);
++int tls1_process_sigalgs(SSL *s)
++	{
++	int idx;
++	size_t i;
++	const EVP_MD *md;
++	CERT *c = s->cert;
++	TLS_SIGALGS *sigptr;
++	if (!tls1_set_shared_sigalgs(s))
++		return 0;
+ 
+ #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ 	if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
+diff --git a/ssl/tls1.h b/ssl/tls1.h
+index 09d1763..3c8de73 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -159,17 +159,19 @@ extern "C" {
+ 
+ #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0
+ 
++#define TLS1_VERSION			0x0301
++#define TLS1_1_VERSION			0x0302
+ #define TLS1_2_VERSION			0x0303
+-#define TLS1_2_VERSION_MAJOR		0x03
+-#define TLS1_2_VERSION_MINOR		0x03
++#define TLS_MAX_VERSION			TLS1_2_VERSION
++
++#define TLS1_VERSION_MAJOR		0x03
++#define TLS1_VERSION_MINOR		0x01
+ 
+-#define TLS1_1_VERSION			0x0302
+ #define TLS1_1_VERSION_MAJOR		0x03
+ #define TLS1_1_VERSION_MINOR		0x02
+ 
+-#define TLS1_VERSION			0x0301
+-#define TLS1_VERSION_MAJOR		0x03
+-#define TLS1_VERSION_MINOR		0x01
++#define TLS1_2_VERSION_MAJOR		0x03
++#define TLS1_2_VERSION_MINOR		0x03
+ 
+ #define TLS1_get_version(s) \
+ 		((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
+@@ -187,6 +189,7 @@ extern "C" {
+ #define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
+ #define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
+ #define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
++#define TLS1_AD_INAPPROPRIATE_FALLBACK	86	/* fatal */
+ #define TLS1_AD_USER_CANCELLED		90
+ #define TLS1_AD_NO_RENEGOTIATION	100
+ /* codes 110-114 are from RFC3546 */
+diff --git a/util/mk1mf.pl b/util/mk1mf.pl
+index 24302e1..28fd921 100755
+--- a/util/mk1mf.pl
++++ b/util/mk1mf.pl
+@@ -52,6 +52,7 @@ my %mf_import = (
+         ENGINES_ASM_OBJ=> \$mf_engines_asm,
+ 	BASEADDR       => \$baseaddr,
+ 	FIPSDIR        => \$fipsdir,
++	EC_ASM	       => \$mf_ec_asm,
+ );
+ 
+ open(IN,"<Makefile") || die "unable to open Makefile!\n";
+@@ -730,6 +731,7 @@ if ($orig_platform eq 'copy') {
+ 	$lib_obj{CRYPTO} .= fix_asm($mf_engines_asm, 'engines');
+ 	$lib_obj{CRYPTO} .= fix_asm($mf_rc4_asm, 'crypto/rc4');
+ 	$lib_obj{CRYPTO} .= fix_asm($mf_modes_asm, 'crypto/modes');
++	$lib_obj{CRYPTO} .= fix_asm($mf_ec_asm, 'crypto/ec');
+ }
+ 
+ foreach (values %lib_nam)
+@@ -737,12 +739,6 @@ foreach (values %lib_nam)
+ 	$lib_obj=$lib_obj{$_};
+ 	local($slib)=$shlib;
+ 
+-	if (($_ eq "SSL") && $no_ssl2 && $no_ssl3)
+-		{
+-		$rules.="\$(O_SSL):\n\n"; 
+-		next;
+-		}
+-
+ 	$defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
+ 	$lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
+ 	$rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
+@@ -1226,6 +1222,7 @@ sub read_options
+ 		"dll" => \$shlib,
+ 		"shared" => 0,
+ 		"no-sctp" => 0,
++		"no-srtp" => 0,
+ 		"no-gmp" => 0,
+ 		"no-rfc3779" => 0,
+ 		"no-montasm" => 0,
+diff --git a/util/mkdef.pl b/util/mkdef.pl
+index 05c5689..a39a56c 100755
+--- a/util/mkdef.pl
++++ b/util/mkdef.pl
+@@ -115,10 +115,12 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
+ 			 "DEPRECATED",
+ 			 # Hide SSL internals
+ 			 "SSL_INTERN",
++			 # SCTP
++		 	 "SCTP",
++			 # SRTP
++			 "SRTP",
+ 			 # SSL TRACE
+ 		 	 "SSL_TRACE",
+-			 # SCTP
+-			 "SCTP",
+ 			 # Unit testing
+ 			 "UNIT_TEST");
+ 
+@@ -140,7 +142,7 @@ my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
+ my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
+ my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
+ my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc; 
+-my $no_nextprotoneg; my $no_sctp; my $no_ssl_trace;
++my $no_nextprotoneg; my $no_sctp; my $no_srtp; my $no_ssl_trace;
+ my $no_unit_test;
+ 
+ my $fips;
+@@ -241,6 +243,7 @@ foreach (@ARGV, split(/ /, $options))
+ 	elsif (/^no-jpake$/)	{ $no_jpake=1; }
+ 	elsif (/^no-srp$/)	{ $no_srp=1; }
+ 	elsif (/^no-sctp$/)	{ $no_sctp=1; }
++	elsif (/^no-srtp$/)	{ $no_srtp=1; }
+ 	elsif (/^no-unit-test$/){ $no_unit_test=1; }
+ 	}
+ 
+@@ -1214,6 +1217,7 @@ sub is_valid
+ 			if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
+ 			if ($keyword eq "SRP" && $no_srp) { return 0; }
+ 			if ($keyword eq "SCTP" && $no_sctp) { return 0; }
++			if ($keyword eq "SRTP" && $no_srtp) { return 0; }
+ 			if ($keyword eq "UNIT_TEST" && $no_unit_test) { return 0; }
+ 			if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
+ 
+diff --git a/util/pl/unix.pl b/util/pl/unix.pl
+index 7b6162e..82f1aa7 100644
+--- a/util/pl/unix.pl
++++ b/util/pl/unix.pl
+@@ -77,6 +77,7 @@ $bf_enc_src="";
+ 	  'aesni-mb-x86_64' => 'crypto/aes',
+ 	  'sha1-mb-x86_64' => 'crypto/sha',
+ 	  'sha256-mb-x86_64' => 'crypto/sha',
++	  'ecp_nistz256-x86_64' => 'crypto/ec',
+          );
+ 
+ # If I were feeling more clever, these could probably be extracted
+diff --git a/util/ssleay.num b/util/ssleay.num
+index ac98f90..7eb4f17 100755
+--- a/util/ssleay.num
++++ b/util/ssleay.num
+@@ -310,14 +310,14 @@ TLSv1_2_method                          350	EXIST::FUNCTION:
+ SSL_SESSION_get_id_len                  351	NOEXIST::FUNCTION:
+ kssl_ctx_get0_client_princ              352	EXIST::FUNCTION:KRB5
+ SSL_export_keying_material              353	EXIST::FUNCTION:TLSEXT
+-SSL_set_tlsext_use_srtp                 354	EXIST::FUNCTION:
++SSL_set_tlsext_use_srtp                 354	EXIST::FUNCTION:SRTP
+ SSL_CTX_set_next_protos_advertised_cb   355	EXIST:!VMS:FUNCTION:NEXTPROTONEG
+ SSL_CTX_set_next_protos_adv_cb          355	EXIST:VMS:FUNCTION:NEXTPROTONEG
+ SSL_get0_next_proto_negotiated          356	EXIST::FUNCTION:NEXTPROTONEG
+-SSL_get_selected_srtp_profile           357	EXIST::FUNCTION:
+-SSL_CTX_set_tlsext_use_srtp             358	EXIST::FUNCTION:
++SSL_get_selected_srtp_profile           357	EXIST::FUNCTION:SRTP
++SSL_CTX_set_tlsext_use_srtp             358	EXIST::FUNCTION:SRTP
+ SSL_select_next_proto                   359	EXIST::FUNCTION:TLSEXT
+-SSL_get_srtp_profiles                   360	EXIST::FUNCTION:
++SSL_get_srtp_profiles                   360	EXIST::FUNCTION:SRTP
+ SSL_CTX_set_next_proto_select_cb        361	EXIST:!VMS:FUNCTION:NEXTPROTONEG
+ SSL_CTX_set_next_proto_sel_cb           361	EXIST:VMS:FUNCTION:NEXTPROTONEG
+ SSL_SESSION_get_compress_id             362	EXIST::FUNCTION:

Modified: openssl/trunk/debian/patches/series
===================================================================
--- openssl/trunk/debian/patches/series	2014-11-06 23:38:23 UTC (rev 701)
+++ openssl/trunk/debian/patches/series	2014-11-06 23:39:56 UTC (rev 702)
@@ -19,3 +19,5 @@
 block_diginotar.patch
 block_digicert_malaysia.patch
 #padlock_conf.patch
+git_snapshot.patch
+no_ssl3_method.patch




More information about the Pkg-openssl-changes mailing list