Changeset 1890

Show
Ignore:
Timestamp:
08/21/08 13:12:27 (3 months ago)
Author:
alo
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cherokee/trunk/ChangeLog

    r1887 r1890  
     12008-08-21  Alvaro Lopez Ortega  <alvaro@alobbs.com> 
     2 
     3        * cherokee/virtual_server.c, cherokee/socket.c, cherokee/socket.h, 
     4        cherokee/downloader.c: Adds TLS SNI support to the OpenSSL 
     5        backend. 
     6 
    172008-08-20  Alvaro Lopez Ortega  <alvaro@alobbs.com> 
    28 
  • cherokee/trunk/cherokee/downloader.c

    r1822 r1890  
    205205        if (ret != ret_ok) { 
    206206 
    207                 /* Ops! It might be a hostname. Try to resolve it. 
     207                /* Oops! It might be a hostname. Try to resolve it. 
    208208                 */ 
    209209                ret = cherokee_socket_gethostbyname (sock, host); 
     
    222222         */ 
    223223        if (protocol == https) { 
    224                 ret = cherokee_socket_init_client_tls (sock); 
     224                ret = cherokee_socket_init_client_tls (sock, host); 
    225225                if (ret != ret_ok) return ret; 
    226226        } 
  • cherokee/trunk/cherokee/socket.c

    r1876 r1890  
    423423        } 
    424424 
     425#ifndef OPENSSL_NO_TLSEXT  
     426        SSL_set_app_data (socket->session, socket); 
     427#endif 
     428 
    425429        /* Set the SSL context cache 
    426430         */ 
     
    17761780 
    17771781ret_t  
    1778 cherokee_socket_init_client_tls (cherokee_socket_t *socket
     1782cherokee_socket_init_client_tls (cherokee_socket_t *socket, cherokee_buffer_t *host
    17791783{ 
    17801784#ifdef HAVE_TLS 
     
    18211825                 (re == GNUTLS_E_INTERRUPTED)); 
    18221826 
     1827        UNUSED (host); 
     1828 
    18231829# elif defined (HAVE_OPENSSL) 
     1830        char *error; 
    18241831 
    18251832        socket->is_tls = TLS; 
     
    18291836        socket->ssl_ctx = SSL_CTX_new (SSLv23_client_method()); 
    18301837        if (socket->ssl_ctx == NULL) { 
    1831                 char *error; 
    1832  
    18331838                OPENSSL_LAST_ERROR(error); 
    18341839                PRINT_ERROR ("ERROR: OpenSSL: Unable to create a new SSL context: %s\n", error); 
     
    18461851        socket->session = SSL_new (socket->ssl_ctx); 
    18471852        if (socket->session == NULL) { 
    1848                 char *error; 
    1849  
    18501853                OPENSSL_LAST_ERROR(error); 
    18511854                PRINT_ERROR ("ERROR: OpenSSL: Unable to create a new SSL connection " 
     
    18581861        re = SSL_set_fd (socket->session, socket->socket); 
    18591862        if (re != 1) { 
    1860                 char *error; 
    1861  
    18621863                OPENSSL_LAST_ERROR(error); 
    18631864                PRINT_ERROR ("ERROR: OpenSSL: Can not set fd(%d): %s\n", socket->socket, error); 
     
    18671868        SSL_set_connect_state (socket->session);  
    18681869 
     1870#ifndef OPENSSL_NO_TLSEXT  
     1871        re = SSL_set_tlsext_host_name (socket->session, host->buf); 
     1872        if (re <= 0) { 
     1873                OPENSSL_LAST_ERROR(error); 
     1874                PRINT_ERROR ("ERROR: OpenSSL: Could set SNI server name: %s\n", error); 
     1875                return ret_error; 
     1876        } 
     1877#endif 
     1878 
    18691879        re = SSL_connect (socket->session); 
    18701880        if (re <= 0) { 
    1871                 char *error; 
    1872  
    18731881                OPENSSL_LAST_ERROR(error); 
    18741882                PRINT_ERROR ("ERROR: OpenSSL: Can not connect: %s\n", error); 
     
    18781886# endif 
    18791887#else  
     1888        UNUSED (host); 
    18801889        UNUSED (socket); 
    18811890#endif 
  • cherokee/trunk/cherokee/socket.h

    r1838 r1890  
    186186 
    187187ret_t cherokee_socket_init_tls          (cherokee_socket_t *socket, cherokee_virtual_server_t *vserver); 
    188 ret_t cherokee_socket_init_client_tls   (cherokee_socket_t *socket); 
     188ret_t cherokee_socket_init_client_tls   (cherokee_socket_t *socket, cherokee_buffer_t *host); 
    189189 
    190190ret_t cherokee_socket_close             (cherokee_socket_t *socket); 
  • cherokee/trunk/cherokee/virtual_server.c

    r1885 r1890  
    220220 
    221221 
     222#ifndef OPENSSL_NO_TLSEXT  
     223static int 
     224openssl_sni_servername_cb (SSL *ssl, int *ad, void *arg) 
     225{ 
     226        ret_t                      ret; 
     227        const char                *servername; 
     228        cherokee_socket_t         *socket; 
     229        cherokee_buffer_t          tmp; 
     230        SSL_CTX                   *ctx; 
     231        cherokee_server_t         *srv       = SRV(arg); 
     232        cherokee_virtual_server_t *vsrv      = NULL; 
     233 
     234        /* Get the pointer to the socket  
     235         */ 
     236        socket = SSL_get_app_data (ssl);  
     237        if (unlikely (socket == NULL)) { 
     238                PRINT_ERROR ("Could not get the socket struct: %p\n", ssl); 
     239                return SSL_TLSEXT_ERR_ALERT_FATAL;  
     240        } 
     241 
     242        /* Read the SNI server name 
     243         */ 
     244        servername = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name); 
     245        if (servername == NULL) { 
     246                TRACE (ENTRIES, "No SNI: Did not provide a server name%s", "\n"); 
     247                return SSL_TLSEXT_ERR_NOACK; 
     248        } 
     249 
     250        TRACE (ENTRIES, "SNI: Switching to servername='%s'\n", servername); 
     251 
     252        /* Try to match the name 
     253         */ 
     254        cherokee_buffer_fake (&tmp, servername, strlen(servername)); 
     255        ret = cherokee_server_get_vserver (srv, &tmp, &vsrv); 
     256        if ((ret != ret_ok) || (vsrv == NULL)) { 
     257                PRINT_ERROR ("Servername did not match: '%s'\n", servername); 
     258                return SSL_TLSEXT_ERR_NOACK;  
     259        } 
     260 
     261        TRACE (ENTRIES, "SNI: Setting new TLS context. Virtual host='%s'\n", 
     262               vsrv->name.buf); 
     263 
     264        /* Set the new SSL context 
     265         */ 
     266        ctx = SSL_set_SSL_CTX (ssl, vsrv->context); 
     267        if (ctx != vsrv->context) { 
     268                PRINT_ERROR ("Could change the SSL context: servername='%s'\n", servername); 
     269        } 
     270 
     271        return SSL_TLSEXT_ERR_OK;  
     272} 
     273#endif  
     274 
     275 
    222276ret_t  
    223277cherokee_virtual_server_init_tls (cherokee_virtual_server_t *vsrv) 
    224278{ 
    225279#ifdef HAVE_TLS 
    226         int rc; 
     280        int   rc; 
     281        char *error; 
    227282 
    228283        /* Check if all of them are empty 
     
    275330        gnutls_anon_set_server_dh_params (vsrv->credentials, vsrv->dh_params); 
    276331        gnutls_certificate_set_rsa_export_params (vsrv->credentials, vsrv->rsa_params); 
     332 
     333        UNUSED(error); 
    277334# endif 
    278335 
     
    290347        rc = SSL_CTX_use_certificate_file (vsrv->context, vsrv->server_cert.buf, SSL_FILETYPE_PEM); 
    291348        if (rc < 0) { 
    292                 char *error; 
    293  
    294349                OPENSSL_LAST_ERROR(error); 
    295350                PRINT_ERROR("ERROR: OpenSSL: Can not use certificate file '%s':  %s\n",  
     
    302357        rc = SSL_CTX_use_PrivateKey_file (vsrv->context, vsrv->server_key.buf, SSL_FILETYPE_PEM); 
    303358        if (rc < 0) { 
    304                 char *error; 
    305  
    306359                OPENSSL_LAST_ERROR(error); 
    307360                PRINT_ERROR("ERROR: OpenSSL: Can not use private key file '%s': %s\n",  
     
    315368        if (rc != 1) { 
    316369                PRINT_ERROR_S("ERROR: OpenSSL: Private key does not match the certificate public key\n"); 
     370                return ret_error; 
     371        } 
     372 
     373        /* Enable SNI 
     374         */ 
     375        rc = SSL_CTX_set_tlsext_servername_callback (vsrv->context, openssl_sni_servername_cb); 
     376        if (rc < 0) { 
     377                OPENSSL_LAST_ERROR(error); 
     378                PRINT_ERROR ("Could activate TLS SNI for '%s': %s\n", vsrv->name.buf, error); 
     379                return ret_error; 
     380        } 
     381 
     382        rc = SSL_CTX_set_tlsext_servername_arg (vsrv->context, VSERVER_SRV(vsrv)); 
     383        if (rc < 0) { 
     384                OPENSSL_LAST_ERROR(error); 
     385                PRINT_ERROR ("Could activate TLS SNI for '%s': %s\n", vsrv->name.buf, error); 
    317386                return ret_error; 
    318387        }