[openssl.org #3068] [PATCH] Safari broken ECDHE-ECDSA workaround

2014-04-29 Thread Tim Hudson via RT
On Tue Jun 04 17:53:41 2013, rob.stradl...@comodo.com wrote:
 The Safari browser on OSX versions 10.8 to 10.8.3 advertises support for
 several ECDHE-ECDSA ciphers but fails to negotiate them.

Closing as resolved.
Ben committed fixes across all branches.

https://github.com/openssl/openssl/commit/cadbbd51c8b4e66515cd3e97754cfeda606c7b15

Tim.

__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


[openssl.org #3068] [PATCH] Safari broken ECDHE-ECDSA workaround

2013-06-04 Thread Rob Stradling via RT
The Safari browser on OSX versions 10.8 to 10.8.3 advertises support for 
several ECDHE-ECDSA ciphers but fails to negotiate them.

When a Safari client connects to an OpenSSL-based server that has the 
attached patch (against the master branch) applied, the server will 
prefer other mutually supported ciphers above ECDHE-ECDSA ciphers.
This patch enables a webserver to have an ECC certificate together with 
an RSA and/or DSA certificate, and to offer ECDHE-ECDSA ciphers without 
fear of breaking compatibility with Safari clients.

The ssl_check_for_safari() function, which fingerprints Safari clients 
based on the TLS Extensions used, was written by Adam Langley.

A representative from Apple has told me that the Safari bug will be 
fixed in OSX 10.8.4.  However, since OSX users won't be forced to 
upgrade, I believe that a significant number of users will still be 
using affected Safari versions a few years from now.

-- 
Rob Stradling
Senior Research  Development Scientist
COMODO - Creating Trust Online


diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 7ad8a54..fff73eb 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3076,7 +3076,10 @@ void ssl3_clear(SSL *s)
 		OPENSSL_free(s-s3-tlsext_authz_client_types);
 		s-s3-tlsext_authz_client_types = NULL;
 		}
-#endif
+#ifndef OPENSSL_NO_EC
+	s-s3-is_probably_safari = 0;
+#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_TLSEXT */
 
 	rp = s-s3-rbuf.buf;
 	wp = s-s3-wbuf.buf;
@@ -4145,8 +4148,15 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 		ii=sk_SSL_CIPHER_find(allow,c);
 		if (ii = 0)
 			{
-			ret=sk_SSL_CIPHER_value(allow,ii);
-			break;
+			if ((alg_k  SSL_kEECDH)  (alg_a  SSL_aECDSA)  s-s3-is_probably_safari)
+{
+if (!ret) ret=sk_SSL_CIPHER_value(allow,ii);
+}
+			else
+{
+ret=sk_SSL_CIPHER_value(allow,ii);
+break;
+}
 			}
 		}
 	return(ret);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index e14a8d4..dd62578 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -568,6 +568,7 @@ struct ssl_session_st
 #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x0080L
 #define SSL_OP_TLS_D5_BUG0x0100L
 #define SSL_OP_TLS_BLOCK_PADDING_BUG			0x0200L
+#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG			0x0400L
 
 /* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
  * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
@@ -578,7 +579,7 @@ struct ssl_session_st
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
  * This used to be 0x000FL before 0.9.7. */
-#define SSL_OP_ALL	0x8BFFL
+#define SSL_OP_ALL	0x8FFFL
 
 /* DTLS options */
 #define SSL_OP_NO_QUERY_MTU 0x1000L
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index d8ed725..0b900b5 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -577,7 +577,14 @@ typedef struct ssl3_state_st
 	 * server echoed our server_authz extension and therefore must send us
 	 * a supplemental data handshake message. */
 	char tlsext_authz_server_promised;
-#endif
+
+#ifndef OPENSSL_NO_EC
+	/* This is set to true if we believe that this is a version of Safari
+	 * running on OS X 10.6 .. 10.8. We wish to know this because Safari
+	 * on 10.8 has broken ECDHE-ECDSA support. */
+	char is_probably_safari;
+#endif	/* OPENSSL_NO_EC */
+#endif	/* OPENSSL_NO_TLSEXT */
 	} SSL3_STATE;
 
 #endif
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 31daa50..c5e2b85 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1716,6 +1716,89 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 	return ret;
 	}
 
+#ifndef OPENSSL_NO_EC
+/* ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |d|, of length |n|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ *   SNI,
+ *   elliptic_curves
+ *   ec_point_formats
+ *
+ * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
+ * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
+ * Sadly we cannot differentiate 10.6 and 10.7 (which work), from 10.8 (which
+ * doesn't).
+ */
+static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsigned char *d, int n) {
+	unsigned short type, size;
+	static const unsigned char kSafariExtensionsBlock[] = {
+		0x00, 0x0a,  /* elliptic_curves extension */
+		0x00, 0x08,  /* 8 bytes */
+		0x00, 0x06,  /* 6 bytes of curve ids */
+		0x00, 0x17,  /* P-256 */
+		0x00, 0x18,  /* P-384 */
+		0x00, 0x19,  /* P-521 */
+
+		0x00, 0x0b,  /* ec_point_formats */
+		0x00, 0x02,  /* 2 bytes */
+		0x01,/* 1 point format */
+		0x00,/* uncompressed */
+	};
+
+	/* The following is only present in TLS 1.2 */
+	static const unsigned char kSafariTLS12ExtensionsBlock[] = {
+		0x00, 0x0d,  /* signature_algorithms */
+		0x00, 0x0c,  /* 12 bytes */
+		0x00, 0x0a,  /* 10 bytes */
+		0x05, 0x01,  /* SHA-384/RSA */
+		0x04, 0x01,  /* SHA-256/RSA */
+		0x02, 0x01,  /* SHA-1/RSA */
+		0x04, 0x03,