Be strict about expecting a server Certificate message.

Introduce a ssl_cipher_has_server_public_key to save the repeated
NULL/PSK/RSA_PSK[*] check. Don't allow skipping to ServerKeyExchange when
expecting Certificate; the messages expected are determined by the cipher
suite. The ssl3_get_server_public_key call is already guarded.

As the previous test demonstrates, this is safe because of the
ssl3_check_cert_and_algorithm call, but avoid the looseness in the parsing
there.

[*] NB: we don't implement RSA_PSK, and OpenSSL has never implemented it.

Change-Id: I0571e6bcbeb8eb883f77878bdc98d1aa3a287cf3
Reviewed-on: https://boringssl-review.googlesource.com/1156
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index d7f3fba..4c4bb67 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1867,3 +1867,19 @@
 	{
 	return ssl->method->get_cipher_by_char(ptr);
 	}
+
+/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a
+ * server public key in the key exchange, sent in a server Certificate
+ * message. Otherwise it returns 0. */
+int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher)
+	{
+	/* Anonymous ciphers do not include a server certificate. */
+	if (cipher->algorithm_auth & SSL_aNULL)
+		return 0;
+	/* Neither do PSK ciphers, except for RSA_PSK. */
+	if ((cipher->algorithm_auth & SSL_aPSK) &&
+		!(cipher->algorithm_mkey & SSL_kRSA))
+		return 0;
+	/* All other ciphers include it. */
+	return 1;
+	}