diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 510d480..418a04f 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -76,27 +76,25 @@
  *   0: (in non-constant time) if the record is publicly invalid.
  *   1: if the padding was valid
  *  -1: otherwise. */
-int ssl3_cbc_remove_padding(const SSL* s,
-			    SSL3_RECORD *rec,
-			    unsigned block_size,
-			    unsigned mac_size)
-	{
-	unsigned padding_length, good;
-	const unsigned overhead = 1 /* padding length byte */ + mac_size;
+int ssl3_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, unsigned block_size,
+                            unsigned mac_size) {
+  unsigned padding_length, good;
+  const unsigned overhead = 1 /* padding length byte */ + mac_size;
 
-	/* These lengths are all public so we can test them in non-constant
-	 * time. */
-	if (overhead > rec->length)
-		return 0;
+  /* These lengths are all public so we can test them in non-constant
+   * time. */
+  if (overhead > rec->length) {
+    return 0;
+  }
 
-	padding_length = rec->data[rec->length-1];
-	good = constant_time_ge(rec->length, padding_length+overhead);
-	/* SSLv3 requires that the padding is minimal. */
-	good &= constant_time_ge(block_size, padding_length+1);
-	padding_length = good & (padding_length+1);
-	rec->length -= padding_length;
-	rec->type |= padding_length<<8;	/* kludge: pass padding length */
-	return constant_time_select_int(good, 1, -1);
+  padding_length = rec->data[rec->length - 1];
+  good = constant_time_ge(rec->length, padding_length + overhead);
+  /* SSLv3 requires that the padding is minimal. */
+  good &= constant_time_ge(block_size, padding_length + 1);
+  padding_length = good & (padding_length + 1);
+  rec->length -= padding_length;
+  rec->type |= padding_length << 8; /* kludge: pass padding length */
+  return constant_time_select_int(good, 1, -1);
 }
 
 /* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
@@ -110,64 +108,61 @@
  *   0: (in non-constant time) if the record is publicly invalid.
  *   1: if the padding was valid
  *  -1: otherwise. */
-int tls1_cbc_remove_padding(const SSL* s,
-			    SSL3_RECORD *rec,
-			    unsigned block_size,
-			    unsigned mac_size)
-	{
-	unsigned padding_length, good, to_check, i;
-	const unsigned overhead = 1 /* padding length byte */ + mac_size;
-	/* Check if version requires explicit IV */
-	if (SSL_USE_EXPLICIT_IV(s))
-		{
-		/* These lengths are all public so we can test them in
-		 * non-constant time.
-		 */
-		if (overhead + block_size > rec->length)
-			return 0;
-		/* We can now safely skip explicit IV */
-		rec->data += block_size;
-		rec->input += block_size;
-		rec->length -= block_size;
-		}
-	else if (overhead > rec->length)
-		return 0;
+int tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, unsigned block_size,
+                            unsigned mac_size) {
+  unsigned padding_length, good, to_check, i;
+  const unsigned overhead = 1 /* padding length byte */ + mac_size;
 
-	padding_length = rec->data[rec->length-1];
+  /* Check if version requires explicit IV */
+  if (SSL_USE_EXPLICIT_IV(s)) {
+    /* These lengths are all public so we can test them in
+     * non-constant time. */
+    if (overhead + block_size > rec->length) {
+      return 0;
+    }
+    /* We can now safely skip explicit IV */
+    rec->data += block_size;
+    rec->input += block_size;
+    rec->length -= block_size;
+  } else if (overhead > rec->length) {
+    return 0;
+  }
 
-	good = constant_time_ge(rec->length, overhead+padding_length);
-	/* The padding consists of a length byte at the end of the record and
-	 * then that many bytes of padding, all with the same value as the
-	 * length byte. Thus, with the length byte included, there are i+1
-	 * bytes of padding.
-	 *
-	 * We can't check just |padding_length+1| bytes because that leaks
-	 * decrypted information. Therefore we always have to check the maximum
-	 * amount of padding possible. (Again, the length of the record is
-	 * public information so we can use it.) */
-	to_check = 256; /* maximum amount of padding, inc length byte. */
-	if (to_check > rec->length)
-		to_check = rec->length;
+  padding_length = rec->data[rec->length - 1];
 
-	for (i = 0; i < to_check; i++)
-		{
-		unsigned char mask = constant_time_ge_8(padding_length, i);
-		unsigned char b = rec->data[rec->length-1-i];
-		/* The final |padding_length+1| bytes should all have the value
-		 * |padding_length|. Therefore the XOR should be zero. */
-		good &= ~(mask&(padding_length ^ b));
-		}
+  good = constant_time_ge(rec->length, overhead + padding_length);
+  /* The padding consists of a length byte at the end of the record and
+   * then that many bytes of padding, all with the same value as the
+   * length byte. Thus, with the length byte included, there are i+1
+   * bytes of padding.
+   *
+   * We can't check just |padding_length+1| bytes because that leaks
+   * decrypted information. Therefore we always have to check the maximum
+   * amount of padding possible. (Again, the length of the record is
+   * public information so we can use it.) */
+  to_check = 256; /* maximum amount of padding, inc length byte. */
+  if (to_check > rec->length) {
+    to_check = rec->length;
+  }
 
-	/* If any of the final |padding_length+1| bytes had the wrong value,
-	 * one or more of the lower eight bits of |good| will be cleared. */
-	good = constant_time_eq(0xff, good & 0xff);
+  for (i = 0; i < to_check; i++) {
+    unsigned char mask = constant_time_ge_8(padding_length, i);
+    unsigned char b = rec->data[rec->length - 1 - i];
+    /* The final |padding_length+1| bytes should all have the value
+     * |padding_length|. Therefore the XOR should be zero. */
+    good &= ~(mask & (padding_length ^ b));
+  }
 
-	padding_length = good & (padding_length+1);
-	rec->length -= padding_length;
-	rec->type |= padding_length<<8;	/* kludge: pass padding length */
+  /* If any of the final |padding_length+1| bytes had the wrong value,
+   * one or more of the lower eight bits of |good| will be cleared. */
+  good = constant_time_eq(0xff, good & 0xff);
 
-	return constant_time_select_int(good, 1, -1);
-	}
+  padding_length = good & (padding_length + 1);
+  rec->length -= padding_length;
+  rec->type |= padding_length << 8; /* kludge: pass padding length */
+
+  return constant_time_select_int(good, 1, -1);
+}
 
 /* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
  * constant time (independent of the concrete value of rec->length, which may
@@ -188,144 +183,135 @@
  */
 #define CBC_MAC_ROTATE_IN_PLACE
 
