diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index c2f2291..1a45805 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -166,2368 +166,2246 @@
 #include "ssl_locl.h"
 #include "../crypto/dh/internal.h"
 
-int ssl3_connect(SSL *s)
-	{
-	BUF_MEM *buf=NULL;
-	void (*cb)(const SSL *ssl,int type,int val)=NULL;
-	int ret= -1;
-	int new_state,state,skip=0;
 
-	assert(s->handshake_func == ssl3_connect);
-	assert(!s->server);
-	assert(!SSL_IS_DTLS(s));
+int ssl3_connect(SSL *s) {
+  BUF_MEM *buf = NULL;
+  void (*cb)(const SSL *ssl, int type, int val) = NULL;
+  int ret = -1;
+  int new_state, state, skip = 0;
 
-	ERR_clear_error();
-	ERR_clear_system_error();
+  assert(s->handshake_func == ssl3_connect);
+  assert(!s->server);
+  assert(!SSL_IS_DTLS(s));
 
-	if (s->info_callback != NULL)
-		cb=s->info_callback;
-	else if (s->ctx->info_callback != NULL)
-		cb=s->ctx->info_callback;
-	
-	s->in_handshake++;
+  ERR_clear_error();
+  ERR_clear_system_error();
 
-	for (;;)
-		{
-		state=s->state;
+  if (s->info_callback != NULL) {
+    cb = s->info_callback;
+  } else if (s->ctx->info_callback != NULL) {
+    cb = s->ctx->info_callback;
+  }
 
-		switch(s->state)
-			{
-		case SSL_ST_RENEGOTIATE:
-			s->renegotiate=1;
-			s->state=SSL_ST_CONNECT;
-			s->ctx->stats.sess_connect_renegotiate++;
-			/* break */
-		case SSL_ST_CONNECT:
-		case SSL_ST_BEFORE|SSL_ST_CONNECT:
+  s->in_handshake++;
 
-			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+  for (;;) {
+    state = s->state;
 
-			if (s->init_buf == NULL)
-				{
-				if ((buf=BUF_MEM_new()) == NULL)
-					{
-					ret= -1;
-					goto end;
-					}
-				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
-					{
-					ret= -1;
-					goto end;
-					}
-				s->init_buf=buf;
-				buf=NULL;
-				}
+    switch (s->state) {
+      case SSL_ST_RENEGOTIATE:
+        s->renegotiate = 1;
+        s->state = SSL_ST_CONNECT;
+        s->ctx->stats.sess_connect_renegotiate++;
+        /* fallthrough */
+      case SSL_ST_CONNECT:
+      case SSL_ST_BEFORE | SSL_ST_CONNECT:
+        if (cb != NULL)
+          cb(s, SSL_CB_HANDSHAKE_START, 1);
 
-			if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
+        if (s->init_buf == NULL) {
+          buf = BUF_MEM_new();
+          if (buf == NULL ||
+              !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
+            ret = -1;
+            goto end;
+          }
 
-			/* setup buffing BIO */
-			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
+          s->init_buf = buf;
+          buf = NULL;
+        }
 
-			/* don't push the buffering BIO quite yet */
+        if (!ssl3_setup_buffers(s) ||
+            !ssl_init_wbio_buffer(s, 0)) {
+          ret = -1;
+          goto end;
+        }
 
-			if (!ssl3_init_finished_mac(s))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
-				ret = -1;
-				goto end;
-				}
+        /* don't push the buffering BIO quite yet */
 
-			s->state=SSL3_ST_CW_CLNT_HELLO_A;
-			s->ctx->stats.sess_connect++;
-			s->init_num=0;
-			break;
+        if (!ssl3_init_finished_mac(s)) {
+          OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
+          ret = -1;
+          goto end;
+        }
 
-		case SSL3_ST_CW_CLNT_HELLO_A:
-		case SSL3_ST_CW_CLNT_HELLO_B:
+        s->state = SSL3_ST_CW_CLNT_HELLO_A;
+        s->ctx->stats.sess_connect++;
+        s->init_num = 0;
+        break;
 
-			s->shutdown=0;
-			ret=ssl3_send_client_hello(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CR_SRVR_HELLO_A;
-			s->init_num=0;
+      case SSL3_ST_CW_CLNT_HELLO_A:
+      case SSL3_ST_CW_CLNT_HELLO_B:
+        s->shutdown = 0;
+        ret = ssl3_send_client_hello(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CR_SRVR_HELLO_A;
+        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;
+        break;
 
-		case SSL3_ST_CR_SRVR_HELLO_A:
-		case SSL3_ST_CR_SRVR_HELLO_B:
-			ret=ssl3_get_server_hello(s);
-			if (ret <= 0) goto end;
+      case SSL3_ST_CR_SRVR_HELLO_A:
+      case SSL3_ST_CR_SRVR_HELLO_B:
+        ret = ssl3_get_server_hello(s);
+        if (ret <= 0) {
+          goto end;
+        }
 
-			if (s->hit)
-				{
-				s->state=SSL3_ST_CR_CHANGE;
-				if (s->tlsext_ticket_expected)
-					{
-					/* receive renewed session ticket */
-					s->state=SSL3_ST_CR_SESSION_TICKET_A;
-					}
-				}
-			else
-				{
-				s->state=SSL3_ST_CR_CERT_A;
-				}
-			s->init_num=0;
-			break;
+        if (s->hit) {
+          s->state = SSL3_ST_CR_CHANGE;
+          if (s->tlsext_ticket_expected) {
+            /* receive renewed session ticket */
+            s->state = SSL3_ST_CR_SESSION_TICKET_A;
+          }
+        } else {
+          s->state = SSL3_ST_CR_CERT_A;
+        }
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_CERT_A:
-		case SSL3_ST_CR_CERT_B:
-			if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
-				{
-				ret=ssl3_get_server_certificate(s);
-				if (ret <= 0) goto end;
-				if (s->s3->tmp.certificate_status_expected)
-					s->state=SSL3_ST_CR_CERT_STATUS_A;
-				else
-					s->state=SSL3_ST_CR_KEY_EXCH_A;
-				}
-			else
-				{
-				skip = 1;
-				s->state=SSL3_ST_CR_KEY_EXCH_A;
-				}
-			s->init_num=0;
-			break;
+      case SSL3_ST_CR_CERT_A:
+      case SSL3_ST_CR_CERT_B:
+        if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+          ret = ssl3_get_server_certificate(s);
+          if (ret <= 0) {
+            goto end;
+          }
+          if (s->s3->tmp.certificate_status_expected) {
+            s->state = SSL3_ST_CR_CERT_STATUS_A;
+          } else {
+            s->state = SSL3_ST_CR_KEY_EXCH_A;
+          }
+        } else {
+          skip = 1;
+          s->state = SSL3_ST_CR_KEY_EXCH_A;
+        }
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_KEY_EXCH_A:
-		case SSL3_ST_CR_KEY_EXCH_B:
-			ret=ssl3_get_server_key_exchange(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CR_CERT_REQ_A;
-			s->init_num=0;
+      case SSL3_ST_CR_KEY_EXCH_A:
+      case SSL3_ST_CR_KEY_EXCH_B:
+        ret = ssl3_get_server_key_exchange(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CR_CERT_REQ_A;
+        s->init_num = 0;
 
-			/* at this point we check that we have the
-			 * required stuff from the server */
-			if (!ssl3_check_cert_and_algorithm(s))
-				{
-				ret= -1;
-				goto end;
-				}
-			break;
+        /* at this point we check that we have the
+         * required stuff from the server */
+        if (!ssl3_check_cert_and_algorithm(s)) {
+          ret = -1;
+          goto end;
+        }
+        break;
 
-		case SSL3_ST_CR_CERT_REQ_A:
-		case SSL3_ST_CR_CERT_REQ_B:
-			ret=ssl3_get_certificate_request(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CR_SRVR_DONE_A;
-			s->init_num=0;
-			break;
+      case SSL3_ST_CR_CERT_REQ_A:
+      case SSL3_ST_CR_CERT_REQ_B:
+        ret = ssl3_get_certificate_request(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CR_SRVR_DONE_A;
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_SRVR_DONE_A:
-		case SSL3_ST_CR_SRVR_DONE_B:
-			ret=ssl3_get_server_done(s);
-			if (ret <= 0) goto end;
-			if (s->s3->tmp.cert_req)
-				s->state=SSL3_ST_CW_CERT_A;
-			else
-				s->state=SSL3_ST_CW_KEY_EXCH_A;
-			s->init_num=0;
+      case SSL3_ST_CR_SRVR_DONE_A:
+      case SSL3_ST_CR_SRVR_DONE_B:
+        ret = ssl3_get_server_done(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        if (s->s3->tmp.cert_req) {
+          s->state = SSL3_ST_CW_CERT_A;
+        } else {
+          s->state = SSL3_ST_CW_KEY_EXCH_A;
+        }
+        s->init_num = 0;
 
-			break;
+        break;
 
-		case SSL3_ST_CW_CERT_A:
-		case SSL3_ST_CW_CERT_B:
-		case SSL3_ST_CW_CERT_C:
-		case SSL3_ST_CW_CERT_D:
-			ret=ssl3_send_client_certificate(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CW_KEY_EXCH_A;
-			s->init_num=0;
-			break;
+      case SSL3_ST_CW_CERT_A:
+      case SSL3_ST_CW_CERT_B:
+      case SSL3_ST_CW_CERT_C:
+      case SSL3_ST_CW_CERT_D:
+        ret = ssl3_send_client_certificate(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CW_KEY_EXCH_A;
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CW_KEY_EXCH_A:
-		case SSL3_ST_CW_KEY_EXCH_B:
-			ret=ssl3_send_client_key_exchange(s);
-			if (ret <= 0) goto end;
-			/* For TLS, cert_req is set to 2, so a cert chain
-			 * of nothing is sent, but no verify packet is sent */
-			if (s->s3->tmp.cert_req == 1)
-				{
-				s->state=SSL3_ST_CW_CERT_VRFY_A;
-				}
-			else
-				{
-				s->state=SSL3_ST_CW_CHANGE_A;
-				s->s3->change_cipher_spec=0;
-				}
+      case SSL3_ST_CW_KEY_EXCH_A:
+      case SSL3_ST_CW_KEY_EXCH_B:
+        ret = ssl3_send_client_key_exchange(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        /* For TLS, cert_req is set to 2, so a cert chain
+         * of nothing is sent, but no verify packet is sent */
+        if (s->s3->tmp.cert_req == 1) {
+          s->state = SSL3_ST_CW_CERT_VRFY_A;
+        } else {
+          s->state = SSL3_ST_CW_CHANGE_A;
+          s->s3->change_cipher_spec = 0;
+        }
 
-			s->init_num=0;
-			break;
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CW_CERT_VRFY_A:
-		case SSL3_ST_CW_CERT_VRFY_B:
-			ret=ssl3_send_cert_verify(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CW_CHANGE_A;
-			s->init_num=0;
-			s->s3->change_cipher_spec=0;
-			break;
+      case SSL3_ST_CW_CERT_VRFY_A:
+      case SSL3_ST_CW_CERT_VRFY_B:
+        ret = ssl3_send_cert_verify(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CW_CHANGE_A;
+        s->init_num = 0;
+        s->s3->change_cipher_spec = 0;
+        break;
 
-		case SSL3_ST_CW_CHANGE_A:
-		case SSL3_ST_CW_CHANGE_B:
-			ret=ssl3_send_change_cipher_spec(s,
-				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
-			if (ret <= 0) goto end;
+      case SSL3_ST_CW_CHANGE_A:
+      case SSL3_ST_CW_CHANGE_B:
+        ret = ssl3_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,
+                                           SSL3_ST_CW_CHANGE_B);
+        if (ret <= 0) {
+          goto end;
+        }
 
- 			s->state=SSL3_ST_CW_FINISHED_A;
-			if (s->s3->tlsext_channel_id_valid)
-				s->state=SSL3_ST_CW_CHANNEL_ID_A;
-			if (s->s3->next_proto_neg_seen)
-				s->state=SSL3_ST_CW_NEXT_PROTO_A;
-			s->init_num=0;
+        s->state = SSL3_ST_CW_FINISHED_A;
+        if (s->s3->tlsext_channel_id_valid) {
+          s->state = SSL3_ST_CW_CHANNEL_ID_A;
+        }
+        if (s->s3->next_proto_neg_seen) {
+          s->state = SSL3_ST_CW_NEXT_PROTO_A;
+        }
+        s->init_num = 0;
 
-			s->session->cipher=s->s3->tmp.new_cipher;
-			if (!s->enc_method->setup_key_block(s))
-				{
-				ret= -1;
-				goto end;
-				}
+        s->session->cipher = s->s3->tmp.new_cipher;
+        if (!s->enc_method->setup_key_block(s)) {
+          ret = -1;
+          goto end;
+        }
 
-			if (!s->enc_method->change_cipher_state(s,
-				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
-				{
-				ret= -1;
-				goto end;
-				}
+        if (!s->enc_method->change_cipher_state(
+                s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+          ret = -1;
+          goto end;
+        }
 
-			break;
+        break;
 
-		case SSL3_ST_CW_NEXT_PROTO_A:
-		case SSL3_ST_CW_NEXT_PROTO_B:
-			ret=ssl3_send_next_proto(s);
-			if (ret <= 0) goto end;
-			if (s->s3->tlsext_channel_id_valid)
-				s->state=SSL3_ST_CW_CHANNEL_ID_A;
-			else
-				s->state=SSL3_ST_CW_FINISHED_A;
-			break;
+      case SSL3_ST_CW_NEXT_PROTO_A:
+      case SSL3_ST_CW_NEXT_PROTO_B:
+        ret = ssl3_send_next_proto(s);
+        if (ret <= 0) {
+          goto end;
+        }
 
-		case SSL3_ST_CW_CHANNEL_ID_A:
-		case SSL3_ST_CW_CHANNEL_ID_B:
-			ret=ssl3_send_channel_id(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CW_FINISHED_A;
-			break;
+        if (s->s3->tlsext_channel_id_valid) {
+          s->state = SSL3_ST_CW_CHANNEL_ID_A;
+        } else {
+          s->state = SSL3_ST_CW_FINISHED_A;
+        }
+        break;
 
-		case SSL3_ST_CW_FINISHED_A:
-		case SSL3_ST_CW_FINISHED_B:
-			ret=ssl3_send_finished(s,
-				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
-				s->enc_method->client_finished_label,
-				s->enc_method->client_finished_label_len);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CW_FLUSH;
+      case SSL3_ST_CW_CHANNEL_ID_A:
+      case SSL3_ST_CW_CHANNEL_ID_B:
+        ret = ssl3_send_channel_id(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CW_FINISHED_A;
+        break;
 
-			if (s->hit)
-				{
-				s->s3->tmp.next_state=SSL_ST_OK;
-				}
-			else
-				{
-				/* This is a non-resumption handshake. If it
-				 * involves ChannelID, then record the
-				 * handshake hashes at this point in the
-				 * session so that any resumption of this
-				 * session with ChannelID can sign those
-				 * hashes. */
-				if (s->s3->tlsext_channel_id_new)
-					{
-					ret = tls1_record_handshake_hashes_for_channel_id(s);
-					if (ret <= 0)
-						goto end;
-					}
-				if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
-				    && ssl3_can_cutthrough(s)
-				    && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
-				   )
-					{
-					s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
-					}
-				else
-					{
-					/* Allow NewSessionTicket if ticket expected */
-					if (s->tlsext_ticket_expected)
-						s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
-					else
-						s->s3->tmp.next_state=SSL3_ST_CR_CHANGE;
-					}
-				}
-			s->init_num=0;
-			break;
+      case SSL3_ST_CW_FINISHED_A:
+      case SSL3_ST_CW_FINISHED_B:
+        ret =
+            ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
+                               s->enc_method->client_finished_label,
+                               s->enc_method->client_finished_label_len);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CW_FLUSH;
 
-		case SSL3_ST_CR_SESSION_TICKET_A:
-		case SSL3_ST_CR_SESSION_TICKET_B:
-			ret=ssl3_get_new_session_ticket(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CR_CHANGE;
-			s->init_num=0;
-		break;
+        if (s->hit) {
+          s->s3->tmp.next_state = SSL_ST_OK;
+        } else {
+          /* This is a non-resumption handshake. If it involves ChannelID, then
+           * record the handshake hashes at this point in the session so that
+           * any resumption of this session with ChannelID can sign those
+           * hashes. */
+          if (s->s3->tlsext_channel_id_new) {
+            ret = tls1_record_handshake_hashes_for_channel_id(s);
+            if (ret <= 0)
+              goto end;
+          }
+          if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) &&
+              ssl3_can_cutthrough(s) &&
+              /* no cutthrough on renegotiation (would complicate the state
+               * machine) */
+              s->s3->previous_server_finished_len == 0) {
+            s->s3->tmp.next_state = SSL3_ST_CUTTHROUGH_COMPLETE;
+          } else {
+            /* Allow NewSessionTicket if ticket expected */
+            if (s->tlsext_ticket_expected) {
+              s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
+            } else {
+              s->s3->tmp.next_state = SSL3_ST_CR_CHANGE;
+            }
+          }
+        }
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_CERT_STATUS_A:
-		case SSL3_ST_CR_CERT_STATUS_B:
-			ret=ssl3_get_cert_status(s);
-			if (ret <= 0) goto end;
-			s->state=SSL3_ST_CR_KEY_EXCH_A;
-			s->init_num=0;
-		break;
+      case SSL3_ST_CR_SESSION_TICKET_A:
+      case SSL3_ST_CR_SESSION_TICKET_B:
+        ret = ssl3_get_new_session_ticket(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CR_CHANGE;
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_CHANGE:
-			/* At this point, the next message must be entirely
-			 * behind a ChangeCipherSpec. */
-			if (!ssl3_expect_change_cipher_spec(s))
-				{
-				ret = -1;
-				goto end;
-				}
-			s->state = SSL3_ST_CR_FINISHED_A;
-			break;
+      case SSL3_ST_CR_CERT_STATUS_A:
+      case SSL3_ST_CR_CERT_STATUS_B:
+        ret = ssl3_get_cert_status(s);
+        if (ret <= 0) {
+          goto end;
+        }
+        s->state = SSL3_ST_CR_KEY_EXCH_A;
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CR_FINISHED_A:
-		case SSL3_ST_CR_FINISHED_B:
-			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
-				SSL3_ST_CR_FINISHED_B);
-			if (ret <= 0) goto end;
+      case SSL3_ST_CR_CHANGE:
+        /* At this point, the next message must be entirely behind a
+         * ChangeCipherSpec. */
+        if (!ssl3_expect_change_cipher_spec(s)) {
+          ret = -1;
+          goto end;
+        }
+        s->state = SSL3_ST_CR_FINISHED_A;
+        break;
 
-			if (s->hit)
-				s->state=SSL3_ST_CW_CHANGE_A;
-			else
-				s->state=SSL_ST_OK;
-			s->init_num=0;
-			break;
+      case SSL3_ST_CR_FINISHED_A:
+      case SSL3_ST_CR_FINISHED_B:
+        ret =
+            ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
+        if (ret <= 0) {
+          goto end;
+        }
 
-		case SSL3_ST_CW_FLUSH:
-			s->rwstate=SSL_WRITING;
-			if (BIO_flush(s->wbio) <= 0)
-				{
-				ret= -1;
-				goto end;
-				}
-			s->rwstate=SSL_NOTHING;
-			s->state=s->s3->tmp.next_state;
-			break;
+        if (s->hit) {
+          s->state = SSL3_ST_CW_CHANGE_A;
+        } else {
+          s->state = SSL_ST_OK;
+        }
+        s->init_num = 0;
+        break;
 
-		case SSL3_ST_CUTTHROUGH_COMPLETE:
-			/* Allow NewSessionTicket if ticket expected */
-			if (s->tlsext_ticket_expected)
-				s->state=SSL3_ST_CR_SESSION_TICKET_A;
-			else
-				s->state=SSL3_ST_CR_CHANGE;
+      case SSL3_ST_CW_FLUSH:
+        s->rwstate = SSL_WRITING;
+        if (BIO_flush(s->wbio) <= 0) {
+          ret = -1;
+          goto end;
+        }
+        s->rwstate = SSL_NOTHING;
+        s->state = s->s3->tmp.next_state;
+        break;
 
-			ssl_free_wbio_buffer(s);
-			ret = 1;
-			goto end;
-			/* break; */
+      case SSL3_ST_CUTTHROUGH_COMPLETE:
+        /* Allow NewSessionTicket if ticket expected */
+        if (s->tlsext_ticket_expected) {
+          s->state = SSL3_ST_CR_SESSION_TICKET_A;
+        } else {
+          s->state = SSL3_ST_CR_CHANGE;
+        }
 
-		case SSL_ST_OK:
-			/* clean a few things up */
-			ssl3_cleanup_key_block(s);
+        ssl_free_wbio_buffer(s);
+        ret = 1;
+        goto end;
 
-			if (s->init_buf != NULL)
-				{
-				BUF_MEM_free(s->init_buf);
-				s->init_buf=NULL;
-				}
+      case SSL_ST_OK:
+        /* clean a few things up */
+        ssl3_cleanup_key_block(s);
 
-			/* Remove write buffering now. */
-			ssl_free_wbio_buffer(s);
+        if (s->init_buf != NULL) {
+          BUF_MEM_free(s->init_buf);
+          s->init_buf = NULL;
+        }
 
-			s->init_num=0;
-			s->renegotiate=0;
-			s->new_session=0;
+        /* Remove write buffering now. */
+        ssl_free_wbio_buffer(s);
 
-			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
-			if (s->hit) s->ctx->stats.sess_hit++;
+        s->init_num = 0;
+        s->renegotiate = 0;
+        s->new_session = 0;
 
-			ret=1;
-			/* s->server=0; */
-			s->ctx->stats.sess_connect_good++;
+        ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+        if (s->hit) {
+          s->ctx->stats.sess_hit++;
+        }
 
-			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+        ret = 1;
+        /* s->server=0; */
+        s->ctx->stats.sess_connect_good++;
 
-			goto end;
-			/* break; */
-			
-		default:
-			OPENSSL_PUT_ERROR(SSL, ssl3_connect, SSL_R_UNKNOWN_STATE);
-			ret= -1;
-			goto end;
-			/* break; */
-			}
+        if (cb != NULL) {
+          cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+        }
 
-		/* did we do anything */
-		if (!s->s3->tmp.reuse_message && !skip)
-			{
-			if ((cb != NULL) && (s->state != state))
-				{
-				new_state=s->state;
-				s->state=state;
-				cb(s,SSL_CB_CONNECT_LOOP,1);
-				s->state=new_state;
-				}
-			}
-		skip=0;
-		}
+        goto end;
+
+      default:
+        OPENSSL_PUT_ERROR(SSL, ssl3_connect, SSL_R_UNKNOWN_STATE);
+        ret = -1;
+        goto end;
+    }
+
+    if (!s->s3->tmp.reuse_message && !skip) {
+      if (cb != NULL && s->state != state) {
+        new_state = s->state;
+        s->state = state;
+        cb(s, SSL_CB_CONNECT_LOOP, 1);
+        s->state = new_state;
+      }
+    }
+    skip = 0;
+  }
+
 end:
-	s->in_handshake--;
-	if (buf != NULL)
-		BUF_MEM_free(buf);
-	if (cb != NULL)
-		cb(s,SSL_CB_CONNECT_EXIT,ret);
-	return(ret);
-	}
+  s->in_handshake--;
+  if (buf != NULL) {
+    BUF_MEM_free(buf);
+  }
+  if (cb != NULL) {
+    cb(s, SSL_CB_CONNECT_EXIT, ret);
+  }
+  return ret;
+}
 
-int ssl3_send_client_hello(SSL *s)
-	{
-	unsigned char *buf;
-	unsigned char *p,*d;
-	int i;
-	unsigned long l;
+int ssl3_send_client_hello(SSL *s) {
+  uint8_t *buf, *p, *d;
+  int i;
+  unsigned long l;
 
-	buf=(unsigned char *)s->init_buf->data;
-	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
-		{
-		if (!s->s3->have_version)
-			{
-			uint16_t max_version = ssl3_get_max_client_version(s);
-			/* Disabling all versions is silly: return an error. */
-			if (max_version == 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_WRONG_SSL_VERSION);
-				goto err;
-				}
-			s->version = max_version;
-			s->client_version = max_version;
-			}
+  buf = (uint8_t *)s->init_buf->data;
+  if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
+    if (!s->s3->have_version) {
+      uint16_t max_version = ssl3_get_max_client_version(s);
+      /* Disabling all versions is silly: return an error. */
+      if (max_version == 0) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_WRONG_SSL_VERSION);
+        goto err;
+      }
+      s->version = max_version;
+      s->client_version = max_version;
+    }
 
-		/* If the configured session was created at a version
-		 * higher than our maximum version, drop it. */
-		if (s->session &&
-			(s->session->session_id_length == 0 ||
-				s->session->not_resumable ||
-				(!SSL_IS_DTLS(s) && s->session->ssl_version > s->version) ||
-				(SSL_IS_DTLS(s) && s->session->ssl_version < s->version)))
-			{
-			SSL_set_session(s, NULL);
-			}
+    /* If the configured session was created at a version higher than our
+     * maximum version, drop it. */
+    if (s->session &&
+        (s->session->session_id_length == 0 || s->session->not_resumable ||
+         (!SSL_IS_DTLS(s) && s->session->ssl_version > s->version) ||
+         (SSL_IS_DTLS(s) && s->session->ssl_version < s->version))) {
+      SSL_set_session(s, NULL);
+    }
 
-		/* else use the pre-loaded session */
+    /* else use the pre-loaded session */
+    p = s->s3->client_random;
 
-		p=s->s3->client_random;
+    /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
+     * renegerate the client_random. The random must be reused. */
+    if (!SSL_IS_DTLS(s) || !s->d1->send_cookie) {
+      ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random));
+    }
 
-		/* If resending the ClientHello in DTLS after a
-		 * HelloVerifyRequest, don't renegerate the client_random. The
-		 * random must be reused. */
-		if (!SSL_IS_DTLS(s) || !s->d1->send_cookie)
-			{
-			ssl_fill_hello_random(s, 0, p,
-					      sizeof(s->s3->client_random));
-			}
+    /* Do the message type and length last. Note: the final argument to
+     * ssl_add_clienthello_tlsext below depends on the size of this prefix. */
+    d = p = ssl_handshake_start(s);
 
-		/* Do the message type and length last.
-		 * Note: the final argument to ssl_add_clienthello_tlsext below
-		 * depends on the size of this prefix. */
-		d=p= ssl_handshake_start(s);
+    /* version indicates the negotiated version: for example from an SSLv2/v3
+     * compatible client hello). The client_version field is the maximum
+     * version we permit and it is also used in RSA encrypted premaster
+     * secrets. Some servers can choke if we initially report a higher version
+     * then renegotiate to a lower one in the premaster secret. This didn't
+     * happen with TLS 1.0 as most servers supported it but it can with TLS 1.1
+     * or later if the server only supports 1.0.
+     *
+     * Possible scenario with previous logic:
+     *   1. Client hello indicates TLS 1.2
+     *   2. Server hello says TLS 1.0
+     *   3. RSA encrypted premaster secret uses 1.2.
+     *   4. Handhaked proceeds using TLS 1.0.
+     *   5. Server sends hello request to renegotiate.
+     *   6. Client hello indicates TLS v1.0 as we now
+     *      know that is maximum server supports.
+     *   7. Server chokes on RSA encrypted premaster secret
+     *      containing version 1.0.
+     *
+     * For interoperability it should be OK to always use the maximum version
+     * we support in client hello and then rely on the checking of version to
+     * ensure the servers isn't being inconsistent: for example initially
+     * negotiating with TLS 1.0 and renegotiating with TLS 1.2. We do this by
+     * using client_version in client hello and not resetting it to the
+     * negotiated version. */
+    *(p++) = s->client_version >> 8;
+    *(p++) = s->client_version & 0xff;
 
-		/* version indicates the negotiated version: for example from
-		 * an SSLv2/v3 compatible client hello). The client_version
-		 * field is the maximum version we permit and it is also
-		 * used in RSA encrypted premaster secrets. Some servers can
-		 * choke if we initially report a higher version then
-		 * renegotiate to a lower one in the premaster secret. This
-		 * didn't happen with TLS 1.0 as most servers supported it
-		 * but it can with TLS 1.1 or later if the server only supports
-		 * 1.0.
-		 *
-		 * Possible scenario with previous logic:
-		 * 	1. Client hello indicates TLS 1.2
-		 * 	2. Server hello says TLS 1.0
-		 *	3. RSA encrypted premaster secret uses 1.2.
-		 * 	4. Handhaked proceeds using TLS 1.0.
-		 *	5. Server sends hello request to renegotiate.
-		 *	6. Client hello indicates TLS v1.0 as we now
-		 *	   know that is maximum server supports.
-		 *	7. Server chokes on RSA encrypted premaster secret
-		 *	   containing version 1.0.
-		 *
-		 * For interoperability it should be OK to always use the
-		 * maximum version we support in client hello and then rely
-		 * on the checking of version to ensure the servers isn't
-		 * being inconsistent: for example initially negotiating with
-		 * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
-		 * client_version in client hello and not resetting it to
-		 * the negotiated version.
-		 */
-		*(p++)=s->client_version>>8;
-		*(p++)=s->client_version&0xff;
+    /* Random stuff */
+    memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
+    p += SSL3_RANDOM_SIZE;
 
-		/* Random stuff */
-		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-		p+=SSL3_RANDOM_SIZE;
+    /* Session ID */
+    if (s->new_session || s->session == NULL) {
+      i = 0;
+    } else {
+      i = s->session->session_id_length;
+    }
+    *(p++) = i;
+    if (i != 0) {
+      if (i > (int)sizeof(s->session->session_id)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+      memcpy(p, s->session->session_id, i);
+      p += i;
+    }
 
-		/* Session ID */
-		if (s->new_session || s->session == NULL)
-			i=0;
-		else
-			i=s->session->session_id_length;
-		*(p++)=i;
-		if (i != 0)
-			{
-			if (i > (int)sizeof(s->session->session_id))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			memcpy(p,s->session->session_id,i);
-			p+=i;
-			}
-		
-		/* cookie stuff for DTLS */
-		if (SSL_IS_DTLS(s))
-			{
-			if ( s->d1->cookie_len > sizeof(s->d1->cookie))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_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)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_NO_CIPHERS_AVAILABLE);
-			goto err;
-			}
-		s2n(i,p);
-		p+=i;
+    /* cookie stuff for DTLS */
+    if (SSL_IS_DTLS(s)) {
+      if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_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;
+    }
 
-		/* COMPRESSION */
-		*(p++)=1;
-		*(p++)=0; /* Add the NULL method */
+    /* Ciphers supported */
+    i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
+    if (i == 0) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello,
+                        SSL_R_NO_CIPHERS_AVAILABLE);
+      goto err;
+    }
+    s2n(i, p);
+    p += i;
 
-		/* TLS extensions*/
-		if (ssl_prepare_clienthello_tlsext(s) <= 0)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_CLIENTHELLO_TLSEXT);
-			goto err;
-			}
-		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf)) == NULL)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
-			goto err;
-			}
-		
-		l= p-d;
-		ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l);
-		s->state=SSL3_ST_CW_CLNT_HELLO_B;
-		}
+    /* COMPRESSION */
+    *(p++) = 1;
+    *(p++) = 0; /* Add the NULL method */
 
