summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2016-12-30 16:57:01 +0000
committerjsing <>2016-12-30 16:57:01 +0000
commited12fcbf0ab8940c5f2d9d2ed9499e25301988f9 (patch)
treea2ed01d37e8c52df3aee7ab1f67260b369a6be4e /src/lib
parentd2c1aaa79508ee1ef726e81f750ddee7f8427547 (diff)
downloadopenbsd-ed12fcbf0ab8940c5f2d9d2ed9499e25301988f9.tar.gz
openbsd-ed12fcbf0ab8940c5f2d9d2ed9499e25301988f9.tar.bz2
openbsd-ed12fcbf0ab8940c5f2d9d2ed9499e25301988f9.zip
Pull out (and largely rewrite) the code that determines the enabled
protocol version range. This also fixes a bug whereby if all protocols were disabled, the client would still use TLSv1.2 in the client hello, only to have if fail with unsupported version when it received and processed the server hello. ok doug@
Diffstat (limited to 'src/lib')
-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;