]>
Commit | Line | Data |
---|---|---|
4f10a291 AM |
1 | From 6bfe55380abbf7528e04e59f18921bd6c896af1c Mon Sep 17 00:00:00 2001 |
2 | From: Bodo Moeller <bodo@openssl.org> | |
3 | Date: Wed, 15 Oct 2014 04:05:42 +0200 | |
4 | Subject: [PATCH] Support TLS_FALLBACK_SCSV. | |
5 | ||
6 | Reviewed-by: Rich Salz <rsalz@openssl.org> | |
7 | --- | |
8 | CHANGES | 6 +++++ | |
9 | apps/s_client.c | 10 +++++++++ | |
10 | crypto/err/openssl.ec | 1 + | |
11 | ssl/d1_lib.c | 10 +++++++++ | |
12 | ssl/dtls1.h | 3 ++- | |
13 | ssl/s23_clnt.c | 3 +++ | |
14 | ssl/s23_srvr.c | 3 +++ | |
15 | ssl/s2_lib.c | 4 +++- | |
16 | ssl/s3_enc.c | 2 +- | |
17 | ssl/s3_lib.c | 29 +++++++++++++++++++++++- | |
18 | ssl/ssl.h | 9 ++++++++ | |
19 | ssl/ssl3.h | 7 +++++- | |
20 | ssl/ssl_err.c | 2 ++ | |
21 | ssl/ssl_lib.c | 60 +++++++++++++++++++++++++++++++++++++------------ | |
22 | ssl/t1_enc.c | 1 + | |
23 | ssl/tls1.h | 15 ++++++++----- | |
24 | 16 files changed, 140 insertions(+), 25 deletions(-) | |
25 | ||
26 | ; *) Add support for TLS_FALLBACK_SCSV. | |
27 | ; Client applications doing fallback retries should call | |
28 | ; SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). | |
29 | ; (CVE-2014-3566) | |
30 | ; [Adam Langley, Bodo Moeller] | |
31 | ; | |
32 | diff --git a/apps/s_client.c b/apps/s_client.c | |
33 | index 4625467..c2e160c 100644 | |
34 | --- a/apps/s_client.c | |
35 | +++ b/apps/s_client.c | |
36 | @@ -337,6 +337,7 @@ static void sc_usage(void) | |
37 | BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n"); | |
38 | BIO_printf(bio_err," -tls1 - just use TLSv1\n"); | |
39 | BIO_printf(bio_err," -dtls1 - just use DTLSv1\n"); | |
40 | + BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n"); | |
41 | BIO_printf(bio_err," -mtu - set the link layer MTU\n"); | |
42 | BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); | |
43 | BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n"); | |
44 | @@ -617,6 +618,7 @@ int MAIN(int argc, char **argv) | |
45 | char *sess_out = NULL; | |
46 | struct sockaddr peer; | |
47 | int peerlen = sizeof(peer); | |
48 | + int fallback_scsv = 0; | |
49 | int enable_timeouts = 0 ; | |
50 | long socket_mtu = 0; | |
51 | #ifndef OPENSSL_NO_JPAKE | |
52 | @@ -823,6 +825,10 @@ int MAIN(int argc, char **argv) | |
53 | meth=DTLSv1_client_method(); | |
54 | socket_type=SOCK_DGRAM; | |
55 | } | |
56 | + else if (strcmp(*argv,"-fallback_scsv") == 0) | |
57 | + { | |
58 | + fallback_scsv = 1; | |
59 | + } | |
60 | else if (strcmp(*argv,"-timeout") == 0) | |
61 | enable_timeouts=1; | |
62 | else if (strcmp(*argv,"-mtu") == 0) | |
63 | @@ -1235,6 +1241,10 @@ bad: | |
64 | SSL_set_session(con, sess); | |
65 | SSL_SESSION_free(sess); | |
66 | } | |
67 | + | |
68 | + if (fallback_scsv) | |
69 | + SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV); | |
70 | + | |
71 | #ifndef OPENSSL_NO_TLSEXT | |
72 | if (servername != NULL) | |
73 | { | |
74 | diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec | |
75 | index e0554b4..34754e5 100644 | |
76 | --- a/crypto/err/openssl.ec | |
77 | +++ b/crypto/err/openssl.ec | |
78 | @@ -71,6 +71,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 | |
79 | R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 | |
80 | R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 | |
81 | R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 | |
82 | +R SSL_R_SSLV3_ALERT_INAPPROPRIATE_FALLBACK 1086 | |
83 | R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 | |
84 | R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 | |
85 | R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 | |
86 | diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c | |
87 | index 6bde16f..82ca653 100644 | |
88 | --- a/ssl/d1_lib.c | |
89 | +++ b/ssl/d1_lib.c | |
90 | @@ -266,6 +266,16 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) | |
91 | case DTLS_CTRL_LISTEN: | |
92 | ret = dtls1_listen(s, parg); | |
93 | break; | |
94 | + case SSL_CTRL_CHECK_PROTO_VERSION: | |
95 | + /* For library-internal use; checks that the current protocol | |
96 | + * is the highest enabled version (according to s->ctx->method, | |
97 | + * as version negotiation may have changed s->method). */ | |
98 | +#if DTLS_MAX_VERSION != DTLS1_VERSION | |
99 | +# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. | |
100 | +#endif | |
101 | + /* Just one protocol version is supported so far; | |
102 | + * fail closed if the version is not as expected. */ | |
103 | + return s->version == DTLS_MAX_VERSION; | |
104 | ||
105 | default: | |
106 | ret = ssl3_ctrl(s, cmd, larg, parg); | |
107 | diff --git a/ssl/dtls1.h b/ssl/dtls1.h | |
108 | index e65d501..192c5de 100644 | |
109 | --- a/ssl/dtls1.h | |
110 | +++ b/ssl/dtls1.h | |
111 | @@ -84,6 +84,8 @@ extern "C" { | |
112 | #endif | |
113 | ||
114 | #define DTLS1_VERSION 0xFEFF | |
115 | +#define DTLS_MAX_VERSION DTLS1_VERSION | |
116 | + | |
117 | #define DTLS1_BAD_VER 0x0100 | |
118 | ||
119 | #if 0 | |
120 | @@ -284,4 +286,3 @@ typedef struct dtls1_record_data_st | |
121 | } | |
122 | #endif | |
123 | #endif | |
124 | - | |
125 | diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c | |
126 | index 2b93c63..d4e43c3 100644 | |
127 | --- a/ssl/s23_clnt.c | |
128 | +++ b/ssl/s23_clnt.c | |
129 | @@ -736,6 +736,9 @@ static int ssl23_get_server_hello(SSL *s) | |
130 | goto err; | |
131 | } | |
132 | ||
133 | + /* ensure that TLS_MAX_VERSION is up-to-date */ | |
134 | + OPENSSL_assert(s->version <= TLS_MAX_VERSION); | |
135 | + | |
136 | if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) | |
137 | { | |
138 | /* fatal alert */ | |
139 | diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c | |
140 | index 2901a6b..567a6b1 100644 | |
141 | --- a/ssl/s23_srvr.c | |
142 | +++ b/ssl/s23_srvr.c | |
143 | @@ -421,6 +421,9 @@ int ssl23_get_client_hello(SSL *s) | |
144 | } | |
145 | } | |
146 | ||
147 | + /* ensure that TLS_MAX_VERSION is up-to-date */ | |
148 | + OPENSSL_assert(s->version <= TLS_MAX_VERSION); | |
149 | + | |
150 | #ifdef OPENSSL_FIPS | |
151 | if (FIPS_mode() && (s->version < TLS1_VERSION)) | |
152 | { | |
153 | diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c | |
154 | index c0bdae5..c63be30 100644 | |
155 | --- a/ssl/s2_lib.c | |
156 | +++ b/ssl/s2_lib.c | |
157 | @@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg) | |
158 | case SSL_CTRL_GET_SESSION_REUSED: | |
159 | ret=s->hit; | |
160 | break; | |
161 | + case SSL_CTRL_CHECK_PROTO_VERSION: | |
162 | + return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); | |
163 | default: | |
164 | break; | |
165 | } | |
166 | @@ -437,7 +439,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) | |
167 | if (p != NULL) | |
168 | { | |
169 | l=c->id; | |
170 | - if ((l & 0xff000000) != 0x02000000) return(0); | |
171 | + if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0); | |
172 | p[0]=((unsigned char)(l>>16L))&0xFF; | |
173 | p[1]=((unsigned char)(l>> 8L))&0xFF; | |
174 | p[2]=((unsigned char)(l ))&0xFF; | |
175 | diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c | |
176 | index 9962677..9db45af 100644 | |
177 | --- a/ssl/s3_enc.c | |
178 | +++ b/ssl/s3_enc.c | |
179 | @@ -900,7 +900,7 @@ int ssl3_alert_code(int code) | |
180 | case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE); | |
181 | case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE); | |
182 | case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); | |
183 | + case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK); | |
184 | default: return(-1); | |
185 | } | |
186 | } | |
187 | - | |
188 | diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c | |
189 | index e17f126..3f17453 100644 | |
190 | --- a/ssl/s3_lib.c | |
191 | +++ b/ssl/s3_lib.c | |
192 | @@ -3355,6 +3355,33 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) | |
193 | #endif | |
194 | ||
195 | #endif /* !OPENSSL_NO_TLSEXT */ | |
196 | + | |
197 | + case SSL_CTRL_CHECK_PROTO_VERSION: | |
198 | + /* For library-internal use; checks that the current protocol | |
199 | + * is the highest enabled version (according to s->ctx->method, | |
200 | + * as version negotiation may have changed s->method). */ | |
201 | + if (s->version == s->ctx->method->version) | |
202 | + return 1; | |
203 | + /* Apparently we're using a version-flexible SSL_METHOD | |
204 | + * (not at its highest protocol version). */ | |
205 | + if (s->ctx->method->version == SSLv23_method()->version) | |
206 | + { | |
207 | +#if TLS_MAX_VERSION != TLS1_2_VERSION | |
208 | +# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. | |
209 | +#endif | |
210 | + if (!(s->options & SSL_OP_NO_TLSv1_2)) | |
211 | + return s->version == TLS1_2_VERSION; | |
212 | + if (!(s->options & SSL_OP_NO_TLSv1_1)) | |
213 | + return s->version == TLS1_1_VERSION; | |
214 | + if (!(s->options & SSL_OP_NO_TLSv1)) | |
215 | + return s->version == TLS1_VERSION; | |
216 | + if (!(s->options & SSL_OP_NO_SSLv3)) | |
217 | + return s->version == SSL3_VERSION; | |
218 | + if (!(s->options & SSL_OP_NO_SSLv2)) | |
219 | + return s->version == SSL2_VERSION; | |
220 | + } | |
221 | + return 0; /* Unexpected state; fail closed. */ | |
222 | + | |
223 | default: | |
224 | break; | |
225 | } | |
226 | @@ -3714,6 +3741,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) | |
227 | break; | |
228 | #endif | |
229 | #endif | |
230 | + | |
231 | default: | |
232 | return(0); | |
233 | } | |
234 | @@ -4296,4 +4324,3 @@ long ssl_get_algorithm2(SSL *s) | |
235 | return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; | |
236 | return alg2; | |
237 | } | |
238 | - | |
239 | diff --git a/ssl/ssl.h b/ssl/ssl.h | |
240 | index b73da5e..b78a1cc 100644 | |
241 | --- a/ssl/ssl.h | |
242 | +++ b/ssl/ssl.h | |
243 | @@ -653,6 +653,10 @@ struct ssl_session_st | |
244 | */ | |
245 | #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L | |
246 | #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L | |
247 | +/* Send TLS_FALLBACK_SCSV in the ClientHello. | |
248 | + * To be set by applications that reconnect with a downgraded protocol | |
249 | + * version; see draft-ietf-tls-downgrade-scsv-00 for details. */ | |
250 | +#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L | |
251 | ||
252 | /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, | |
253 | * they cannot be used to clear bits. */ | |
254 | @@ -1511,6 +1515,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) | |
255 | #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE | |
256 | #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE | |
257 | #define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ | |
258 | +#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */ | |
259 | ||
260 | #define SSL_ERROR_NONE 0 | |
261 | #define SSL_ERROR_SSL 1 | |
262 | @@ -1621,6 +1626,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) | |
263 | #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 | |
264 | #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 | |
265 | ||
266 | +#define SSL_CTRL_CHECK_PROTO_VERSION 119 | |
267 | + | |
268 | #define DTLSv1_get_timeout(ssl, arg) \ | |
269 | SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) | |
270 | #define DTLSv1_handle_timeout(ssl) \ | |
271 | @@ -2379,6 +2386,7 @@ void ERR_load_SSL_strings(void); | |
272 | #define SSL_R_HTTPS_PROXY_REQUEST 155 | |
273 | #define SSL_R_HTTP_REQUEST 156 | |
274 | #define SSL_R_ILLEGAL_PADDING 283 | |
275 | +#define SSL_R_INAPPROPRIATE_FALLBACK 373 | |
276 | #define SSL_R_INCONSISTENT_COMPRESSION 340 | |
277 | #define SSL_R_INVALID_CHALLENGE_LENGTH 158 | |
278 | #define SSL_R_INVALID_COMMAND 280 | |
279 | @@ -2525,6 +2533,7 @@ void ERR_load_SSL_strings(void); | |
280 | #define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 | |
281 | #define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 | |
282 | #define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 | |
283 | +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 | |
284 | #define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 | |
285 | #define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 | |
286 | #define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 | |
287 | diff --git a/ssl/ssl3.h b/ssl/ssl3.h | |
288 | index 37f19e3..85f1504 100644 | |
289 | --- a/ssl/ssl3.h | |
290 | +++ b/ssl/ssl3.h | |
291 | @@ -128,9 +128,14 @@ | |
292 | extern "C" { | |
293 | #endif | |
294 | ||
295 | -/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ | |
296 | +/* Signalling cipher suite value from RFC 5746 | |
297 | + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */ | |
298 | #define SSL3_CK_SCSV 0x030000FF | |
299 | ||
300 | +/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 | |
301 | + * (TLS_FALLBACK_SCSV) */ | |
302 | +#define SSL3_CK_FALLBACK_SCSV 0x03005600 | |
303 | + | |
304 | #define SSL3_CK_RSA_NULL_MD5 0x03000001 | |
305 | #define SSL3_CK_RSA_NULL_SHA 0x03000002 | |
306 | #define SSL3_CK_RSA_RC4_40_MD5 0x03000003 | |
307 | diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c | |
308 | index d2f0dec..1b7eb47 100644 | |
309 | --- a/ssl/ssl_err.c | |
310 | +++ b/ssl/ssl_err.c | |
311 | @@ -383,6 +383,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= | |
312 | {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"}, | |
313 | {ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"}, | |
314 | {ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"}, | |
315 | +{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"}, | |
316 | {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"}, | |
317 | {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, | |
318 | {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, | |
319 | @@ -529,6 +530,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= | |
320 | {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"}, | |
321 | {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"}, | |
322 | {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"}, | |
323 | +{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"}, | |
324 | {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"}, | |
325 | {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"}, | |
326 | {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"}, | |
327 | diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c | |
328 | index cc094e4..3f66fc0 100644 | |
329 | --- a/ssl/ssl_lib.c | |
330 | +++ b/ssl/ssl_lib.c | |
331 | @@ -1387,6 +1387,8 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, | |
332 | ||
333 | if (sk == NULL) return(0); | |
334 | q=p; | |
335 | + if (put_cb == NULL) | |
336 | + put_cb = s->method->put_cipher_by_char; | |
337 | ||
338 | for (i=0; i<sk_SSL_CIPHER_num(sk); i++) | |
339 | { | |
340 | @@ -1411,24 +1413,36 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, | |
341 | !(s->srp_ctx.srp_Mask & SSL_kSRP)) | |
342 | continue; | |
343 | #endif /* OPENSSL_NO_SRP */ | |
344 | - j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); | |
345 | + j = put_cb(c,p); | |
346 | p+=j; | |
347 | } | |
348 | - /* If p == q, no ciphers and caller indicates an error. Otherwise | |
349 | - * add SCSV if not renegotiating. | |
350 | - */ | |
351 | - if (p != q && !s->renegotiate) | |
352 | + /* If p == q, no ciphers; caller indicates an error. | |
353 | + * Otherwise, add applicable SCSVs. */ | |
354 | + if (p != q) | |
355 | { | |
356 | - static SSL_CIPHER scsv = | |
357 | + if (!s->renegotiate) | |
358 | { | |
359 | - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
360 | - }; | |
361 | - j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p); | |
362 | - p+=j; | |
363 | + static SSL_CIPHER scsv = | |
364 | + { | |
365 | + 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
366 | + }; | |
367 | + j = put_cb(&scsv,p); | |
368 | + p+=j; | |
369 | #ifdef OPENSSL_RI_DEBUG | |
370 | - fprintf(stderr, "SCSV sent by client\n"); | |
371 | + fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); | |
372 | #endif | |
373 | - } | |
374 | + } | |
375 | + | |
376 | + if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) | |
377 | + { | |
378 | + static SSL_CIPHER scsv = | |
379 | + { | |
380 | + 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
381 | + }; | |
382 | + j = put_cb(&scsv,p); | |
383 | + p+=j; | |
384 | + } | |
385 | + } | |
386 | ||
387 | return(p-q); | |
388 | } | |
389 | @@ -1439,11 +1453,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, | |
390 | const SSL_CIPHER *c; | |
391 | STACK_OF(SSL_CIPHER) *sk; | |
392 | int i,n; | |
393 | + | |
394 | if (s->s3) | |
395 | s->s3->send_connection_binding = 0; | |
396 | ||
397 | n=ssl_put_cipher_by_char(s,NULL,NULL); | |
398 | - if ((num%n) != 0) | |
399 | + if (n == 0 || (num%n) != 0) | |
400 | { | |
401 | SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); | |
402 | return(NULL); | |
403 | @@ -1458,7 +1473,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, | |
404 | ||
405 | for (i=0; i<num; i+=n) | |
406 | { | |
407 | - /* Check for SCSV */ | |
408 | + /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ | |
409 | if (s->s3 && (n != 3 || !p[0]) && | |
410 | (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && | |
411 | (p[n-1] == (SSL3_CK_SCSV & 0xff))) | |
412 | @@ -1478,6 +1493,23 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, | |
413 | continue; | |
414 | } | |
415 | ||
416 | + /* Check for TLS_FALLBACK_SCSV */ | |
417 | + if ((n != 3 || !p[0]) && | |
418 | + (p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && | |
419 | + (p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) | |
420 | + { | |
421 | + /* The SCSV indicates that the client previously tried a higher version. | |
422 | + * Fail if the current version is an unexpected downgrade. */ | |
423 | + if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) | |
424 | + { | |
425 | + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK); | |
426 | + if (s->s3) | |
427 | + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK); | |
428 | + goto err; | |
429 | + } | |
430 | + continue; | |
431 | + } | |
432 | + | |
433 | c=ssl_get_cipher_by_char(s,p); | |
434 | p+=n; | |
435 | if (c != NULL) | |
436 | diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c | |
437 | index 1427484..1923cf3 100644 | |
438 | --- a/ssl/t1_enc.c | |
439 | +++ b/ssl/t1_enc.c | |
440 | @@ -1241,6 +1241,7 @@ int tls1_alert_code(int code) | |
441 | case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); | |
442 | case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); | |
443 | case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); | |
444 | + case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK); | |
445 | #if 0 /* not appropriate for TLS, not used for DTLS */ | |
446 | case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return | |
447 | (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); | |
448 | diff --git a/ssl/tls1.h b/ssl/tls1.h | |
449 | index c992091..6ae8876 100644 | |
450 | --- a/ssl/tls1.h | |
451 | +++ b/ssl/tls1.h | |
452 | @@ -159,17 +159,19 @@ extern "C" { | |
453 | ||
454 | #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 | |
455 | ||
456 | +#define TLS1_VERSION 0x0301 | |
457 | +#define TLS1_1_VERSION 0x0302 | |
458 | #define TLS1_2_VERSION 0x0303 | |
459 | -#define TLS1_2_VERSION_MAJOR 0x03 | |
460 | -#define TLS1_2_VERSION_MINOR 0x03 | |
461 | +#define TLS_MAX_VERSION TLS1_2_VERSION | |
462 | + | |
463 | +#define TLS1_VERSION_MAJOR 0x03 | |
464 | +#define TLS1_VERSION_MINOR 0x01 | |
465 | ||
466 | -#define TLS1_1_VERSION 0x0302 | |
467 | #define TLS1_1_VERSION_MAJOR 0x03 | |
468 | #define TLS1_1_VERSION_MINOR 0x02 | |
469 | ||
470 | -#define TLS1_VERSION 0x0301 | |
471 | -#define TLS1_VERSION_MAJOR 0x03 | |
472 | -#define TLS1_VERSION_MINOR 0x01 | |
473 | +#define TLS1_2_VERSION_MAJOR 0x03 | |
474 | +#define TLS1_2_VERSION_MINOR 0x03 | |
475 | ||
476 | #define TLS1_get_version(s) \ | |
477 | ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) | |
478 | @@ -187,6 +189,7 @@ extern "C" { | |
479 | #define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ | |
480 | #define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ | |
481 | #define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ | |
482 | +#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */ | |
483 | #define TLS1_AD_USER_CANCELLED 90 | |
484 | #define TLS1_AD_NO_RENEGOTIATION 100 | |
485 | /* codes 110-114 are from RFC3546 */ | |
486 | -- | |
487 | 1.7.9.5 | |
488 |