From 6979bbfe4fd79a2951b19171936b69968db66c1e Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Wed, 2 Sep 2015 17:59:15 +0000
Subject: Replace dtls1_client_hello() with ssl3_client_hello() - both are
 basically the same code, with two slight differences for DTLS handling.

Also, make use of send_cookie to determine if the client random needs to
be preserved, rather than testing if it is zeroed (hopefully your random
number generator never returned all zeros, since the existing code would
break). Inspired by BoringSSL.

ok doug@
---
 src/lib/libssl/d1_clnt.c          | 105 +++-----------------------------------
 src/lib/libssl/s3_clnt.c          |  27 ++++++++--
 src/lib/libssl/src/ssl/d1_clnt.c  | 105 +++-----------------------------------
 src/lib/libssl/src/ssl/s3_clnt.c  |  27 ++++++++--
 src/lib/libssl/src/ssl/ssl_locl.h |   3 +-
 src/lib/libssl/ssl_locl.h         |   3 +-
 6 files changed, 58 insertions(+), 212 deletions(-)

(limited to 'src/lib')

diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c
index b087535ce1..23d6b372c9 100644
--- a/src/lib/libssl/d1_clnt.c
+++ b/src/lib/libssl/d1_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_clnt.c,v 1.47 2015/07/15 18:35:34 beck Exp $ */
+/* $OpenBSD: d1_clnt.c,v 1.48 2015/09/02 17:59:15 jsing Exp $ */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -263,7 +263,7 @@ dtls1_connect(SSL *s)
 			}
 
 			dtls1_start_timer(s);
-			ret = dtls1_client_hello(s);
+			ret = ssl3_client_hello(s);
 			if (ret <= 0)
 				goto end;
 
@@ -275,9 +275,10 @@ dtls1_connect(SSL *s)
 
 			s->init_num = 0;
 
-				/* turn on buffering for the next lot of output */
-				if (s->bbio != s->wbio)
-					s->wbio = BIO_push(s->bbio, s->wbio);
+			/* turn on buffering for the next lot of output */
+			if (s->bbio != s->wbio)
+				s->wbio = BIO_push(s->bbio, s->wbio);
+
 			break;
 
 		case SSL3_ST_CR_SRVR_HELLO_A:
@@ -603,100 +604,6 @@ end:
 	return (ret);
 }
 
-int
-dtls1_client_hello(SSL *s)
-{
-	unsigned char *bufend, *d, *p;
-	unsigned int i;
-
-	if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
-		SSL_SESSION *sess = s->session;
-
-		if ((s->session == NULL) ||
-		    (s->session->ssl_version != s->version) ||
-		    (!sess->session_id_length && !sess->tlsext_tick) ||
-		    (s->session->not_resumable)) {
-			if (!ssl_get_new_session(s, 0))
-				goto err;
-		}
-		/* else use the pre-loaded session */
-
-		p = s->s3->client_random;
-
-		/* if client_random is initialized, reuse it, we are
-		 * required to use same upon reply to HelloVerify */
-		for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++)
-			;
-		if (i == sizeof(s->s3->client_random))
-			arc4random_buf(p, sizeof(s->s3->client_random));
-
-		d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO);
-
-		*(p++) = s->version >> 8;
-		*(p++) = s->version&0xff;
-		s->client_version = s->version;
-
-		/* Random stuff */
-		memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
-		p += SSL3_RANDOM_SIZE;
-
-		/* Session ID */
-		if (s->new_session)
-			i = 0;
-		else
-			i = s->session->session_id_length;
-		*(p++) = i;
-		if (i != 0) {
-			if (i > sizeof s->session->session_id) {
-				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
-				    ERR_R_INTERNAL_ERROR);
-				goto err;
-			}
-			memcpy(p, s->session->session_id, i);
-			p += i;
-		}
-
-		/* cookie stuff */
-		if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
-			goto err;
-		}
-		*(p++) = s->d1->cookie_len;
-		memcpy(p, s->d1->cookie, s->d1->cookie_len);
-		p += s->d1->cookie_len;
-
-		/* Ciphers supported */
-		i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
-		if (i == 0) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
-			    SSL_R_NO_CIPHERS_AVAILABLE);
-			goto err;
-		}
-		s2n(i, p);
-		p += i;
-
-		/* add in (no) COMPRESSION */
-		*(p++) = 1;
-		*(p++) = 0; /* Add the NULL method */
-
-		bufend = (unsigned char *)s->init_buf->data +
-		    SSL3_RT_MAX_PLAIN_LENGTH;
-		if ((p = ssl_add_clienthello_tlsext(s, p, bufend)) == NULL) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
-			goto err;
-		}
-
-		ssl3_handshake_msg_finish(s, p - d);
-
-		s->state = SSL3_ST_CW_CLNT_HELLO_B;
-	}
-
-	/* SSL3_ST_CW_CLNT_HELLO_B */
-	return (ssl3_handshake_write(s));
-err:
-	return (-1);
-}
-
 static int
 dtls1_get_hello_verify(SSL *s)
 {
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index 5b9af06aa5..1d1a0c77f0 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_clnt.c,v 1.124 2015/09/01 13:38:27 jsing Exp $ */
+/* $OpenBSD: s3_clnt.c,v 1.125 2015/09/02 17:59:15 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -584,7 +584,6 @@ end:
 	return (ret);
 }
 
-
 int
 ssl3_client_hello(SSL *s)
 {
@@ -603,7 +602,13 @@ ssl3_client_hello(SSL *s)
 		}
 		/* else use the pre-loaded session */
 
-		arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
+		/*
+		 * If a DTLS ClientHello message is being resent after a
+		 * HelloVerifyRequest, we must retain the original client
+		 * random value.
+		 */
+		if (!SSL_IS_DTLS(s) || s->d1->send_cookie == 0)
+			arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
 
 		d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO);
 
