summaryrefslogtreecommitdiff
path: root/src/lib/libssl/s23_clnt.c
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/libssl/s23_clnt.c
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/libssl/s23_clnt.c')
-rw-r--r--src/lib/libssl/s23_clnt.c47
1 files changed, 9 insertions, 38 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