-	/* SSL3_ST_CW_CLNT_HELLO_B */
-	return ssl_do_write(s);
+    /* TLS extensions*/
+    if (ssl_prepare_clienthello_tlsext(s) <= 0) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_CLIENTHELLO_TLSEXT);
+      goto err;
+    }
+
+    p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
+                                   p - buf);
+    if (p == NULL) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+      goto err;
+    }
+
+    l = p - d;
+    ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l);
+    s->state = SSL3_ST_CW_CLNT_HELLO_B;
+  }
+
+  /* SSL3_ST_CW_CLNT_HELLO_B */
+  return ssl_do_write(s);
+
 err:
-	return(-1);
-	}
+  return -1;
+}
 
-int ssl3_get_server_hello(SSL *s)
-	{
-	STACK_OF(SSL_CIPHER) *sk;
-	const SSL_CIPHER *c;
-	CERT *ct = s->cert;
-	int al=SSL_AD_INTERNAL_ERROR,ok;
-	long n;
-	CBS server_hello, server_random, session_id;
-	uint16_t server_version, cipher_suite;
-	uint8_t compression_method;
-	unsigned long mask_ssl;
+int ssl3_get_server_hello(SSL *s) {
+  STACK_OF(SSL_CIPHER) * sk;
+  const SSL_CIPHER *c;
+  CERT *ct = s->cert;
+  int al = SSL_AD_INTERNAL_ERROR, ok;
+  long n;
+  CBS server_hello, server_random, session_id;
+  uint16_t server_version, cipher_suite;
+  uint8_t compression_method;
+  unsigned long mask_ssl;
 
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_SRVR_HELLO_A,
-		SSL3_ST_CR_SRVR_HELLO_B,
-		SSL3_MT_SERVER_HELLO,
-		20000, /* ?? */
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
+  n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A,
+                                 SSL3_ST_CR_SRVR_HELLO_B, SSL3_MT_SERVER_HELLO,
+                                 20000, /* ?? */
+                                 SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-	if (!ok) return((int)n);
+  if (!ok) {
+    return n;
+  }
 
-	CBS_init(&server_hello, s->init_msg, n);
+  CBS_init(&server_hello, s->init_msg, n);
 
-	if (!CBS_get_u16(&server_hello, &server_version) ||
-		!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
-		!CBS_get_u8_length_prefixed(&server_hello, &session_id) ||
-		CBS_len(&session_id) > SSL3_SESSION_ID_SIZE ||
-		!CBS_get_u16(&server_hello, &cipher_suite) ||
-		!CBS_get_u8(&server_hello, &compression_method))
-		{
-		al = SSL_AD_DECODE_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
-		goto f_err;
-		}
+  if (!CBS_get_u16(&server_hello, &server_version) ||
+      !CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
+      !CBS_get_u8_length_prefixed(&server_hello, &session_id) ||
+      CBS_len(&session_id) > SSL3_SESSION_ID_SIZE ||
+      !CBS_get_u16(&server_hello, &cipher_suite) ||
+      !CBS_get_u8(&server_hello, &compression_method)) {
+    al = SSL_AD_DECODE_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
+    goto f_err;
+  }
 
-	if (!s->s3->have_version)
-		{
-		if (!ssl3_is_version_enabled(s, server_version))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
-			s->version = server_version;
-			/* Mark the version as fixed so the record-layer version
-			 * is not clamped to TLS 1.0. */
-			s->s3->have_version = 1;
-			al = SSL_AD_PROTOCOL_VERSION;
-			goto f_err;
-			}
-		s->version = server_version;
-		s->enc_method = ssl3_get_enc_method(server_version);
-		assert(s->enc_method != NULL);
-		/* At this point, the connection's version is known and
-		 * s->version is fixed. Begin enforcing the record-layer
-		 * version. */
-		s->s3->have_version = 1;
-		}
-	else if (server_version != s->version)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_VERSION);
-		al = SSL_AD_PROTOCOL_VERSION;
-		goto f_err;
-		}
+  if (!s->s3->have_version) {
+    if (!ssl3_is_version_enabled(s, server_version)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
+      s->version = server_version;
+      /* Mark the version as fixed so the record-layer version is not clamped
+       * to TLS 1.0. */
+      s->s3->have_version = 1;
+      al = SSL_AD_PROTOCOL_VERSION;
+      goto f_err;
+    }
+    s->version = server_version;
+    s->enc_method = ssl3_get_enc_method(server_version);
+    assert(s->enc_method != NULL);
+    /* At this point, the connection's version is known and s->version is
+     * fixed. Begin enforcing the record-layer version. */
+    s->s3->have_version = 1;
+  } else if (server_version != s->version) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_VERSION);
+    al = SSL_AD_PROTOCOL_VERSION;
+    goto f_err;
+  }
 
