Lines 2328-2348
static apr_status_t set_challenge_creds(conn_rec *
Link Here
|
2328 |
* This function sets the virtual host from an extended |
2328 |
* This function sets the virtual host from an extended |
2329 |
* client hello with a server name indication extension ("SNI", cf. RFC 6066). |
2329 |
* client hello with a server name indication extension ("SNI", cf. RFC 6066). |
2330 |
*/ |
2330 |
*/ |
2331 |
static apr_status_t init_vhost(conn_rec *c, SSL *ssl) |
2331 |
static apr_status_t init_vhost(conn_rec *c, SSL *ssl, const char *servername) |
2332 |
{ |
2332 |
{ |
2333 |
const char *servername; |
|
|
2334 |
X509 *cert; |
2333 |
X509 *cert; |
2335 |
EVP_PKEY *key; |
2334 |
EVP_PKEY *key; |
2336 |
|
2335 |
|
2337 |
if (c) { |
2336 |
if (c) { |
2338 |
SSLConnRec *sslcon = myConnConfig(c); |
2337 |
SSLConnRec *sslcon = myConnConfig(c); |
|
|
2338 |
|
2339 |
if (sslcon->vhost_found) { |
2340 |
/* already found the vhost? */ |
2341 |
return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND; |
2342 |
} |
2343 |
sslcon->vhost_found = -1; |
2339 |
|
2344 |
|
2340 |
if (sslcon->server != c->base_server) { |
2345 |
if (!servername) { |
2341 |
/* already found the vhost */ |
2346 |
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); |
2342 |
return APR_SUCCESS; |
|
|
2343 |
} |
2347 |
} |
2344 |
|
|
|
2345 |
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); |
2346 |
if (servername) { |
2348 |
if (servername) { |
2347 |
if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, |
2349 |
if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, |
2348 |
(void *)servername)) { |
2350 |
(void *)servername)) { |
Lines 2349-2355
static apr_status_t set_challenge_creds(conn_rec *
Link Here
|
2349 |
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043) |
2351 |
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043) |
2350 |
"SSL virtual host for servername %s found", |
2352 |
"SSL virtual host for servername %s found", |
2351 |
servername); |
2353 |
servername); |
2352 |
|
2354 |
|
|
|
2355 |
sslcon->vhost_found = +1; |
2353 |
return APR_SUCCESS; |
2356 |
return APR_SUCCESS; |
2354 |
} |
2357 |
} |
2355 |
else if (ssl_is_challenge(c, servername, &cert, &key)) { |
2358 |
else if (ssl_is_challenge(c, servername, &cert, &key)) { |
Lines 2399-2410
static apr_status_t set_challenge_creds(conn_rec *
Link Here
|
2399 |
int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) |
2402 |
int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) |
2400 |
{ |
2403 |
{ |
2401 |
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
2404 |
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
2402 |
apr_status_t status = init_vhost(c, ssl); |
2405 |
apr_status_t status = init_vhost(c, ssl, NULL); |
2403 |
|
2406 |
|
2404 |
return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; |
2407 |
return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; |
2405 |
} |
2408 |
} |
2406 |
|
2409 |
|
|
|
2410 |
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) |
2407 |
/* |
2411 |
/* |
|
|
2412 |
* This callback function is called when the ClientHello is received. |
2413 |
*/ |
2414 |
int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg) |
2415 |
{ |
2416 |
char *servername = NULL; |
2417 |
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
2418 |
const unsigned char *pos; |
2419 |
size_t len, remaining; |
2420 |
(void)arg; |
2421 |
|
2422 |
/* We can't use SSL_get_servername() at this earliest OpenSSL connection |
2423 |
* stage, and there is no SSL_client_hello_get0_servername() provided as |
2424 |
* of OpenSSL 1.1.1. So the code below, that extracts the SNI from the |
2425 |
* ClientHello's TLS extensions, is taken from some test code in OpenSSL, |
2426 |
* i.e. client_hello_select_server_ctx() in "test/handshake_helper.c". |
2427 |
*/ |
2428 |
|
2429 |
/* |
2430 |
* The server_name extension was given too much extensibility when it |
2431 |
* was written, so parsing the normal case is a bit complex. |
2432 |
*/ |
2433 |
if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos, |
2434 |
&remaining) |
2435 |
|| remaining <= 2) |
2436 |
goto give_up; |
2437 |
|
2438 |
/* Extract the length of the supplied list of names. */ |
2439 |
len = (*(pos++) << 8); |
2440 |
len += *(pos++); |
2441 |
if (len + 2 != remaining) |
2442 |
goto give_up; |
2443 |
remaining = len; |
2444 |
|
2445 |
/* |
2446 |
* The list in practice only has a single element, so we only consider |
2447 |
* the first one. |
2448 |
*/ |
2449 |
if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name) |
2450 |
goto give_up; |
2451 |
remaining--; |
2452 |
|
2453 |
/* Now we can finally pull out the byte array with the actual hostname. */ |
2454 |
len = (*(pos++) << 8); |
2455 |
len += *(pos++); |
2456 |
if (len + 2 != remaining) |
2457 |
goto give_up; |
2458 |
|
2459 |
/* Use the SNI to switch to the relevant vhost, should it differ from |
2460 |
* c->base_server. |
2461 |
*/ |
2462 |
servername = apr_pstrmemdup(c->pool, (const char *)pos, len); |
2463 |
|
2464 |
give_up: |
2465 |
init_vhost(c, ssl, servername); |
2466 |
return SSL_CLIENT_HELLO_SUCCESS; |
2467 |
} |
2468 |
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ |
2469 |
|
2470 |
/* |
2408 |
* Find a (name-based) SSL virtual host where either the ServerName |
2471 |
* Find a (name-based) SSL virtual host where either the ServerName |
2409 |
* or one of the ServerAliases matches the supplied name (to be used |
2472 |
* or one of the ServerAliases matches the supplied name (to be used |
2410 |
* with ap_vhost_iterate_given_conn()) |
2473 |
* with ap_vhost_iterate_given_conn()) |
Lines 2423-2428
static int ssl_find_vhost(void *servername, conn_r
Link Here
|
2423 |
if (found && (ssl = sslcon->ssl) && |
2486 |
if (found && (ssl = sslcon->ssl) && |
2424 |
(sc = mySrvConfig(s))) { |
2487 |
(sc = mySrvConfig(s))) { |
2425 |
SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); |
2488 |
SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); |
|
|
2489 |
|
2426 |
/* |
2490 |
/* |
2427 |
* SSL_set_SSL_CTX() only deals with the server cert, |
2491 |
* SSL_set_SSL_CTX() only deals with the server cert, |
2428 |
* so we need to duplicate a few additional settings |
2492 |
* so we need to duplicate a few additional settings |
Lines 2429-2434
static int ssl_find_vhost(void *servername, conn_r
Link Here
|
2429 |
* from the ctx by hand |
2493 |
* from the ctx by hand |
2430 |
*/ |
2494 |
*/ |
2431 |
SSL_set_options(ssl, SSL_CTX_get_options(ctx)); |
2495 |
SSL_set_options(ssl, SSL_CTX_get_options(ctx)); |
|
|
2496 |
#if OPENSSL_VERSION_NUMBER >= 0x10100000L \ |
2497 |
&& (!defined(LIBRESSL_VERSION_NUMBER) \ |
2498 |
|| LIBRESSL_VERSION_NUMBER >= 0x20800000L) |
2499 |
SSL_set_min_proto_version(ssl, SSL_CTX_get_min_proto_version(ctx)); |
2500 |
SSL_set_max_proto_version(ssl, SSL_CTX_get_max_proto_version(ctx)); |
2501 |
#endif |
2432 |
if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || |
2502 |
if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || |
2433 |
(SSL_num_renegotiations(ssl) == 0)) { |
2503 |
(SSL_num_renegotiations(ssl) == 0)) { |
2434 |
/* |
2504 |
/* |
Lines 2625-2631
int ssl_callback_alpn_select(SSL *ssl,
Link Here
|
2625 |
* they callback the SNI. We need to make sure that we know which vhost |
2695 |
* they callback the SNI. We need to make sure that we know which vhost |
2626 |
* we are dealing with so we respect the correct protocols. |
2696 |
* we are dealing with so we respect the correct protocols. |
2627 |
*/ |
2697 |
*/ |
2628 |
init_vhost(c, ssl); |
2698 |
init_vhost(c, ssl, NULL); |
2629 |
|
2699 |
|
2630 |
proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos); |
2700 |
proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos); |
2631 |
if (!proposed) { |
2701 |
if (!proposed) { |