Call cert_cb before resolving resumption.
This is in preparation for determining the cipher suite (which, in TLS
1.2, requires the certificate be known) before resumption.
Note this has caller-visible effects:
- cert_cb is now called whether resumption occurs or not. Our only
consumer which uses this as a server is Node which will require a
patch to fix up their mucking about with SSL_get_session. (But the
patch should be quite upstreamable. More 1.1.0-compatible and
generally saner.)
- cert_cb is now called before new_session_cb and dos_protection_cb.
BUG=116
Change-Id: I6cc745757f63281fad714d4548f23880570204b0
Reviewed-on: https://boringssl-review.googlesource.com/11846
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index ca4223e..0a8b97b 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -123,6 +123,75 @@
return ssl_hs_error;
}
+ hs->state = state_select_parameters;
+ return ssl_hs_ok;
+}
+
+static const SSL_CIPHER *choose_tls13_cipher(
+ const SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
+ if (client_hello->cipher_suites_len % 2 != 0) {
+ return NULL;
+ }
+
+ CBS cipher_suites;
+ CBS_init(&cipher_suites, client_hello->cipher_suites,
+ client_hello->cipher_suites_len);
+
+ const int aes_is_fine = EVP_has_aes_hardware();
+
+ const SSL_CIPHER *best = NULL;
+ while (CBS_len(&cipher_suites) > 0) {
+ uint16_t cipher_suite;
+ if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
+ return NULL;
+ }
+
+ const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
+ if (candidate == NULL || !ssl_is_valid_cipher(ssl, candidate)) {
+ continue;
+ }
+
+ /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
+ * ChaCha20 if we do not have AES hardware. */
+ if (aes_is_fine) {
+ return candidate;
+ }
+
+ if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
+ return candidate;
+ }
+
+ if (best == NULL) {
+ best = candidate;
+ }
+ }
+
+ return best;
+}
+
+static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
+ /* Call |cert_cb| to update server certificates if required. */
+ if (ssl->cert->cert_cb != NULL) {
+ int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+ if (rv == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ if (rv < 0) {
+ hs->state = state_select_parameters;
+ return ssl_hs_x509_lookup;
+ }
+ }
+
+ struct ssl_early_callback_ctx client_hello;
+ if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
+ ssl->init_num)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+
uint8_t alert = SSL_AD_DECODE_ERROR;
SSL_SESSION *session = NULL;
CBS pre_shared_key, binders;
@@ -182,77 +251,6 @@
return ssl_hs_error;
}
- hs->state = state_select_parameters;
- return ssl_hs_ok;
-}
-
-static const SSL_CIPHER *choose_tls13_cipher(
- const SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
- if (client_hello->cipher_suites_len % 2 != 0) {
- return NULL;
- }
-
- CBS cipher_suites;
- CBS_init(&cipher_suites, client_hello->cipher_suites,
- client_hello->cipher_suites_len);
-
- const int aes_is_fine = EVP_has_aes_hardware();
-
- const SSL_CIPHER *best = NULL;
- while (CBS_len(&cipher_suites) > 0) {
- uint16_t cipher_suite;
- if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- return NULL;
- }
-
- const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
- if (candidate == NULL || !ssl_is_valid_cipher(ssl, candidate)) {
- continue;
- }
-
- /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
- * ChaCha20 if we do not have AES hardware. */
- if (aes_is_fine) {
- return candidate;
- }
-
- if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
- return candidate;
- }
-
- if (best == NULL) {
- best = candidate;
- }
- }
-
- return best;
-}
-
-static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
- if (!ssl->s3->session_reused) {
- /* Call |cert_cb| to update server certificates if required. */
- if (ssl->cert->cert_cb != NULL) {
- int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
- if (rv == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- if (rv < 0) {
- hs->state = state_select_parameters;
- return ssl_hs_x509_lookup;
- }
- }
- }
-
- struct ssl_early_callback_ctx client_hello;
- if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
- ssl->init_num)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
- }
-
if (ssl->s3->session_reused) {
/* Clients may not offer sessions containing unsupported ciphers. */
if (!ssl_client_cipher_list_contains_cipher(
@@ -287,7 +285,6 @@
/* Resolve ALPN after the cipher suite is selected. HTTP/2 negotiation depends
* on the cipher suite. */
- uint8_t alert;
if (!ssl_negotiate_alpn(ssl, &alert, &client_hello)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;