summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libssl/s23_clnt.c47
-rw-r--r--src/lib/libssl/ssl_lib.c44
-rw-r--r--src/lib/libssl/ssl_locl.h3
3 files changed, 54 insertions, 40 deletions
diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c
index 8674cdf627..2511a94b28 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.47 2016/12/04 14:32:30 jsing Exp $ */ 1/* $OpenBSD: s23_clnt.c,v 1.48 2016/12/30 16:57:01 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 *
@@ -231,43 +231,15 @@ ssl23_client_hello(SSL *s)
231 unsigned char *buf; 231 unsigned char *buf;
232 unsigned char *p, *d; 232 unsigned char *p, *d;
233 unsigned long l; 233 unsigned long l;
234 int version = 0, version_major, version_minor; 234 uint16_t version;
235 int ret;
236 unsigned long mask, options = s->options;
237 size_t outlen; 235 size_t outlen;
238 236 int ret;
239 /*
240 * SSL_OP_NO_X disables all protocols above X *if* there are
241 * some protocols below X enabled. This is required in order
242 * to maintain "version capability" vector contiguous. So
243 * that if application wants to disable TLS1.0 in favour of
244 * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the
245 * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
246 */
247 mask = SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1;
248 version = TLS1_2_VERSION;
249
250 if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask)
251 version = TLS1_1_VERSION;
252 mask &= ~SSL_OP_NO_TLSv1_1;
253 if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
254 version = TLS1_VERSION;
255 mask &= ~SSL_OP_NO_TLSv1;
256 237
257 buf = (unsigned char *)s->init_buf->data; 238 buf = (unsigned char *)s->init_buf->data;
258 if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { 239 if (s->state == SSL23_ST_CW_CLNT_HELLO_A) {
259 arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); 240 arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
260 241
261 if (version == TLS1_2_VERSION) { 242 if (ssl_enabled_version_range(s, NULL, &version) == -1) {
262 version_major = TLS1_2_VERSION_MAJOR;
263 version_minor = TLS1_2_VERSION_MINOR;
264 } else if (version == TLS1_1_VERSION) {
265 version_major = TLS1_1_VERSION_MAJOR;
266 version_minor = TLS1_1_VERSION_MINOR;
267 } else if (version == TLS1_VERSION) {
268 version_major = TLS1_VERSION_MAJOR;
269 version_minor = TLS1_VERSION_MINOR;
270 } else {
271 SSLerr(SSL_F_SSL23_CLIENT_HELLO, 243 SSLerr(SSL_F_SSL23_CLIENT_HELLO,
272 SSL_R_NO_PROTOCOLS_AVAILABLE); 244 SSL_R_NO_PROTOCOLS_AVAILABLE);
273 return (-1); 245 return (-1);
@@ -283,8 +255,8 @@ ssl23_client_hello(SSL *s)
283 */ 255 */
284 d = p = &(buf[SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH]); 256 d = p = &(buf[SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH]);
285 257
286 *(p++) = version_major; 258 *(p++) = version >> 8;
287 *(p++) = version_minor; 259 *(p++) = version & 0xff;
288 260
289 /* Random stuff */ 261 /* Random stuff */
290 memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); 262 memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
@@ -334,7 +306,7 @@ ssl23_client_hello(SSL *s)
334 /* fill in 5-byte record header */ 306 /* fill in 5-byte record header */
335 d = buf; 307 d = buf;
336 *(d++) = SSL3_RT_HANDSHAKE; 308 *(d++) = SSL3_RT_HANDSHAKE;
337 *(d++) = version_major; 309 *(d++) = version >> 8;
338 310
339 /* 311 /*
340 * Some servers hang if we use long client hellos 312 * Some servers hang if we use long client hellos
@@ -343,7 +315,7 @@ ssl23_client_hello(SSL *s)
343 if (TLS1_get_client_version(s) > TLS1_VERSION) 315 if (TLS1_get_client_version(s) > TLS1_VERSION)
344 *(d++) = 1; 316 *(d++) = 1;
345 else 317 else
346 *(d++) = version_minor; 318 *(d++) = version & 0xff;
347 s2n((int)l, d); 319 s2n((int)l, d);
348 320
349 /* number of bytes to write */ 321 /* number of bytes to write */
@@ -362,8 +334,7 @@ ssl23_client_hello(SSL *s)
362 334
363 if ((ret >= 2) && s->msg_callback) { 335 if ((ret >= 2) && s->msg_callback) {
364 /* Client Hello has been sent; tell msg_callback */ 336 /* Client Hello has been sent; tell msg_callback */
365 337 s->msg_callback(1, s->client_version, SSL3_RT_HANDSHAKE,
366 s->msg_callback(1, version, SSL3_RT_HANDSHAKE,
367 s->init_buf->data + 5, ret - 5, s, s->msg_callback_arg); 338 s->init_buf->data + 5, ret - 5, s, s->msg_callback_arg);
368 } 339 }
369 340
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index 5d93a3bc13..11f46161a9 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.122 2016/12/04 14:32:30 jsing Exp $ */ 1/* $OpenBSD: ssl_lib.c,v 1.123 2016/12/30 16:57:01 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 *
@@ -2484,6 +2484,48 @@ SSL_get_version(const SSL *s)
2484 return ssl_version_string(s->version); 2484 return ssl_version_string(s->version);
2485} 2485}
2486 2486
2487int
2488ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
2489{
2490 uint16_t min_version, max_version;
2491
2492 /*
2493 * The enabled versions have to be a contiguous range, which means we
2494 * cannot enable and disable single versions at our whim, even though
2495 * this is what the OpenSSL flags allow. The historical way this has
2496 * been handled is by making a flag mean that all higher versions
2497 * are disabled, if any version lower than the flag is enabled.
2498 */
2499
2500 min_version = 0;
2501 max_version = TLS1_2_VERSION;
2502
2503 if ((s->options & SSL_OP_NO_TLSv1) == 0)
2504 min_version = TLS1_VERSION;
2505 else if ((s->options & SSL_OP_NO_TLSv1_1) == 0)
2506 min_version = TLS1_1_VERSION;
2507 else if ((s->options & SSL_OP_NO_TLSv1_2) == 0)
2508 min_version = TLS1_2_VERSION;
2509
2510 if ((s->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
2511 max_version = TLS1_1_VERSION;
2512 if ((s->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
2513 max_version = TLS1_VERSION;
2514 if ((s->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
2515 max_version = 0;
2516
2517 /* Everything has been disabled... */
2518 if (min_version == 0 || max_version == 0)
2519 return -1;
2520
2521 if (min_ver != NULL)
2522 *min_ver = min_version;
2523 if (max_ver != NULL)
2524 *max_ver = max_version;
2525
2526 return 0;
2527}
2528
2487uint16_t 2529uint16_t
2488ssl_max_server_version(SSL *s) 2530ssl_max_server_version(SSL *s)
2489{ 2531{
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index de977846a4..e8fbd23572 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.142 2016/12/30 15:12:45 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.143 2016/12/30 16:57:01 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 *
@@ -497,6 +497,7 @@ extern SSL3_ENC_METHOD ssl3_undef_enc_method;
497extern SSL_CIPHER ssl3_ciphers[]; 497extern SSL_CIPHER ssl3_ciphers[];
498 498
499const char *ssl_version_string(int ver); 499const char *ssl_version_string(int ver);
500int ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
500uint16_t ssl_max_server_version(SSL *s); 501uint16_t ssl_max_server_version(SSL *s);
501 502
502extern SSL3_ENC_METHOD DTLSv1_enc_data; 503extern SSL3_ENC_METHOD DTLSv1_enc_data;