-	/* Copy over the server random. */
-	memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
+  /* Copy over the server random. */
+  memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
 
-	assert(s->session == NULL || s->session->session_id_length > 0);
-	if (s->session != NULL &&
-		CBS_mem_equal(&session_id,
-			s->session->session_id, s->session->session_id_length))
-		{
-		if(s->sid_ctx_length != s->session->sid_ctx_length
-			|| memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length))
-			{
-			/* actually a client application bug */
-			al = SSL_AD_ILLEGAL_PARAMETER;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
-			goto f_err;
-			}
-		s->hit = 1;
-		}
-	else
-		{
-		/* The session wasn't resumed. Create a fresh SSL_SESSION to
-		 * fill out. */
-		s->hit = 0;
-		if (!ssl_get_new_session(s, 0))
-			{
-			goto f_err;
-			}
-		/* Note: session_id could be empty. */
-		s->session->session_id_length = CBS_len(&session_id);
-		memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id));
-		}
+  assert(s->session == NULL || s->session->session_id_length > 0);
+  if (s->session != NULL && CBS_mem_equal(&session_id, s->session->session_id,
+                                          s->session->session_id_length)) {
+    if (s->sid_ctx_length != s->session->sid_ctx_length ||
+        memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
+      /* actually a client application bug */
+      al = SSL_AD_ILLEGAL_PARAMETER;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                        SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+      goto f_err;
+    }
+    s->hit = 1;
+  } else {
+    /* The session wasn't resumed. Create a fresh SSL_SESSION to
+     * fill out. */
+    s->hit = 0;
+    if (!ssl_get_new_session(s, 0)) {
+      goto f_err;
+    }
+    /* Note: session_id could be empty. */
+    s->session->session_id_length = CBS_len(&session_id);
+    memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id));
+  }
 
-	c = ssl3_get_cipher_by_value(cipher_suite);
-	if (c == NULL)
-		{
-		/* unknown cipher */
-		al = SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNKNOWN_CIPHER_RETURNED);
-		goto f_err;
-		}
-	/* ct->mask_ssl was computed from client capabilities. Now
-	 * that the final version is known, compute a new mask_ssl. */
-	if (!SSL_USE_TLS1_2_CIPHERS(s))
-		mask_ssl = SSL_TLSV1_2;
-	else
-		mask_ssl = 0;
-	/* If it is a disabled cipher we didn't send it in client hello,
-	 * so return an error.
-	 */
-	if (c->algorithm_ssl & mask_ssl ||
-		c->algorithm_mkey & ct->mask_k ||
-		c->algorithm_auth & ct->mask_a)
-		{
-		al=SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
-		goto f_err;
-		}
+  c = ssl3_get_cipher_by_value(cipher_suite);
+  if (c == NULL) {
+    /* unknown cipher */
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                      SSL_R_UNKNOWN_CIPHER_RETURNED);
+    goto f_err;
+  }
+  /* ct->mask_ssl was computed from client capabilities. Now
+   * that the final version is known, compute a new mask_ssl. */
+  if (!SSL_USE_TLS1_2_CIPHERS(s)) {
+    mask_ssl = SSL_TLSV1_2;
+  } else {
+    mask_ssl = 0;
+  }
+  /* If the cipher is disabled then we didn't sent it in the ClientHello, so if
+   * the server selected it, it's an error. */
+  if ((c->algorithm_ssl & mask_ssl) ||
+      (c->algorithm_mkey & ct->mask_k) ||
+      (c->algorithm_auth & ct->mask_a)) {
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+    goto f_err;
+  }
 
-	sk=ssl_get_ciphers_by_id(s);
-	if (!sk_SSL_CIPHER_find(sk, NULL, c))
-		{
-		/* we did not say we would use this cipher */
-		al=SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
-		goto f_err;
-		}
+  sk = ssl_get_ciphers_by_id(s);
+  if (!sk_SSL_CIPHER_find(sk, NULL, c)) {
+    /* we did not say we would use this cipher */
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+    goto f_err;
+  }
 
-	/* Depending on the session caching (internal/external), the cipher
-	   and/or cipher_id values may not be set. Make sure that
-	   cipher_id is set and use it for comparison. */
-	if (s->session->cipher)
-		s->session->cipher_id = s->session->cipher->id;
-	if (s->hit && (s->session->cipher_id != c->id))
-		{
-		al = SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
-		goto f_err;
-		}
-	s->s3->tmp.new_cipher=c;
+  /* Depending on the session caching (internal/external), the cipher
+     and/or cipher_id values may not be set. Make sure that cipher_id is set
+     and use it for comparison. */
+  if (s->session->cipher) {
+    s->session->cipher_id = s->session->cipher->id;
+  }
+  if (s->hit && s->session->cipher_id != c->id) {
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                      SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+    goto f_err;
+  }
+  s->s3->tmp.new_cipher = c;
 
-	/* Most clients also require that the negotiated version match the
-	 * session's version if resuming. However OpenSSL has historically not
-	 * had the corresponding logic on the server, so this may not be
-	 * compatible, depending on other factors. (Whether the ClientHello
-	 * version is clamped to the session's version and whether the session
-	 * cache is keyed on IP address.)
-	 *
-	 * TODO(davidben): See if we can still enforce this? Perhaps for the
-	 * future TLS 1.3 and forward if this is fixed upstream. */
+  /* Most clients also require that the negotiated version match the session's
+   * version if resuming. However OpenSSL has historically not had the
+   * corresponding logic on the server, so this may not be compatible,
+   * depending on other factors. (Whether the ClientHello version is clamped to
+   * the session's version and whether the session cache is keyed on IP
+   * address.)
+   *
+   * TODO(davidben): See if we can still enforce this? Perhaps for the future
+   * TLS 1.3 and forward if this is fixed upstream. */
 
-	/* Don't digest cached records if no sigalgs: we may need them for
-	 * client authentication.
-	 */
-	if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s, free_handshake_buffer))
-		goto f_err;
+  /* Don't digest cached records if no sigalgs: we may need them for client
+   * authentication. */
+  if (!SSL_USE_SIGALGS(s) &&
+      !ssl3_digest_cached_records(s, free_handshake_buffer)) {
+    goto f_err;
+  }
 
-	/* Only the NULL compression algorithm is supported. */
-	if (compression_method != 0)
-		{
-		al = SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
-		goto f_err;
-		}
+  /* Only the NULL compression algorithm is supported. */
+  if (compression_method != 0) {
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                      SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+    goto f_err;
+  }
 
-	/* TLS extensions */
-	if (!ssl_parse_serverhello_tlsext(s, &server_hello))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_PARSE_TLSEXT);
-		goto err; 
-		}
+  /* TLS extensions */
+  if (!ssl_parse_serverhello_tlsext(s, &server_hello)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_PARSE_TLSEXT);
+    goto err;
+  }
 
-        /* There should be nothing left over in the record. */
-	if (CBS_len(&server_hello) != 0)
-		{
-		/* wrong packet length */
-		al=SSL_AD_DECODE_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_PACKET_LENGTH);
-		goto f_err;
-		}
+  /* There should be nothing left over in the record. */
+  if (CBS_len(&server_hello) != 0) {
+    /* wrong packet length */
+    al = SSL_AD_DECODE_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_PACKET_LENGTH);
+    goto f_err;
+  }
 
-	return(1);
+  return 1;
+
 f_err:
-	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+  ssl3_send_alert(s, SSL3_AL_FATAL, al);
 err:
-	return(-1);
-	}
+  return -1;
+}
 
-int ssl3_get_server_certificate(SSL *s)
-	{
-	int al,i,ok,ret= -1;
-	unsigned long n;
-	X509 *x=NULL;
-	STACK_OF(X509) *sk=NULL;
-	SESS_CERT *sc;
-	EVP_PKEY *pkey=NULL;
-	CBS cbs, certificate_list;
-	const uint8_t* data;
+int ssl3_get_server_certificate(SSL *s) {
+  int al, i, ok, ret = -1;
+  unsigned long n;
+  X509 *x = NULL;
+  STACK_OF(X509) *sk = NULL;
+  SESS_CERT *sc;
+  EVP_PKEY *pkey = NULL;
+  CBS cbs, certificate_list;
+  const uint8_t *data;
 
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_CERT_A,
-		SSL3_ST_CR_CERT_B,
-		SSL3_MT_CERTIFICATE,
-		s->max_cert_list,
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
+  n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B,
+                                 SSL3_MT_CERTIFICATE, s->max_cert_list,
+                                 SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-	if (!ok) return((int)n);
+  if (!ok) {
+    return n;
+  }
 
-	CBS_init(&cbs, s->init_msg, n);
+  CBS_init(&cbs, s->init_msg, n);
 
-	if ((sk=sk_X509_new_null()) == NULL)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+  sk = sk_X509_new_null();
+  if (sk == NULL) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
 
-	if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list) ||
-		CBS_len(&cbs) != 0)
-		{
-		al = SSL_AD_DECODE_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_LENGTH_MISMATCH);
-		goto f_err;
-		}
+  if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list) ||
+      CBS_len(&cbs) != 0) {
+    al = SSL_AD_DECODE_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_LENGTH_MISMATCH);
+    goto f_err;
+  }
 
-	while (CBS_len(&certificate_list) > 0)
-		{
-		CBS certificate;
-		if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERT_LENGTH_MISMATCH);
-			goto f_err;
-			}
-		data = CBS_data(&certificate);
-		x = d2i_X509(NULL, &data, CBS_len(&certificate));
-		if (x == NULL)
-			{
-			al = SSL_AD_BAD_CERTIFICATE;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_ASN1_LIB);
-			goto f_err;
-			}
-		if (data != CBS_data(&certificate) + CBS_len(&certificate))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERT_LENGTH_MISMATCH);
-			goto f_err;
-			}
-		if (!sk_X509_push(sk, x))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		x=NULL;
-		}
+  while (CBS_len(&certificate_list) > 0) {
+    CBS certificate;
+    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                        SSL_R_CERT_LENGTH_MISMATCH);
+      goto f_err;
+    }
+    data = CBS_data(&certificate);
+    x = d2i_X509(NULL, &data, CBS_len(&certificate));
+    if (x == NULL) {
+      al = SSL_AD_BAD_CERTIFICATE;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_ASN1_LIB);
+      goto f_err;
+    }
+    if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                        SSL_R_CERT_LENGTH_MISMATCH);
+      goto f_err;
+    }
+    if (!sk_X509_push(sk, x)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+    x = NULL;
+  }
 
