Remove support on both sides for *_fixed_(ec)dh client auth.

In the fixed_ecdh case, it wasn't even implemented, but there was stub code for
it. It complicates the ClientKeyExchange (the client parameters become implicit
in the certificate) and isn't used.

Change-Id: I3627a37042539c90e05e59cd0cb3cd6c56225561
Reviewed-on: https://boringssl-review.googlesource.com/1563
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 4edb6df..665f2c6 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -341,7 +341,6 @@
 #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
 #define SSL3_FLAGS_POP_BUFFER			0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
-#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 #define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020
 /* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec
  * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 51fd144..99cfefd 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -375,9 +375,6 @@
 			dtls1_start_timer(s);
 			ret=ssl3_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-
-			/* EAY EAY EAY need to check for DH fix cert
-			 * sent back */
 			/* 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)
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 33cd349..fd5bc11 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -492,22 +492,9 @@
 		case SSL3_ST_SR_KEY_EXCH_A:
 		case SSL3_ST_SR_KEY_EXCH_B:
 			ret=ssl3_get_client_key_exchange(s);
-			if (ret <= 0) goto end;
-
-			s->state=SSL3_ST_SR_CERT_VRFY_A;
-			s->init_num=0;
-
-			if (ret == 2)
-				{
-				/* For the ECDH ciphersuites when
-				 * the client sends its ECDH pub key in
-				 * a certificate, the CertificateVerify
-				 * message is not sent.
-				 */
-				s->state=SSL3_ST_SR_FINISHED_A;
-				s->init_num = 0;
-				}
-			else if (SSL_USE_SIGALGS(s))
+			if (ret <= 0)
+				goto end;
+			if (SSL_USE_SIGALGS(s))
 				{
 				s->state=SSL3_ST_SR_CERT_VRFY_A;
 				s->init_num=0;
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index cba98a7..253cf81 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -362,17 +362,8 @@
 		case SSL3_ST_CW_KEY_EXCH_B:
 			ret=ssl3_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-			/* EAY EAY EAY need to check for DH fix cert
-			 * sent back */
 			/* For TLS, cert_req is set to 2, so a cert chain
 			 * of nothing is sent, but no verify packet is sent */
-			/* XXX: For now, we do not support client 
-			 * authentication in ECDH cipher suites with
-			 * ECDH (rather than ECDSA) certificates.
-			 * We need to skip the certificate verify 
-			 * message when client's ECDH public key is sent 
-			 * inside the client certificate.
-			 */
 			if (s->s3->tmp.cert_req == 1)
 				{
 				s->state=SSL3_ST_CW_CERT_VRFY_A;
@@ -382,11 +373,6 @@
 				s->state=SSL3_ST_CW_CHANGE_A;
 				s->s3->change_cipher_spec=0;
 				}
-			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
-				{
-				s->state=SSL3_ST_CW_CHANGE_A;
-				s->s3->change_cipher_spec=0;
-				}
 
 			s->init_num=0;
 			break;
@@ -2122,33 +2108,17 @@
 					goto err;
 					}
 				}
-			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
+			/* generate a new random key */
+			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
 				{
-				/* Use client certificate key */
-				EVP_PKEY *clkey = s->cert->key->privatekey;
-				dh_clnt = NULL;
-				if (clkey)
-					dh_clnt = EVP_PKEY_get1_DH(clkey);
-				if (dh_clnt == NULL)
-					{
-					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
-					goto err;
-					}
+				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+				goto err;
 				}