-void ssl3_cbc_copy_mac(unsigned char* out,
-		       const SSL3_RECORD *rec,
-		       unsigned md_size,unsigned orig_len)
-	{
+void ssl3_cbc_copy_mac(unsigned char *out, const SSL3_RECORD *rec,
+                       unsigned md_size, unsigned orig_len) {
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
-	unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE];
-	unsigned char *rotated_mac;
+  unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
+  unsigned char *rotated_mac;
 #else
-	unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+  unsigned char rotated_mac[EVP_MAX_MD_SIZE];
 #endif
 
-	/* mac_end is the index of |rec->data| just after the end of the MAC. */
-	unsigned mac_end = rec->length;
-	unsigned mac_start = mac_end - md_size;
-	/* scan_start contains the number of bytes that we can ignore because
-	 * the MAC's position can only vary by 255 bytes. */
-	unsigned scan_start = 0;
-	unsigned i, j;
-	unsigned div_spoiler;
-	unsigned rotate_offset;
+  /* mac_end is the index of |rec->data| just after the end of the MAC. */
+  unsigned mac_end = rec->length;
+  unsigned mac_start = mac_end - md_size;
+  /* scan_start contains the number of bytes that we can ignore because
+   * the MAC's position can only vary by 255 bytes. */
+  unsigned scan_start = 0;
+  unsigned i, j;
+  unsigned div_spoiler;
+  unsigned rotate_offset;
 
-	assert(orig_len >= md_size);
-	assert(md_size <= EVP_MAX_MD_SIZE);
+  assert(orig_len >= md_size);
+  assert(md_size <= EVP_MAX_MD_SIZE);
 
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
-	rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63);
+  rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63);
 #endif
 
