提交 dece3209 编写于 作者: R Rob Stradling

Don't prefer ECDHE-ECDSA ciphers when the client appears to be Safari on OS X.

OS X 10.8..10.8.3 has broken support for ECDHE-ECDSA ciphers.
上级 c3eb3376
......@@ -88,9 +88,10 @@ As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
...
=item SSL_OP_MSIE_SSLV2_RSA_PADDING
=item SSL_OP_SAFARI_ECDHE_ECDSA_BUG
As of OpenSSL 0.9.7h and 0.9.8a, this option has no effect.
Don't prefer ECDHE-ECDSA ciphers when the client appears to be Safari on OS X.
OS X 10.8..10.8.3 has broken support for ECDHE-ECDSA ciphers.
=item SSL_OP_SSLEAY_080_CLIENT_DH_BUG
......
......@@ -3089,7 +3089,10 @@ void ssl3_clear(SSL *s)
s->s3->tlsext_custom_types = NULL;
}
s->s3->tlsext_custom_types_count = 0;
#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;
......@@ -4170,8 +4173,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);
......
......@@ -615,7 +615,7 @@ struct ssl_session_st
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L
#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */
#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L
#define SSL_OP_TLS_D5_BUG 0x00000100L
#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L
......
......@@ -596,6 +596,14 @@ typedef struct ssl3_state_st
* processed. */
unsigned char *alpn_selected;
unsigned alpn_selected_len;
#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 or newer. We wish to know this because Safari
* on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */
char is_probably_safari;
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_NO_TLSEXT */
} SSL3_STATE;
......
......@@ -1899,6 +1899,89 @@ parse_error:
return -1;
}
#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, 10.7 and 10.8.4 (which work), from
* 10.8..10.8.3 (which don't work).
*/
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, /* SHA-256/ECDSA */
0x02, 0x03, /* SHA-1/ECDSA */
};
if (data >= (d+n-2))
return;
data += 2;
if (data > (d+n-4))
return;
n2s(data,type);
n2s(data,size);
if (type != TLSEXT_TYPE_server_name)
return;
if (data+size > d+n)
return;
data += size;
if (TLS1_get_version(s) >= TLS1_2_VERSION)
{
const size_t len1 = sizeof(kSafariExtensionsBlock);
const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
if (data + len1 + len2 != d+n)
return;
if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
return;
if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
return;
}
else
{
const size_t len = sizeof(kSafariExtensionsBlock);
if (data + len != d+n)
return;
if (memcmp(data, kSafariExtensionsBlock, len) != 0)
return;
}
s->s3->is_probably_safari = 1;
}
#endif /* OPENSSL_NO_EC */
static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
{
unsigned short type;
......@@ -1932,6 +2015,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
#endif
#ifndef OPENSSL_NO_EC
if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
ssl_check_for_safari(s, data, d, n);
#endif /* OPENSSL_NO_EC */
/* Clear any signature algorithms extension received */
if (s->cert->peer_sigalgs)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册