-			else
+			if (!DH_generate_key(dh_clnt))
 				{
-				/* 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;
-					}
+				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+				DH_free(dh_clnt);
+				goto err;
 				}
 
 			/* use the 'p' output buffer for the DH key, but
@@ -2172,16 +2142,11 @@
 			/* clean up */
 			memset(p,0,n);
 
-			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
-				n = 0;
-			else
-				{
-				/* send off the data */
-				n=BN_num_bytes(dh_clnt->pub_key);
-				s2n(n,p);
-				BN_bn2bin(dh_clnt->pub_key,p);
-				n+=2;
-				}
+			/* send off the data */
+			n=BN_num_bytes(dh_clnt->pub_key);
+			s2n(n,p);
+			BN_bn2bin(dh_clnt->pub_key,p);
+			n+=2;
 
 			DH_free(dh_clnt);
 
@@ -2194,7 +2159,6 @@
 			{
 			const EC_GROUP *srvr_group = NULL;
 			EC_KEY *tkey;
-			int ecdh_clnt_cert = 0;
 			int field_size = 0;
 			unsigned char *pre_ms;
 			unsigned char *t;
@@ -2208,34 +2172,6 @@
 				goto err;
 				}
 
-			/* Did we send out the client's
-			 * ECDH share for use in premaster
-			 * computation as part of client certificate?
-			 * If so, set ecdh_clnt_cert to 1.
-			 */
-			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
-				{
-				/* XXX: For now, we do not support client
-				 * authentication using ECDH certificates.
-				 * To add such support, one needs to add
-				 * code that checks for appropriate 
-				 * conditions and sets ecdh_clnt_cert to 1.
-				 * For example, the cert have an ECC
-				 * key on the same curve as the server's
-				 * and the key should be authorized for
-				 * key agreement.
-				 *
-				 * One also needs to add code in ssl3_connect
-				 * to skip sending the certificate verify
-				 * message.
-				 *
-				 * if ((s->cert->key->privatekey != NULL) &&
-				 *     (s->cert->key->privatekey->type ==
-				 *      EVP_PKEY_EC) && ...)
-				 * ecdh_clnt_cert = 1;
-				 */
-				}
-
 			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
 				{
 				tkey = s->session->sess_cert->peer_ecdh_tmp;
@@ -2276,34 +2212,11 @@
 				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
 				goto err;
 				}
-			if (ecdh_clnt_cert) 
-				{ 
-				/* Reuse key info from our certificate
-				 * We only need our private key to perform
-				 * the ECDH computation.
-				 */
-				const BIGNUM *priv_key;
-				tkey = s->cert->key->privatekey->pkey.ec;
-				priv_key = EC_KEY_get0_private_key(tkey);
-				if (priv_key == NULL)
-					{
-					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
-					goto err;
-					}
-				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
-					{
-					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
-					goto err;
-					}
-				}
-			else 
+			/* Generate a new ECDH key pair */
+			if (!(EC_KEY_generate_key(clnt_ecdh)))
 				{
-				/* 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;
-					}
+				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+				goto err;
 				}
 
 			/* use the 'p' output buffer for the ECDH key, but
@@ -2355,59 +2268,51 @@
 				}
 			memset(p, 0, n); /* clean up */
 
-			if (ecdh_clnt_cert)
-				{
-				/* Send empty client key exch message */
-				n = 0;
-				}
-			else 
-				{
-				/* First check the size of encoding and
-				 * allocate memory accordingly.
-				 */
-				encoded_pt_len = 
-				    EC_POINT_point2oct(srvr_group, 
+			/* 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 * 
+			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);
-
-				n = 0;
-				if ((alg_a & SSL_aPSK) && psk_len != 0)
-					{
-					i = strlen(s->session->psk_identity);
-					s2n(i, p);
-					memcpy(p, s->session->psk_identity, i);
-					p += i;
-					n = i + 2;
-					}
-
-				*p = encoded_pt_len; /* length of encoded point */
-				/* Encoded point will be copied here */
-				p += 1;
-				n += 1;
-				/* copy the point */
-				memcpy((unsigned char *)p, encodedPoint, encoded_pt_len);
-				/* increment n to account for length field */
-				n += encoded_pt_len;
+			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);
+
+			n = 0;
+			if ((alg_a & SSL_aPSK) && psk_len != 0)
+				{
+				i = strlen(s->session->psk_identity);
+				s2n(i, p);
+				memcpy(p, s->session->psk_identity, i);
+				p += i;
+				n = i + 2;
+				}
+
+			*p = encoded_pt_len; /* length of encoded point */
+			/* Encoded point will be copied here */
+			p += 1;
+			n += 1;
+			/* copy the point */
+			memcpy((unsigned char *)p, encodedPoint, encoded_pt_len);
+			/* increment n to account for length field */
+			n += encoded_pt_len;
+
 			/* Free allocated memory */
 			BN_CTX_free(bn_ctx);
 			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
@@ -2560,12 +2465,10 @@
 	}
 
 /* Check a certificate can be used for client authentication. Currently
- * check cert exists, if we have a suitable digest for TLS 1.2 if
- * static DH client certificates can be used.
+ * check the cert exists and if we have a suitable digest for TLS 1.2.
  */
 static int ssl3_check_client_certificate(SSL *s)
 	{
-	unsigned long alg_k;
 	if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey)
 		return 0;
 	/* If no suitable signature algorithm can't use certificate */
@@ -2576,29 +2479,6 @@
 	if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT &&
 		!tls1_check_chain(s, NULL, NULL, NULL, -2))
 		return 0;
-	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
-	/* See if we can use client certificate for fixed DH */
-	if (alg_k & (SSL_kDHr|SSL_kDHd))
-		{
-		SESS_CERT *scert = s->session->sess_cert;
-		int i = scert->peer_cert_type;
-		EVP_PKEY *clkey = NULL, *spkey = NULL;
-		clkey = s->cert->key->privatekey;
-		/* If client key not DH assume it can be used */
-		if (EVP_PKEY_id(clkey) != EVP_PKEY_DH)
-			return 1;
-		if (i >= 0)
-			spkey = X509_get_pubkey(scert->peer_pkeys[i].x509);
-		if (spkey)
-			{
-			/* Compare server and client parameters */
-			i = EVP_PKEY_cmp_parameters(clkey, spkey);
-			EVP_PKEY_free(spkey);
-			if (i != 1)
-				return 0;
-			}
-		s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
-		}
 	return 1;
 	}
 
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index bd8761e..c151a8b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2538,8 +2538,6 @@
 #ifndef OPENSSL_NO_ECDSA
 	int have_ecdsa_sign = 0;
 #endif