-	/* This information is public so it's safe to branch based on it. */
-	if (orig_len > md_size + 255 + 1)
-		scan_start = orig_len - (md_size + 255 + 1);
-	/* div_spoiler contains a multiple of md_size that is used to cause the
-	 * modulo operation to be constant time. Without this, the time varies
-	 * based on the amount of padding when running on Intel chips at least.
-	 *
-	 * The aim of right-shifting md_size is so that the compiler doesn't
-	 * figure out that it can remove div_spoiler as that would require it
-	 * to prove that md_size is always even, which I hope is beyond it. */
-	div_spoiler = md_size >> 1;
-	div_spoiler <<= (sizeof(div_spoiler)-1)*8;
-	rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+  /* This information is public so it's safe to branch based on it. */
+  if (orig_len > md_size + 255 + 1) {
+    scan_start = orig_len - (md_size + 255 + 1);
+  }
+  /* div_spoiler contains a multiple of md_size that is used to cause the
+   * modulo operation to be constant time. Without this, the time varies
+   * based on the amount of padding when running on Intel chips at least.
+   *
+   * The aim of right-shifting md_size is so that the compiler doesn't
+   * figure out that it can remove div_spoiler as that would require it
+   * to prove that md_size is always even, which I hope is beyond it. */
+  div_spoiler = md_size >> 1;
+  div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
+  rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
 
-	memset(rotated_mac, 0, md_size);
-	for (i = scan_start, j = 0; i < orig_len; i++)
-		{
-		unsigned char mac_started = constant_time_ge_8(i, mac_start);
-		unsigned char mac_ended = constant_time_ge_8(i, mac_end);
-		unsigned char b = rec->data[i];
-		rotated_mac[j++] |= b & mac_started & ~mac_ended;
-		j &= constant_time_lt(j,md_size);
-		}
+  memset(rotated_mac, 0, md_size);
+  for (i = scan_start, j = 0; i < orig_len; i++) {
+    unsigned char mac_started = constant_time_ge_8(i, mac_start);
+    unsigned char mac_ended = constant_time_ge_8(i, mac_end);
+    unsigned char b = rec->data[i];
+    rotated_mac[j++] |= b & mac_started & ~mac_ended;
+    j &= constant_time_lt(j, md_size);
+  }
 
-	/* Now rotate the MAC */
+/* Now rotate the MAC */
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
-	j = 0;
-	for (i = 0; i < md_size; i++)
-		{
-		/* in case cache-line is 32 bytes, touch second line */
-		((volatile unsigned char *)rotated_mac)[rotate_offset^32];
-		out[j++] = rotated_mac[rotate_offset++];
-		rotate_offset &= constant_time_lt(rotate_offset,md_size);
-		}
+  j = 0;
+  for (i = 0; i < md_size; i++) {
+    /* in case cache-line is 32 bytes, touch second line */
+    ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32];
+    out[j++] = rotated_mac[rotate_offset++];
+    rotate_offset &= constant_time_lt(rotate_offset, md_size);
+  }
 #else
-	memset(out, 0, md_size);
-	rotate_offset = md_size - rotate_offset;
-	rotate_offset &= constant_time_lt(rotate_offset,md_size);
-	for (i = 0; i < md_size; i++)
-		{
-		for (j = 0; j < md_size; j++)
-			out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
-		rotate_offset++;
-		rotate_offset &= constant_time_lt(rotate_offset,md_size);
-		}
+  memset(out, 0, md_size);
+  rotate_offset = md_size - rotate_offset;
+  rotate_offset &= constant_time_lt(rotate_offset, md_size);
+  for (i = 0; i < md_size; i++) {
+    for (j = 0; j < md_size; j++) {
+      out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+    }
+    rotate_offset++;
+    rotate_offset &= constant_time_lt(rotate_offset, md_size);
+  }
 #endif
-	}
+}
 
 /* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
  * little-endian order. The value of p is advanced by four. */
 #define u32toLE(n, p) \
-	(*((p)++)=(unsigned char)(n), \
-	 *((p)++)=(unsigned char)(n>>8), \
-	 *((p)++)=(unsigned char)(n>>16), \
-	 *((p)++)=(unsigned char)(n>>24))
+  (*((p)++)=(unsigned char)(n), \
+   *((p)++)=(unsigned char)(n>>8), \
+   *((p)++)=(unsigned char)(n>>16), \
+   *((p)++)=(unsigned char)(n>>24))
 
 /* These functions serialize the state of a hash and thus perform the standard
  * "final" operation without adding the padding and length that such a function
  * typically does. */
-static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
-	{
-	SHA_CTX *sha1 = ctx;
-	l2n(sha1->h0, md_out);
-	l2n(sha1->h1, md_out);
-	l2n(sha1->h2, md_out);
-	l2n(sha1->h3, md_out);
-	l2n(sha1->h4, md_out);
-	}
+static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) {
+  SHA_CTX *sha1 = ctx;
+  l2n(sha1->h0, md_out);
+  l2n(sha1->h1, md_out);
+  l2n(sha1->h2, md_out);
+  l2n(sha1->h3, md_out);
+  l2n(sha1->h4, md_out);
+}
 #define LARGEST_DIGEST_CTX SHA_CTX
 
