summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2015-02-22 15:54:27 +0000
committerjsing <>2015-02-22 15:54:27 +0000
commit78601da9335579c01a88b356a8323117f14ec379 (patch)
tree38ba794e823ec25b4428f85632c6cdd2573912da /src/lib
parent9ca594bf596db20fe3bf5a6e78e6df39cf9e10cd (diff)
downloadopenbsd-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')
-rw-r--r--src/lib/libssl/src/ssl/s3_enc.c4
-rw-r--r--src/lib/libssl/src/ssl/ssl.h7
-rw-r--r--src/lib/libssl/src/ssl/ssl3.h7
-rw-r--r--src/lib/libssl/src/ssl/ssl_err.c4
-rw-r--r--src/lib/libssl/src/ssl/ssl_lib.c62
-rw-r--r--src/lib/libssl/src/ssl/ssl_locl.h3
-rw-r--r--src/lib/libssl/src/ssl/t1_enc.c4
-rw-r--r--src/lib/libssl/src/ssl/tls1.h3
-rw-r--r--src/lib/libssl/ssl.h7
-rw-r--r--src/lib/libssl/ssl3.h7
-rw-r--r--src/lib/libssl/ssl_err.c4
-rw-r--r--src/lib/libssl/ssl_lib.c62
-rw-r--r--src/lib/libssl/ssl_locl.h3
-rw-r--r--src/lib/libssl/t1_enc.c4
-rw-r--r--src/lib/libssl/tls1.h3
15 files changed, 159 insertions, 25 deletions
diff --git a/src/lib/libssl/src/ssl/s3_enc.c b/src/lib/libssl/src/ssl/s3_enc.c
index 0c7cda3c60..7e244b6c19 100644
--- a/src/lib/libssl/src/ssl/s3_enc.c
+++ b/src/lib/libssl/src/ssl/s3_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_enc.c,v 1.58 2014/12/15 00:46:53 doug Exp $ */ 1/* $OpenBSD: s3_enc.c,v 1.59 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 *
@@ -846,6 +846,8 @@ ssl3_alert_code(int code)
846 return (SSL3_AD_HANDSHAKE_FAILURE); 846 return (SSL3_AD_HANDSHAKE_FAILURE);
847 case SSL_AD_UNKNOWN_PSK_IDENTITY: 847 case SSL_AD_UNKNOWN_PSK_IDENTITY:
848 return (TLS1_AD_UNKNOWN_PSK_IDENTITY); 848 return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
849 case SSL_AD_INAPPROPRIATE_FALLBACK:
850 return (TLS1_AD_INAPPROPRIATE_FALLBACK);
849 default: 851 default:
850 return (-1); 852 return (-1);
851 } 853 }
diff --git a/src/lib/libssl/src/ssl/ssl.h b/src/lib/libssl/src/ssl/ssl.h
index 626b967f15..73d007400f 100644
--- a/src/lib/libssl/src/ssl/ssl.h
+++ b/src/lib/libssl/src/ssl/ssl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl.h,v 1.82 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl.h,v 1.83 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 *
@@ -1363,7 +1363,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
1363#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME 1363#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
1364#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 1364#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
1365#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 1365#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
1366#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ 1366#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
1367#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */
1367 1368
1368#define SSL_ERROR_NONE 0 1369#define SSL_ERROR_NONE 0
1369#define SSL_ERROR_SSL 1 1370#define SSL_ERROR_SSL 1
@@ -2174,6 +2175,7 @@ void ERR_load_SSL_strings(void);
2174#define SSL_R_HTTPS_PROXY_REQUEST 155 2175#define SSL_R_HTTPS_PROXY_REQUEST 155
2175#define SSL_R_HTTP_REQUEST 156 2176#define SSL_R_HTTP_REQUEST 156
2176#define SSL_R_ILLEGAL_PADDING 283 2177#define SSL_R_ILLEGAL_PADDING 283
2178#define SSL_R_INAPPROPRIATE_FALLBACK 373
2177#define SSL_R_INCONSISTENT_COMPRESSION 340 2179#define SSL_R_INCONSISTENT_COMPRESSION 340
2178#define SSL_R_INVALID_CHALLENGE_LENGTH 158 2180#define SSL_R_INVALID_CHALLENGE_LENGTH 158
2179#define SSL_R_INVALID_COMMAND 280 2181#define SSL_R_INVALID_COMMAND 280
@@ -2319,6 +2321,7 @@ void ERR_load_SSL_strings(void);
2319#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 2321#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
2320#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 2322#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051
2321#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 2323#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
2324#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
2322#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 2325#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
2323#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 2326#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
2324#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 2327#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
diff --git a/src/lib/libssl/src/ssl/ssl3.h b/src/lib/libssl/src/ssl/ssl3.h
index 644e8df16b..61f600c55d 100644
--- a/src/lib/libssl/src/ssl/ssl3.h
+++ b/src/lib/libssl/src/ssl/ssl3.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl3.h,v 1.35 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl3.h,v 1.36 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 *
@@ -125,9 +125,12 @@
125extern "C" { 125extern "C" {
126#endif 126#endif
127 127
128/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ 128/* TLS_EMPTY_RENEGOTIATION_INFO_SCSV from RFC 5746. */
129#define SSL3_CK_SCSV 0x030000FF 129#define SSL3_CK_SCSV 0x030000FF
130 130
131/* TLS_FALLBACK_SCSV from draft-ietf-tls-downgrade-scsv-03. */
132#define SSL3_CK_FALLBACK_SCSV 0x03005600
133
131#define SSL3_CK_RSA_NULL_MD5 0x03000001 134#define SSL3_CK_RSA_NULL_MD5 0x03000001
132#define SSL3_CK_RSA_NULL_SHA 0x03000002 135#define SSL3_CK_RSA_NULL_SHA 0x03000002
133#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 136#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
diff --git a/src/lib/libssl/src/ssl/ssl_err.c b/src/lib/libssl/src/ssl/ssl_err.c
index 891d5216c2..04742b60ca 100644
--- a/src/lib/libssl/src/ssl/ssl_err.c
+++ b/src/lib/libssl/src/ssl/ssl_err.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_err.c,v 1.28 2014/12/14 15:30:50 jsing Exp $ */ 1/* $OpenBSD: ssl_err.c,v 1.29 2015/02/22 15:54:27 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -385,6 +385,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
385 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"}, 385 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"},
386 {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"}, 386 {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"},
387 {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"}, 387 {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"},
388 {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
388 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, 389 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
389 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, 390 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
390 {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"}, 391 {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"},
@@ -530,6 +531,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
530 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"}, 531 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"},
531 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"}, 532 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"},
532 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"}, 533 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"},
534 {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"},
533 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"}, 535 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"},
534 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"}, 536 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"},
535 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"}, 537 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"},
diff --git a/src/lib/libssl/src/ssl/ssl_lib.c b/src/lib/libssl/src/ssl/ssl_lib.c
index 58835931d2..d7b5283501 100644
--- a/src/lib/libssl/src/ssl/ssl_lib.c
+++ b/src/lib/libssl/src/ssl/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
2570uint16_t
2571ssl_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
2546SSL * 2600SSL *
2547SSL_dup(SSL *s) 2601SSL_dup(SSL *s)
2548{ 2602{
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h
index 3b7694fc94..c38aa3a90d 100644
--- a/src/lib/libssl/src/ssl/ssl_locl.h
+++ b/src/lib/libssl/src/ssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.87 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.88 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 *
@@ -545,6 +545,7 @@ extern SSL_CIPHER ssl3_ciphers[];
545 545
546SSL_METHOD *ssl_bad_method(int ver); 546SSL_METHOD *ssl_bad_method(int ver);
547const char *ssl_version_string(int ver); 547const char *ssl_version_string(int ver);
548uint16_t ssl_max_server_version(SSL *s);
548 549
549extern SSL3_ENC_METHOD TLSv1_enc_data; 550extern SSL3_ENC_METHOD TLSv1_enc_data;
550extern SSL3_ENC_METHOD TLSv1_1_enc_data; 551extern SSL3_ENC_METHOD TLSv1_1_enc_data;
diff --git a/src/lib/libssl/src/ssl/t1_enc.c b/src/lib/libssl/src/ssl/t1_enc.c
index f7c4bc8dde..6e069edd4b 100644
--- a/src/lib/libssl/src/ssl/t1_enc.c
+++ b/src/lib/libssl/src/ssl/t1_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_enc.c,v 1.76 2015/02/07 18:53:55 doug Exp $ */ 1/* $OpenBSD: t1_enc.c,v 1.77 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 *
@@ -1240,6 +1240,8 @@ tls1_alert_code(int code)
1240 return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); 1240 return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
1241 case SSL_AD_UNKNOWN_PSK_IDENTITY: 1241 case SSL_AD_UNKNOWN_PSK_IDENTITY:
1242 return (TLS1_AD_UNKNOWN_PSK_IDENTITY); 1242 return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
1243 case SSL_AD_INAPPROPRIATE_FALLBACK:
1244 return(TLS1_AD_INAPPROPRIATE_FALLBACK);
1243 default: 1245 default:
1244 return (-1); 1246 return (-1);
1245 } 1247 }
diff --git a/src/lib/libssl/src/ssl/tls1.h b/src/lib/libssl/src/ssl/tls1.h
index 6182daa837..3dffb97b5c 100644
--- a/src/lib/libssl/src/ssl/tls1.h
+++ b/src/lib/libssl/src/ssl/tls1.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls1.h,v 1.24 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: tls1.h,v 1.25 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 *
@@ -187,6 +187,7 @@ extern "C" {
187#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ 187#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */
188#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ 188#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */
189#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ 189#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */
190#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
190#define TLS1_AD_USER_CANCELLED 90 191#define TLS1_AD_USER_CANCELLED 90
191#define TLS1_AD_NO_RENEGOTIATION 100 192#define TLS1_AD_NO_RENEGOTIATION 100
192/* Codes 110-114 are from RFC 3546. */ 193/* Codes 110-114 are from RFC 3546. */
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 626b967f15..73d007400f 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl.h,v 1.82 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl.h,v 1.83 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 *
@@ -1363,7 +1363,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
1363#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME 1363#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
1364#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 1364#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
1365#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 1365#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
1366#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ 1366#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
1367#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */
1367 1368
1368#define SSL_ERROR_NONE 0 1369#define SSL_ERROR_NONE 0
1369#define SSL_ERROR_SSL 1 1370#define SSL_ERROR_SSL 1
@@ -2174,6 +2175,7 @@ void ERR_load_SSL_strings(void);
2174#define SSL_R_HTTPS_PROXY_REQUEST 155 2175#define SSL_R_HTTPS_PROXY_REQUEST 155
2175#define SSL_R_HTTP_REQUEST 156 2176#define SSL_R_HTTP_REQUEST 156
2176#define SSL_R_ILLEGAL_PADDING 283 2177#define SSL_R_ILLEGAL_PADDING 283
2178#define SSL_R_INAPPROPRIATE_FALLBACK 373
2177#define SSL_R_INCONSISTENT_COMPRESSION 340 2179#define SSL_R_INCONSISTENT_COMPRESSION 340
2178#define SSL_R_INVALID_CHALLENGE_LENGTH 158 2180#define SSL_R_INVALID_CHALLENGE_LENGTH 158
2179#define SSL_R_INVALID_COMMAND 280 2181#define SSL_R_INVALID_COMMAND 280
@@ -2319,6 +2321,7 @@ void ERR_load_SSL_strings(void);
2319#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 2321#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
2320#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 2322#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051
2321#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 2323#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
2324#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
2322#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 2325#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
2323#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 2326#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
2324#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 2327#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h
index 644e8df16b..61f600c55d 100644
--- a/src/lib/libssl/ssl3.h
+++ b/src/lib/libssl/ssl3.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl3.h,v 1.35 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl3.h,v 1.36 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 *
@@ -125,9 +125,12 @@
125extern "C" { 125extern "C" {
126#endif 126#endif
127 127
128/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ 128/* TLS_EMPTY_RENEGOTIATION_INFO_SCSV from RFC 5746. */
129#define SSL3_CK_SCSV 0x030000FF 129#define SSL3_CK_SCSV 0x030000FF
130 130
131/* TLS_FALLBACK_SCSV from draft-ietf-tls-downgrade-scsv-03. */
132#define SSL3_CK_FALLBACK_SCSV 0x03005600
133
131#define SSL3_CK_RSA_NULL_MD5 0x03000001 134#define SSL3_CK_RSA_NULL_MD5 0x03000001
132#define SSL3_CK_RSA_NULL_SHA 0x03000002 135#define SSL3_CK_RSA_NULL_SHA 0x03000002
133#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 136#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c
index 891d5216c2..04742b60ca 100644
--- a/src/lib/libssl/ssl_err.c
+++ b/src/lib/libssl/ssl_err.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_err.c,v 1.28 2014/12/14 15:30:50 jsing Exp $ */ 1/* $OpenBSD: ssl_err.c,v 1.29 2015/02/22 15:54:27 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -385,6 +385,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
385 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"}, 385 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"},
386 {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"}, 386 {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"},
387 {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"}, 387 {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"},
388 {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
388 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, 389 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
389 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, 390 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
390 {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"}, 391 {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"},
@@ -530,6 +531,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
530 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"}, 531 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"},
531 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"}, 532 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"},
532 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"}, 533 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"},
534 {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"},
533 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"}, 535 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"},
534 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"}, 536 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"},
535 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"}, 537 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"},
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
2570uint16_t
2571ssl_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
2546SSL * 2600SSL *
2547SSL_dup(SSL *s) 2601SSL_dup(SSL *s)
2548{ 2602{
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 3b7694fc94..c38aa3a90d 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.87 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.88 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 *
@@ -545,6 +545,7 @@ extern SSL_CIPHER ssl3_ciphers[];
545 545
546SSL_METHOD *ssl_bad_method(int ver); 546SSL_METHOD *ssl_bad_method(int ver);
547const char *ssl_version_string(int ver); 547const char *ssl_version_string(int ver);
548uint16_t ssl_max_server_version(SSL *s);
548 549
549extern SSL3_ENC_METHOD TLSv1_enc_data; 550extern SSL3_ENC_METHOD TLSv1_enc_data;
550extern SSL3_ENC_METHOD TLSv1_1_enc_data; 551extern SSL3_ENC_METHOD TLSv1_1_enc_data;
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index f7c4bc8dde..6e069edd4b 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_enc.c,v 1.76 2015/02/07 18:53:55 doug Exp $ */ 1/* $OpenBSD: t1_enc.c,v 1.77 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 *
@@ -1240,6 +1240,8 @@ tls1_alert_code(int code)
1240 return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); 1240 return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
1241 case SSL_AD_UNKNOWN_PSK_IDENTITY: 1241 case SSL_AD_UNKNOWN_PSK_IDENTITY:
1242 return (TLS1_AD_UNKNOWN_PSK_IDENTITY); 1242 return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
1243 case SSL_AD_INAPPROPRIATE_FALLBACK:
1244 return(TLS1_AD_INAPPROPRIATE_FALLBACK);
1243 default: 1245 default:
1244 return (-1); 1246 return (-1);
1245 } 1247 }
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index 6182daa837..3dffb97b5c 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls1.h,v 1.24 2015/02/12 03:45:25 jsing Exp $ */ 1/* $OpenBSD: tls1.h,v 1.25 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 *
@@ -187,6 +187,7 @@ extern "C" {
187#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ 187#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */
188#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ 188#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */
189#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ 189#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */
190#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
190#define TLS1_AD_USER_CANCELLED 90 191#define TLS1_AD_USER_CANCELLED 90
191#define TLS1_AD_NO_RENEGOTIATION 100 192#define TLS1_AD_NO_RENEGOTIATION 100
192/* Codes 110-114 are from RFC 3546. */ 193/* Codes 110-114 are from RFC 3546. */