@@ -660,6 +665,18 @@ ssl3_client_hello(SSL *s)
 			p += i;
 		}
 
+		/* DTLS Cookie. */
+		if (SSL_IS_DTLS(s)) {
+			if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
+				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			*(p++) = s->d1->cookie_len;
+			memcpy(p, s->d1->cookie, s->d1->cookie_len);
+			p += s->d1->cookie_len;
+		}
+
 		/* Ciphers supported */
 		i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
 		if (i == 0) {
@@ -683,9 +700,9 @@ ssl3_client_hello(SSL *s)
 			goto err;
 		}
 
-		s->state = SSL3_ST_CW_CLNT_HELLO_B;
-
 		ssl3_handshake_msg_finish(s, p - d);
+
+		s->state = SSL3_ST_CW_CLNT_HELLO_B;
 	}
 
 	/* SSL3_ST_CW_CLNT_HELLO_B */
diff --git a/src/lib/libssl/src/ssl/d1_clnt.c b/src/lib/libssl/src/ssl/d1_clnt.c
index b087535ce1..23d6b372c9 100644
--- a/src/lib/libssl/src/ssl/d1_clnt.c
+++ b/src/lib/libssl/src/ssl/d1_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_clnt.c,v 1.47 2015/07/15 18:35:34 beck Exp $ */
+/* $OpenBSD: d1_clnt.c,v 1.48 2015/09/02 17:59:15 jsing Exp $ */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -263,7 +263,7 @@ dtls1_connect(SSL *s)
 			}
 
 			dtls1_start_timer(s);
-			ret = dtls1_client_hello(s);
+			ret = ssl3_client_hello(s);
 			if (ret <= 0)
 				goto end;
 
@@ -275,9 +275,10 @@ dtls1_connect(SSL *s)
 
 			s->init_num = 0;
 
-				/* turn on buffering for the next lot of output */
-				if (s->bbio != s->wbio)
-					s->wbio = BIO_push(s->bbio, s->wbio);
+			/* turn on buffering for the next lot of output */
+			if (s->bbio != s->wbio)
+				s->wbio = BIO_push(s->bbio, s->wbio);
+
 			break;
 
 		case SSL3_ST_CR_SRVR_HELLO_A:
@@ -603,100 +604,6 @@ end:
 	return (ret);
 }
 