-static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
-	{
-	SHA256_CTX *sha256 = ctx;
-	unsigned i;
+static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) {
+  SHA256_CTX *sha256 = ctx;
+  unsigned i;
 
-	for (i = 0; i < 8; i++)
-		{
-		l2n(sha256->h[i], md_out);
-		}
-	}
+  for (i = 0; i < 8; i++) {
+    l2n(sha256->h[i], md_out);
+  }
+}
 #undef  LARGEST_DIGEST_CTX
 #define LARGEST_DIGEST_CTX SHA256_CTX
 
-static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
-	{
-	SHA512_CTX *sha512 = ctx;
-	unsigned i;
+static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) {
+  SHA512_CTX *sha512 = ctx;
+  unsigned i;
 
-	for (i = 0; i < 8; i++)
-		{
-		l2n8(sha512->h[i], md_out);
-		}
-	}
+  for (i = 0; i < 8; i++) {
+    l2n8(sha512->h[i], md_out);
+  }
+}
 #undef  LARGEST_DIGEST_CTX
 #define LARGEST_DIGEST_CTX SHA512_CTX
 
 /* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
  * which ssl3_cbc_digest_record supports. */
-char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
-	{
-	switch (EVP_MD_CTX_type(ctx))
-		{
-		case NID_sha1:
-		case NID_sha256:
-		case NID_sha384:
-			return 1;
-		default:
-			return 0;
-		}
-	}
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) {
+  switch (EVP_MD_CTX_type(ctx)) {
+    case NID_sha1:
+    case NID_sha256:
+    case NID_sha384:
+      return 1;
+
+    default:
+      return 0;
+  }
+}
 
 /* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
  * record.
@@ -346,277 +332,270 @@
  * functions, above, we know that data_plus_mac_size is large enough to contain
  * a padding byte and MAC. (If the padding was invalid, it might contain the
  * padding too. ) */
