Make ssl3_choose_cipher and dependencies static.
Each of these functions is called only once, but they're interspersed
between s3_lib.c and ssl_lib.c.
Change-Id: Ic496e364b091fc8e01fc0653fe73c83c47f690d9
Reviewed-on: https://boringssl-review.googlesource.com/12583
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/handshake_server.c b/ssl/handshake_server.c
index 14c3a55..4bac0d5 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -652,6 +652,169 @@
return 0;
}
+static STACK_OF(SSL_CIPHER) *
+ ssl_parse_client_cipher_list(const SSL_CLIENT_HELLO *client_hello) {
+ CBS cipher_suites;
+ CBS_init(&cipher_suites, client_hello->cipher_suites,
+ client_hello->cipher_suites_len);
+
+ STACK_OF(SSL_CIPHER) *sk = sk_SSL_CIPHER_new_null();
+ if (sk == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ while (CBS_len(&cipher_suites) > 0) {
+ uint16_t cipher_suite;
+
+ if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ goto err;
+ }
+
+ const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite);
+ if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ return sk;
+
+err:
+ sk_SSL_CIPHER_free(sk);
+ return NULL;
+}
+
+/* ssl_get_compatible_server_ciphers determines the key exchange and
+ * authentication cipher suite masks compatible with the server configuration
+ * and current ClientHello parameters of |hs|. It sets |*out_mask_k| to the key
+ * exchange mask and |*out_mask_a| to the authentication mask. */
+static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs,
+ uint32_t *out_mask_k,
+ uint32_t *out_mask_a) {
+ SSL *const ssl = hs->ssl;
+ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ *out_mask_k = SSL_kGENERIC;
+ *out_mask_a = SSL_aGENERIC;
+ return;
+ }
+
+ uint32_t mask_k = 0;
+ uint32_t mask_a = 0;
+
+ if (ssl->cert->x509_leaf != NULL && ssl_has_private_key(ssl)) {
+ int type = ssl_private_key_type(ssl);
+ if (type == NID_rsaEncryption) {
+ mask_k |= SSL_kRSA;
+ mask_a |= SSL_aRSA;
+ } else if (ssl_is_ecdsa_key_type(type)) {
+ mask_a |= SSL_aECDSA;
+ }
+ }
+
+ if (ssl->cert->dh_tmp != NULL || ssl->cert->dh_tmp_cb != NULL) {
+ mask_k |= SSL_kDHE;
+ }
+
+ /* Check for a shared group to consider ECDHE ciphers. */
+ uint16_t unused;
+ if (tls1_get_shared_group(hs, &unused)) {
+ mask_k |= SSL_kECDHE;
+ }
+
+ /* CECPQ1 ciphers are always acceptable if supported by both sides. */
+ mask_k |= SSL_kCECPQ1;
+
+ /* PSK requires a server callback. */
+ if (ssl->psk_server_callback != NULL) {
+ mask_k |= SSL_kPSK;
+ mask_a |= SSL_aPSK;
+ }
+
+ *out_mask_k = mask_k;
+ *out_mask_a = mask_a;
+}
+
+static const SSL_CIPHER *ssl3_choose_cipher(
+ SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
+ const struct ssl_cipher_preference_list_st *server_pref) {
+ SSL *const ssl = hs->ssl;
+ const SSL_CIPHER *c, *ret = NULL;
+ STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow;
+ int ok;
+ size_t cipher_index;
+ uint32_t alg_k, alg_a, mask_k, mask_a;
+ /* in_group_flags will either be NULL, or will point to an array of bytes
+ * which indicate equal-preference groups in the |prio| stack. See the
+ * comment about |in_group_flags| in the |ssl_cipher_preference_list_st|
+ * struct. */
+ const uint8_t *in_group_flags;
+ /* group_min contains the minimal index so far found in a group, or -1 if no
+ * such value exists yet. */
+ int group_min = -1;
+
+ STACK_OF(SSL_CIPHER) *clnt = ssl_parse_client_cipher_list(client_hello);
+ if (clnt == NULL) {
+ return NULL;
+ }
+
+ if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
+ prio = srvr;
+ in_group_flags = server_pref->in_group_flags;
+ allow = clnt;
+ } else {
+ prio = clnt;
+ in_group_flags = NULL;
+ allow = srvr;
+ }
+
+ ssl_get_compatible_server_ciphers(hs, &mask_k, &mask_a);
+
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
+ c = sk_SSL_CIPHER_value(prio, i);
+
+ ok = 1;
+
+ /* Check the TLS version. */
+ if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) ||
+ SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl)) {
+ ok = 0;
+ }
+
+ alg_k = c->algorithm_mkey;
+ alg_a = c->algorithm_auth;
+
+ ok = ok && (alg_k & mask_k) && (alg_a & mask_a);
+
+ if (ok && sk_SSL_CIPHER_find(allow, &cipher_index, c)) {
+ if (in_group_flags != NULL && in_group_flags[i] == 1) {
+ /* This element of |prio| is in a group. Update the minimum index found
+ * so far and continue looking. */
+ if (group_min == -1 || (size_t)group_min > cipher_index) {
+ group_min = cipher_index;
+ }
+ } else {
+ if (group_min != -1 && (size_t)group_min < cipher_index) {
+ cipher_index = group_min;
+ }
+ ret = sk_SSL_CIPHER_value(allow, cipher_index);
+ break;
+ }
+ }
+
+ if (in_group_flags != NULL && in_group_flags[i] == 0 && group_min != -1) {
+ /* We are about to leave a group, but we found a match in it, so that's
+ * our answer. */
+ ret = sk_SSL_CIPHER_value(allow, group_min);
+ break;
+ }
+ }
+
+ sk_SSL_CIPHER_free(clnt);
+ return ret;
+}
+
static int ssl3_get_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
uint8_t al = SSL_AD_INTERNAL_ERROR;
diff --git a/ssl/internal.h b/ssl/internal.h
index 9fd416d..3b297ea 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1143,9 +1143,6 @@
int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
CBS *out, uint16_t extension_type);
-STACK_OF(SSL_CIPHER) *
- ssl_parse_client_cipher_list(const SSL_CLIENT_HELLO *client_hello);
-
int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello,
uint16_t id);
@@ -1717,13 +1714,6 @@
STACK_OF(X509) * cert_chain);
void ssl_update_cache(SSL_HANDSHAKE *hs, int mode);
-/* ssl_get_compatible_server_ciphers determines the key exchange and
- * authentication cipher suite masks compatible with the server configuration
- * and current ClientHello parameters of |hs|. It sets |*out_mask_k| to the key
- * exchange mask and |*out_mask_a| to the authentication mask. */
-void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs, uint32_t *out_mask_k,
- uint32_t *out_mask_a);
-
int ssl_verify_alarm_type(long type);
int ssl3_get_finished(SSL_HANDSHAKE *hs);
@@ -1753,10 +1743,6 @@
int ssl3_write_bytes(SSL *ssl, int type, const void *buf, int len);
int ssl3_output_cert_chain(SSL *ssl);
-const SSL_CIPHER *ssl3_choose_cipher(
- SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
- const struct ssl_cipher_preference_list_st *srvr);
-
int ssl3_new(SSL *ssl);
void ssl3_free(SSL *ssl);
int ssl3_accept(SSL_HANDSHAKE *hs);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 505a7c6..b5006f6 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -240,85 +240,6 @@
return NULL;
}
-const SSL_CIPHER *ssl3_choose_cipher(
- SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
- const struct ssl_cipher_preference_list_st *server_pref) {
- SSL *const ssl = hs->ssl;
- const SSL_CIPHER *c, *ret = NULL;
- STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow;
- int ok;
- size_t cipher_index;
- uint32_t alg_k, alg_a, mask_k, mask_a;
- /* in_group_flags will either be NULL, or will point to an array of bytes
- * which indicate equal-preference groups in the |prio| stack. See the
- * comment about |in_group_flags| in the |ssl_cipher_preference_list_st|
- * struct. */
- const uint8_t *in_group_flags;
- /* group_min contains the minimal index so far found in a group, or -1 if no
- * such value exists yet. */
- int group_min = -1;
-
- STACK_OF(SSL_CIPHER) *clnt = ssl_parse_client_cipher_list(client_hello);
- if (clnt == NULL) {
- return NULL;
- }
-
- if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
- prio = srvr;
- in_group_flags = server_pref->in_group_flags;
- allow = clnt;
- } else {
- prio = clnt;
- in_group_flags = NULL;
- allow = srvr;
- }
-
- ssl_get_compatible_server_ciphers(hs, &mask_k, &mask_a);
-
- for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
- c = sk_SSL_CIPHER_value(prio, i);
-
- ok = 1;
-
- /* Check the TLS version. */
- if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) ||
- SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl)) {
- ok = 0;
- }
-
- alg_k = c->algorithm_mkey;
- alg_a = c->algorithm_auth;
-
- ok = ok && (alg_k & mask_k) && (alg_a & mask_a);
-
- if (ok && sk_SSL_CIPHER_find(allow, &cipher_index, c)) {
- if (in_group_flags != NULL && in_group_flags[i] == 1) {
- /* This element of |prio| is in a group. Update the minimum index found
- * so far and continue looking. */
- if (group_min == -1 || (size_t)group_min > cipher_index) {
- group_min = cipher_index;
- }
- } else {
- if (group_min != -1 && (size_t)group_min < cipher_index) {
- cipher_index = group_min;
- }
- ret = sk_SSL_CIPHER_value(allow, cipher_index);
- break;
- }
- }
-
- if (in_group_flags != NULL && in_group_flags[i] == 0 && group_min != -1) {
- /* We are about to leave a group, but we found a match in it, so that's
- * our answer. */
- ret = sk_SSL_CIPHER_value(allow, group_min);
- break;
- }
- }
-
- sk_SSL_CIPHER_free(clnt);
- return ret;
-}
-
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
* handshake macs if required. */
uint32_t ssl_get_algorithm_prf(const SSL *ssl) {
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 7ac4016..1febfeb 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1692,40 +1692,6 @@
return 1;
}
-STACK_OF(SSL_CIPHER) *
- ssl_parse_client_cipher_list(const SSL_CLIENT_HELLO *client_hello) {
- CBS cipher_suites;
- CBS_init(&cipher_suites, client_hello->cipher_suites,
- client_hello->cipher_suites_len);
-
- STACK_OF(SSL_CIPHER) *sk = sk_SSL_CIPHER_new_null();
- if (sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- while (CBS_len(&cipher_suites) > 0) {
- uint16_t cipher_suite;
-
- if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
- goto err;
- }
-
- const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite);
- if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- return sk;
-
-err:
- sk_SSL_CIPHER_free(sk);
- return NULL;
-}
-
const char *SSL_get_servername(const SSL *ssl, const int type) {
if (type != TLSEXT_NAMETYPE_host_name) {
return NULL;
@@ -2060,51 +2026,6 @@
return ssl->s3->hs->num_certificate_types;
}
-void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs, uint32_t *out_mask_k,
- uint32_t *out_mask_a) {
- SSL *const ssl = hs->ssl;
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- *out_mask_k = SSL_kGENERIC;
- *out_mask_a = SSL_aGENERIC;
- return;
- }
-
- uint32_t mask_k = 0;
- uint32_t mask_a = 0;
-
- if (ssl->cert->x509_leaf != NULL && ssl_has_private_key(ssl)) {
- int type = ssl_private_key_type(ssl);
- if (type == NID_rsaEncryption) {
- mask_k |= SSL_kRSA;
- mask_a |= SSL_aRSA;
- } else if (ssl_is_ecdsa_key_type(type)) {
- mask_a |= SSL_aECDSA;
- }
- }
-
- if (ssl->cert->dh_tmp != NULL || ssl->cert->dh_tmp_cb != NULL) {
- mask_k |= SSL_kDHE;
- }
-
- /* Check for a shared group to consider ECDHE ciphers. */
- uint16_t unused;
- if (tls1_get_shared_group(hs, &unused)) {
- mask_k |= SSL_kECDHE;
- }
-
- /* CECPQ1 ciphers are always acceptable if supported by both sides. */
- mask_k |= SSL_kCECPQ1;
-
- /* PSK requires a server callback. */
- if (ssl->psk_server_callback != NULL) {
- mask_k |= SSL_kPSK;
- mask_a |= SSL_aPSK;
- }
-
- *out_mask_k = mask_k;
- *out_mask_a = mask_a;
-}
-
void ssl_update_cache(SSL_HANDSHAKE *hs, int mode) {
SSL *const ssl = hs->ssl;
SSL_CTX *ctx = ssl->initial_ctx;