-	int nostrict = 1;
-	unsigned long alg_k;
 
 	/* If we have custom certificate types set, use them */
 	if (s->cert->client_certificate_types)
@@ -2550,8 +2548,6 @@
 		}
 	/* get configured sigalgs */
 	siglen = tls12_get_psigalgs(s, &sig);
-	if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
-		nostrict = 0;
 	for (i = 0; i < siglen; i+=2, sig+=2)
 		{
 		switch(sig[1])
@@ -2571,45 +2567,12 @@
 			}
 		}
 
-	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-
-#ifndef OPENSSL_NO_DH
-	if (alg_k & (SSL_kDHr|SSL_kEDH))
-		{
-		/* Since this refers to a certificate signed with an RSA
-		 * algorithm, only check for rsa signing in strict mode.
-		 */
-		if (nostrict || have_rsa_sign)
-			p[ret++]=SSL3_CT_RSA_FIXED_DH;
-#  ifndef OPENSSL_NO_DSA
-		if (nostrict || have_dsa_sign)
-			p[ret++]=SSL3_CT_DSS_FIXED_DH;
-#  endif
-		}
-	if ((s->version == SSL3_VERSION) &&
-		(alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
-		{
-		p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH;
-#  ifndef OPENSSL_NO_DSA
-		p[ret++]=SSL3_CT_DSS_EPHEMERAL_DH;
-#  endif
-		}
-#endif /* !OPENSSL_NO_DH */
 	if (have_rsa_sign)
 		p[ret++]=SSL3_CT_RSA_SIGN;
 #ifndef OPENSSL_NO_DSA
 	if (have_dsa_sign)
 		p[ret++]=SSL3_CT_DSS_SIGN;
 #endif
-#ifndef OPENSSL_NO_ECDH
-	if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION))
-		{
-		if (nostrict || have_rsa_sign)
-			p[ret++]=TLS_CT_RSA_FIXED_ECDH;
-		if (nostrict || have_ecdsa_sign)
-			p[ret++]=TLS_CT_ECDSA_FIXED_ECDH;
-		}
-#endif
 
 #ifndef OPENSSL_NO_ECDSA
 	/* ECDSA certs can be used with RSA cipher suites as well 
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 235abab..231c47f 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -259,7 +259,6 @@
 
 			s->init_num=0;
 			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
-			s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
 
 			if (s->state != SSL_ST_RENEGOTIATE)
 				{
@@ -493,17 +492,7 @@
 			ret=ssl3_get_client_key_exchange(s);
 			if (ret <= 0)
 				goto end;
-			if (ret == 2)
-				{
-				/* For the ECDH ciphersuites when
-				 * the client sends its ECDH pub key in
-				 * a certificate, the CertificateVerify
-				 * message is not sent.
-				 */
-				s->init_num = 0;
-				s->state = SSL3_ST_SR_CHANGE;
-				}
-			else if (SSL_USE_SIGALGS(s))
+			if (SSL_USE_SIGALGS(s))
 				{
 				s->state=SSL3_ST_SR_CERT_VRFY_A;
 				s->init_num=0;
@@ -1885,13 +1874,12 @@
 	unsigned long alg_a;
 	uint8_t *premaster_secret = NULL;
 	size_t premaster_secret_len = 0;
-	int skip_certificate_verify = 0;
 	RSA *rsa=NULL;
 	uint8_t *decrypt_buf = NULL;
 	EVP_PKEY *pkey=NULL;
 #ifndef OPENSSL_NO_DH
 	BIGNUM *pub=NULL;
-	DH *dh_srvr, *dh_clnt = NULL;
+	DH *dh_srvr;
 #endif
 
 #ifndef OPENSSL_NO_ECDH
@@ -1972,8 +1960,7 @@
 		}
 
 	/* Depending on the key exchange method, compute |premaster_secret| and
-	 * |premaster_secret_len|. Also, for DH and ECDH, set
-	 * |skip_certificate_verify| as appropriate. */
+	 * |premaster_secret_len|. */
 	if (alg_k & SSL_kRSA)
 		{
 		CBS encrypted_premaster_secret;
@@ -2139,6 +2126,7 @@
 		EVP_PKEY *skey = NULL;
 
 		if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) ||