-int ssl3_cbc_digest_record(
-	const EVP_MD_CTX *ctx,
-	unsigned char* md_out,
-	size_t* md_out_size,
-	const unsigned char header[13],
-	const unsigned char *data,
-	size_t data_plus_mac_size,
-	size_t data_plus_mac_plus_padding_size,
-	const unsigned char *mac_secret,
-	unsigned mac_secret_length,
-	char is_sslv3)
-	{
-	union {	double align;
-		unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
-	void (*md_final_raw)(void *ctx, unsigned char *md_out);
-	void (*md_transform)(void *ctx, const unsigned char *block);
-	unsigned md_size, md_block_size = 64;
-	unsigned sslv3_pad_length = 40, header_length, variance_blocks,
-		 len, max_mac_bytes, num_blocks,
-		 num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
-	unsigned int bits;	/* at most 18 bits */
-	unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
-	/* hmac_pad is the masked HMAC key. */
-	unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
-	unsigned char first_block[MAX_HASH_BLOCK_SIZE];
-	unsigned char mac_out[EVP_MAX_MD_SIZE];
-	unsigned i, j, md_out_size_u;
-	EVP_MD_CTX md_ctx;
-	/* mdLengthSize is the number of bytes in the length field that terminates
-	* the hash. */
-	unsigned md_length_size = 8;
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char *md_out,
+                           size_t *md_out_size, const unsigned char header[13],
+                           const unsigned char *data, size_t data_plus_mac_size,
+                           size_t data_plus_mac_plus_padding_size,
+                           const unsigned char *mac_secret,
+                           unsigned mac_secret_length, char is_sslv3) {
+  union {
+    double align;
+    unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
+  } md_state;
+  void (*md_final_raw)(void *ctx, unsigned char *md_out);
+  void (*md_transform)(void *ctx, const unsigned char *block);
+  unsigned md_size, md_block_size = 64;
+  unsigned sslv3_pad_length = 40, header_length, variance_blocks, len,
+           max_mac_bytes, num_blocks, num_starting_blocks, k, mac_end_offset, c,
+           index_a, index_b;
+  unsigned int bits; /* at most 18 bits */
+  unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+  /* hmac_pad is the masked HMAC key. */
+  unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+  unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+  unsigned char mac_out[EVP_MAX_MD_SIZE];
+  unsigned i, j, md_out_size_u;
+  EVP_MD_CTX md_ctx;
+  /* mdLengthSize is the number of bytes in the length field that terminates
+  * the hash. */
+  unsigned md_length_size = 8;
 
-	/* This is a, hopefully redundant, check that allows us to forget about
-	 * many possible overflows later in this function. */
-	assert(data_plus_mac_plus_padding_size < 1024*1024);
+  /* This is a, hopefully redundant, check that allows us to forget about
+   * many possible overflows later in this function. */
+  assert(data_plus_mac_plus_padding_size < 1024 * 1024);
 
-	switch (EVP_MD_CTX_type(ctx))
-		{
-		case NID_sha1:
-			SHA1_Init((SHA_CTX*)md_state.c);
-			md_final_raw = tls1_sha1_final_raw;
-			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
-			md_size = 20;
-			break;
-		case NID_sha256:
-			SHA256_Init((SHA256_CTX*)md_state.c);
-			md_final_raw = tls1_sha256_final_raw;
-			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
-			md_size = 32;
-			break;
-		case NID_sha384:
-			SHA384_Init((SHA512_CTX*)md_state.c);
-			md_final_raw = tls1_sha512_final_raw;
-			md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
-			md_size = 384/8;
-			md_block_size = 128;
-			md_length_size = 16;
-			break;
-		default:
-			/* ssl3_cbc_record_digest_supported should have been
-			 * called first to check that the hash function is
-			 * supported. */
-			assert(0);
-			*md_out_size = 0;
-			return 0;
-		}
+  switch (EVP_MD_CTX_type(ctx)) {
+    case NID_sha1:
+      SHA1_Init((SHA_CTX *)md_state.c);
+      md_final_raw = tls1_sha1_final_raw;
+      md_transform =
+          (void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
+      md_size = 20;
+      break;
 
-	assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
-	assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
-	assert(md_size <= EVP_MAX_MD_SIZE);
+    case NID_sha256:
+      SHA256_Init((SHA256_CTX *)md_state.c);
+      md_final_raw = tls1_sha256_final_raw;
+      md_transform =
+          (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
+      md_size = 32;
+      break;
 
-	header_length = 13;
-	if (is_sslv3)
-		{
-		header_length =
-			mac_secret_length +
-			sslv3_pad_length +
-			8 /* sequence number */ +
-			1 /* record type */ +
-			2 /* record length */;
-		}
+    case NID_sha384:
+      SHA384_Init((SHA512_CTX *)md_state.c);
+      md_final_raw = tls1_sha512_final_raw;
+      md_transform =
+          (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
+      md_size = 384 / 8;
+      md_block_size = 128;
+      md_length_size = 16;
+      break;
 
-	/* variance_blocks is the number of blocks of the hash that we have to
-	 * calculate in constant time because they could be altered by the
-	 * padding value.
-	 *
-	 * In SSLv3, the padding must be minimal so the end of the plaintext
-	 * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
-	 * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
-	 * termination (0x80 + 64-bit length) don't fit in the final block, we
-	 * say that the final two blocks can vary based on the padding.
-	 *
-	 * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
-	 * required to be minimal. Therefore we say that the final six blocks
-	 * can vary based on the padding.
-	 *
-	 * Later in the function, if the message is short and there obviously
-	 * cannot be this many blocks then variance_blocks can be reduced. */
-	variance_blocks = is_sslv3 ? 2 : 6;
-	/* From now on we're dealing with the MAC, which conceptually has 13
-	 * bytes of `header' before the start of the data (TLS) or 71/75 bytes
-	 * (SSLv3) */
-	len = data_plus_mac_plus_padding_size + header_length;
-	/* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
-	* |header|, assuming that there's no padding. */
-	max_mac_bytes = len - md_size - 1;
-	/* num_blocks is the maximum number of hash blocks. */
-	num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
-	/* In order to calculate the MAC in constant time we have to handle
-	 * the final blocks specially because the padding value could cause the
-	 * end to appear somewhere in the final |variance_blocks| blocks and we
-	 * can't leak where. However, |num_starting_blocks| worth of data can
-	 * be hashed right away because no padding value can affect whether
-	 * they are plaintext. */
-	num_starting_blocks = 0;
-	/* k is the starting byte offset into the conceptual header||data where
-	 * we start processing. */
-	k = 0;
-	/* mac_end_offset is the index just past the end of the data to be
-	 * MACed. */
-	mac_end_offset = data_plus_mac_size + header_length - md_size;
-	/* c is the index of the 0x80 byte in the final hash block that
-	 * contains application data. */
-	c = mac_end_offset % md_block_size;
-	/* index_a is the hash block number that contains the 0x80 terminating
-	 * value. */
-	index_a = mac_end_offset / md_block_size;
-	/* index_b is the hash block number that contains the 64-bit hash
-	 * length, in bits. */
-	index_b = (mac_end_offset + md_length_size) / md_block_size;
-	/* bits is the hash-length in bits. It includes the additional hash
-	 * block for the masked HMAC key, or whole of |header| in the case of
-	 * SSLv3. */
+    default:
+      /* ssl3_cbc_record_digest_supported should have been
+       * called first to check that the hash function is
+       * supported. */
+      assert(0);
+      *md_out_size = 0;
+      return 0;
+  }
 
-	/* For SSLv3, if we're going to have any starting blocks then we need
-	 * at least two because the header is larger than a single block. */
-	if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0))
-		{
-		num_starting_blocks = num_blocks - variance_blocks;
-		k = md_block_size*num_starting_blocks;
-		}
+  assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+  assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+  assert(md_size <= EVP_MAX_MD_SIZE);
 
-	bits = 8*mac_end_offset;
-	if (!is_sslv3)
-		{
-		/* Compute the initial HMAC block. For SSLv3, the padding and
-		 * secret bytes are included in |header| because they take more
-		 * than a single block. */
-		bits += 8*md_block_size;
-		memset(hmac_pad, 0, md_block_size);
-		assert(mac_secret_length <= sizeof(hmac_pad));
-		memcpy(hmac_pad, mac_secret, mac_secret_length);
-		for (i = 0; i < md_block_size; i++)
-			hmac_pad[i] ^= 0x36;
+  header_length = 13;
+  if (is_sslv3) {
+    header_length = mac_secret_length + sslv3_pad_length +
+                    8 /* sequence number */ + 1 /* record type */ +
+                    2 /* record length */;
+  }
 
-		md_transform(md_state.c, hmac_pad);
-		}
+  /* variance_blocks is the number of blocks of the hash that we have to
+   * calculate in constant time because they could be altered by the
+   * padding value.
+   *
+   * In SSLv3, the padding must be minimal so the end of the plaintext
+   * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
+   * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
+   * termination (0x80 + 64-bit length) don't fit in the final block, we
+   * say that the final two blocks can vary based on the padding.
+   *
+   * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+   * required to be minimal. Therefore we say that the final six blocks
+   * can vary based on the padding.
+   *
+   * Later in the function, if the message is short and there obviously
+   * cannot be this many blocks then variance_blocks can be reduced. */
+  variance_blocks = is_sslv3 ? 2 : 6;
+  /* From now on we're dealing with the MAC, which conceptually has 13
+   * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+   * (SSLv3) */
+  len = data_plus_mac_plus_padding_size + header_length;
+  /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
+  * |header|, assuming that there's no padding. */
+  max_mac_bytes = len - md_size - 1;
+  /* num_blocks is the maximum number of hash blocks. */
+  num_blocks =
+      (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
+  /* In order to calculate the MAC in constant time we have to handle
+   * the final blocks specially because the padding value could cause the
+   * end to appear somewhere in the final |variance_blocks| blocks and we
+   * can't leak where. However, |num_starting_blocks| worth of data can
+   * be hashed right away because no padding value can affect whether
+   * they are plaintext. */
+  num_starting_blocks = 0;
+  /* k is the starting byte offset into the conceptual header||data where
+   * we start processing. */
+  k = 0;
+  /* mac_end_offset is the index just past the end of the data to be
+   * MACed. */
+  mac_end_offset = data_plus_mac_size + header_length - md_size;
+  /* c is the index of the 0x80 byte in the final hash block that
+   * contains application data. */
+  c = mac_end_offset % md_block_size;
+  /* index_a is the hash block number that contains the 0x80 terminating
+   * value. */
+  index_a = mac_end_offset / md_block_size;
+  /* index_b is the hash block number that contains the 64-bit hash
+   * length, in bits. */
+  index_b = (mac_end_offset + md_length_size) / md_block_size;
+  /* bits is the hash-length in bits. It includes the additional hash
+   * block for the masked HMAC key, or whole of |header| in the case of
+   * SSLv3. */
 
-	memset(length_bytes,0,md_length_size-4);
-	length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
-	length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
-	length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
-	length_bytes[md_length_size-1] = (unsigned char)bits;
+  /* For SSLv3, if we're going to have any starting blocks then we need
+   * at least two because the header is larger than a single block. */
+  if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) {
+    num_starting_blocks = num_blocks - variance_blocks;
+    k = md_block_size * num_starting_blocks;
+  }
 
-	if (k > 0)
-		{
-		if (is_sslv3)
-			{
-			/* The SSLv3 header is larger than a single block.
-			 * overhang is the number of bytes beyond a single
-			 * block that the header consumes: 7 bytes (SHA1). */
-			unsigned overhang = header_length-md_block_size;
-			md_transform(md_state.c, header);
-			memcpy(first_block, header + md_block_size, overhang);
-			memcpy(first_block + overhang, data, md_block_size-overhang);
-			md_transform(md_state.c, first_block);
-			for (i = 1; i < k/md_block_size - 1; i++)
-				md_transform(md_state.c, data + md_block_size*i - overhang);
-			}
-		else
-			{
-			/* k is a multiple of md_block_size. */
-			memcpy(first_block, header, 13);
-			memcpy(first_block+13, data, md_block_size-13);
-			md_transform(md_state.c, first_block);
-			for (i = 1; i < k/md_block_size; i++)
-				md_transform(md_state.c, data + md_block_size*i - 13);
-			}
-		}
+  bits = 8 * mac_end_offset;
+  if (!is_sslv3) {
+    /* Compute the initial HMAC block. For SSLv3, the padding and
+     * secret bytes are included in |header| because they take more
+     * than a single block. */
+    bits += 8 * md_block_size;
+    memset(hmac_pad, 0, md_block_size);
+    assert(mac_secret_length <= sizeof(hmac_pad));
+    memcpy(hmac_pad, mac_secret, mac_secret_length);
+    for (i = 0; i < md_block_size; i++) {
+      hmac_pad[i] ^= 0x36;
+    }
 
-	memset(mac_out, 0, sizeof(mac_out));
+    md_transform(md_state.c, hmac_pad);
+  }
 
-	/* We now process the final hash blocks. For each block, we construct
-	 * it in constant time. If the |i==index_a| then we'll include the 0x80
-	 * bytes and zero pad etc. For each block we selectively copy it, in
-	 * constant time, to |mac_out|. */
-	for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++)
-		{
-		unsigned char block[MAX_HASH_BLOCK_SIZE];
-		unsigned char is_block_a = constant_time_eq_8(i, index_a);
-		unsigned char is_block_b = constant_time_eq_8(i, index_b);
-		for (j = 0; j < md_block_size; j++)
-			{
-			unsigned char b = 0, is_past_c, is_past_cp1;
-			if (k < header_length)
-				b = header[k];
-			else if (k < data_plus_mac_plus_padding_size + header_length)
-				b = data[k-header_length];
-			k++;
+  memset(length_bytes, 0, md_length_size - 4);
+  length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
+  length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
+  length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
+  length_bytes[md_length_size - 1] = (unsigned char)bits;
 
-			is_past_c = is_block_a & constant_time_ge_8(j, c);
-			is_past_cp1 = is_block_a & constant_time_ge_8(j, c+1);
-			/* If this is the block containing the end of the
-			 * application data, and we are at the offset for the
-			 * 0x80 value, then overwrite b with 0x80. */
-			b = constant_time_select_8(is_past_c, 0x80, b);
-			/* If this the the block containing the end of the
-			 * application data and we're past the 0x80 value then
-			 * just write zero. */
-			b = b&~is_past_cp1;
-			/* If this is index_b (the final block), but not
-			 * index_a (the end of the data), then the 64-bit
-			 * length didn't fit into index_a and we're having to
-			 * add an extra block of zeros. */
-			b &= ~is_block_b | is_block_a;
+  if (k > 0) {
+    if (is_sslv3) {
+      /* The SSLv3 header is larger than a single block.
+       * overhang is the number of bytes beyond a single
+       * block that the header consumes: 7 bytes (SHA1). */
+      unsigned overhang = header_length - md_block_size;
+      md_transform(md_state.c, header);
+      memcpy(first_block, header + md_block_size, overhang);
+      memcpy(first_block + overhang, data, md_block_size - overhang);
+      md_transform(md_state.c, first_block);
+      for (i = 1; i < k / md_block_size - 1; i++) {
+        md_transform(md_state.c, data + md_block_size * i - overhang);
+      }
+    } else {
+      /* k is a multiple of md_block_size. */
+      memcpy(first_block, header, 13);
+      memcpy(first_block + 13, data, md_block_size - 13);
+      md_transform(md_state.c, first_block);
+      for (i = 1; i < k / md_block_size; i++) {
+        md_transform(md_state.c, data + md_block_size * i - 13);
+      }
+    }
+  }
 
-			/* The final bytes of one of the blocks contains the
-			 * length. */
-			if (j >= md_block_size - md_length_size)
-				{
-				/* If this is index_b, write a length byte. */
-				b = constant_time_select_8(is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
-				}
-			block[j] = b;
-			}
+  memset(mac_out, 0, sizeof(mac_out));
 
-		md_transform(md_state.c, block);
-		md_final_raw(md_state.c, block);
-		/* If this is index_b, copy the hash value to |mac_out|. */
-		for (j = 0; j < md_size; j++)
-			mac_out[j] |= block[j]&is_block_b;
-		}
+  /* We now process the final hash blocks. For each block, we construct
+   * it in constant time. If the |i==index_a| then we'll include the 0x80
+   * bytes and zero pad etc. For each block we selectively copy it, in
+   * constant time, to |mac_out|. */
+  for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks;
+       i++) {
+    unsigned char block[MAX_HASH_BLOCK_SIZE];
+    unsigned char is_block_a = constant_time_eq_8(i, index_a);
+    unsigned char is_block_b = constant_time_eq_8(i, index_b);
+    for (j = 0; j < md_block_size; j++) {
+      unsigned char b = 0, is_past_c, is_past_cp1;
+      if (k < header_length) {
+        b = header[k];
+      } else if (k < data_plus_mac_plus_padding_size + header_length) {
+        b = data[k - header_length];
+      }
+      k++;
 
-	EVP_MD_CTX_init(&md_ctx);
-	if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */))
-		{
-		EVP_MD_CTX_cleanup(&md_ctx);
-		return 0;
-		}
+      is_past_c = is_block_a & constant_time_ge_8(j, c);
+      is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1);
+      /* If this is the block containing the end of the
+       * application data, and we are at the offset for the
+       * 0x80 value, then overwrite b with 0x80. */
+      b = constant_time_select_8(is_past_c, 0x80, b);
+      /* If this the the block containing the end of the
+       * application data and we're past the 0x80 value then
+       * just write zero. */
+      b = b & ~is_past_cp1;
+      /* If this is index_b (the final block), but not
+       * index_a (the end of the data), then the 64-bit
+       * length didn't fit into index_a and we're having to
+       * add an extra block of zeros. */
+      b &= ~is_block_b | is_block_a;
 
-	if (is_sslv3)
-		{
-		/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
-		memset(hmac_pad, 0x5c, sslv3_pad_length);
+      /* The final bytes of one of the blocks contains the
+       * length. */
+      if (j >= md_block_size - md_length_size) {
+        /* If this is index_b, write a length byte. */
+        b = constant_time_select_8(
+            is_block_b, length_bytes[j - (md_block_size - md_length_size)], b);
+      }
+      block[j] = b;
+    }
 
-		EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
-		EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
-		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
-		}
-	else
-		{
-		/* Complete the HMAC in the standard manner. */
-		for (i = 0; i < md_block_size; i++)
-			hmac_pad[i] ^= 0x6a;
+    md_transform(md_state.c, block);
+    md_final_raw(md_state.c, block);
+    /* If this is index_b, copy the hash value to |mac_out|. */
+    for (j = 0; j < md_size; j++) {
+      mac_out[j] |= block[j] & is_block_b;
+    }
+  }
 
-		EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
-		EVP_DigestUpdate(&md_ctx, mac_out, md_size);
-		}
-	EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
-	*md_out_size = md_out_size_u;
-	EVP_MD_CTX_cleanup(&md_ctx);
+  EVP_MD_CTX_init(&md_ctx);
+  if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) {
+    EVP_MD_CTX_cleanup(&md_ctx);
+    return 0;
+  }
 
-	return 1;
-	}
+  if (is_sslv3) {
+    /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+    memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+    EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
+    EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
+    EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+  } else {
+    /* Complete the HMAC in the standard manner. */
+    for (i = 0; i < md_block_size; i++) {
+      hmac_pad[i] ^= 0x6a;
+    }
+
+    EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
+    EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+  }
+  EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
+  *md_out_size = md_out_size_u;
+  EVP_MD_CTX_cleanup(&md_ctx);
+
+  return 1;
+}
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;
+}