-	i=ssl_verify_cert_chain(s,sk);
-	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
-		)
-		{
-		al=ssl_verify_alarm_type(s->verify_result);
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERTIFICATE_VERIFY_FAILED);
-		goto f_err; 
-		}
-	ERR_clear_error(); /* but we keep s->verify_result */
+  i = ssl_verify_cert_chain(s, sk);
+  if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
+    al = ssl_verify_alarm_type(s->verify_result);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                      SSL_R_CERTIFICATE_VERIFY_FAILED);
+    goto f_err;
+  }
+  ERR_clear_error(); /* but we keep s->verify_result */
 
-	sc=ssl_sess_cert_new();
-	if (sc == NULL) goto err;
+  sc = ssl_sess_cert_new();
+  if (sc == NULL) {
+    goto err;
+  }
 
-	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
-	s->session->sess_cert=sc;
+  if (s->session->sess_cert) {
+    ssl_sess_cert_free(s->session->sess_cert);
+  }
+  s->session->sess_cert = sc;
 
-	sc->cert_chain=sk;
-	/* Inconsistency alert: cert_chain does include the peer's
-	 * certificate, which we don't include in s3_srvr.c */
-	x=sk_X509_value(sk,0);
-	sk=NULL;
- 	/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
+  sc->cert_chain = sk;
+  /* Inconsistency alert: cert_chain does include the peer's certificate, which
+   * we don't include in s3_srvr.c */
+  x = sk_X509_value(sk, 0);
+  sk = NULL;
+  /* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
 
-	pkey=X509_get_pubkey(x);
+  pkey = X509_get_pubkey(x);
 
-	if ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))
-		{
-		x=NULL;
-		al=SSL3_AL_FATAL;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
-		goto f_err;
-		}
+  if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) {
+    x = NULL;
+    al = SSL3_AL_FATAL;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                      SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
+    goto f_err;
+  }
 
-	i = ssl_cert_type(pkey);
-	if (i < 0)
-		{
-		x=NULL;
-		al=SSL3_AL_FATAL;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
-		goto f_err;
-		}
+  i = ssl_cert_type(pkey);
+  if (i < 0) {
+    x = NULL;
+    al = SSL3_AL_FATAL;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                      SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+    goto f_err;
+  }
 
-	int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
-	if (exp_idx >= 0 && i != exp_idx)
-		{
-		x=NULL;
-		al=SSL_AD_ILLEGAL_PARAMETER;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_WRONG_CERTIFICATE_TYPE);
-		goto f_err;
-		}
-	sc->peer_cert_type=i;
-	/* Why would the following ever happen?
-	 * We just created sc a couple of lines ago. */
-	if (sc->peer_pkeys[i].x509 != NULL)
-		X509_free(sc->peer_pkeys[i].x509);
-	sc->peer_pkeys[i].x509 = X509_up_ref(x);
-	sc->peer_key = &(sc->peer_pkeys[i]);
+  int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+  if (exp_idx >= 0 && i != exp_idx) {
+    x = NULL;
+    al = SSL_AD_ILLEGAL_PARAMETER;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
+                      SSL_R_WRONG_CERTIFICATE_TYPE);
+    goto f_err;
+  }
+  sc->peer_cert_type = i;
+  /* Why would the following ever happen? We just created sc a couple of lines
+   * ago. */
+  if (sc->peer_pkeys[i].x509 != NULL) {
+    X509_free(sc->peer_pkeys[i].x509);
+  }
+  sc->peer_pkeys[i].x509 = X509_up_ref(x);
+  sc->peer_key = &(sc->peer_pkeys[i]);
 
-	if (s->session->peer != NULL)
-		X509_free(s->session->peer);
-	s->session->peer = X509_up_ref(x);
+  if (s->session->peer != NULL) {
+    X509_free(s->session->peer);
+  }
+  s->session->peer = X509_up_ref(x);
 
-	s->session->verify_result = s->verify_result;
+  s->session->verify_result = s->verify_result;
 
-	x=NULL;
-	ret=1;
-	if (0)
-		{
+  x = NULL;
+  ret = 1;
+
+  if (0) {
+  f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+  }
+
+err:
+  EVP_PKEY_free(pkey);
+  X509_free(x);
+  sk_X509_pop_free(sk, X509_free);
+  return ret;
+}
+
+int ssl3_get_server_key_exchange(SSL *s) {
+  EVP_MD_CTX md_ctx;
+  int al, ok;
+  long n, alg_k, alg_a;
+  EVP_PKEY *pkey = NULL;
+  const EVP_MD *md = NULL;
+  RSA *rsa = NULL;
+  DH *dh = NULL;
+  EC_KEY *ecdh = NULL;
+  BN_CTX *bn_ctx = NULL;
+  EC_POINT *srvr_ecpoint = NULL;
+  CBS server_key_exchange, server_key_exchange_orig, parameter;
+
+  /* use same message size as in ssl3_get_certificate_request() as
+   * ServerKeyExchange message may be skipped */
+  n = s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A,
+                                 SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list,
+                                 SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
+  if (!ok) {
+    return n;
+  }
+
+  if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
+    if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        SSL_R_UNEXPECTED_MESSAGE);
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+      return -1;
+    }
+
+    /* In plain PSK ciphersuite, ServerKeyExchange can be
+       omitted if no identity hint is sent. Set session->sess_cert anyway to
+       avoid problems later.*/
+    if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) {
+      /* PSK ciphersuites that also send a Certificate would have already
+       * initialized |sess_cert|. */
+      if (s->session->sess_cert == NULL) {
+        s->session->sess_cert = ssl_sess_cert_new();
+      }
+
+      /* TODO(davidben): This should be reset in one place with the rest of the
+       * handshake state. */
+      if (s->s3->tmp.peer_psk_identity_hint) {
+        OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
+        s->s3->tmp.peer_psk_identity_hint = NULL;
+      }
+    }
+    s->s3->tmp.reuse_message = 1;
+    return 1;
+  }
+
+  /* Retain a copy of the original CBS to compute the signature over. */
+  CBS_init(&server_key_exchange, s->init_msg, n);
+  server_key_exchange_orig = server_key_exchange;
+
+  if (s->session->sess_cert != NULL) {
+    if (s->session->sess_cert->peer_dh_tmp) {
+      DH_free(s->session->sess_cert->peer_dh_tmp);
+      s->session->sess_cert->peer_dh_tmp = NULL;
+    }
+    if (s->session->sess_cert->peer_ecdh_tmp) {
+      EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
+      s->session->sess_cert->peer_ecdh_tmp = NULL;
+    }
+  } else {
+    s->session->sess_cert = ssl_sess_cert_new();
+  }
+
+  alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+  alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+  EVP_MD_CTX_init(&md_ctx);
+
+  if (alg_a & SSL_aPSK) {
+    CBS psk_identity_hint;
+
+    /* Each of the PSK key exchanges begins with a psk_identity_hint. */
+    if (!CBS_get_u16_length_prefixed(&server_key_exchange,
+                                     &psk_identity_hint)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+      goto f_err;
+    }
+
+    /* Store PSK identity hint for later use, hint is used in
+     * ssl3_send_client_key_exchange.  Assume that the maximum length of a PSK
+     * identity hint can be as long as the maximum length of a PSK identity.
+     * Also do not allow NULL characters; identities are saved as C strings.
+     *
+     * TODO(davidben): Should invalid hints be ignored? It's a hint rather than
+     * a specific identity. */
+    if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
+        CBS_contains_zero_byte(&psk_identity_hint)) {
+      al = SSL_AD_HANDSHAKE_FAILURE;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        SSL_R_DATA_LENGTH_TOO_LONG);
+      goto f_err;
+    }
+
+    /* Save the identity hint as a C string. */
+    if (!CBS_strdup(&psk_identity_hint, &s->s3->tmp.peer_psk_identity_hint)) {
+      al = SSL_AD_INTERNAL_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        ERR_R_MALLOC_FAILURE);
+      goto f_err;
+    }
+  }
+
+  if (alg_k & SSL_kEDH) {
+    CBS dh_p, dh_g, dh_Ys;
+
+    if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) ||
+        CBS_len(&dh_p) == 0 ||
+        !CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) ||
+        CBS_len(&dh_g) == 0 ||
+        !CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
+        CBS_len(&dh_Ys) == 0) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+      goto f_err;
+    }
+
+    dh = DH_new();
+    if (dh == NULL) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_DH_LIB);
+      goto err;
+    }
+
+    if ((dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL ||
+        (dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL ||
+        (dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)) ==
+            NULL) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
+      goto err;
+    }
+
+    if (DH_size(dh) < 512 / 8) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        SSL_R_BAD_DH_P_LENGTH);
+      goto err;
+    }
+
+    if (alg_a & SSL_aRSA) {
+      pkey = X509_get_pubkey(
+          s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+    }
+    /* else anonymous DH, so no certificate or pkey. */
+
+    s->session->sess_cert->peer_dh_tmp = dh;
+    dh = NULL;
+  } else if (alg_k & SSL_kEECDH) {
+    uint16_t curve_id;
+    int curve_nid = 0;
+    EC_GROUP *ngroup;
+    const EC_GROUP *group;
+    CBS point;
+
+    /* Extract elliptic curve parameters and the server's ephemeral ECDH public
+     * key.  Check curve is one of our preferences, if not server has sent an
+     * invalid curve. */
+    if (!tls1_check_curve(s, &server_key_exchange, &curve_id)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_WRONG_CURVE);
+      goto f_err;
+    }
+
+    curve_nid = tls1_ec_curve_id2nid(curve_id);
+    if (curve_nid == 0) {
+      al = SSL_AD_INTERNAL_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+      goto f_err;
+    }
+
+    ecdh = EC_KEY_new();
+    if (ecdh == NULL) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+
+    ngroup = EC_GROUP_new_by_curve_name(curve_nid);
+    if (ngroup == NULL ||
+        EC_KEY_set_group(ecdh, ngroup) == 0) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB);
+      goto err;
+    }
+    EC_GROUP_free(ngroup);
+
+    group = EC_KEY_get0_group(ecdh);
+
+    /* Next, get the encoded ECPoint */
+    if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+      goto f_err;
+    }
+
+    if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
+        ((bn_ctx = BN_CTX_new()) == NULL)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+
+    if (!EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&point),
+                            CBS_len(&point), bn_ctx)) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_ECPOINT);
+      goto f_err;
+    }
+
+    /* The ECC/TLS specification does not mention the use of DSA to sign
+     * ECParameters in the server key exchange message. We do support RSA and
+     * ECDSA. */
+    if (alg_a & SSL_aRSA) {
+      pkey = X509_get_pubkey(
+          s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+    } else if (alg_a & SSL_aECDSA) {
+      pkey =
+          X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
+    }
+    /* else anonymous ECDH, so no certificate or pkey. */
+    EC_KEY_set_public_key(ecdh, srvr_ecpoint);
+    s->session->sess_cert->peer_ecdh_tmp = ecdh;
+    ecdh = NULL;
+    BN_CTX_free(bn_ctx);
+    bn_ctx = NULL;
+    EC_POINT_free(srvr_ecpoint);
+    srvr_ecpoint = NULL;
+  } else if (!(alg_k & SSL_kPSK)) {
+    al = SSL_AD_UNEXPECTED_MESSAGE;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                      SSL_R_UNEXPECTED_MESSAGE);
+    goto f_err;
+  }
+
+  /* At this point, |server_key_exchange| contains the signature, if any, while
+   * |server_key_exchange_orig| contains the entire message. From that, derive
+   * a CBS containing just the parameter. */
+  CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
+           CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
+
+  /* if it was signed, check the signature */
+  if (pkey != NULL) {
+    CBS signature;
+
+    if (SSL_USE_SIGALGS(s)) {
+      if (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey)) {
+        goto f_err;
+      }
+    } else if (pkey->type == EVP_PKEY_RSA) {
+      md = EVP_md5_sha1();
+    } else {
+      md = EVP_sha1();
+    }
+
+    /* The last field in |server_key_exchange| is the signature. */
+    if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
+        CBS_len(&server_key_exchange) != 0) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+      goto f_err;
+    }
+
+    if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) ||
+        !EVP_DigestVerifyUpdate(&md_ctx, s->s3->client_random,
+                                SSL3_RANDOM_SIZE) ||
+        !EVP_DigestVerifyUpdate(&md_ctx, s->s3->server_random,
+                                SSL3_RANDOM_SIZE) ||
+        !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter),
+                                CBS_len(&parameter)) ||
+        !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
+                               CBS_len(&signature))) {
+      /* bad signature */
+      al = SSL_AD_DECRYPT_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
+      goto f_err;
+    }
+  } else {
+    if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+      /* Might be wrong key type, check it */
+      if (ssl3_check_cert_and_algorithm(s)) {
+        /* Otherwise this shouldn't happen */
+        OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+      }
+      goto err;
+    }
+    /* still data left over */
+    if (CBS_len(&server_key_exchange) > 0) {
+      al = SSL_AD_DECODE_ERROR;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
+                        SSL_R_EXTRA_DATA_IN_MESSAGE);
+      goto f_err;
+    }
+  }
+  EVP_PKEY_free(pkey);
+  EVP_MD_CTX_cleanup(&md_ctx);
+  return 1;
+
 f_err:
-		ssl3_send_alert(s,SSL3_AL_FATAL,al);
-		}
+  ssl3_send_alert(s, SSL3_AL_FATAL, al);
 err:
-	EVP_PKEY_free(pkey);
-	X509_free(x);
-	sk_X509_pop_free(sk,X509_free);
-	return(ret);
-	}
+  EVP_PKEY_free(pkey);
+  if (rsa != NULL) {
+    RSA_free(rsa);
+  }
+  if (dh != NULL) {
+    DH_free(dh);
+  }
+  BN_CTX_free(bn_ctx);
+  EC_POINT_free(srvr_ecpoint);
+  if (ecdh != NULL) {
+    EC_KEY_free(ecdh);
+  }
+  EVP_MD_CTX_cleanup(&md_ctx);
+  return -1;
+}
 
-int ssl3_get_server_key_exchange(SSL *s)
-	{
-	EVP_MD_CTX md_ctx;
-	int al,ok;
-	long n,alg_k,alg_a;
-	EVP_PKEY *pkey=NULL;
-	const EVP_MD *md = NULL;
-	RSA *rsa=NULL;
-	DH *dh=NULL;
-	EC_KEY *ecdh = NULL;
-	BN_CTX *bn_ctx = NULL;
-	EC_POINT *srvr_ecpoint = NULL;
-	CBS server_key_exchange, server_key_exchange_orig, parameter;
+static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b) {
+  return X509_NAME_cmp(*a, *b);
+}
 
-	/* use same message size as in ssl3_get_certificate_request()
-	 * as ServerKeyExchange message may be skipped */
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_KEY_EXCH_A,
-		SSL3_ST_CR_KEY_EXCH_B,
-		-1,
-		s->max_cert_list,
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
-	if (!ok) return((int)n);
+int ssl3_get_certificate_request(SSL *s) {
+  int ok, ret = 0;
+  unsigned long n;
+  X509_NAME *xn = NULL;
+  STACK_OF(X509_NAME) *ca_sk = NULL;
+  CBS cbs;
+  CBS certificate_types;
+  CBS certificate_authorities;
+  const uint8_t *data;
 
-	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
-		{
-		if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
-			ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
-			return -1;
-			}
+  n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A,
+                                 SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list,
+                                 SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-		/* In plain PSK ciphersuite, ServerKeyExchange can be
-		   omitted if no identity hint is sent. Set
-		   session->sess_cert anyway to avoid problems
-		   later.*/
-		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)
-			{
-			/* PSK ciphersuites that also send a
-			 * Certificate would have already initialized
-			 * |sess_cert|. */
-			if (s->session->sess_cert == NULL)
-				s->session->sess_cert = ssl_sess_cert_new();
+  if (!ok) {
+    return n;
+  }
 
-			/* TODO(davidben): This should be reset in one place
-			 * with the rest of the handshake state. */
-			if (s->s3->tmp.peer_psk_identity_hint)
-				{
-				OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
-				s->s3->tmp.peer_psk_identity_hint = NULL;
-				}
-			}
-		s->s3->tmp.reuse_message=1;
-		return(1);
-		}
+  s->s3->tmp.cert_req = 0;
 