-int
-dtls1_client_hello(SSL *s)
-{
-	unsigned char *bufend, *d, *p;
-	unsigned int i;
-
-	if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
-		SSL_SESSION *sess = s->session;
-
-		if ((s->session == NULL) ||
-		    (s->session->ssl_version != s->version) ||
-		    (!sess->session_id_length && !sess->tlsext_tick) ||
-		    (s->session->not_resumable)) {
-			if (!ssl_get_new_session(s, 0))
-				goto err;
-		}
-		/* else use the pre-loaded session */
-
-		p = s->s3->client_random;
-
-		/* if client_random is initialized, reuse it, we are
-		 * required to use same upon reply to HelloVerify */
-		for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++)
-			;
-		if (i == sizeof(s->s3->client_random))
-			arc4random_buf(p, sizeof(s->s3->client_random));
-
-		d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO);
-
-		*(p++) = s->version >> 8;
-		*(p++) = s->version&0xff;
-		s->client_version = s->version;
-
-		/* Random stuff */
-		memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
-		p += SSL3_RANDOM_SIZE;
-
-		/* Session ID */
-		if (s->new_session)
-			i = 0;
-		else
-			i = s->session->session_id_length;
-		*(p++) = i;
-		if (i != 0) {
-			if (i > sizeof s->session->session_id) {
-				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
-				    ERR_R_INTERNAL_ERROR);
-				goto err;
-			}
-			memcpy(p, s->session->session_id, i);
-			p += i;
-		}
-
-		/* cookie stuff */
-		if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
-			goto err;
-		}
-		*(p++) = s->d1->cookie_len;
-		memcpy(p, s->d1->cookie, s->d1->cookie_len);
-		p += s->d1->cookie_len;
-
-		/* Ciphers supported */
-		i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
-		if (i == 0) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
-			    SSL_R_NO_CIPHERS_AVAILABLE);
-			goto err;
-		}
-		s2n(i, p);
-		p += i;
-
-		/* add in (no) COMPRESSION */
-		*(p++) = 1;
-		*(p++) = 0; /* Add the NULL method */
-
-		bufend = (unsigned char *)s->init_buf->data +
-		    SSL3_RT_MAX_PLAIN_LENGTH;
-		if ((p = ssl_add_clienthello_tlsext(s, p, bufend)) == NULL) {
-			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
-			goto err;
-		}
-
-		ssl3_handshake_msg_finish(s, p - d);
-
-		s->state = SSL3_ST_CW_CLNT_HELLO_B;
-	}
-
-	/* SSL3_ST_CW_CLNT_HELLO_B */
-	return (ssl3_handshake_write(s));
-err:
-	return (-1);
-}
-
 static int
 dtls1_get_hello_verify(SSL *s)
 {
diff --git a/src/lib/libssl/src/ssl/s3_clnt.c b/src/lib/libssl/src/ssl/s3_clnt.c
index 5b9af06aa5..1d1a0c77f0 100644
--- a/src/lib/libssl/src/ssl/s3_clnt.c
+++ b/src/lib/libssl/src/ssl/s3_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_clnt.c,v 1.124 2015/09/01 13:38:27 jsing Exp $ */
+/* $OpenBSD: s3_clnt.c,v 1.125 2015/09/02 17:59:15 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -584,7 +584,6 @@ end:
 	return (ret);
 }
 
-
 int
 ssl3_client_hello(SSL *s)
 {
@@ -603,7 +602,13 @@ ssl3_client_hello(SSL *s)
 		}
 		/* else use the pre-loaded session */
 
-		arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
+		/*
+		 * If a DTLS ClientHello message is being resent after a
+		 * HelloVerifyRequest, we must retain the original client
+		 * random value.
+		 */
+		if (!SSL_IS_DTLS(s) || s->d1->send_cookie == 0)
+			arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
 
 		d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO);
 
@@ -660,6 +665,18 @@ ssl3_client_hello(SSL *s)
 			p += i;
 		}
 
+		/* DTLS Cookie. */
+		if (SSL_IS_DTLS(s)) {
+			if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
+				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			*(p++) = s->d1->cookie_len;
+			memcpy(p, s->d1->cookie, s->d1->cookie_len);
+			p += s->d1->cookie_len;
+		}
+
 		/* Ciphers supported */
 		i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
 		if (i == 0) {
@@ -683,9 +700,9 @@ ssl3_client_hello(SSL *s)
 			goto err;
 		}
 
-		s->state = SSL3_ST_CW_CLNT_HELLO_B;
-
 		ssl3_handshake_msg_finish(s, p - d);
+
+		s->state = SSL3_ST_CW_CLNT_HELLO_B;
 	}
 
 	/* SSL3_ST_CW_CLNT_HELLO_B */
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h
index b7853b24c8..8c8dec77b6 100644
--- a/src/lib/libssl/src/ssl/ssl_locl.h
+++ b/src/lib/libssl/src/ssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.102 2015/09/01 13:38:27 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.103 2015/09/02 17:59:15 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -729,7 +729,6 @@ int ssl3_check_cert_and_algorithm(SSL *s);
 int ssl3_check_finished(SSL *s);
 int ssl3_send_next_proto(SSL *s);
 
-int dtls1_client_hello(SSL *s);
 int dtls1_send_client_certificate(SSL *s);
 int dtls1_send_client_key_exchange(SSL *s);
 int dtls1_send_client_verify(SSL *s);
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index b7853b24c8..8c8dec77b6 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.102 2015/09/01 13:38:27 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.103 2015/09/02 17:59:15 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -729,7 +729,6 @@ int ssl3_check_cert_and_algorithm(SSL *s);
 int ssl3_check_finished(SSL *s);
 int ssl3_send_next_proto(SSL *s);
 
-int dtls1_client_hello(SSL *s);
 int dtls1_send_client_certificate(SSL *s);
 int dtls1_send_client_key_exchange(SSL *s);
 int dtls1_send_client_verify(SSL *s);
-- 
cgit v1.2.3-55-g6feb