Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fail the connection in SSLv3 if server selects ECDHE #3734

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion ssl/ssl_lib.c
Expand Up @@ -1944,7 +1944,7 @@ STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
ssl_set_client_disabled(s);
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) {
if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) {
if (!sk)
sk = sk_SSL_CIPHER_new_null();
if (!sk)
Expand Down
2 changes: 1 addition & 1 deletion ssl/ssl_locl.h
Expand Up @@ -2070,7 +2070,7 @@ __owur size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs);
__owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
const unsigned char *sig, EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int echde);

__owur int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
int maxlen);
Expand Down
4 changes: 2 additions & 2 deletions ssl/statem/statem_clnt.c
Expand Up @@ -1038,7 +1038,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
* If it is a disabled cipher we either didn't send it in client hello,
* or it's not allowed for the selected protocol. So we return an error.
*/
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK)) {
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK, 1)) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
goto f_err;
Expand Down Expand Up @@ -2919,7 +2919,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, unsigned char *p)
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
c = sk_SSL_CIPHER_value(sk, i);
/* Skip disabled ciphers */
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0))
continue;
j = s->method->put_cipher_by_char(c, p);
p += j;
Expand Down
20 changes: 16 additions & 4 deletions ssl/t1_lib.c
Expand Up @@ -863,19 +863,31 @@ void ssl_set_client_disabled(SSL *s)
* @s: SSL connection that you want to use the cipher on
* @c: cipher to check
* @op: Security check that you want to do
* @ecdhe: If set to 1 then TLSv1 ECDHE ciphers are also allowed in SSLv3
*
* Returns 1 when it's disabled, 0 when enabled.
*/
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int ecdhe)
{
if (c->algorithm_mkey & s->s3->tmp.mask_k
|| c->algorithm_auth & s->s3->tmp.mask_a)
return 1;
if (s->s3->tmp.max_ver == 0)
return 1;
if (!SSL_IS_DTLS(s) && ((c->min_tls > s->s3->tmp.max_ver)
|| (c->max_tls < s->s3->tmp.min_ver)))
return 1;
if (!SSL_IS_DTLS(s)) {
int min_tls = c->min_tls;

/*
* For historical reasons we will allow ECHDE to be selected by a server
* in SSLv3 if we are a client
*/
if (min_tls == TLS1_VERSION && ecdhe
&& (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0)
min_tls = SSL3_VERSION;

if ((min_tls > s->s3->tmp.max_ver) || (c->max_tls < s->s3->tmp.min_ver))
return 1;
}
if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver)
|| DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver)))
return 1;
Expand Down