-	/* Retain a copy of the original CBS to compute the signature
-	 * over. */
-	CBS_init(&server_key_exchange, s->init_msg, n);
-	server_key_exchange_orig = server_key_exchange;
+  if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) {
+    s->s3->tmp.reuse_message = 1;
+    /* If we get here we don't need any cached handshake records as we wont be
+     * doing client auth. */
+    if (s->s3->handshake_buffer &&
+        !ssl3_digest_cached_records(s, free_handshake_buffer)) {
+      goto err;
+    }
+    return 1;
+  }
 
-	if (s->session->sess_cert != NULL)
-		{
-		if (s->session->sess_cert->peer_dh_tmp)
-			{
-			DH_free(s->session->sess_cert->peer_dh_tmp);
-			s->session->sess_cert->peer_dh_tmp=NULL;
-			}
-		if (s->session->sess_cert->peer_ecdh_tmp)
-			{
-			EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
-			s->session->sess_cert->peer_ecdh_tmp=NULL;
-			}
-		}
-	else
-		{
-		s->session->sess_cert=ssl_sess_cert_new();
-		}
+  if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                      SSL_R_WRONG_MESSAGE_TYPE);
+    goto err;
+  }
 
-	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
-	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
-	EVP_MD_CTX_init(&md_ctx);
+  /* TLS does not like anon-DH with client cert */
+  if (s->version > SSL3_VERSION &&
+      (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) {
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                      SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
+    goto err;
+  }
 
-	if (alg_a & SSL_aPSK)
-		{
-		CBS psk_identity_hint;
+  CBS_init(&cbs, s->init_msg, n);
 
-		/* Each of the PSK key exchanges begins with a
-		 * psk_identity_hint. */
-		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &psk_identity_hint))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
-			goto f_err;
-			}
+  ca_sk = sk_X509_NAME_new(ca_dn_cmp);
+  if (ca_sk == NULL) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
 
-		/* Store PSK identity hint for later use, hint is used in
-		 * ssl3_send_client_key_exchange.  Assume that the maximum
-		 * length of a PSK identity hint can be as long as the maximum
-		 * length of a PSK identity. Also do not allow NULL
-		 * characters; identities are saved as C strings.
-		 *
-		 * TODO(davidben): Should invalid hints be ignored? It's a hint
-		 * rather than a specific identity. */
-		if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
-			CBS_contains_zero_byte(&psk_identity_hint))
-			{
-			al = SSL_AD_HANDSHAKE_FAILURE;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DATA_LENGTH_TOO_LONG);
-			goto f_err;
-			}
+  /* get the certificate types */
+  if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
+    goto err;
+  }
 
-		/* Save the identity hint as a C string. */
-		if (!CBS_strdup(&psk_identity_hint, &s->s3->tmp.peer_psk_identity_hint))
-			{
-			al = SSL_AD_INTERNAL_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
-			goto f_err;
-			}
-		}
+  if (!CBS_stow(&certificate_types, &s->s3->tmp.certificate_types,
+                &s->s3->tmp.num_certificate_types)) {
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+    goto err;
+  }
 
-	if (alg_k & SSL_kEDH)
-		{
-		CBS dh_p, dh_g, dh_Ys;
+  if (SSL_USE_SIGALGS(s)) {
+    CBS supported_signature_algorithms;
+    if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms)) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
+      goto err;
+    }
 
-		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) ||
-			CBS_len(&dh_p) == 0 ||
-			!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) ||
-			CBS_len(&dh_g) == 0 ||
-			!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
-			CBS_len(&dh_Ys) == 0)
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
-			goto f_err;
-			}
+    if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                        SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+      goto err;
+    }
+  }
 
-		if ((dh=DH_new()) == NULL)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_DH_LIB);
-			goto err;
-			}
+  /* get the CA RDNs */
+  if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_LENGTH_MISMATCH);
+    goto err;
+  }
 
-		if (!(dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
-			goto err;
-			}
-		if (!(dh->g=BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
-			goto err;
-			}
-		if (!(dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
-			goto err;
-			}
+  while (CBS_len(&certificate_authorities) > 0) {
+    CBS distinguished_name;
+    if (!CBS_get_u16_length_prefixed(&certificate_authorities,
+                                     &distinguished_name)) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                        SSL_R_CA_DN_TOO_LONG);
+      goto err;
+    }
 
-		if (DH_size(dh) < 512/8)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_DH_P_LENGTH);
-			goto err;
-			}
+    data = CBS_data(&distinguished_name);
 
-		if (alg_a & SSL_aRSA)
-			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
-		/* else anonymous DH, so no certificate or pkey. */
+    xn = d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name));
+    if (xn == NULL) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_ASN1_LIB);
+      goto err;
+    }
 
-		s->session->sess_cert->peer_dh_tmp=dh;
-		dh=NULL;
-		}
+    if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_INTERNAL_ERROR);
+      goto err;
+    }
 
-	else if (alg_k & SSL_kEECDH)
-		{
-		uint16_t curve_id;
-		int curve_nid = 0;
-		EC_GROUP *ngroup;
-		const EC_GROUP *group;
-		CBS point;
+    if (CBS_len(&distinguished_name) != 0) {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                        SSL_R_CA_DN_LENGTH_MISMATCH);
+      goto err;
+    }
 
-		/* Extract elliptic curve parameters and the server's
-		 * ephemeral ECDH public key.  Check curve is one of
-		 * our preferences, if not server has sent an invalid
-		 * curve.
-		 */
-		if (!tls1_check_curve(s, &server_key_exchange, &curve_id))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_WRONG_CURVE);
-			goto f_err;
-			}
+    if (!sk_X509_NAME_push(ca_sk, xn)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
+                        ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+  }
 
-		if ((curve_nid = tls1_ec_curve_id2nid(curve_id)) == 0)
-			{
-			al=SSL_AD_INTERNAL_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
-			goto f_err;
-			}
+  /* we should setup a certificate to return.... */
+  s->s3->tmp.cert_req = 1;
+  if (s->s3->tmp.ca_names != NULL) {
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+  }
+  s->s3->tmp.ca_names = ca_sk;
+  ca_sk = NULL;
 
-		if ((ecdh=EC_KEY_new()) == NULL)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		ngroup = EC_GROUP_new_by_curve_name(curve_nid);
-		if (ngroup == NULL)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB);
-			goto err;
-			}
-		if (EC_KEY_set_group(ecdh, ngroup) == 0)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB);
-			goto err;
-			}
-		EC_GROUP_free(ngroup);
+  ret = 1;
 
-		group = EC_KEY_get0_group(ecdh);
+err:
+  if (ca_sk != NULL) {
+    sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
+  }
+  return ret;
+}
 
-		/* Next, get the encoded ECPoint */
-		if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
-			goto f_err;
-			}
+int ssl3_get_new_session_ticket(SSL *s) {
+  int ok, al, ret = 0;
+  long n;
+  CBS new_session_ticket, ticket;
 
-		if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
-		    ((bn_ctx = BN_CTX_new()) == NULL))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
+  n = s->method->ssl_get_message(
+      s, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B,
+      SSL3_MT_NEWSESSION_TICKET, 16384, SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-		if (!EC_POINT_oct2point(group, srvr_ecpoint,
-				CBS_data(&point), CBS_len(&point), bn_ctx))
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_ECPOINT);
-			goto f_err;
-			}
+  if (!ok) {
+    return n;
+  }
 
-		/* The ECC/TLS specification does not mention
-		 * the use of DSA to sign ECParameters in the server
-		 * key exchange message. We do support RSA and ECDSA.
-		 */
-		if (0) ;
-		else if (alg_a & SSL_aRSA)
-			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
-		else if (alg_a & SSL_aECDSA)
-			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
-		/* else anonymous ECDH, so no certificate or pkey. */
-		EC_KEY_set_public_key(ecdh, srvr_ecpoint);
-		s->session->sess_cert->peer_ecdh_tmp=ecdh;
-		ecdh=NULL;
-		BN_CTX_free(bn_ctx);
-		bn_ctx = NULL;
-		EC_POINT_free(srvr_ecpoint);
-		srvr_ecpoint = NULL;
-		}
+  CBS_init(&new_session_ticket, s->init_msg, n);
 
-	else if (!(alg_k & SSL_kPSK))
-		{
-		al=SSL_AD_UNEXPECTED_MESSAGE;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
-		goto f_err;
-		}
+  if (!CBS_get_u32(&new_session_ticket,
+                   &s->session->tlsext_tick_lifetime_hint) ||
+      !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
+      CBS_len(&new_session_ticket) != 0) {
+    al = SSL_AD_DECODE_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, SSL_R_DECODE_ERROR);
+    goto f_err;
+  }
 
-	/* At this point, |server_key_exchange| contains the
-	 * signature, if any, while |server_key_exchange_orig|
-	 * contains the entire message. From that, derive a CBS
-	 * containing just the parameter. */
-	CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
-		CBS_len(&server_key_exchange_orig) -
-		CBS_len(&server_key_exchange));
+  if (!CBS_stow(&ticket, &s->session->tlsext_tick,
+                &s->session->tlsext_ticklen)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
 
-	/* if it was signed, check the signature */
-	if (pkey != NULL)
-		{
-		CBS signature;
+  /* There are two ways to detect a resumed ticket sesion. One is to set an
+   * appropriate session ID and then the server must return a match in
+   * ServerHello. This allows the normal client session ID matching to work and
+   * we know much earlier that the ticket has been accepted.
+   *
+   * The other way is to set zero length session ID when the ticket is
+   * presented and rely on the handshake to determine session resumption.
+   *
+   * We choose the former approach because this fits in with assumptions
+   * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is
+   * SHA256 is disabled) hash of the ticket. */
+  EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), s->session->session_id,
+             &s->session->session_id_length, EVP_sha256(), NULL);
+  ret = 1;
+  return ret;
 
-		if (SSL_USE_SIGALGS(s))
-			{
-			if (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey))
-				goto f_err;
-			}
-		else if (pkey->type == EVP_PKEY_RSA)
-			{
-			md = EVP_md5_sha1();
-			}
-		else
-			{
-			md = EVP_sha1();
-			}
-
-		/* The last field in |server_key_exchange| is the
-		 * signature. */
-		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
-			CBS_len(&server_key_exchange) != 0)
-			{
-			al = SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
-			goto f_err;
-			}
-
-		if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) ||
-			!EVP_DigestVerifyUpdate(&md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) ||
-			!EVP_DigestVerifyUpdate(&md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) ||
-			!EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&parameter), CBS_len(&parameter)) ||
-			!EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature), CBS_len(&signature)))
-			{
-			/* bad signature */
-			al=SSL_AD_DECRYPT_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
-			goto f_err;
-			}
-		}
-	else
-		{
-		if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
-			{
-			/* Might be wrong key type, check it */
-			if (ssl3_check_cert_and_algorithm(s))
-				/* Otherwise this shouldn't happen */
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_INTERNAL_ERROR);
-			goto err;
-			}
-		/* still data left over */
-		if (CBS_len(&server_key_exchange) > 0)
-			{
-			al=SSL_AD_DECODE_ERROR;
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_EXTRA_DATA_IN_MESSAGE);
-			goto f_err;
-			}
-		}
-	EVP_PKEY_free(pkey);
-	EVP_MD_CTX_cleanup(&md_ctx);
-	return(1);
 f_err:
-	ssl3_send_alert(s,SSL3_AL_FATAL,al);
+  ssl3_send_alert(s, SSL3_AL_FATAL, al);
 err:
-	EVP_PKEY_free(pkey);
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (dh != NULL)
-		DH_free(dh);
-	BN_CTX_free(bn_ctx);
-	EC_POINT_free(srvr_ecpoint);
-	if (ecdh != NULL)
-		EC_KEY_free(ecdh);
-	EVP_MD_CTX_cleanup(&md_ctx);
-	return(-1);
-	}
+  return -1;
+}
 
-static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b)
-	{
-	return(X509_NAME_cmp(*a,*b));
-	}
+int ssl3_get_cert_status(SSL *s) {
+  int ok, al;
+  long n;
+  CBS certificate_status, ocsp_response;
+  uint8_t status_type;
 
-int ssl3_get_certificate_request(SSL *s)
-	{
-	int ok,ret=0;
-	unsigned long n;
-	X509_NAME *xn=NULL;
-	STACK_OF(X509_NAME) *ca_sk=NULL;
-	CBS cbs;
-	CBS certificate_types;
-	CBS certificate_authorities;
-	const uint8_t *data;
+  n = s->method->ssl_get_message(
+      s, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B,
+      SSL3_MT_CERTIFICATE_STATUS, 16384, SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_CERT_REQ_A,
-		SSL3_ST_CR_CERT_REQ_B,
-		-1,
-		s->max_cert_list,
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
+  if (!ok) {
+    return n;
+  }
 
-	if (!ok) return((int)n);
+  CBS_init(&certificate_status, s->init_msg, n);
+  if (!CBS_get_u8(&certificate_status, &status_type) ||
+      status_type != TLSEXT_STATUSTYPE_ocsp ||
+      !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) ||
+      CBS_len(&ocsp_response) == 0 ||
+      CBS_len(&certificate_status) != 0) {
+    al = SSL_AD_DECODE_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_DECODE_ERROR);
+    goto f_err;
+  }
 
-	s->s3->tmp.cert_req=0;
+  if (!CBS_stow(&ocsp_response, &s->session->ocsp_response,
+                &s->session->ocsp_response_length)) {
+    al = SSL_AD_INTERNAL_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
+    goto f_err;
+  }
+  return 1;
 
-	if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
-		{
-		s->s3->tmp.reuse_message=1;
-		/* If we get here we don't need any cached handshake records
-		 * as we wont be doing client auth.
-		 */
-		if (s->s3->handshake_buffer)
-			{
-			if (!ssl3_digest_cached_records(s, free_handshake_buffer))
-				goto err;
-			}
-		return(1);
-		}
-
-	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST)
-		{
-		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_WRONG_MESSAGE_TYPE);
-		goto err;
-		}
-
-	/* TLS does not like anon-DH with client cert */
-	if (s->version > SSL3_VERSION)
-		{
-		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
-			goto err;
-			}
-		}
-
-	CBS_init(&cbs, s->init_msg, n);
-
-	ca_sk = sk_X509_NAME_new(ca_dn_cmp);
-	if (ca_sk == NULL)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* get the certificate types */
-	if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types))
-		{
-		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
-		goto err;
-		}
-	if (!CBS_stow(&certificate_types,
-			&s->s3->tmp.certificate_types,
-			&s->s3->tmp.num_certificate_types))
-		{
-		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-		goto err;
-		}
-	if (SSL_USE_SIGALGS(s))
-		{
-		CBS supported_signature_algorithms;
-		if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms))
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
-			goto err;
-			}
-		if (!tls1_process_sigalgs(s, &supported_signature_algorithms))
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_SIGNATURE_ALGORITHMS_ERROR);
-			goto err;
-			}
-		}
-
-	/* get the CA RDNs */
-	if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities))
-		{
-		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_LENGTH_MISMATCH);
-		goto err;
-		}
-
-	while (CBS_len(&certificate_authorities) > 0)
-		{
-		CBS distinguished_name;
-		if (!CBS_get_u16_length_prefixed(&certificate_authorities, &distinguished_name))
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_CA_DN_TOO_LONG);
-			goto err;
-			}
-
-		data = CBS_data(&distinguished_name);
-		if ((xn=d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name))) == NULL)
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_ASN1_LIB);
-			goto err;
-			}
-
-		if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name)))
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_INTERNAL_ERROR);
-			goto err;
-			}
-		if (CBS_len(&distinguished_name) != 0)
-			{
-			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_CA_DN_LENGTH_MISMATCH);
-			goto err;
-			}
-		if (!sk_X509_NAME_push(ca_sk,xn))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* we should setup a certificate to return.... */
-	s->s3->tmp.cert_req=1;
-	if (s->s3->tmp.ca_names != NULL)
-		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
-	s->s3->tmp.ca_names=ca_sk;
-	ca_sk=NULL;
-
-	ret=1;
-err:
-	if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free);
-	return(ret);
-	}
-
-int ssl3_get_new_session_ticket(SSL *s)
-	{
-	int ok,al,ret=0;
-	long n;
-	CBS new_session_ticket, ticket;
-
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_SESSION_TICKET_A,
-		SSL3_ST_CR_SESSION_TICKET_B,
-		SSL3_MT_NEWSESSION_TICKET,
-		16384,
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
-
-	if (!ok)
-		return((int)n);
-
-	CBS_init(&new_session_ticket, s->init_msg, n);
-
-	if (!CBS_get_u32(&new_session_ticket, &s->session->tlsext_tick_lifetime_hint) ||
-		!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
-		CBS_len(&new_session_ticket) != 0)
-		{
-		al = SSL_AD_DECODE_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, SSL_R_DECODE_ERROR);
-		goto f_err;
-		}
-
-	if (!CBS_stow(&ticket, &s->session->tlsext_tick, &s->session->tlsext_ticklen))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* There are two ways to detect a resumed ticket sesion.
-	 * One is to set an appropriate session ID and then the server
-	 * must return a match in ServerHello. This allows the normal
-	 * client session ID matching to work and we know much 
-	 * earlier that the ticket has been accepted.
-	 * 
-	 * The other way is to set zero length session ID when the
-	 * ticket is presented and rely on the handshake to determine
-	 * session resumption.
-	 *
-	 * We choose the former approach because this fits in with
-	 * assumptions elsewhere in OpenSSL. The session ID is set
-	 * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the
-	 * ticket.
-	 */ 
-	EVP_Digest(CBS_data(&ticket), CBS_len(&ticket),
-			s->session->session_id, &s->session->session_id_length,
-							EVP_sha256(), NULL);
-	ret=1;
-	return(ret);
 f_err:
