Skip to content

Commit cf6da05

Browse files
committed
Support TLS_FALLBACK_SCSV.
Reviewed-by: Stephen Henson <steve@openssl.org>
1 parent ffa08b3 commit cf6da05

File tree

16 files changed

+153
-29
lines changed

16 files changed

+153
-29
lines changed

CHANGES

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@
305305

306306
Changes between 1.0.1h and 1.0.2 [xx XXX xxxx]
307307

308+
*) Add support for TLS_FALLBACK_SCSV.
309+
Client applications doing fallback retries should call
310+
SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
311+
(CVE-2014-3566)
312+
[Adam Langley, Bodo Moeller]
313+
308314
*) Accelerated NIST P-256 elliptic curve implementation for x86_64
309315
(other platforms pending).
310316
[Shay Gueron (Intel Corp), Andy Polyakov]

apps/s_client.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ static void sc_usage(void)
341341
BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n");
342342
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
343343
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
344+
BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
344345
BIO_printf(bio_err," -mtu - set the link layer MTU\n");
345346
BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
346347
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
@@ -650,6 +651,7 @@ int MAIN(int argc, char **argv)
650651
char *sess_out = NULL;
651652
struct sockaddr peer;
652653
int peerlen = sizeof(peer);
654+
int fallback_scsv = 0;
653655
int enable_timeouts = 0 ;
654656
long socket_mtu = 0;
655657
#ifndef OPENSSL_NO_JPAKE
@@ -940,6 +942,10 @@ static char *jpake_secret = NULL;
940942
meth=DTLSv1_2_client_method();
941943
socket_type=SOCK_DGRAM;
942944
}
945+
else if (strcmp(*argv,"-fallback_scsv") == 0)
946+
{
947+
fallback_scsv = 1;
948+
}
943949
else if (strcmp(*argv,"-timeout") == 0)
944950
enable_timeouts=1;
945951
else if (strcmp(*argv,"-mtu") == 0)
@@ -1439,6 +1445,10 @@ static char *jpake_secret = NULL;
14391445
SSL_set_session(con, sess);
14401446
SSL_SESSION_free(sess);
14411447
}
1448+
1449+
if (fallback_scsv)
1450+
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
1451+
14421452
#ifndef OPENSSL_NO_TLSEXT
14431453
if (servername != NULL)
14441454
{

crypto/err/openssl.ec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
7474
R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070
7575
R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
7676
R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
77+
R SSL_R_SSLV3_ALERT_INAPPROPRIATE_FALLBACK 1086
7778
R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
7879
R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
7980
R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110

ssl/d1_lib.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,25 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
294294
case DTLS_CTRL_LISTEN:
295295
ret = dtls1_listen(s, parg);
296296
break;
297+
case SSL_CTRL_CHECK_PROTO_VERSION:
298+
/* For library-internal use; checks that the current protocol
299+
* is the highest enabled version (according to s->ctx->method,
300+
* as version negotiation may have changed s->method). */
301+
if (s->version == s->ctx->method->version)
302+
return 1;
303+
/* Apparently we're using a version-flexible SSL_METHOD
304+
* (not at its highest protocol version). */
305+
if (s->ctx->method->version == DTLS_method()->version)
306+
{
307+
#if DTLS_MAX_VERSION != DTLS1_2_VERSION
308+
# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
309+
#endif
310+
if (!(s->options & SSL_OP_NO_DTLSv1_2))
311+
return s->version == DTLS1_2_VERSION;
312+
if (!(s->options & SSL_OP_NO_DTLSv1))
313+
return s->version == DTLS1_VERSION;
314+
}
315+
return 0; /* Unexpected state; fail closed. */
297316

298317
default:
299318
ret = ssl3_ctrl(s, cmd, larg, parg);

ssl/dtls1.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ extern "C" {
8484
#endif
8585

8686
#define DTLS1_VERSION 0xFEFF
87-
#define DTLS1_BAD_VER 0x0100
8887
#define DTLS1_2_VERSION 0xFEFD
88+
#define DTLS_MAX_VERSION DTLS1_2_VERSION
89+
90+
#define DTLS1_BAD_VER 0x0100
91+
8992
/* Special value for method supporting multiple versions */
9093
#define DTLS_ANY_VERSION 0x1FFFF
9194

@@ -287,4 +290,3 @@ typedef struct dtls1_record_data_st
287290
}
288291
#endif
289292
#endif
290-

ssl/s23_clnt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,9 @@ static int ssl23_get_server_hello(SSL *s)
752752
goto err;
753753
}
754754

755+
/* ensure that TLS_MAX_VERSION is up-to-date */
756+
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
757+
755758
if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL))
756759
{
757760
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_VERSION_TOO_LOW);

ssl/s23_srvr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ int ssl23_get_client_hello(SSL *s)
421421
}
422422
}
423423

424+
/* ensure that TLS_MAX_VERSION is up-to-date */
425+
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
426+
424427
if (s->version < TLS1_2_VERSION && tls1_suiteb(s))
425428
{
426429
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,

ssl/s2_lib.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
391391
case SSL_CTRL_GET_SESSION_REUSED:
392392
ret=s->hit;
393393
break;
394+
case SSL_CTRL_CHECK_PROTO_VERSION:
395+
return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
394396
default:
395397
break;
396398
}
@@ -434,7 +436,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
434436
if (p != NULL)
435437
{
436438
l=c->id;
437-
if ((l & 0xff000000) != 0x02000000) return(0);
439+
if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
438440
p[0]=((unsigned char)(l>>16L))&0xFF;
439441
p[1]=((unsigned char)(l>> 8L))&0xFF;
440442
p[2]=((unsigned char)(l ))&0xFF;

ssl/s3_enc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ int ssl3_alert_code(int code)
937937
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
938938
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
939939
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
940+
case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
940941
default: return(-1);
941942
}
942943
}
943-

ssl/s3_lib.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3924,6 +3924,33 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
39243924
return (int)sess->tlsext_ecpointformatlist_length;
39253925
}
39263926
#endif
3927+
3928+
case SSL_CTRL_CHECK_PROTO_VERSION:
3929+
/* For library-internal use; checks that the current protocol
3930+
* is the highest enabled version (according to s->ctx->method,
3931+
* as version negotiation may have changed s->method). */
3932+
if (s->version == s->ctx->method->version)
3933+
return 1;
3934+
/* Apparently we're using a version-flexible SSL_METHOD
3935+
* (not at its highest protocol version). */
3936+
if (s->ctx->method->version == SSLv23_method()->version)
3937+
{
3938+
#if TLS_MAX_VERSION != TLS1_2_VERSION
3939+
# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
3940+
#endif
3941+
if (!(s->options & SSL_OP_NO_TLSv1_2))
3942+
return s->version == TLS1_2_VERSION;
3943+
if (!(s->options & SSL_OP_NO_TLSv1_1))
3944+
return s->version == TLS1_1_VERSION;
3945+
if (!(s->options & SSL_OP_NO_TLSv1))
3946+
return s->version == TLS1_VERSION;
3947+
if (!(s->options & SSL_OP_NO_SSLv3))
3948+
return s->version == SSL3_VERSION;
3949+
if (!(s->options & SSL_OP_NO_SSLv2))
3950+
return s->version == SSL2_VERSION;
3951+
}
3952+
return 0; /* Unexpected state; fail closed. */
3953+
39273954
default:
39283955
break;
39293956
}
@@ -4844,4 +4871,3 @@ long ssl_get_algorithm2(SSL *s)
48444871
return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
48454872
return alg2;
48464873
}
4847-

0 commit comments

Comments
 (0)