Ticket #386: lighttpd_1.4.x_r2118_tls_server_name_indication.patch

File lighttpd_1.4.x_r2118_tls_server_name_indication.patch, 10.2 kB (added by phc, 4 months ago)

TLS server name indication support (lighttpd 1.4.x-svn)

  • a/src/base.h

    old new  
    3131#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H 
    3232# define USE_OPENSSL 
    3333# include <openssl/ssl.h> 
     34# if ! defined OPENSSL_NO_TLSEXT && ! defined SSL_CTRL_SET_TLSEXT_HOSTNAME 
     35#  define OPENSSL_NO_TLSEXT 
     36# endif 
    3437#endif 
    3538 
    3639#ifdef HAVE_FAM_H 
     
    415418#ifdef USE_OPENSSL 
    416419        SSL *ssl; 
    417420        buffer *ssl_error_want_reuse_buffer; 
     421#ifndef OPENSSL_NO_TLSEXT 
     422        buffer *tlsext_server_name; 
     423#endif 
    418424#endif 
    419425        /* etag handling */ 
    420426        etag_flags_t etag_flags; 
  • a/src/configfile-glue.c

    old new  
    272272                        default: 
    273273                                break; 
    274274                        } 
     275#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT 
     276                } else if (!buffer_is_empty(con->tlsext_server_name)) { 
     277                        l = con->tlsext_server_name; 
     278#endif 
    275279                } else { 
    276280                        l = srv->empty_string; 
    277281                } 
  • a/src/configfile.c

    old new  
    285285        PATCH(is_ssl); 
    286286 
    287287        PATCH(ssl_pemfile); 
     288        PATCH(ssl_ctx); 
    288289        PATCH(ssl_ca_file); 
    289290        PATCH(ssl_cipher_list); 
    290291        PATCH(ssl_use_sslv2); 
     
    343344                                PATCH(etag_use_size); 
    344345                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) { 
    345346                                PATCH(ssl_pemfile); 
     347                                PATCH(ssl_ctx); 
    346348                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) { 
    347349                                PATCH(ssl_ca_file); 
    348350                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv2"))) { 
  • a/src/connections.c

    old new  
    674674        CLEAN(server_name); 
    675675        CLEAN(error_handler); 
    676676        CLEAN(dst_addr_buf); 
     677#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT 
     678        CLEAN(tlsext_server_name); 
     679#endif 
    677680 
    678681#undef CLEAN 
    679682        con->write_queue = chunkqueue_init(); 
     
    738741                CLEAN(server_name); 
    739742                CLEAN(error_handler); 
    740743                CLEAN(dst_addr_buf); 
     744#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT 
     745                CLEAN(tlsext_server_name); 
     746#endif 
    741747#undef CLEAN 
    742748                free(con->plugin_ctx); 
    743749                free(con->cond_cache); 
     
    13451351                                return NULL; 
    13461352                        } 
    13471353 
     1354#ifndef OPENSSL_NO_TLSEXT 
     1355                        SSL_set_app_data(con->ssl, con); 
     1356#endif 
    13481357                        SSL_set_accept_state(con->ssl); 
    13491358                        con->conf.is_ssl=1; 
    13501359 
  • a/src/network.c

    old new  
    6161        } 
    6262        return HANDLER_GO_ON; 
    6363} 
     64 
     65#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT 
     66int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { 
     67        const char *servername; 
     68        connection *con = (connection *) SSL_get_app_data(ssl); 
     69 
     70        buffer_copy_string(con->uri.scheme, "https"); 
     71 
     72        if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 
     73                log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     74                                "failed to get TLS server name"); 
     75                return SSL_TLSEXT_ERR_NOACK; 
     76        } 
     77        buffer_copy_string(con->tlsext_server_name, servername); 
     78        buffer_to_lower(con->tlsext_server_name); 
     79 
     80        config_cond_cache_reset(srv, con); 
     81        config_setup_connection(srv, con); 
     82 
     83        config_patch_connection(srv, con, COMP_SERVER_SOCKET); 
     84        config_patch_connection(srv, con, COMP_HTTP_SCHEME); 
     85        config_patch_connection(srv, con, COMP_HTTP_HOST); 
     86 
     87        if (NULL == con->conf.ssl_ctx) { 
     88                log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
     89                                "null SSL_CTX for TLS server name", con->tlsext_server_name); 
     90                return SSL_TLSEXT_ERR_ALERT_FATAL; 
     91        } 
     92 
     93        /* switch to new SSL_CTX in reaction to a client's server_name extension */ 
     94        if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) { 
     95                log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
     96                                "failed to set SSL_CTX for TLS server name", con->tlsext_server_name); 
     97                return SSL_TLSEXT_ERR_ALERT_FATAL; 
     98        } 
     99 
     100        return SSL_TLSEXT_ERR_OK; 
     101} 
     102#endif 
    64103 
    65104int network_server_init(server *srv, buffer *host_token, specific_config *s) { 
    66105        int val; 
     
    312351 
    313352        if (s->is_ssl) { 
    314353#ifdef USE_OPENSSL 
    315                 if (srv->ssl_is_init == 0) { 
    316                         SSL_load_error_strings(); 
    317                         SSL_library_init(); 
    318                         srv->ssl_is_init = 1; 
    319  
    320                         if (0 == RAND_status()) { 
    321                                 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
    322                                                 "not enough entropy in the pool"); 
    323                                 return -1; 
    324                         } 
    325                 } 
    326  
    327                 if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { 
    328                         log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
    329                                         ERR_error_string(ERR_get_error(), NULL)); 
    330                         return -1; 
    331                 } 
    332  
    333                 if (!s->ssl_use_sslv2) { 
    334                         /* disable SSLv2 */ 
    335                         if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { 
    336                                 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
    337                                                 ERR_error_string(ERR_get_error(), NULL)); 
    338                                 return -1; 
    339                         } 
    340                 } 
    341  
    342                 if (!buffer_is_empty(s->ssl_cipher_list)) { 
    343                         /* Disable support for low encryption ciphers */ 
    344                         if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { 
    345                                 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
    346                                                 ERR_error_string(ERR_get_error(), NULL)); 
    347                                 return -1; 
    348                         } 
    349                 } 
    350  
    351                 if (buffer_is_empty(s->ssl_pemfile)) { 
     354                if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) { 
    352355                        log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); 
    353356                        return -1; 
    354357                } 
    355  
    356                 if (!buffer_is_empty(s->ssl_ca_file)) { 
    357                         if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { 
    358                                 log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
    359                                                 ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); 
    360                                 return -1; 
    361                         } 
    362                 } 
    363  
    364                 if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { 
    365                         log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
    366                                         ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); 
    367                         return -1; 
    368                 } 
    369  
    370                 if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { 
    371                         log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
    372                                         ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); 
    373                         return -1; 
    374                 } 
    375  
    376                 if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { 
    377                         log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", 
    378                                         "Private key does not match the certificate public key, reason:", 
    379                                         ERR_error_string(ERR_get_error(), NULL), 
    380                                         s->ssl_pemfile); 
    381                         return -1; 
    382                 } 
    383                 SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); 
    384                 SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 
    385  
    386                 srv_socket->ssl_ctx = s->ssl_ctx; 
    387358#else 
    388359 
    389360                buffer_free(srv_socket->srv_token); 
     
    490461                { NETWORK_BACKEND_WRITE,                "write" }, 
    491462                { NETWORK_BACKEND_UNSET,                NULL } 
    492463        }; 
     464 
     465#ifdef USE_OPENSSL 
     466        /* load SSL certificates */ 
     467        for (i = 0; i < srv->config_context->used; i++) { 
     468                data_config *dc = (data_config *)srv->config_context->data[i]; 
     469                specific_config *s = srv->config_storage[i]; 
     470 
     471                if (buffer_is_empty(s->ssl_pemfile)) continue; 
     472 
     473#ifdef OPENSSL_NO_TLSEXT 
     474                if (COMP_HTTP_HOST == dc->comp) { 
     475                    log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     476                                    "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions"); 
     477                    return -1; 
     478                } 
     479#endif 
     480 
     481                if (srv->ssl_is_init == 0) { 
     482                        SSL_load_error_strings(); 
     483                        SSL_library_init(); 
     484                        srv->ssl_is_init = 1; 
     485 
     486                        if (0 == RAND_status()) { 
     487                                log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     488                                                "not enough entropy in the pool"); 
     489                                return -1; 
     490                        } 
     491                } 
     492 
     493                if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { 
     494                        log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     495                                        ERR_error_string(ERR_get_error(), NULL)); 
     496                        return -1; 
     497                } 
     498 
     499                if (!s->ssl_use_sslv2) { 
     500                        /* disable SSLv2 */ 
     501                        if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { 
     502                                log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     503                                                ERR_error_string(ERR_get_error(), NULL)); 
     504                                return -1; 
     505                        } 
     506                } 
     507 
     508                if (!buffer_is_empty(s->ssl_cipher_list)) { 
     509                        /* Disable support for low encryption ciphers */ 
     510                        if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { 
     511                                log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     512                                                ERR_error_string(ERR_get_error(), NULL)); 
     513                                return -1; 
     514                        } 
     515                } 
     516 
     517                if (!buffer_is_empty(s->ssl_ca_file)) { 
     518                        if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { 
     519                                log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
     520                                                ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); 
     521                                return -1; 
     522                        } 
     523                } 
     524 
     525                if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { 
     526                        log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
     527                                        ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); 
     528                        return -1; 
     529                } 
     530 
     531                if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { 
     532                        log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
     533                                        ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); 
     534                        return -1; 
     535                } 
     536 
     537                if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { 
     538                        log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", 
     539                                        "Private key does not match the certificate public key, reason:", 
     540                                        ERR_error_string(ERR_get_error(), NULL), 
     541                                        s->ssl_pemfile); 
     542                        return -1; 
     543                } 
     544                SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); 
     545                SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 
     546 
     547#ifndef OPENSSL_NO_TLSEXT 
     548                if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) || 
     549                    !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) { 
     550                        log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
     551                                        "failed to initialize TLS servername callback, openssl library does not support TLS servername extension"); 
     552                        return -1; 
     553                } 
     554#endif 
     555        } 
     556#endif 
    493557 
    494558        b = buffer_init(); 
    495559