-	ssl3_send_alert(s,SSL3_AL_FATAL,al);
-err:
-	return(-1);
-	}
+  ssl3_send_alert(s, SSL3_AL_FATAL, al);
+  return -1;
+}
 
-int ssl3_get_cert_status(SSL *s)
-	{
-	int ok, al;
-	long n;
-	CBS certificate_status, ocsp_response;
-	uint8_t status_type;
+int ssl3_get_server_done(SSL *s) {
+  int ok;
+  long n;
 
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_CERT_STATUS_A,
-		SSL3_ST_CR_CERT_STATUS_B,
-		SSL3_MT_CERTIFICATE_STATUS,
-		16384,
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
+  n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A,
+                                 SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE,
+                                 30, /* should be very small, like 0 :-) */
+                                 SSL_GET_MESSAGE_HASH_MESSAGE, &ok);
 
-	if (!ok) return((int)n);
+  if (!ok) {
+    return n;
+  }
 
-	CBS_init(&certificate_status, s->init_msg, n);
-	if (!CBS_get_u8(&certificate_status, &status_type) ||
-		status_type != TLSEXT_STATUSTYPE_ocsp ||
-		!CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) ||
-		CBS_len(&ocsp_response) == 0 ||
-		CBS_len(&certificate_status) != 0)
-		{
-		al = SSL_AD_DECODE_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_DECODE_ERROR);
-		goto f_err;
-		}
+  if (n > 0) {
+    /* should contain no data */
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_server_done, SSL_R_LENGTH_MISMATCH);
+    return -1;
+  }
 
-	if (!CBS_stow(&ocsp_response,
-			&s->session->ocsp_response, &s->session->ocsp_response_length))
-		{
-		al = SSL_AD_INTERNAL_ERROR;
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
-		goto f_err;
-		}
-	return 1;
-f_err:
-	ssl3_send_alert(s,SSL3_AL_FATAL,al);
-	return(-1);
-	}
-
-int ssl3_get_server_done(SSL *s)
-	{
-	int ok,ret=0;
-	long n;
-
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_CR_SRVR_DONE_A,
-		SSL3_ST_CR_SRVR_DONE_B,
-		SSL3_MT_SERVER_DONE,
-		30, /* should be very small, like 0 :-) */
-		SSL_GET_MESSAGE_HASH_MESSAGE,
-		&ok);
-
-	if (!ok) return((int)n);
-	if (n > 0)
-		{
-		/* should contain no data */
-		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
-		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_done, SSL_R_LENGTH_MISMATCH);
-		return -1;
-		}
-	ret=1;
-	return(ret);
-	}
-
-
-int ssl3_send_client_key_exchange(SSL *s)
-	{
-	unsigned char *p;
-	int n = 0;
-	unsigned long alg_k;
-	unsigned long alg_a;
-	unsigned char *q;
-	EVP_PKEY *pkey=NULL;
-	EC_KEY *clnt_ecdh = NULL;
-	const EC_POINT *srvr_ecpoint = NULL;
-	EVP_PKEY *srvr_pub_pkey = NULL;
-	unsigned char *encodedPoint = NULL;
-	int encoded_pt_len = 0;
-	BN_CTX * bn_ctx = NULL;
-	unsigned int psk_len = 0;
-	unsigned char psk[PSK_MAX_PSK_LEN];
-	uint8_t *pms = NULL;
-	size_t pms_len = 0;
-
-	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
-		{
-		p = ssl_handshake_start(s);
-
-		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
-		alg_a=s->s3->tmp.new_cipher->algorithm_auth;
-
-		/* If using a PSK key exchange, prepare the pre-shared key. */
-		if (alg_a & SSL_aPSK)
-			{
-			char identity[PSK_MAX_IDENTITY_LEN + 1];
-			size_t identity_len;
-
-			if (s->psk_client_callback == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_PSK_NO_CLIENT_CB);
-				goto err;
-				}
-
-			memset(identity, 0, sizeof(identity));
-			psk_len = s->psk_client_callback(s, s->s3->tmp.peer_psk_identity_hint,
-				identity, sizeof(identity), psk, sizeof(psk));
-			if (psk_len > PSK_MAX_PSK_LEN)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			else if (psk_len == 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_PSK_IDENTITY_NOT_FOUND);
-				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-				goto err;
-				}
-			identity_len = OPENSSL_strnlen(identity, sizeof(identity));
-			if (identity_len > PSK_MAX_IDENTITY_LEN)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-
-			if (s->session->psk_identity != NULL)
-				OPENSSL_free(s->session->psk_identity);
-			s->session->psk_identity = BUF_strdup(identity);
-			if (s->session->psk_identity == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			/* Write out psk_identity. */
-			s2n(identity_len, p);
-			memcpy(p, identity, identity_len);
-			p += identity_len;
-			n = 2 + identity_len;
-			}
-
-		/* Depending on the key exchange method, compute |pms|
-		 * and |pms_len|. */
-		if (alg_k & SSL_kRSA)
-			{
-			RSA *rsa;
-			size_t enc_pms_len;
-
-			pms_len = SSL_MAX_MASTER_KEY_LENGTH;
-			pms = OPENSSL_malloc(pms_len);
-			if (pms == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			if (s->session->sess_cert == NULL)
-				{
-				/* We should always have a server certificate with SSL_kRSA. */
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-
-			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
-			if ((pkey == NULL) ||
-				(pkey->type != EVP_PKEY_RSA) ||
-				(pkey->pkey.rsa == NULL))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				if (pkey != NULL)
-					EVP_PKEY_free(pkey);
-				goto err;
-				}
-			rsa=pkey->pkey.rsa;
-			EVP_PKEY_free(pkey);
-				
-			pms[0]=s->client_version>>8;
-			pms[1]=s->client_version&0xff;
-			if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2))
-				goto err;
-
-			s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
-
-			q=p;
-			/* In TLS and beyond, reserve space for the length prefix. */
-			if (s->version > SSL3_VERSION)
-				{
-				p += 2;
-				n += 2;
-				}
-			if (!RSA_encrypt(rsa, &enc_pms_len, p, RSA_size(rsa),
-					pms, pms_len, RSA_PKCS1_PADDING))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_BAD_RSA_ENCRYPT);
-				goto err;
-				}
-			n += enc_pms_len;
-
-			/* Log the premaster secret, if logging is enabled. */
-			if (!ssl_ctx_log_rsa_client_key_exchange(s->ctx,
-					p, enc_pms_len, pms, pms_len))
-				{
-				goto err;
-				}
-
-			/* Fill in the length prefix. */
-			if (s->version > SSL3_VERSION)
-				{
-				s2n(enc_pms_len, q);
-				}
-			}
-		else if (alg_k & SSL_kEDH)
-			{
-			DH *dh_srvr, *dh_clnt;
-			SESS_CERT *scert = s->session->sess_cert;
-			int dh_len;
-			size_t pub_len;
-
-			if (scert == NULL) 
-				{
-				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
-				goto err;
-				}
-
-			if (scert->peer_dh_tmp == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			dh_srvr=scert->peer_dh_tmp;
-
-			/* generate a new random key */
-			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
-				goto err;
-				}
-			if (!DH_generate_key(dh_clnt))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
-				DH_free(dh_clnt);
-				goto err;
-				}
-
-			pms_len = DH_size(dh_clnt);
-			pms = OPENSSL_malloc(pms_len);
-			if (pms == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				DH_free(dh_clnt);
-				goto err;
-				}
-
-			dh_len = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt);
-			if (dh_len <= 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
-				DH_free(dh_clnt);
-				goto err;
-				}
-			pms_len = dh_len;
-
-			/* send off the data */
-			pub_len = BN_num_bytes(dh_clnt->pub_key);
-			s2n(pub_len, p);
-			BN_bn2bin(dh_clnt->pub_key, p);
-			n += 2 + pub_len;
-
-			DH_free(dh_clnt);
-			}
-
-		else if (alg_k & SSL_kEECDH)
-			{
-			const EC_GROUP *srvr_group = NULL;
-			EC_KEY *tkey;
-			int field_size = 0, ecdh_len;
-
-			if (s->session->sess_cert == NULL) 
-				{
-				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
-				goto err;
-				}
-
-			if (s->session->sess_cert->peer_ecdh_tmp == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			tkey = s->session->sess_cert->peer_ecdh_tmp;
-
-			srvr_group   = EC_KEY_get0_group(tkey);
-			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
-
-			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-
-			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
-				goto err;
-				}
-			/* Generate a new ECDH key pair */
-			if (!(EC_KEY_generate_key(clnt_ecdh)))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
-				goto err;
-				}
-
-			field_size = EC_GROUP_get_degree(srvr_group);
-			if (field_size <= 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
-				goto err;
-				}
-
-			pms_len = (field_size + 7) / 8;
-			pms = OPENSSL_malloc(pms_len);
-			if (pms == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			ecdh_len = ECDH_compute_key(pms, pms_len, srvr_ecpoint, clnt_ecdh, NULL);
-			if (ecdh_len <= 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
-				goto err;
-				}
-			pms_len = ecdh_len;
-
-			/* First check the size of encoding and
-			 * allocate memory accordingly.
-			 */
-			encoded_pt_len = 
-				EC_POINT_point2oct(srvr_group, 
-					EC_KEY_get0_public_key(clnt_ecdh), 
-					POINT_CONVERSION_UNCOMPRESSED, 
-					NULL, 0, NULL);
-
-			encodedPoint = (unsigned char *) 
-				OPENSSL_malloc(encoded_pt_len * 
-					sizeof(unsigned char)); 
-			bn_ctx = BN_CTX_new();
-			if ((encodedPoint == NULL) || 
-				(bn_ctx == NULL)) 
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			/* Encode the public key */
-			encoded_pt_len = EC_POINT_point2oct(srvr_group,
-				EC_KEY_get0_public_key(clnt_ecdh),
-				POINT_CONVERSION_UNCOMPRESSED,
-				encodedPoint, encoded_pt_len, bn_ctx);
-
-			*p = encoded_pt_len; /* length of encoded point */
-			/* Encoded point will be copied here */
-			p += 1;
-			n += 1;
-			/* copy the point */
-			memcpy(p, encodedPoint, encoded_pt_len);
-			/* increment n to account for length field */
-			n += encoded_pt_len;
-
-			/* Free allocated memory */
-			BN_CTX_free(bn_ctx);
-			bn_ctx = NULL;
-			OPENSSL_free(encodedPoint);
-			encodedPoint = NULL;
-			EC_KEY_free(clnt_ecdh);
-			clnt_ecdh = NULL;
-			EVP_PKEY_free(srvr_pub_pkey);
-			srvr_pub_pkey = NULL;
-			}
-		else if (alg_k & SSL_kPSK)
-			{
-			/* For plain PSK, other_secret is a block of 0s with the same
-			 * length as the pre-shared key. */
-			pms_len = psk_len;
-			pms = OPENSSL_malloc(pms_len);
-			if (pms == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			memset(pms, 0, pms_len);
-			}
-		else
-			{
-			ssl3_send_alert(s, SSL3_AL_FATAL,
-			    SSL_AD_HANDSHAKE_FAILURE);
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-			goto err;
-			}
-
-		/* For a PSK cipher suite, other_secret is combined
-		 * with the pre-shared key. */
-		if (alg_a & SSL_aPSK)
-			{
-			CBB cbb, child;
-			uint8_t *new_pms;
-			size_t new_pms_len;
-
-			if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
-				!CBB_add_bytes(&child, pms, pms_len) ||
-				!CBB_add_u16_length_prefixed(&cbb, &child) ||
-				!CBB_add_bytes(&child, psk, psk_len) ||
-				!CBB_finish(&cbb, &new_pms, &new_pms_len))
-				{
-				CBB_cleanup(&cbb);
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			OPENSSL_cleanse(pms, pms_len);
-			OPENSSL_free(pms);
-			pms = new_pms;
-			pms_len = new_pms_len;
-			}
-
-		/* The message must be added to the finished hash before
-		 * calculating the master secret. */
-		ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n);
-		s->state=SSL3_ST_CW_KEY_EXCH_B;
-
-		s->session->master_key_length =
-			s->enc_method->generate_master_secret(s,
-				s->session->master_key,
-				pms, pms_len);
-		if (s->session->master_key_length == 0)
-			{
-			goto err;
-			}
-		s->session->extended_master_secret = s->s3->tmp.extended_master_secret;
-		OPENSSL_cleanse(pms, pms_len);
-		OPENSSL_free(pms);
-		}
-
-	/* SSL3_ST_CW_KEY_EXCH_B */
-	return s->enc_method->do_write(s);
-
-err:
-	BN_CTX_free(bn_ctx);
-	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
-	if (clnt_ecdh != NULL) 
-		EC_KEY_free(clnt_ecdh);
-	EVP_PKEY_free(srvr_pub_pkey);
-	if (pms)
-		{
-		OPENSSL_cleanse(pms, pms_len);
-		OPENSSL_free(pms);
-		}
-	return -1;
-	}
-
-int ssl3_send_cert_verify(SSL *s)
-	{
-	unsigned char *buf, *p;
-	const EVP_MD *md = NULL;
-	uint8_t digest[EVP_MAX_MD_SIZE];
-	size_t digest_length;
-	EVP_PKEY *pkey;
-	EVP_PKEY_CTX *pctx = NULL;
-	size_t signature_length = 0;
-	unsigned long n = 0;
-
-	buf=(unsigned char *)s->init_buf->data;
-
-	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
-		{
-		p= ssl_handshake_start(s);
-		pkey = s->cert->key->privatekey;
-
-		/* Write out the digest type if needbe. */
-		if (SSL_USE_SIGALGS(s))
-			{
-			md = tls1_choose_signing_digest(s, pkey);
-			if (!tls12_get_sigandhash(p, pkey, md))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			p += 2;
-			n += 2;
-			}
-
-		/* Compute the digest. */
-		if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey))
-			goto err;
-
-		/* The handshake buffer is no longer necessary. */
-		if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, free_handshake_buffer))
-			goto err;
-
-		/* Sign the digest. */
-		pctx = EVP_PKEY_CTX_new(pkey, NULL);
-		if (pctx == NULL)
-			goto err;
-
-		/* Initialize the EVP_PKEY_CTX and determine the size of the signature. */
-		if (!EVP_PKEY_sign_init(pctx) ||
-			!EVP_PKEY_CTX_set_signature_md(pctx, md) ||
-			!EVP_PKEY_sign(pctx, NULL, &signature_length,
-				digest, digest_length))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
-			goto err;
-			}
-
-		if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH)
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, SSL_R_DATA_LENGTH_TOO_LONG);
-			goto err;
-			}
-
-		if (!EVP_PKEY_sign(pctx, &p[2], &signature_length,
-				digest, digest_length))
-			{
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
-			goto err;
-			}
-
-		s2n(signature_length, p);
-		n += signature_length + 2;
-
-		ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n);
-		s->state=SSL3_ST_CW_CERT_VRFY_B;
-		}
-	EVP_PKEY_CTX_free(pctx);
-	return ssl_do_write(s);
-err:
-	EVP_PKEY_CTX_free(pctx);
-	return(-1);
-	}
-
-/* ssl3_has_client_certificate returns true if a client certificate is
- * configured. */
-static int ssl3_has_client_certificate(SSL *s)
-	{
-	return s->cert && s->cert->key->x509 && s->cert->key->privatekey;
-	}
-
-int ssl3_send_client_certificate(SSL *s)
-	{
-	X509 *x509=NULL;
-	EVP_PKEY *pkey=NULL;
-	int i;
-
-	if (s->state ==	SSL3_ST_CW_CERT_A)
-		{
-		/* Let cert callback update client certificates if required */
-		if (s->cert->cert_cb)
-			{
-			i = s->cert->cert_cb(s, s->cert->cert_cb_arg);
-			if (i < 0)
-				{
-				s->rwstate=SSL_X509_LOOKUP;
-				return -1;
-				}
-			if (i == 0)
-				{
-				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
-				return 0;
-				}
-			s->rwstate=SSL_NOTHING;
-			}
-		if (ssl3_has_client_certificate(s))
-			s->state=SSL3_ST_CW_CERT_C;
-		else
-			s->state=SSL3_ST_CW_CERT_B;
-		}
-
-	/* We need to get a client cert */
-	if (s->state == SSL3_ST_CW_CERT_B)
-		{
-		/* If we get an error, we need to
-		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
-		 * We then get retried later */
-		i = ssl_do_client_cert_cb(s, &x509, &pkey);
-		if (i < 0)
-			{
-			s->rwstate=SSL_X509_LOOKUP;
-			return(-1);
-			}
-		s->rwstate=SSL_NOTHING;
-		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
-			{
-			s->state=SSL3_ST_CW_CERT_B;
-			if (	!SSL_use_certificate(s,x509) ||
-				!SSL_use_PrivateKey(s,pkey))
-				i=0;
-			}
-		else if (i == 1)
-			{
-			i=0;
-			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_certificate, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
-			}
-
-		if (x509 != NULL) X509_free(x509);
-		if (pkey != NULL) EVP_PKEY_free(pkey);
-		if (i && !ssl3_has_client_certificate(s))
-			i = 0;
-		if (i == 0)
-			{
-			if (s->version == SSL3_VERSION)
-				{
-				s->s3->tmp.cert_req=0;
-				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
-				return(1);
-				}
-			else
-				{
-				s->s3->tmp.cert_req=2;
-				}
-			}
-
-		/* Ok, we have a cert */
-		s->state=SSL3_ST_CW_CERT_C;
-		}
-
-	if (s->state == SSL3_ST_CW_CERT_C)
-		{
-		s->state=SSL3_ST_CW_CERT_D;
-		ssl3_output_cert_chain(s,
-			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key);
-		}
-	/* SSL3_ST_CW_CERT_D */
-	return ssl_do_write(s);
-	}
-
-#define has_bits(i,m)	(((i)&(m)) == (m))
-
-int ssl3_check_cert_and_algorithm(SSL *s)
-	{
-	int i,idx;
-	long alg_k,alg_a;
-	EVP_PKEY *pkey=NULL;
-	SESS_CERT *sc;
-	DH *dh;
-
-	/* we don't have a certificate */
-	if (!ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
-		return 1;
-
-	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
-	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
-
-	sc=s->session->sess_cert;
-	if (sc == NULL)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, ERR_R_INTERNAL_ERROR);
-		goto err;
-		}
-
-	dh=s->session->sess_cert->peer_dh_tmp;
-
-	/* This is the passed certificate */
-
-	idx=sc->peer_cert_type;
-	if (idx == SSL_PKEY_ECC)
-		{
-		if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
-		    						s) == 0) 
-			{ /* check failed */
-			OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_BAD_ECC_CERT);
-			goto f_err;
-			}
-		else 
-			{
-			return 1;
-			}
-		}
-	else if (alg_a & SSL_aECDSA)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_ECDSA_SIGNING_CERT);
-		goto f_err;
-		}
-	pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
-	i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
-	EVP_PKEY_free(pkey);
-
-	
-	/* Check that we have a certificate if we require one */
-	if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_RSA_SIGNING_CERT);
-		goto f_err;
-		}
-	if ((alg_k & SSL_kRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_ENC))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_RSA_ENCRYPTING_CERT);
-		goto f_err;
-		}
-	if ((alg_k & SSL_kEDH) && 
-		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_DH_KEY);
-		goto f_err;
-		}
-
-	return(1);
-f_err:
-	ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-err:
-	return(0);
-	}
-
-int ssl3_send_next_proto(SSL *s)
-	{
-	unsigned int len, padding_len;
-	uint8_t *d, *p;
-
-	if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
-		{
-		len = s->next_proto_negotiated_len;
-		padding_len = 32 - ((len + 2) % 32);
-
-		d = p = ssl_handshake_start(s);
-		*(p++) = len;
-		memcpy(p, s->next_proto_negotiated, len);
-		p += len;
-		*(p++) = padding_len;
-		memset(p, 0, padding_len);
-		p += padding_len;
-
-		ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d);
-		s->state = SSL3_ST_CW_NEXT_PROTO_B;
-		}
-
-	return ssl_do_write(s);
+  return 1;
 }
 
 
