* This callback function is called when the ClientHello is received. */
| 2275 | * This callback function is called when the ClientHello is received. |
| 2276 | */ |
| 2277 | int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg) |
| 2278 | { |
| 2279 | char *servername = NULL; |
| 2280 | conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
| 2281 | const unsigned char *pos; |
| 2282 | size_t len, remaining; |
| 2283 | (void)arg; |
| 2284 | |
| 2285 | /* We can't use SSL_get_servername() at this earliest OpenSSL connection |
| 2286 | * stage, and there is no SSL_client_hello_get0_servername() provided as |
| 2287 | * of OpenSSL 1.1.1. So the code below, that extracts the SNI from the |
| 2288 | * ClientHello's TLS extensions, is taken from some test code in OpenSSL, |
| 2289 | * i.e. client_hello_select_server_ctx() in "test/handshake_helper.c". |
| 2290 | */ |
| 2291 | |
| 2292 | /* |
| 2293 | * The server_name extension was given too much extensibility when it |
| 2294 | * was written, so parsing the normal case is a bit complex. |
| 2295 | */ |
| 2296 | if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos, |
| 2297 | &remaining) |
| 2298 | || remaining <= 2) |
| 2299 | goto give_up; |
| 2300 | |
| 2301 | /* Extract the length of the supplied list of names. */ |
| 2302 | len = (*(pos++) << 8); |
| 2303 | len += *(pos++); |
| 2304 | if (len + 2 != remaining) |
| 2305 | goto give_up; |
| 2306 | remaining = len; |
| 2307 | |
| 2308 | /* |
| 2309 | * The list in practice only has a single element, so we only consider |
| 2310 | * the first one. |
| 2311 | */ |
| 2312 | if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name) |
| 2313 | goto give_up; |
| 2314 | remaining--; |
| 2315 | |
| 2316 | /* Now we can finally pull out the byte array with the actual hostname. */ |
| 2317 | len = (*(pos++) << 8); |
| 2318 | len += *(pos++); |
| 2319 | if (len + 2 != remaining) |
| 2320 | goto give_up; |
| 2321 | |
| 2322 | /* Use the SNI to switch to the relevant vhost, should it differ from |
| 2323 | * c->base_server. |
| 2324 | */ |
| 2325 | servername = apr_pstrmemdup(c->pool, (const char *)pos, len); |
| 2326 | |
| 2327 | give_up: |
| 2328 | init_vhost(c, ssl, servername); |
| 2329 | return SSL_CLIENT_HELLO_SUCCESS; |
| 2330 | } |
| 2331 | #endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ |
| 2332 | |
| 2333 | /* |
nothing calls this directly
no test coverage detected