Remove SSL_OP_EPHEMERAL_RSA quirk.

Also fix a place where fixes for the condition for sending ServerKeyExchange in
s3_srvr.c were never propogated to d1_srvr.c. Tidy up that logic to use
ssl_cipher_requires_server_key_exchange and simplify the PSK check.

Change-Id: Ie36d378f733e59a8df405bc869f2346af59bd574
Reviewed-on: https://boringssl-review.googlesource.com/1283
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 59c5ec3..5fe5a58 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -164,6 +164,7 @@
 	BUF_MEM *buf;
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	unsigned long alg_k;
+	unsigned long alg_a;
 	int ret= -1;
 	int new_state,state,skip=0;
 	int listen;
@@ -375,28 +376,22 @@
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+			alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
-
-			/* only send if a DH key exchange or
-			 * RSA but we have a sign only certificate */
-			if (s->s3->tmp.use_rsa_tmp
-			/* PSK: send ServerKeyExchange if PSK identity
-			 * hint if provided */
-			    || ((alg_k & SSL_kPSK) && s->session->psk_identity_hint)
-			    || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
-			    || (alg_k & SSL_kEECDH)
-			    || ((alg_k & SSL_kRSA)
+			/* Send a ServerKeyExchange message if:
+			 * - The key exchange is ephemeral or anonymous
+			 *   Diffie-Hellman.
+			 * - There is a PSK identity hint.
+			 * - We have a signing-only RSA key.
+			 *   TODO(davidben): Remove this?
+			 *
+			 * TODO(davidben): This logic is currently duplicated
+			 * in s3_srvr.c. Fix this. In the meantime, keep them
+			 * in sync.
+			 */
+			if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) ||
+			    ((alg_a & SSL_aPSK) && s->session->psk_identity_hint) ||
+			    ((alg_k & SSL_kRSA)
 				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
 				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
 					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index ab94786..94720a8 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -374,38 +374,20 @@
 			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 			alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
-			/* clear this, it may get reset by
-			 * send_server_key_exchange */
-			if ((s->options & SSL_OP_EPHEMERAL_RSA)
-				)
-				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
-				 * even when forbidden by protocol specs
-				 * (handshake may fail as clients are not required to
-				 * be able to handle this) */
-				s->s3->tmp.use_rsa_tmp=1;
-			else
-				s->s3->tmp.use_rsa_tmp=0;
-
-
-			/* only send if a DH key exchange, fortezza or
-			 * RSA but we have a sign only certificate
+			/* Send a ServerKeyExchange message if:
+			 * - The key exchange is ephemeral or anonymous
+			 *   Diffie-Hellman.
+			 * - There is a PSK identity hint.
+			 * - We have a signing-only RSA key.
+			 *   TODO(davidben): Remove this?
 			 *
-			 * PSK: may send PSK identity hints
-			 *
-			 * For ECC ciphersuites, we send a serverKeyExchange
-			 * message only if the cipher suite is either
-			 * ECDH-anon or ECDHE. In other cases, the
-			 * server certificate contains the server's
-			 * public key for key exchange.
+			 * TODO(davidben): This logic is currently duplicated
+			 * in d1_srvr.c. Fix this. In the meantime, keep them
+			 * in sync.
 			 */
-			if (s->s3->tmp.use_rsa_tmp
-			/* PSK: send ServerKeyExchange if either:
-			 *   - PSK identity hint is provided, or
-			 *   - the key exchange is kEECDH. */
-			    || ((alg_a & SSL_aPSK) && ((alg_k & SSL_kEECDH) || s->session->psk_identity_hint))
-			    || (alg_k & SSL_kEDH)
-			    || (alg_k & SSL_kEECDH)
-			    || ((alg_k & SSL_kRSA)
+			if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) ||
+			    ((alg_a & SSL_aPSK) && s->session->psk_identity_hint) ||
+			    ((alg_k & SSL_kRSA)
 				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
 				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
 					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
@@ -1528,7 +1510,6 @@
 				}
 			r[0]=rsa->n;
 			r[1]=rsa->e;
-			s->s3->tmp.use_rsa_tmp=1;
 			}
 #ifndef OPENSSL_NO_DH
 		else if (alg_k & SSL_kEDH)
@@ -2083,34 +2064,16 @@
 		unsigned char version_good;
 		size_t j;
 
-		/* FIX THIS UP EAY EAY EAY EAY */
-		if (s->s3->tmp.use_rsa_tmp)
+		pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
+		if (	(pkey == NULL) ||
+			(pkey->type != EVP_PKEY_RSA) ||
+			(pkey->pkey.rsa == NULL))
 			{
-			if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
-				rsa=s->cert->rsa_tmp;
-			/* Don't do a callback because rsa_tmp should
-			 * be sent already */
-			if (rsa == NULL)
-				{
-				al=SSL_AD_HANDSHAKE_FAILURE;
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_TMP_RSA_PKEY);
-				goto f_err;
-
-				}
+			al=SSL_AD_HANDSHAKE_FAILURE;
+			OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_RSA_CERTIFICATE);
+			goto f_err;
 			}
-		else
-			{
-			pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
-			if (	(pkey == NULL) ||
-				(pkey->type != EVP_PKEY_RSA) ||
-				(pkey->pkey.rsa == NULL))
-				{
-				al=SSL_AD_HANDSHAKE_FAILURE;
-				OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_RSA_CERTIFICATE);
-				goto f_err;
-				}
-			rsa=pkey->pkey.rsa;
-			}
+		rsa=pkey->pkey.rsa;
 
 		/* TLS and [incidentally] DTLS{0xFEFF}
 		 *
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index f1fc69b..c150044 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1842,7 +1842,7 @@
  * TODO(davidben): Can we remove the RSA one? This is a remnant of
  * RSA_EXPORT ciphers which required this (it was used to generate an
  * ephemeral 512-bit RSA encryption key), but it's allowed for all RSA
- * ciphers. There's even a SSL_OP_EPHEMERAL_RSA to always use it. */
+ * ciphers. */
 int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher)
 	{
 	/* Ephemeral Diffie-Hellman key exchanges require a