-int ssl3_send_channel_id(SSL *s)
-	{
-	uint8_t *d;
-	int ret = -1, public_key_len;
-	EVP_MD_CTX md_ctx;
-	size_t sig_len;
-	ECDSA_SIG *sig = NULL;
-	uint8_t *public_key = NULL, *derp, *der_sig = NULL;
+int ssl3_send_client_key_exchange(SSL *s) {
+  uint8_t *p;
+  int n = 0;
+  unsigned long alg_k;
+  unsigned long alg_a;
+  uint8_t *q;
+  EVP_PKEY *pkey = NULL;
+  EC_KEY *clnt_ecdh = NULL;
+  const EC_POINT *srvr_ecpoint = NULL;
+  EVP_PKEY *srvr_pub_pkey = NULL;
+  uint8_t *encodedPoint = NULL;
+  int encoded_pt_len = 0;
+  BN_CTX *bn_ctx = NULL;
+  unsigned int psk_len = 0;
+  uint8_t psk[PSK_MAX_PSK_LEN];
+  uint8_t *pms = NULL;
+  size_t pms_len = 0;
 
-	if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
-		return ssl_do_write(s);
+  if (s->state == SSL3_ST_CW_KEY_EXCH_A) {
+    p = ssl_handshake_start(s);
 
-	if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb)
-		{
-		EVP_PKEY *key = NULL;
-		s->ctx->channel_id_cb(s, &key);
-		if (key != NULL)
-			{
-			s->tlsext_channel_id_private = key;
-			}
-		}
-	if (!s->tlsext_channel_id_private)
-		{
-		s->rwstate=SSL_CHANNEL_ID_LOOKUP;
-		return (-1);
-		}
-	s->rwstate=SSL_NOTHING;
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
-	d = ssl_handshake_start(s);
-	if (s->s3->tlsext_channel_id_new)
-		s2n(TLSEXT_TYPE_channel_id_new, d);
-	else
-		s2n(TLSEXT_TYPE_channel_id, d);
-	s2n(TLSEXT_CHANNEL_ID_SIZE, d);
+    /* If using a PSK key exchange, prepare the pre-shared key. */
+    if (alg_a & SSL_aPSK) {
+      char identity[PSK_MAX_IDENTITY_LEN + 1];
+      size_t identity_len;
 
-	EVP_MD_CTX_init(&md_ctx);
+      if (s->psk_client_callback == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          SSL_R_PSK_NO_CLIENT_CB);
+        goto err;
+      }
 
-	public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
-	if (public_key_len <= 0)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
-		goto err;
-		}
-	/* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
-	 * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
-	 * field elements as 32-byte, big-endian numbers. */
-	if (public_key_len != 65)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
-		goto err;
-		}
-	public_key = OPENSSL_malloc(public_key_len);
-	if (!public_key)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+      memset(identity, 0, sizeof(identity));
+      psk_len =
+          s->psk_client_callback(s, s->s3->tmp.peer_psk_identity_hint, identity,
+                                 sizeof(identity), psk, sizeof(psk));
+      if (psk_len > PSK_MAX_PSK_LEN) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      } else if (psk_len == 0) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          SSL_R_PSK_IDENTITY_NOT_FOUND);
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+        goto err;
+      }
 
-	derp = public_key;
-	i2d_PublicKey(s->tlsext_channel_id_private, &derp);
+      identity_len = OPENSSL_strnlen(identity, sizeof(identity));
+      if (identity_len > PSK_MAX_IDENTITY_LEN) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
 
-	if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
-			       s->tlsext_channel_id_private) != 1)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNINIT_FAILED);
-		goto err;
-		}
+      if (s->session->psk_identity != NULL) {
+        OPENSSL_free(s->session->psk_identity);
+      }
 
-	if (!tls1_channel_id_hash(&md_ctx, s))
-		goto err;
+      s->session->psk_identity = BUF_strdup(identity);
+      if (s->session->psk_identity == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
 
-	if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-		goto err;
-		}
+      /* Write out psk_identity. */
+      s2n(identity_len, p);
+      memcpy(p, identity, identity_len);
+      p += identity_len;
+      n = 2 + identity_len;
+    }
 
-	der_sig = OPENSSL_malloc(sig_len);
-	if (!der_sig)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
+    /* Depending on the key exchange method, compute |pms| and |pms_len|. */
+    if (alg_k & SSL_kRSA) {
+      RSA *rsa;
+      size_t enc_pms_len;
 
-	if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-		goto err;
-		}
+      pms_len = SSL_MAX_MASTER_KEY_LENGTH;
+      pms = OPENSSL_malloc(pms_len);
+      if (pms == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
 
-	derp = der_sig;
-	sig = d2i_ECDSA_SIG(NULL, (const unsigned char**) &derp, sig_len);
-	if (sig == NULL)
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
-		goto err;
-		}
+      if (s->session->sess_cert == NULL) {
+        /* We should always have a server certificate with SSL_kRSA. */
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
 
-	/* The first byte of public_key will be 0x4, denoting an uncompressed key. */
-	memcpy(d, public_key + 1, 64);
-	d += 64;
-	if (!BN_bn2bin_padded(d, 32, sig->r) ||
-		!BN_bn2bin_padded(d + 32, 32, sig->s))
-		{
-		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_INTERNAL_ERROR);
-		goto err;
-		}
+      pkey = X509_get_pubkey(
+          s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+      if (pkey == NULL ||
+          pkey->type != EVP_PKEY_RSA ||
+          pkey->pkey.rsa == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        if (pkey != NULL) {
+          EVP_PKEY_free(pkey);
+        }
+        goto err;
+      }
 
-	ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS,
-		2 + 2 + TLSEXT_CHANNEL_ID_SIZE);
-	s->state = SSL3_ST_CW_CHANNEL_ID_B;
+      rsa = pkey->pkey.rsa;
+      EVP_PKEY_free(pkey);
 
