Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/t1_lib.c')
-rw-r--r--ssl/t1_lib.c348
1 files changed, 155 insertions, 193 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 434286bf..16cac15e 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -110,7 +110,6 @@
#include <assert.h>
#include <limits.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -120,7 +119,7 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/type_check.h>
@@ -292,77 +291,77 @@ int SSL_early_callback_ctx_extension_get(
return 0;
}
-static const uint16_t eccurves_default[] = {
- SSL_CURVE_X25519,
- SSL_CURVE_SECP256R1,
- SSL_CURVE_SECP384R1,
+static const uint16_t kDefaultGroups[] = {
+ SSL_GROUP_X25519,
+ SSL_GROUP_SECP256R1,
+ SSL_GROUP_SECP384R1,
#if defined(BORINGSSL_ANDROID_SYSTEM)
- SSL_CURVE_SECP521R1,
+ SSL_GROUP_SECP521R1,
#endif
};
-/* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the
- * list of allowed curve IDs. If |get_peer_curves| is non-zero, return the
- * peer's curve list. Otherwise, return the preferred list. */
-static void tls1_get_curvelist(SSL *ssl, int get_peer_curves,
- const uint16_t **out_curve_ids,
- size_t *out_curve_ids_len) {
- if (get_peer_curves) {
- /* Only clients send a curve list, so this function is only called
- * on the server. */
+/* tls1_get_grouplist sets |*out_group_ids| and |*out_group_ids_len| to the
+ * list of allowed group IDs. If |get_peer_groups| is non-zero, return the
+ * peer's group list. Otherwise, return the preferred list. */
+static void tls1_get_grouplist(SSL *ssl, int get_peer_groups,
+ const uint16_t **out_group_ids,
+ size_t *out_group_ids_len) {
+ if (get_peer_groups) {
+ /* Only clients send a supported group list, so this function is only
+ * called on the server. */
assert(ssl->server);
- *out_curve_ids = ssl->s3->tmp.peer_ellipticcurvelist;
- *out_curve_ids_len = ssl->s3->tmp.peer_ellipticcurvelist_length;
+ *out_group_ids = ssl->s3->tmp.peer_supported_group_list;
+ *out_group_ids_len = ssl->s3->tmp.peer_supported_group_list_len;
return;
}
- *out_curve_ids = ssl->tlsext_ellipticcurvelist;
- *out_curve_ids_len = ssl->tlsext_ellipticcurvelist_length;
- if (!*out_curve_ids) {
- *out_curve_ids = eccurves_default;
- *out_curve_ids_len = sizeof(eccurves_default) / sizeof(eccurves_default[0]);
+ *out_group_ids = ssl->supported_group_list;
+ *out_group_ids_len = ssl->supported_group_list_len;
+ if (!*out_group_ids) {
+ *out_group_ids = kDefaultGroups;
+ *out_group_ids_len = sizeof(kDefaultGroups) / sizeof(kDefaultGroups[0]);
}
}
-int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id) {
- const uint16_t *curves, *peer_curves, *pref, *supp;
- size_t curves_len, peer_curves_len, pref_len, supp_len, i, j;
+int tls1_get_shared_group(SSL *ssl, uint16_t *out_group_id) {
+ const uint16_t *groups, *peer_groups, *pref, *supp;
+ size_t groups_len, peer_groups_len, pref_len, supp_len, i, j;
/* Can't do anything on client side */
if (ssl->server == 0) {
return 0;
}
- tls1_get_curvelist(ssl, 0 /* local curves */, &curves, &curves_len);
- tls1_get_curvelist(ssl, 1 /* peer curves */, &peer_curves, &peer_curves_len);
+ tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
+ tls1_get_grouplist(ssl, 1 /* peer groups */, &peer_groups, &peer_groups_len);
- if (peer_curves_len == 0) {
- /* Clients are not required to send a supported_curves extension. In this
- * case, the server is free to pick any curve it likes. See RFC 4492,
+ if (peer_groups_len == 0) {
+ /* Clients are not required to send a supported_groups extension. In this
+ * case, the server is free to pick any group it likes. See RFC 4492,
* section 4, paragraph 3.
*
* However, in the interests of compatibility, we will skip ECDH if the
* client didn't send an extension because we can't be sure that they'll
- * support our favoured curve. */
+ * support our favoured group. */
return 0;
}
if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
- pref = curves;
- pref_len = curves_len;
- supp = peer_curves;
- supp_len = peer_curves_len;
+ pref = groups;
+ pref_len = groups_len;
+ supp = peer_groups;
+ supp_len = peer_groups_len;
} else {
- pref = peer_curves;
- pref_len = peer_curves_len;
- supp = curves;
- supp_len = curves_len;
+ pref = peer_groups;
+ pref_len = peer_groups_len;
+ supp = groups;
+ supp_len = groups_len;
}
for (i = 0; i < pref_len; i++) {
for (j = 0; j < supp_len; j++) {
if (pref[i] == supp[j]) {
- *out_curve_id = pref[i];
+ *out_group_id = pref[i];
return 1;
}
}
@@ -371,34 +370,34 @@ int tls1_get_shared_curve(SSL *ssl, uint16_t *out_curve_id) {
return 0;
}
-int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
+int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len,
const int *curves, size_t ncurves) {
- uint16_t *curve_ids;
+ uint16_t *group_ids;
size_t i;
- curve_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
- if (curve_ids == NULL) {
+ group_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
+ if (group_ids == NULL) {
return 0;
}
for (i = 0; i < ncurves; i++) {
- if (!ssl_nid_to_curve_id(&curve_ids[i], curves[i])) {
- OPENSSL_free(curve_ids);
+ if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) {
+ OPENSSL_free(group_ids);
return 0;
}
}
- OPENSSL_free(*out_curve_ids);
- *out_curve_ids = curve_ids;
- *out_curve_ids_len = ncurves;
+ OPENSSL_free(*out_group_ids);
+ *out_group_ids = group_ids;
+ *out_group_ids_len = ncurves;
return 1;
}
-/* tls1_curve_params_from_ec_key sets |*out_curve_id| and |*out_comp_id| to the
- * TLS curve ID and point format, respectively, for |ec|. It returns one on
+/* tls1_curve_params_from_ec_key sets |*out_group_id| and |*out_comp_id| to the
+ * TLS group ID and point format, respectively, for |ec|. It returns one on
* success and zero on failure. */
-static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
+static int tls1_curve_params_from_ec_key(uint16_t *out_group_id,
uint8_t *out_comp_id, EC_KEY *ec) {
int nid;
uint16_t id;
@@ -413,14 +412,14 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
return 0;
}
- /* Determine curve ID */
+ /* Determine group ID */
nid = EC_GROUP_get_curve_name(grp);
- if (!ssl_nid_to_curve_id(&id, nid)) {
+ if (!ssl_nid_to_group_id(&id, nid)) {
return 0;
}
- /* Set the named curve ID. Arbitrary explicit curves are not supported. */
- *out_curve_id = id;
+ /* Set the named group ID. Arbitrary explicit groups are not supported. */
+ *out_group_id = id;
if (out_comp_id) {
if (EC_KEY_get0_public_key(ec) == NULL) {
@@ -436,35 +435,35 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
return 1;
}
-/* tls1_check_curve_id returns one if |curve_id| is consistent with both our
- * and the peer's curve preferences. Note: if called as the client, only our
+/* tls1_check_group_id returns one if |group_id| is consistent with both our
+ * and the peer's group preferences. Note: if called as the client, only our
* preferences are checked; the peer (the server) does not send preferences. */
-int tls1_check_curve_id(SSL *ssl, uint16_t curve_id) {
- const uint16_t *curves;
- size_t curves_len, i, get_peer_curves;
+int tls1_check_group_id(SSL *ssl, uint16_t group_id) {
+ const uint16_t *groups;
+ size_t groups_len, i, get_peer_groups;
/* Check against our list, then the peer's list. */
- for (get_peer_curves = 0; get_peer_curves <= 1; get_peer_curves++) {
- if (get_peer_curves && !ssl->server) {
+ for (get_peer_groups = 0; get_peer_groups <= 1; get_peer_groups++) {
+ if (get_peer_groups && !ssl->server) {
/* Servers do not present a preference list so, if we are a client, only
* check our list. */
continue;
}
- tls1_get_curvelist(ssl, get_peer_curves, &curves, &curves_len);
- if (get_peer_curves && curves_len == 0) {
- /* Clients are not required to send a supported_curves extension. In this
- * case, the server is free to pick any curve it likes. See RFC 4492,
+ tls1_get_grouplist(ssl, get_peer_groups, &groups, &groups_len);
+ if (get_peer_groups && groups_len == 0) {
+ /* Clients are not required to send a supported_groups extension. In this
+ * case, the server is free to pick any group it likes. See RFC 4492,
* section 4, paragraph 3. */
continue;
}
- for (i = 0; i < curves_len; i++) {
- if (curves[i] == curve_id) {
+ for (i = 0; i < groups_len; i++) {
+ if (groups[i] == group_id) {
break;
}
}
- if (i == curves_len) {
+ if (i == groups_len) {
return 0;
}
}
@@ -475,7 +474,7 @@ int tls1_check_curve_id(SSL *ssl, uint16_t curve_id) {
int tls1_check_ec_cert(SSL *ssl, X509 *x) {
int ret = 0;
EVP_PKEY *pkey = X509_get_pubkey(x);
- uint16_t curve_id;
+ uint16_t group_id;
uint8_t comp_id;
if (!pkey) {
@@ -483,8 +482,8 @@ int tls1_check_ec_cert(SSL *ssl, X509 *x) {
}
EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
if (ec_key == NULL ||
- !tls1_curve_params_from_ec_key(&curve_id, &comp_id, ec_key) ||
- !tls1_check_curve_id(ssl, curve_id) ||
+ !tls1_curve_params_from_ec_key(&group_id, &comp_id, ec_key) ||
+ !tls1_check_group_id(ssl, group_id) ||
comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) {
goto done;
}
@@ -688,82 +687,44 @@ static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
return 1;
}
- /* The servername extension is treated as follows:
- *
- * - Only the hostname type is supported with a maximum length of 255.
- * - The servername is rejected if too long or if it contains zeros, in
- * which case an fatal alert is generated.
- * - The servername field is maintained together with the session cache.
- * - When a session is resumed, the servername callback is invoked in order
- * to allow the application to position itself to the right context.
- * - The servername is acknowledged if it is new for a session or when
- * it is identical to a previously used for the same session.
- * Applications can control the behaviour. They can at any time
- * set a 'desirable' servername for a new SSL object. This can be the
- * case for example with HTTPS when a Host: header field is received and
- * a renegotiation is requested. In this case, a possible servername
- * presented in the new client hello is only acknowledged if it matches
- * the value of the Host: field.
- * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- * if they provide for changing an explicit servername context for the
- * session,
- * i.e. when the session has been established with a servername extension.
- */
-
- CBS server_name_list;
- char have_seen_host_name = 0;
-
+ CBS server_name_list, host_name;
+ uint8_t name_type;
if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
- CBS_len(&server_name_list) == 0 ||
+ !CBS_get_u8(&server_name_list, &name_type) ||
+ /* Although the server_name extension was intended to be extensible to
+ * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
+ * different name types will cause an error. Further, RFC 4366 originally
+ * defined syntax inextensibly. RFC 6066 corrected this mistake, but
+ * adding new name types is no longer feasible.
+ *
+ * Act as if the extensibility does not exist to simplify parsing. */
+ !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+ CBS_len(&server_name_list) != 0 ||
CBS_len(contents) != 0) {
return 0;
}
- /* Decode each ServerName in the extension. */
- while (CBS_len(&server_name_list) > 0) {
- uint8_t name_type;
- CBS host_name;
-
- if (!CBS_get_u8(&server_name_list, &name_type) ||
- !CBS_get_u16_length_prefixed(&server_name_list, &host_name)) {
- return 0;
- }
-
- /* Only host_name is supported. */
- if (name_type != TLSEXT_NAMETYPE_host_name) {
- continue;
- }
-
- if (have_seen_host_name) {
- /* The ServerNameList MUST NOT contain more than one name of the same
- * name_type. */
- return 0;
- }
+ if (name_type != TLSEXT_NAMETYPE_host_name ||
+ CBS_len(&host_name) == 0 ||
+ CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
+ CBS_contains_zero_byte(&host_name)) {
+ *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ return 0;
+ }
- have_seen_host_name = 1;
+ /* TODO(davidben): SNI should be resolved before resumption. We have the
+ * early callback as a replacement, but we should fix the current callback
+ * and avoid the need for |SSL_CTX_set_session_id_context|. */
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
- if (CBS_len(&host_name) == 0 ||
- CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
- CBS_contains_zero_byte(&host_name)) {
- *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ /* Copy the hostname as a string. */
+ if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- if (!ssl->hit) {
- assert(ssl->session->tlsext_hostname == NULL);
- if (ssl->session->tlsext_hostname) {
- /* This should be impossible. */
- return 0;
- }
-
- /* Copy the hostname as a string. */
- if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
-
- ssl->s3->tmp.should_ack_sni = 1;
- }
+ ssl->s3->tmp.should_ack_sni = 1;
}
return 1;
@@ -1848,35 +1809,36 @@ static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
}
-/* EC supported curves.
+/* Negotiated Groups
*
- * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
+ * https://tools.ietf.org/html/rfc4492#section-5.1.2
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-12#section-6.3.2.2 */
-static void ext_ec_curves_init(SSL *ssl) {
- OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
- ssl->s3->tmp.peer_ellipticcurvelist = NULL;
- ssl->s3->tmp.peer_ellipticcurvelist_length = 0;
+static void ext_supported_groups_init(SSL *ssl) {
+ OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
+ ssl->s3->tmp.peer_supported_group_list = NULL;
+ ssl->s3->tmp.peer_supported_group_list_len = 0;
}
-static int ext_ec_curves_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_supported_groups_add_clienthello(SSL *ssl, CBB *out) {
if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
return 1;
}
- CBB contents, curves_bytes;
- if (!CBB_add_u16(out, TLSEXT_TYPE_elliptic_curves) ||
+ CBB contents, groups_bytes;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
- !CBB_add_u16_length_prefixed(&contents, &curves_bytes)) {
+ !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) {
return 0;
}
- const uint16_t *curves;
- size_t curves_len;
- tls1_get_curvelist(ssl, 0, &curves, &curves_len);
+ const uint16_t *groups;
+ size_t groups_len;
+ tls1_get_grouplist(ssl, 0, &groups, &groups_len);
size_t i;
- for (i = 0; i < curves_len; i++) {
- if (!CBB_add_u16(&curves_bytes, curves[i])) {
+ for (i = 0; i < groups_len; i++) {
+ if (!CBB_add_u16(&groups_bytes, groups[i])) {
return 0;
}
}
@@ -1884,54 +1846,55 @@ static int ext_ec_curves_add_clienthello(SSL *ssl, CBB *out) {
return CBB_flush(out);
}
-static int ext_ec_curves_parse_serverhello(SSL *ssl, uint8_t *out_alert,
- CBS *contents) {
+static int ext_supported_groups_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
/* This extension is not expected to be echoed by servers and is ignored. */
return 1;
}
-static int ext_ec_curves_parse_clienthello(SSL *ssl, uint8_t *out_alert,
- CBS *contents) {
+static int ext_supported_groups_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
return 1;
}
- CBS elliptic_curve_list;
- if (!CBS_get_u16_length_prefixed(contents, &elliptic_curve_list) ||
- CBS_len(&elliptic_curve_list) == 0 ||
- (CBS_len(&elliptic_curve_list) & 1) != 0 ||
+ CBS supported_group_list;
+ if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) ||
+ CBS_len(&supported_group_list) == 0 ||
+ (CBS_len(&supported_group_list) & 1) != 0 ||
CBS_len(contents) != 0) {
return 0;
}
- ssl->s3->tmp.peer_ellipticcurvelist = OPENSSL_malloc(CBS_len(&elliptic_curve_list));
- if (ssl->s3->tmp.peer_ellipticcurvelist == NULL) {
+ ssl->s3->tmp.peer_supported_group_list = OPENSSL_malloc(
+ CBS_len(&supported_group_list));
+ if (ssl->s3->tmp.peer_supported_group_list == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- const size_t num_curves = CBS_len(&elliptic_curve_list) / 2;
+ const size_t num_groups = CBS_len(&supported_group_list) / 2;
size_t i;
- for (i = 0; i < num_curves; i++) {
- if (!CBS_get_u16(&elliptic_curve_list,
- &ssl->s3->tmp.peer_ellipticcurvelist[i])) {
+ for (i = 0; i < num_groups; i++) {
+ if (!CBS_get_u16(&supported_group_list,
+ &ssl->s3->tmp.peer_supported_group_list[i])) {
goto err;
}
}
- assert(CBS_len(&elliptic_curve_list) == 0);
- ssl->s3->tmp.peer_ellipticcurvelist_length = num_curves;
+ assert(CBS_len(&supported_group_list) == 0);
+ ssl->s3->tmp.peer_supported_group_list_len = num_groups;
return 1;
err:
- OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
- ssl->s3->tmp.peer_ellipticcurvelist = NULL;
+ OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
+ ssl->s3->tmp.peer_supported_group_list = NULL;
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
-static int ext_ec_curves_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_supported_groups_add_serverhello(SSL *ssl, CBB *out) {
/* Servers don't echo this extension. */
return 1;
}
@@ -2038,13 +2001,16 @@ static const struct tls_extension kExtensions[] = {
ext_ec_point_parse_clienthello,
ext_ec_point_add_serverhello,
},
+ /* The final extension must be non-empty. WebSphere Application Server 7.0 is
+ * intolerant to the last extension being zero-length. See
+ * https://crbug.com/363583. */
{
- TLSEXT_TYPE_elliptic_curves,
- ext_ec_curves_init,
- ext_ec_curves_add_clienthello,
- ext_ec_curves_parse_serverhello,
- ext_ec_curves_parse_clienthello,
- ext_ec_curves_add_serverhello,
+ TLSEXT_TYPE_supported_groups,
+ ext_supported_groups_init,
+ ext_supported_groups_add_clienthello,
+ ext_supported_groups_parse_serverhello,
+ ext_supported_groups_parse_clienthello,
+ ext_supported_groups_add_serverhello,
},
};
@@ -2124,9 +2090,10 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
* NB: because this code works out the length of all existing extensions
* it MUST always appear last. */
size_t padding_len = 0x200 - header_len;
- /* Extensions take at least four bytes to encode. Always include least
+ /* Extensions take at least four bytes to encode. Always include at least
* one byte of data if including the extension. WebSphere Application
- * Server 7.0 is intolerant to the last extension being zero-length. */
+ * Server 7.0 is intolerant to the last extension being zero-length. See
+ * https://crbug.com/363583. */
if (padding_len >= 4 + 1) {
padding_len -= 4;
} else {
@@ -2368,14 +2335,10 @@ static int ssl_check_clienthello_tlsext(SSL *ssl) {
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- /* The handling of the ECPointFormats extension is done elsewhere, namely in
- * ssl3_choose_cipher in s3_lib.c. */
-
- if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ if (ssl->ctx->tlsext_servername_callback != 0) {
ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
- ssl->ctx->tlsext_servername_arg);
- } else if (ssl->initial_ctx != NULL &&
- ssl->initial_ctx->tlsext_servername_callback != 0) {
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
ret = ssl->initial_ctx->tlsext_servername_callback(
ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}
@@ -2402,11 +2365,10 @@ static int ssl_check_serverhello_tlsext(SSL *ssl) {
int ret = SSL_TLSEXT_ERR_OK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- if (ssl->ctx != NULL && ssl->ctx->tlsext_servername_callback != 0) {
+ if (ssl->ctx->tlsext_servername_callback != 0) {
ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
- ssl->ctx->tlsext_servername_arg);
- } else if (ssl->initial_ctx != NULL &&
- ssl->initial_ctx->tlsext_servername_callback != 0) {
+ ssl->ctx->tlsext_servername_arg);
+ } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
ret = ssl->initial_ctx->tlsext_servername_callback(
ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
}