diff options
author | jsing <> | 2015-02-22 15:54:27 +0000 |
---|---|---|
committer | jsing <> | 2015-02-22 15:54:27 +0000 |
commit | 78601da9335579c01a88b356a8323117f14ec379 (patch) | |
tree | 38ba794e823ec25b4428f85632c6cdd2573912da /src/lib/libssl/ssl_lib.c | |
parent | 9ca594bf596db20fe3bf5a6e78e6df39cf9e10cd (diff) | |
download | openbsd-78601da9335579c01a88b356a8323117f14ec379.tar.gz openbsd-78601da9335579c01a88b356a8323117f14ec379.tar.bz2 openbsd-78601da9335579c01a88b356a8323117f14ec379.zip |
Reluctantly add server-side support for TLS_FALLBACK_SCSV.
This allows for clients that willingly choose to perform a downgrade and
attempt to establish a second connection at a lower protocol after the
previous attempt unexpectedly failed, to be notified and have the second
connection aborted, if the server does in fact support a higher protocol.
TLS has perfectly good version negotiation and client-side fallback is
dangerous. Despite this, in order to maintain maximum compatability with
broken web servers, most mainstream browsers implement this. Furthermore,
TLS_FALLBACK_SCSV only works if both the client and server support it and
there is effectively no way to tell if this is the case, unless you control
both ends.
Unfortunately, various auditors and vulnerability scanners (including
certain online assessment websites) consider the presence of a not yet
standardised feature to be important for security, even if the clients do
not perform client-side downgrade or the server only supports current TLS
protocols.
Diff is loosely based on OpenSSL with some inspiration from BoringSSL.
Discussed with beck@ and miod@.
ok bcook@
Diffstat (limited to 'src/lib/libssl/ssl_lib.c')
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 58835931d2..d7b5283501 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.100 2015/02/22 15:29:39 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.101 2015/02/22 15:54:27 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1419,7 +1419,9 @@ ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, int num, | |||
1419 | const SSL_CIPHER *c; | 1419 | const SSL_CIPHER *c; |
1420 | STACK_OF(SSL_CIPHER) *sk; | 1420 | STACK_OF(SSL_CIPHER) *sk; |
1421 | int i; | 1421 | int i; |
1422 | unsigned long cipher_id; | ||
1422 | uint16_t cipher_value; | 1423 | uint16_t cipher_value; |
1424 | uint16_t max_version; | ||
1423 | 1425 | ||
1424 | if (s->s3) | 1426 | if (s->s3) |
1425 | s->s3->send_connection_binding = 0; | 1427 | s->s3->send_connection_binding = 0; |
@@ -1440,10 +1442,13 @@ ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, int num, | |||
1440 | 1442 | ||
1441 | for (i = 0; i < num; i += SSL3_CIPHER_VALUE_SIZE) { | 1443 | for (i = 0; i < num; i += SSL3_CIPHER_VALUE_SIZE) { |
1442 | n2s(p, cipher_value); | 1444 | n2s(p, cipher_value); |
1445 | cipher_id = SSL3_CK_ID | cipher_value; | ||
1443 | 1446 | ||
1444 | /* Check for SCSV */ | 1447 | if (s->s3 != NULL && cipher_id == SSL3_CK_SCSV) { |
1445 | if (s->s3 && (SSL3_CK_ID | cipher_value) == SSL3_CK_SCSV) { | 1448 | /* |
1446 | /* SCSV is fatal if renegotiating. */ | 1449 | * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if |
1450 | * renegotiating. | ||
1451 | */ | ||
1447 | if (s->renegotiate) { | 1452 | if (s->renegotiate) { |
1448 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, | 1453 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, |
1449 | SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); | 1454 | SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); |
@@ -1456,6 +1461,25 @@ ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, int num, | |||
1456 | continue; | 1461 | continue; |
1457 | } | 1462 | } |
1458 | 1463 | ||
1464 | if (cipher_id == SSL3_CK_FALLBACK_SCSV) { | ||
1465 | /* | ||
1466 | * TLS_FALLBACK_SCSV indicates that the client | ||
1467 | * previously tried a higher protocol version. | ||
1468 | * Fail if the current version is an unexpected | ||
1469 | * downgrade. | ||
1470 | */ | ||
1471 | max_version = ssl_max_server_version(s); | ||
1472 | if (max_version == 0 || s->version < max_version) { | ||
1473 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, | ||
1474 | SSL_R_INAPPROPRIATE_FALLBACK); | ||
1475 | if (s->s3 != NULL) | ||
1476 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
1477 | SSL_AD_INAPPROPRIATE_FALLBACK); | ||
1478 | goto err; | ||
1479 | } | ||
1480 | continue; | ||
1481 | } | ||
1482 | |||
1459 | if ((c = ssl3_get_cipher_by_value(cipher_value)) != NULL) { | 1483 | if ((c = ssl3_get_cipher_by_value(cipher_value)) != NULL) { |
1460 | if (!sk_SSL_CIPHER_push(sk, c)) { | 1484 | if (!sk_SSL_CIPHER_push(sk, c)) { |
1461 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, | 1485 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, |
@@ -2543,6 +2567,36 @@ SSL_get_version(const SSL *s) | |||
2543 | return ssl_version_string(s->version); | 2567 | return ssl_version_string(s->version); |
2544 | } | 2568 | } |
2545 | 2569 | ||
2570 | uint16_t | ||
2571 | ssl_max_server_version(SSL *s) | ||
2572 | { | ||
2573 | uint16_t max_version; | ||
2574 | |||
2575 | /* | ||
2576 | * The SSL method will be changed during version negotiation, as such | ||
2577 | * we want to use the SSL method from the context. | ||
2578 | */ | ||
2579 | max_version = s->ctx->method->version; | ||
2580 | |||
2581 | if (SSL_IS_DTLS(s)) | ||
2582 | return (DTLS1_VERSION); | ||
2583 | |||
2584 | if ((s->options & SSL_OP_NO_TLSv1_2) == 0 && | ||
2585 | max_version >= TLS1_2_VERSION) | ||
2586 | return (TLS1_2_VERSION); | ||
2587 | if ((s->options & SSL_OP_NO_TLSv1_1) == 0 && | ||
2588 | max_version >= TLS1_1_VERSION) | ||
2589 | return (TLS1_1_VERSION); | ||
2590 | if ((s->options & SSL_OP_NO_TLSv1) == 0 && | ||
2591 | max_version >= TLS1_VERSION) | ||
2592 | return (TLS1_VERSION); | ||
2593 | if ((s->options & SSL_OP_NO_SSLv3) == 0 && | ||
2594 | max_version >= SSL3_VERSION) | ||
2595 | return (SSL3_VERSION); | ||
2596 | |||
2597 | return (0); | ||
2598 | } | ||
2599 | |||
2546 | SSL * | 2600 | SSL * |
2547 | SSL_dup(SSL *s) | 2601 | SSL_dup(SSL *s) |
2548 | { | 2602 | { |