View | Details | Raw Unified | Return to bug 62939
Collapse All | Expand All

(-)modules/ssl/ssl_engine_init.c (-2 / +14 lines)
Lines 498-504 static apr_status_t ssl_init_ctx_tls_extensions(se Link Here
498
                 "Configuring TLS extension handling");
498
                 "Configuring TLS extension handling");
499
499
500
    /*
500
    /*
501
     * Server name indication (SNI)
501
     * The Server Name Indication (SNI) provided by the ClientHello can be
502
     * used to select the right (name-based-)vhost and its SSL configuration
503
     * before the handshake takes place.
502
     */
504
     */
503
    if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
505
    if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
504
                          ssl_callback_ServerNameIndication) ||
506
                          ssl_callback_ServerNameIndication) ||
Lines 510-515 static apr_status_t ssl_init_ctx_tls_extensions(se Link Here
510
        return ssl_die(s);
512
        return ssl_die(s);
511
    }
513
    }
512
514
515
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
516
    /*
517
     * The ClientHello callback also allows to retrieve the SNI, but since it
518
     * runs at the earliest possible connection stage we can even set the TLS
519
     * protocol version(s) according to the selected (name-based-)vhost, which
520
     * is not possible at the SNI callback stage (due to OpenSSL internals).
521
     */
522
    SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL);
523
#endif
524
513
#ifdef HAVE_OCSP_STAPLING
525
#ifdef HAVE_OCSP_STAPLING
514
    /*
526
    /*
515
     * OCSP Stapling support, status_request extension
527
     * OCSP Stapling support, status_request extension
Lines 678-684 static apr_status_t ssl_init_ctx_protocol(server_r Link Here
678
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
690
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
679
    /* We first determine the maximum protocol version we should provide */
691
    /* We first determine the maximum protocol version we should provide */
680
#if SSL_HAVE_PROTOCOL_TLSV1_3
692
#if SSL_HAVE_PROTOCOL_TLSV1_3
681
    if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
693
    if (protocol & SSL_PROTOCOL_TLSV1_3) {
682
        prot = TLS1_3_VERSION;
694
        prot = TLS1_3_VERSION;
683
    } else  
695
    } else  
684
#endif
696
#endif
(-)modules/ssl/ssl_engine_kernel.c (-10 / +80 lines)
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) {
(-)modules/ssl/ssl_private.h (+4 lines)
Lines 554-559 typedef struct { Link Here
554
    
554
    
555
    const char *cipher_suite; /* cipher suite used in last reneg */
555
    const char *cipher_suite; /* cipher suite used in last reneg */
556
    int service_unavailable;  /* thouugh we negotiate SSL, no requests will be served */
556
    int service_unavailable;  /* thouugh we negotiate SSL, no requests will be served */
557
    int vhost_found;          /* whether we found vhost from SNI already */
557
} SSLConnRec;
558
} SSLConnRec;
558
559
559
/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
560
/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
Lines 928-933 void ssl_callback_Info(const SSL *, int, i Link Here
928
#ifdef HAVE_TLSEXT
929
#ifdef HAVE_TLSEXT
929
int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
930
int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
930
#endif
931
#endif
932
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
933
int          ssl_callback_ClientHello(SSL *, int *, void *);
934
#endif
931
#ifdef HAVE_TLS_SESSION_TICKETS
935
#ifdef HAVE_TLS_SESSION_TICKETS
932
int         ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
936
int         ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
933
                                       EVP_CIPHER_CTX *, HMAC_CTX *, int);
937
                                       EVP_CIPHER_CTX *, HMAC_CTX *, int);

Return to bug 62939