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; + }