-	ret = ssl_do_write(s);
+      pms[0] = s->client_version >> 8;
+      pms[1] = s->client_version & 0xff;
+      if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) {
+        goto err;
+      }
+
+      s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
+
+      q = p;
+      /* In TLS and beyond, reserve space for the length prefix. */
+      if (s->version > SSL3_VERSION) {
+        p += 2;
+        n += 2;
+      }
+      if (!RSA_encrypt(rsa, &enc_pms_len, p, RSA_size(rsa), pms, pms_len,
+                       RSA_PKCS1_PADDING)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          SSL_R_BAD_RSA_ENCRYPT);
+        goto err;
+      }
+      n += enc_pms_len;
+
+      /* Log the premaster secret, if logging is enabled. */
+      if (!ssl_ctx_log_rsa_client_key_exchange(s->ctx, p, enc_pms_len, pms,
+                                               pms_len)) {
+        goto err;
+      }
+
+      /* Fill in the length prefix. */
+      if (s->version > SSL3_VERSION) {
+        s2n(enc_pms_len, q);
+      }
+    } else if (alg_k & SSL_kEDH) {
+      DH *dh_srvr, *dh_clnt;
+      SESS_CERT *scert = s->session->sess_cert;
+      int dh_len;
+      size_t pub_len;
+
+      if (scert == NULL) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          SSL_R_UNEXPECTED_MESSAGE);
+        goto err;
+      }
+
+      if (scert->peer_dh_tmp == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+      dh_srvr = scert->peer_dh_tmp;
+
+      /* generate a new random key */
+      dh_clnt = DHparams_dup(dh_srvr);
+      if (dh_clnt == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+        goto err;
+      }
+      if (!DH_generate_key(dh_clnt)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+        DH_free(dh_clnt);
+        goto err;
+      }
+
+      pms_len = DH_size(dh_clnt);
+      pms = OPENSSL_malloc(pms_len);
+      if (pms == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        DH_free(dh_clnt);
+        goto err;
+      }
+
+      dh_len = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt);
+      if (dh_len <= 0) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+        DH_free(dh_clnt);
+        goto err;
+      }
+      pms_len = dh_len;
+
+      /* send off the data */
+      pub_len = BN_num_bytes(dh_clnt->pub_key);
+      s2n(pub_len, p);
+      BN_bn2bin(dh_clnt->pub_key, p);
+      n += 2 + pub_len;
+
+      DH_free(dh_clnt);
+    } else if (alg_k & SSL_kEECDH) {
+      const EC_GROUP *srvr_group = NULL;
+      EC_KEY *tkey;
+      int field_size = 0, ecdh_len;
+
+      if (s->session->sess_cert == NULL) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          SSL_R_UNEXPECTED_MESSAGE);
+        goto err;
+      }
+
+      if (s->session->sess_cert->peer_ecdh_tmp == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+
+      tkey = s->session->sess_cert->peer_ecdh_tmp;
+
+      srvr_group = EC_KEY_get0_group(tkey);
+      srvr_ecpoint = EC_KEY_get0_public_key(tkey);
+      if (srvr_group == NULL || srvr_ecpoint == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+
+      clnt_ecdh = EC_KEY_new();
+      if (clnt_ecdh == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+
+      if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
+        goto err;
+      }
+
+      /* Generate a new ECDH key pair */
+      if (!EC_KEY_generate_key(clnt_ecdh)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+        goto err;
+      }
+
+      field_size = EC_GROUP_get_degree(srvr_group);
+      if (field_size <= 0) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+        goto err;
+      }
+
+      pms_len = (field_size + 7) / 8;
+      pms = OPENSSL_malloc(pms_len);
+      if (pms == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+
+      ecdh_len = ECDH_compute_key(pms, pms_len, srvr_ecpoint, clnt_ecdh, NULL);
+      if (ecdh_len <= 0) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+        goto err;
+      }
+      pms_len = ecdh_len;
+
+      /* First check the size of encoding and allocate memory accordingly. */
+      encoded_pt_len =
+          EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh),
+                             POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+
+      encodedPoint =
+          (uint8_t *)OPENSSL_malloc(encoded_pt_len * sizeof(uint8_t));
+      bn_ctx = BN_CTX_new();
+      if (encodedPoint == NULL || bn_ctx == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+
+      /* Encode the public key */
+      encoded_pt_len = EC_POINT_point2oct(
+          srvr_group, EC_KEY_get0_public_key(clnt_ecdh),
+          POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, bn_ctx);
+
+      *p = encoded_pt_len; /* length of encoded point */
+      /* Encoded point will be copied here */
+      p += 1;
+      n += 1;
+      /* copy the point */
+      memcpy(p, encodedPoint, encoded_pt_len);
+      /* increment n to account for length field */
+      n += encoded_pt_len;
+
+      /* Free allocated memory */
+      BN_CTX_free(bn_ctx);
+      bn_ctx = NULL;
+      OPENSSL_free(encodedPoint);
+      encodedPoint = NULL;
+      EC_KEY_free(clnt_ecdh);
+      clnt_ecdh = NULL;
+      EVP_PKEY_free(srvr_pub_pkey);
+      srvr_pub_pkey = NULL;
+    } else if (alg_k & SSL_kPSK) {
+      /* For plain PSK, other_secret is a block of 0s with the same length as
+       * the pre-shared key. */
+      pms_len = psk_len;
+      pms = OPENSSL_malloc(pms_len);
+      if (pms == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+      memset(pms, 0, pms_len);
+    } else {
+      ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                        ERR_R_INTERNAL_ERROR);
+      goto err;
+    }
+
+    /* For a PSK cipher suite, other_secret is combined with the pre-shared
+     * key. */
+    if (alg_a & SSL_aPSK) {
+      CBB cbb, child;
+      uint8_t *new_pms;
+      size_t new_pms_len;
+
+      if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+      if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+          !CBB_add_bytes(&child, pms, pms_len) ||
+          !CBB_add_u16_length_prefixed(&cbb, &child) ||
+          !CBB_add_bytes(&child, psk, psk_len) ||
+          !CBB_finish(&cbb, &new_pms, &new_pms_len)) {
+        CBB_cleanup(&cbb);
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
+                          ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+      OPENSSL_cleanse(pms, pms_len);
+      OPENSSL_free(pms);
+      pms = new_pms;
+      pms_len = new_pms_len;
+    }
+
+    /* The message must be added to the finished hash before calculating the
+     * master secret. */
+    ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n);
+    s->state = SSL3_ST_CW_KEY_EXCH_B;
+
+    s->session->master_key_length = s->enc_method->generate_master_secret(
+        s, s->session->master_key, pms, pms_len);
+    if (s->session->master_key_length == 0) {
+      goto err;
+    }
+    s->session->extended_master_secret = s->s3->tmp.extended_master_secret;
+    OPENSSL_cleanse(pms, pms_len);
+    OPENSSL_free(pms);
+  }
+
+  /* SSL3_ST_CW_KEY_EXCH_B */
+  return s->enc_method->do_write(s);
 
 err:
-	EVP_MD_CTX_cleanup(&md_ctx);
-	if (public_key)
-		OPENSSL_free(public_key);
-	if (der_sig)
-		OPENSSL_free(der_sig);
-	if (sig)
-		ECDSA_SIG_free(sig);
+  BN_CTX_free(bn_ctx);
+  if (encodedPoint != NULL) {
+    OPENSSL_free(encodedPoint);
+  }
+  if (clnt_ecdh != NULL) {
+    EC_KEY_free(clnt_ecdh);
+  }
+  EVP_PKEY_free(srvr_pub_pkey);
+  if (pms) {
+    OPENSSL_cleanse(pms, pms_len);
+    OPENSSL_free(pms);
+  }
+  return -1;
+}
 
-	return ret;
-	}
+int ssl3_send_cert_verify(SSL *s) {
+  uint8_t *buf, *p;
+  const EVP_MD *md = NULL;
+  uint8_t digest[EVP_MAX_MD_SIZE];
+  size_t digest_length;
+  EVP_PKEY *pkey;
+  EVP_PKEY_CTX *pctx = NULL;
+  size_t signature_length = 0;
+  unsigned long n = 0;
 
-int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
-	{
-	int i = 0;
-	if (s->ctx->client_cert_cb)
-		i = s->ctx->client_cert_cb(s,px509,ppkey);
-	return i;
-	}
+  buf = (uint8_t *)s->init_buf->data;
+
+  if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
+    p = ssl_handshake_start(s);
+    pkey = s->cert->key->privatekey;
+
+    /* Write out the digest type if needbe. */
+    if (SSL_USE_SIGALGS(s)) {
+      md = tls1_choose_signing_digest(s, pkey);
+      if (!tls12_get_sigandhash(p, pkey, md)) {
+        OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+      p += 2;
+      n += 2;
+    }
+
+    /* Compute the digest. */
+    if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) {
+      goto err;
+    }
+
+    /* The handshake buffer is no longer necessary. */
+    if (s->s3->handshake_buffer &&
+        !ssl3_digest_cached_records(s, free_handshake_buffer)) {
+      goto err;
+    }
+
+    /* Sign the digest. */
+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (pctx == NULL) {
+      goto err;
+    }
+
+    /* Initialize the EVP_PKEY_CTX and determine the size of the signature. */
+    if (!EVP_PKEY_sign_init(pctx) || !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
+        !EVP_PKEY_sign(pctx, NULL, &signature_length, digest, digest_length)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
+      goto err;
+    }
+
+    if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, SSL_R_DATA_LENGTH_TOO_LONG);
+      goto err;
+    }
+
+    if (!EVP_PKEY_sign(pctx, &p[2], &signature_length, digest, digest_length)) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
+      goto err;
+    }
+
+    s2n(signature_length, p);
+    n += signature_length + 2;
+
+    ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n);
+    s->state = SSL3_ST_CW_CERT_VRFY_B;
+  }
+
+  EVP_PKEY_CTX_free(pctx);
+  return ssl_do_write(s);
+
+err:
+  EVP_PKEY_CTX_free(pctx);
+  return -1;
+}
+
+/* ssl3_has_client_certificate returns true if a client certificate is
+ * configured. */
+static int ssl3_has_client_certificate(SSL *s) {
+  return s->cert && s->cert->key->x509 && s->cert->key->privatekey;
+}
+
+int ssl3_send_client_certificate(SSL *s) {
+  X509 *x509 = NULL;
+  EVP_PKEY *pkey = NULL;
+  int i;
+
+  if (s->state == SSL3_ST_CW_CERT_A) {
+    /* Let cert callback update client certificates if required */
+    if (s->cert->cert_cb) {
+      i = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+      if (i < 0) {
+        s->rwstate = SSL_X509_LOOKUP;
+        return -1;
+      }
+      if (i == 0) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        return 0;
+      }
+      s->rwstate = SSL_NOTHING;
+    }
+
+    if (ssl3_has_client_certificate(s)) {
+      s->state = SSL3_ST_CW_CERT_C;
+    } else {
+      s->state = SSL3_ST_CW_CERT_B;
+    }
+  }
+
+  /* We need to get a client cert */
+  if (s->state == SSL3_ST_CW_CERT_B) {
+    /* If we get an error, we need to:
+     *   ssl->rwstate=SSL_X509_LOOKUP; return(-1);
+     * We then get retried later */
+    i = ssl_do_client_cert_cb(s, &x509, &pkey);
+    if (i < 0) {
+      s->rwstate = SSL_X509_LOOKUP;
+      return -1;
+    }
+    s->rwstate = SSL_NOTHING;
+    if (i == 1 && pkey != NULL && x509 != NULL) {
+      s->state = SSL3_ST_CW_CERT_B;
+      if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) {
+        i = 0;
+      }
+    } else if (i == 1) {
+      i = 0;
+      OPENSSL_PUT_ERROR(SSL, ssl3_send_client_certificate,
+                        SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+    }
+
+    if (x509 != NULL) {
+      X509_free(x509);
+    }
+    if (pkey != NULL) {
+      EVP_PKEY_free(pkey);
+    }
+    if (i && !ssl3_has_client_certificate(s)) {
+      i = 0;
+    }
+    if (i == 0) {
+      if (s->version == SSL3_VERSION) {
+        s->s3->tmp.cert_req = 0;
+        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+        return 1;
+      } else {
+        s->s3->tmp.cert_req = 2;
+      }
+    }
+
+    /* Ok, we have a cert */
+    s->state = SSL3_ST_CW_CERT_C;
+  }
+
+  if (s->state == SSL3_ST_CW_CERT_C) {
+    s->state = SSL3_ST_CW_CERT_D;
+    ssl3_output_cert_chain(s, (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key);
+  }
+
+  /* SSL3_ST_CW_CERT_D */
+  return ssl_do_write(s);
+}
+
+#define has_bits(i, m) (((i) & (m)) == (m))
+
+int ssl3_check_cert_and_algorithm(SSL *s) {
+  int i, idx;
+  long alg_k, alg_a;
+  EVP_PKEY *pkey = NULL;
+  SESS_CERT *sc;
+  DH *dh;
+
+  /* we don't have a certificate */
+  if (!ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+    return 1;
+  }
+
+  alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+  alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+
+  sc = s->session->sess_cert;
+  if (sc == NULL) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, ERR_R_INTERNAL_ERROR);
+    goto err;
+  }
+
+  dh = s->session->sess_cert->peer_dh_tmp;
+
+  /* This is the passed certificate */
+
+  idx = sc->peer_cert_type;
+  if (idx == SSL_PKEY_ECC) {
+    if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) {
+      /* check failed */
+      OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_BAD_ECC_CERT);
+      goto f_err;
+    } else {
+      return 1;
+    }
+  } else if (alg_a & SSL_aECDSA) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
+                      SSL_R_MISSING_ECDSA_SIGNING_CERT);
+    goto f_err;
+  }
+  pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509);
+  i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey);
+  EVP_PKEY_free(pkey);
+
+  /* Check that we have a certificate if we require one */
+  if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
+                      SSL_R_MISSING_RSA_SIGNING_CERT);
+    goto f_err;
+  }
+
+  if ((alg_k & SSL_kRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
+                      SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+    goto f_err;
+  }
+
+  if ((alg_k & SSL_kEDH) &&
+      !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || dh != NULL)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_DH_KEY);
+    goto f_err;
+  }
+
+  return 1;
+
+f_err:
+  ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+err:
+  return 0;
+}
+
+int ssl3_send_next_proto(SSL *s) {
+  unsigned int len, padding_len;
+  uint8_t *d, *p;
+
+  if (s->state == SSL3_ST_CW_NEXT_PROTO_A) {
+    len = s->next_proto_negotiated_len;
+    padding_len = 32 - ((len + 2) % 32);
+
+    d = p = ssl_handshake_start(s);
+    *(p++) = len;
+    memcpy(p, s->next_proto_negotiated, len);
+    p += len;
+    *(p++) = padding_len;
+    memset(p, 0, padding_len);
+    p += padding_len;
+
+    ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d);
+    s->state = SSL3_ST_CW_NEXT_PROTO_B;
+  }
+
+  return ssl_do_write(s);
+}
+
+int ssl3_send_channel_id(SSL *s) {
+  uint8_t *d;
+  int ret = -1, public_key_len;
+  EVP_MD_CTX md_ctx;
+  size_t sig_len;
+  ECDSA_SIG *sig = NULL;
+  uint8_t *public_key = NULL, *derp, *der_sig = NULL;
+
+  if (s->state != SSL3_ST_CW_CHANNEL_ID_A) {
+    return ssl_do_write(s);
+  }
+
+  if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb) {
+    EVP_PKEY *key = NULL;
+    s->ctx->channel_id_cb(s, &key);
+    if (key != NULL) {
+      s->tlsext_channel_id_private = key;
+    }
+  }
+
+  if (!s->tlsext_channel_id_private) {
+    s->rwstate = SSL_CHANNEL_ID_LOOKUP;
+    return -1;
+  }
+  s->rwstate = SSL_NOTHING;
+
+  d = ssl_handshake_start(s);
+  if (s->s3->tlsext_channel_id_new) {
+    s2n(TLSEXT_TYPE_channel_id_new, d);
+  } else {
+    s2n(TLSEXT_TYPE_channel_id, d);
+  }
+  s2n(TLSEXT_CHANNEL_ID_SIZE, d);
+
+  EVP_MD_CTX_init(&md_ctx);
+
+  public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
+  if (public_key_len <= 0) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
+                      SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
+    goto err;
+  }
+
+  /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
+   * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
+   * field elements as 32-byte, big-endian numbers. */
+  if (public_key_len != 65) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
+    goto err;
+  }
+  public_key = OPENSSL_malloc(public_key_len);
+  if (!public_key) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
+
+  derp = public_key;
+  i2d_PublicKey(s->tlsext_channel_id_private, &derp);
+
+  if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
+                         s->tlsext_channel_id_private) != 1) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
+                      SSL_R_EVP_DIGESTSIGNINIT_FAILED);
+    goto err;
+  }
+
+  if (!tls1_channel_id_hash(&md_ctx, s)) {
+    goto err;
+  }
+
+  if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
+                      SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+    goto err;
+  }
+
+  der_sig = OPENSSL_malloc(sig_len);
+  if (!der_sig) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
+    goto err;
+  }
+
+  if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
+                      SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+    goto err;
+  }
+
+  derp = der_sig;
+  sig = d2i_ECDSA_SIG(NULL, (const uint8_t **)&derp, sig_len);
+  if (sig == NULL) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
+    goto err;
+  }
+
+  /* The first byte of public_key will be 0x4, denoting an uncompressed key. */
+  memcpy(d, public_key + 1, 64);
+  d += 64;
+  if (!BN_bn2bin_padded(d, 32, sig->r) ||
+      !BN_bn2bin_padded(d + 32, 32, sig->s)) {
+    OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_INTERNAL_ERROR);
+    goto err;
+  }
+
+  ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS,
+                           2 + 2 + TLSEXT_CHANNEL_ID_SIZE);
+  s->state = SSL3_ST_CW_CHANNEL_ID_B;
+
+  ret = ssl_do_write(s);
+
+err:
+  EVP_MD_CTX_cleanup(&md_ctx);
+  if (public_key) {
+    OPENSSL_free(public_key);
+  }
+  if (der_sig) {
+    OPENSSL_free(der_sig);
+  }
+  if (sig) {
+    ECDSA_SIG_free(sig);
+  }
+
+  return ret;
+}
+
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) {
+  int i = 0;
+  if (s->ctx->client_cert_cb) {
+    i = s->ctx->client_cert_cb(s, px509, ppkey);
+  }
+  return i;
+}
