diff options
author | jsing <> | 2017-01-03 16:57:15 +0000 |
---|---|---|
committer | jsing <> | 2017-01-03 16:57:15 +0000 |
commit | 5bf1d8eae1dc8ce16782f7063874adf628e6d7c8 (patch) | |
tree | 578935c9d2b0a3d0cd5d0f160e725d3c62e7a3f7 /src | |
parent | c20fa45999bc9c9e18b6372552c975600aa2aae2 (diff) | |
download | openbsd-5bf1d8eae1dc8ce16782f7063874adf628e6d7c8.tar.gz openbsd-5bf1d8eae1dc8ce16782f7063874adf628e6d7c8.tar.bz2 openbsd-5bf1d8eae1dc8ce16782f7063874adf628e6d7c8.zip |
Pull out, rework and dedup the code that determines the highest shared
version.
ok beck@ doug@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/s23_clnt.c | 4 | ||||
-rw-r--r-- | src/lib/libssl/s23_srvr.c | 98 | ||||
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 36 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 |
4 files changed, 62 insertions, 79 deletions
diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c index 2511a94b28..c4fad5b011 100644 --- a/src/lib/libssl/s23_clnt.c +++ b/src/lib/libssl/s23_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s23_clnt.c,v 1.48 2016/12/30 16:57:01 jsing Exp $ */ | 1 | /* $OpenBSD: s23_clnt.c,v 1.49 2017/01/03 16:57:15 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 | * |
@@ -239,7 +239,7 @@ ssl23_client_hello(SSL *s) | |||
239 | if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { | 239 | if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { |
240 | arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); | 240 | arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); |
241 | 241 | ||
242 | if (ssl_enabled_version_range(s, NULL, &version) == -1) { | 242 | if (ssl_enabled_version_range(s, NULL, &version) != 1) { |
243 | SSLerr(SSL_F_SSL23_CLIENT_HELLO, | 243 | SSLerr(SSL_F_SSL23_CLIENT_HELLO, |
244 | SSL_R_NO_PROTOCOLS_AVAILABLE); | 244 | SSL_R_NO_PROTOCOLS_AVAILABLE); |
245 | return (-1); | 245 | return (-1); |
diff --git a/src/lib/libssl/s23_srvr.c b/src/lib/libssl/s23_srvr.c index edb1f637ea..35bc271f00 100644 --- a/src/lib/libssl/s23_srvr.c +++ b/src/lib/libssl/s23_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s23_srvr.c,v 1.48 2016/11/04 18:33:11 guenther Exp $ */ | 1 | /* $OpenBSD: s23_srvr.c,v 1.49 2017/01/03 16:57:15 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 | * |
@@ -220,17 +220,16 @@ ssl23_get_client_hello(SSL *s) | |||
220 | * 6-8 length > Client Hello message | 220 | * 6-8 length > Client Hello message |
221 | * 9/10 client_version / | 221 | * 9/10 client_version / |
222 | */ | 222 | */ |
223 | uint16_t client_version = 0; | ||
224 | uint16_t shared_version; | ||
223 | unsigned char *p, *d, *d_len, *dd; | 225 | unsigned char *p, *d, *d_len, *dd; |
224 | unsigned int i; | 226 | unsigned int i; |
225 | unsigned int csl, sil, cl; | 227 | unsigned int csl, sil, cl; |
226 | int n = 0, j; | 228 | int n = 0, j; |
227 | int type = 0; | 229 | int type = 0; |
228 | int v[2]; | ||
229 | 230 | ||
230 | if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { | 231 | if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { |
231 | /* read the initial header */ | 232 | /* read the initial header */ |
232 | v[0] = v[1] = 0; | ||
233 | |||
234 | if (!ssl3_setup_buffers(s)) | 233 | if (!ssl3_setup_buffers(s)) |
235 | return -1; | 234 | return -1; |
236 | 235 | ||
@@ -246,37 +245,14 @@ ssl23_get_client_hello(SSL *s) | |||
246 | /* | 245 | /* |
247 | * SSLv2 header | 246 | * SSLv2 header |
248 | */ | 247 | */ |
249 | if ((p[3] == 0x00) && (p[4] == 0x02)) { | 248 | client_version = p[3] << 8 | p[4]; |
250 | /* SSLv2 support has been removed */ | 249 | |
250 | if (!ssl_max_shared_version(s, client_version, | ||
251 | &shared_version)) | ||
251 | goto unsupported; | 252 | goto unsupported; |
252 | 253 | ||
253 | } else if (p[3] == SSL3_VERSION_MAJOR) { | 254 | s->version = shared_version; |
254 | v[0] = p[3]; | 255 | s->state = SSL23_ST_SR_CLNT_HELLO_B; |
255 | v[1] = p[4]; | ||
256 | /* SSLv3/TLS */ | ||
257 | |||
258 | if (p[4] >= TLS1_VERSION_MINOR) { | ||
259 | if (p[4] >= TLS1_2_VERSION_MINOR && | ||
260 | !(s->options & SSL_OP_NO_TLSv1_2)) { | ||
261 | s->version = TLS1_2_VERSION; | ||
262 | s->state = SSL23_ST_SR_CLNT_HELLO_B; | ||
263 | } else if (p[4] >= TLS1_1_VERSION_MINOR && | ||
264 | !(s->options & SSL_OP_NO_TLSv1_1)) { | ||
265 | s->version = TLS1_1_VERSION; | ||
266 | /* type=2; */ /* done later to survive restarts */ | ||
267 | s->state = SSL23_ST_SR_CLNT_HELLO_B; | ||
268 | } else if (!(s->options & SSL_OP_NO_TLSv1)) { | ||
269 | s->version = TLS1_VERSION; | ||
270 | /* type=2; */ /* done later to survive restarts */ | ||
271 | s->state = SSL23_ST_SR_CLNT_HELLO_B; | ||
272 | } else { | ||
273 | goto unsupported; | ||
274 | } | ||
275 | } else { | ||
276 | /* SSLv3 support has been removed */ | ||
277 | goto unsupported; | ||
278 | } | ||
279 | } | ||
280 | } else if ((p[0] == SSL3_RT_HANDSHAKE) && | 256 | } else if ((p[0] == SSL3_RT_HANDSHAKE) && |
281 | (p[1] == SSL3_VERSION_MAJOR) && | 257 | (p[1] == SSL3_VERSION_MAJOR) && |
282 | (p[5] == SSL3_MT_CLIENT_HELLO) && | 258 | (p[5] == SSL3_MT_CLIENT_HELLO) && |
@@ -286,7 +262,6 @@ ssl23_get_client_hello(SSL *s) | |||
286 | * SSLv3 or tls1 header | 262 | * SSLv3 or tls1 header |
287 | */ | 263 | */ |
288 | 264 | ||
289 | v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ | ||
290 | /* We must look at client_version inside the Client Hello message | 265 | /* We must look at client_version inside the Client Hello message |
291 | * to get the correct minor version. | 266 | * to get the correct minor version. |
292 | * However if we have only a pathologically small fragment of the | 267 | * However if we have only a pathologically small fragment of the |
@@ -300,43 +275,21 @@ ssl23_get_client_hello(SSL *s) | |||
300 | SSL_R_RECORD_TOO_SMALL); | 275 | SSL_R_RECORD_TOO_SMALL); |
301 | return -1; | 276 | return -1; |
302 | } | 277 | } |
303 | /* if major version number > 3 set minor to a value | 278 | client_version = p[9] << 8 | p[10]; |
304 | * which will use the highest version 3 we support. | 279 | |
305 | * If TLS 2.0 ever appears we will need to revise | 280 | if (!ssl_max_shared_version(s, client_version, |
306 | * this.... | 281 | &shared_version)) { |
307 | */ | 282 | if (s->options & SSL_OP_NO_TLSv1) |
308 | if (p[9] > SSL3_VERSION_MAJOR) | ||
309 | v[1] = 0xff; | ||
310 | else | ||
311 | v[1] = p[10]; /* minor version according to client_version */ | ||
312 | if (v[1] >= TLS1_VERSION_MINOR) { | ||
313 | if (v[1] >= TLS1_2_VERSION_MINOR && | ||
314 | !(s->options & SSL_OP_NO_TLSv1_2)) { | ||
315 | s->version = TLS1_2_VERSION; | ||
316 | type = 3; | ||
317 | } else if (v[1] >= TLS1_1_VERSION_MINOR && | ||
318 | !(s->options & SSL_OP_NO_TLSv1_1)) { | ||
319 | s->version = TLS1_1_VERSION; | ||
320 | type = 3; | ||
321 | } else if (!(s->options & SSL_OP_NO_TLSv1)) { | ||
322 | s->version = TLS1_VERSION; | ||
323 | type = 3; | ||
324 | } else { | ||
325 | goto unsupported; | ||
326 | } | ||
327 | } else { | ||
328 | /* SSLv3 */ | ||
329 | if (!(s->options & SSL_OP_NO_TLSv1)) { | ||
330 | /* we won't be able to use TLS of course, | ||
331 | * but this will send an appropriate alert */ | ||
332 | s->version = TLS1_VERSION; | ||
333 | type = 3; | ||
334 | } else { | ||
335 | goto unsupported; | 283 | goto unsupported; |
336 | } | 284 | /* |
285 | * We won't be able to use TLS of course, | ||
286 | * but this will send an appropriate alert. | ||
287 | */ | ||
288 | shared_version = TLS1_VERSION; | ||
337 | } | 289 | } |
338 | } | 290 | s->version = shared_version; |
339 | else if ((strncmp("GET ", (char *)p, 4) == 0) || | 291 | type = 3; |
292 | } else if ((strncmp("GET ", (char *)p, 4) == 0) || | ||
340 | (strncmp("POST ",(char *)p, 5) == 0) || | 293 | (strncmp("POST ",(char *)p, 5) == 0) || |
341 | (strncmp("HEAD ",(char *)p, 5) == 0) || | 294 | (strncmp("HEAD ",(char *)p, 5) == 0) || |
342 | (strncmp("PUT ", (char *)p, 4) == 0)) { | 295 | (strncmp("PUT ", (char *)p, 4) == 0)) { |
@@ -362,8 +315,7 @@ ssl23_get_client_hello(SSL *s) | |||
362 | 315 | ||
363 | type = 2; | 316 | type = 2; |
364 | p = s->packet; | 317 | p = s->packet; |
365 | v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ | 318 | client_version = p[3] << 8 | p[4]; |
366 | v[1] = p[4]; | ||
367 | 319 | ||
368 | /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 | 320 | /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 |
369 | * header is sent directly on the wire, not wrapped as a TLS | 321 | * header is sent directly on the wire, not wrapped as a TLS |
@@ -421,8 +373,8 @@ ssl23_get_client_hello(SSL *s) | |||
421 | d += 3; | 373 | d += 3; |
422 | 374 | ||
423 | /* client_version */ | 375 | /* client_version */ |
424 | *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ | 376 | *(d++) = client_version >> 8; |
425 | *(d++) = v[1]; | 377 | *(d++) = client_version & 0xff; |
426 | 378 | ||
427 | /* lets populate the random area */ | 379 | /* lets populate the random area */ |
428 | /* get the challenge_length */ | 380 | /* get the challenge_length */ |
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 11f46161a9..a4ca1afb1d 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.123 2016/12/30 16:57:01 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.124 2017/01/03 16:57:15 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 | * |
@@ -2516,14 +2516,44 @@ ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver) | |||
2516 | 2516 | ||
2517 | /* Everything has been disabled... */ | 2517 | /* Everything has been disabled... */ |
2518 | if (min_version == 0 || max_version == 0) | 2518 | if (min_version == 0 || max_version == 0) |
2519 | return -1; | 2519 | return 0; |
2520 | 2520 | ||
2521 | if (min_ver != NULL) | 2521 | if (min_ver != NULL) |
2522 | *min_ver = min_version; | 2522 | *min_ver = min_version; |
2523 | if (max_ver != NULL) | 2523 | if (max_ver != NULL) |
2524 | *max_ver = max_version; | 2524 | *max_ver = max_version; |
2525 | 2525 | ||
2526 | return 0; | 2526 | return 1; |
2527 | } | ||
2528 | |||
2529 | int | ||
2530 | ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) | ||
2531 | { | ||
2532 | uint16_t min_version, max_version, shared_version; | ||
2533 | |||
2534 | *max_ver = 0; | ||
2535 | |||
2536 | if (peer_ver >= TLS1_2_VERSION) | ||
2537 | shared_version = TLS1_2_VERSION; | ||
2538 | else if (peer_ver >= TLS1_1_VERSION) | ||
2539 | shared_version = TLS1_1_VERSION; | ||
2540 | else if (peer_ver >= TLS1_VERSION) | ||
2541 | shared_version = TLS1_VERSION; | ||
2542 | else | ||
2543 | return 0; | ||
2544 | |||
2545 | if (!ssl_enabled_version_range(s, &min_version, &max_version)) | ||
2546 | return 0; | ||
2547 | |||
2548 | if (shared_version < min_version) | ||
2549 | return 0; | ||
2550 | |||
2551 | if (shared_version > max_version) | ||
2552 | shared_version = max_version; | ||
2553 | |||
2554 | *max_ver = shared_version; | ||
2555 | |||
2556 | return 1; | ||
2527 | } | 2557 | } |
2528 | 2558 | ||
2529 | uint16_t | 2559 | uint16_t |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index e8fbd23572..800c56e31b 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.143 2016/12/30 16:57:01 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.144 2017/01/03 16:57:15 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 | * |
@@ -498,6 +498,7 @@ extern SSL_CIPHER ssl3_ciphers[]; | |||
498 | 498 | ||
499 | const char *ssl_version_string(int ver); | 499 | const char *ssl_version_string(int ver); |
500 | int ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver); | 500 | int ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver); |
501 | int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver); | ||
501 | uint16_t ssl_max_server_version(SSL *s); | 502 | uint16_t ssl_max_server_version(SSL *s); |
502 | 503 | ||
503 | extern SSL3_ENC_METHOD DTLSv1_enc_data; | 504 | extern SSL3_ENC_METHOD DTLSv1_enc_data; |