+			CBS_len(&dh_Yc) == 0 ||
 			CBS_len(&client_key_exchange) != 0)
 			{
 			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
@@ -2172,33 +2160,7 @@
 		else
 			dh_srvr=s->s3->tmp.dh;
 
-		if (CBS_len(&dh_Yc) == 0)
-			{
-			/* Get pubkey from the client certificate. This is the
-			 * 'implicit' case of ClientDiffieHellman.
-			 *
-			 * TODO(davidben): Either lose this code or fix a bug
-			 * (or get the spec changed): if there is a fixed_dh
-			 * client certificate, per spec, the 'implicit' mode
-			 * MUST be used. This logic will still accept 'explicit'
-			 * mode. */
-			EVP_PKEY *clkey=X509_get_pubkey(s->session->peer);
-			if (clkey)
-				{
-				if (EVP_PKEY_cmp_parameters(clkey, skey) == 1)
-					dh_clnt = EVP_PKEY_get1_DH(clkey);
-				}
-			if (dh_clnt == NULL)
-				{
-				al=SSL_AD_HANDSHAKE_FAILURE;
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_TMP_DH_KEY);
-				goto f_err;
-				}
-			EVP_PKEY_free(clkey);
-			pub = dh_clnt->pub_key;
-			}
-		else
-			pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL);
+		pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL);
 		if (pub == NULL)
 			{
 			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_BN_LIB);
@@ -2223,15 +2185,10 @@
 
 		DH_free(s->s3->tmp.dh);
 		s->s3->tmp.dh=NULL;
-		if (dh_clnt)
-			DH_free(dh_clnt);
-		else
-			BN_clear_free(pub);
+		BN_clear_free(pub);
 		pub=NULL;
 
 		premaster_secret_len = dh_len;
-		if (dh_clnt)
-			skip_certificate_verify = 1;
 		}
 #endif
 
@@ -2242,6 +2199,7 @@
 		const EC_KEY   *tkey;
 		const EC_GROUP *group;
 		const BIGNUM *priv_key;
+		CBS ecdh_Yc;
 
 		/* initialize structures for server's ECDH key pair */
 		if ((srvr_ecdh = EC_KEY_new()) == NULL) 
@@ -2281,72 +2239,28 @@
 			goto err;
 			}
 
-		if (CBS_len(&client_key_exchange) == 0)
+		/* Get client's public key from encoded point
+		 * in the ClientKeyExchange message.
+		 */
+		if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) ||
+			CBS_len(&client_key_exchange) != 0)
 			{
-			/* Client Publickey was in Client Certificate */
-
-			 if (alg_k & SSL_kEECDH)
-				 {
-				 al=SSL_AD_HANDSHAKE_FAILURE;
-				 OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_TMP_ECDH_KEY);
-				 goto f_err;
-				 }
-			if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
-			    == NULL) || 
-			    (clnt_pub_pkey->type != EVP_PKEY_EC))
-				{
-				/* XXX: For now, we do not support client
-				 * authentication using ECDH certificates
-				 * so this branch (n == 0L) of the code is
-				 * never executed. When that support is
-				 * added, we ought to ensure the key 
-				 * received in the certificate is 
-				 * authorized for key agreement.
-				 * ECDH_compute_key implicitly checks that
-				 * the two ECDH shares are for the same
-				 * group.
-				 */
-			   	al=SSL_AD_HANDSHAKE_FAILURE;
-			   	OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
-			   	goto f_err;
-			   	}
-
-			if (EC_POINT_copy(clnt_ecpoint,
-			    EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
-				goto err;
-				}
-			/* Skip certificate verify processing */
-			skip_certificate_verify = 1;
+			al = SSL_AD_DECODE_ERROR;
+			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
+			goto f_err;
 			}
-		else
+
+		if ((bn_ctx = BN_CTX_new()) == NULL)
 			{
-			CBS ecdh_Yc;
+			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
 
-			/* Get client's public key from encoded point
-			 * in the ClientKeyExchange message.
-			 */
-			if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) ||
-				CBS_len(&client_key_exchange) != 0)
-				{
-				al = SSL_AD_DECODE_ERROR;
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
-				goto f_err;
-				}
-
-			if ((bn_ctx = BN_CTX_new()) == NULL)
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-
-			if (!EC_POINT_oct2point(group, clnt_ecpoint,
-					CBS_data(&ecdh_Yc), CBS_len(&ecdh_Yc), bn_ctx))
-				{
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
-				goto err;
-				}
+		if (!EC_POINT_oct2point(group, clnt_ecpoint,
+				CBS_data(&ecdh_Yc), CBS_len(&ecdh_Yc), bn_ctx))
+			{
+			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
+			goto err;
 			}
 
 		/* Allocate a buffer for both the secret and the PSK. */
@@ -2441,7 +2355,7 @@
 
 	OPENSSL_cleanse(premaster_secret, premaster_secret_len);
 	OPENSSL_free(premaster_secret);
-	return skip_certificate_verify ? 2 : 1;
+	return 1;
 f_err:
 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
 err: