Changeset 654805357ada928555def99685df092926437bac

Show
Ignore:
Timestamp:
03/04/05 17:51:51 (3 years ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1109955111 +0000
git-parent:

[a8f95d102633b2f9ed471bb1e49d1f8de656e97f]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1109955111 +0000
Message:

TLS session resumption support

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • AUTHORS

    re4ab29e r6548053  
    334334S: France 
    335335 
     336N: R� Denis-Courmont 
     337E: rem@videolan.org 
     338C: courmisch 
     339D: SSL/TLS support (core, HTTP server, HTTP input) 
     340S: France 
     341 
  • modules/misc/gnutls.c

    rfd520c5 r6548053  
    22 * tls.c 
    33 ***************************************************************************** 
    4  * Copyright (C) 2004 VideoLAN 
     4 * Copyright (C) 2004-2005 VideoLAN 
    55 * $Id: httpd.c 8263 2004-07-24 09:06:58Z courmisch $ 
    66 * 
     
    4242#include <gnutls/gnutls.h> 
    4343 
    44 #define DH_BITS 1024 
    45  
     44#define DH_BITS             1024 
     45#define CACHE_EXPIRATION    3600 
     46#define CACHE_SIZE          64 
    4647 
    4748/***************************************************************************** 
     
    5556    "Allows you to modify the Diffie-Hellman prime's number of bits " \ 
    5657    "(used for TLS or SSL-based server-side encryption)." ) 
     58 
     59#define CACHE_EXPIRATION_TEXT N_("Expiration time for resumed TLS sessions") 
     60#define CACHE_EXPIRATION_LONGTEXT N_( \ 
     61    "Defines the delay before resumed TLS sessions will be expired " \ 
     62    "(in seconds)." ) 
     63 
     64#define CACHE_SIZE_TEXT N_("Number of resumed TLS sessions") 
     65#define CACHE_SIZE_LONGTEXT N_( \ 
     66    "Allows you to modify the maximum number of resumed TLS sessions that " \ 
     67    "the cache will hold." ) 
     68 
    5769 
    5870vlc_module_begin(); 
     
    6577    add_integer( "dh-bits", DH_BITS, NULL, DH_BITS_TEXT, 
    6678                 DH_BITS_LONGTEXT, VLC_TRUE ); 
     79    add_integer( "tls-cache-expiration", CACHE_EXPIRATION, NULL, 
     80                 CACHE_EXPIRATION_TEXT, CACHE_EXPIRATION_LONGTEXT, VLC_TRUE ); 
     81    add_integer( "tls-cache-size", CACHE_SIZE, NULL, CACHE_SIZE_TEXT, 
     82                 CACHE_SIZE_LONGTEXT, VLC_TRUE ); 
    6783vlc_module_end(); 
    6884 
    6985 
     86#define MAX_SESSION_ID    32 
     87#define MAX_SESSION_DATA  1024 
     88 
     89typedef struct saved_session_t 
     90{ 
     91    char id[MAX_SESSION_ID]; 
     92    char data[MAX_SESSION_DATA]; 
     93 
     94    unsigned i_idlen; 
     95    unsigned i_datalen; 
     96} saved_session_t; 
     97 
    7098 
    7199typedef struct tls_server_sys_t 
    72100{ 
    73     gnutls_certificate_credentials x509_cred; 
    74     gnutls_dh_params dh_params; 
     101    gnutls_certificate_credentials  x509_cred; 
     102    gnutls_dh_params                dh_params; 
     103 
     104    struct saved_session_t          *p_cache; 
     105    struct saved_session_t          *p_store; 
     106    int                             i_cache_size; 
     107    vlc_mutex_t                     cache_lock; 
    75108} tls_server_sys_t; 
    76109 
     
    87120    gnutls_certificate_credentials x509_cred; 
    88121} tls_client_sys_t; 
     122 
     123 
     124static int 
     125_get_Int (vlc_object_t *p_this, const char *var) 
     126{ 
     127    vlc_value_t value; 
     128 
     129    if( var_Get( p_this, var, &value ) != VLC_SUCCESS ) 
     130    { 
     131        var_Create( p_this, var, VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
     132        var_Get( p_this, var, &value ); 
     133    } 
     134 
     135    return value.i_int; 
     136} 
     137 
     138#define get_Int( a, b ) _get_Int( (vlc_object_t *)(a), (b) ) 
    89139 
    90140 
     
    313363 
    314364/***************************************************************************** 
     365 * TLS session resumption callbacks 
     366 *****************************************************************************/ 
     367static int cb_store( void *p_server, gnutls_datum key, gnutls_datum data ) 
     368{ 
     369    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys; 
     370 
     371    if( ( p_sys->i_cache_size == 0 ) 
     372     || ( key.size > MAX_SESSION_ID ) 
     373     || ( data.size > MAX_SESSION_DATA ) ) 
     374        return -1; 
     375 
     376    vlc_mutex_lock( &p_sys->cache_lock ); 
     377 
     378    memcpy( p_sys->p_store->id, key.data, key.size); 
     379    memcpy( p_sys->p_store->data, data.data, data.size ); 
     380    p_sys->p_store->i_idlen = key.size; 
     381    p_sys->p_store->i_datalen = data.size; 
     382 
     383    p_sys->p_store++; 
     384    if( ( p_sys->p_store - p_sys->p_cache ) == p_sys->i_cache_size ) 
     385        p_sys->p_store = p_sys->p_cache; 
     386 
     387    vlc_mutex_unlock( &p_sys->cache_lock ); 
     388 
     389    return 0; 
     390} 
     391 
     392 
     393static const gnutls_datum err_datum = { NULL, 0 }; 
     394 
     395static gnutls_datum cb_fetch( void *p_server, gnutls_datum key ) 
     396{ 
     397    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys; 
     398    saved_session_t *p_session, *p_end; 
     399 
     400    p_session = p_sys->p_cache; 
     401    p_end = p_session + p_sys->i_cache_size; 
     402 
     403    vlc_mutex_lock( &p_sys->cache_lock ); 
     404 
     405    while( p_session < p_end ) 
     406    { 
     407        if( ( p_session->i_idlen == key.size ) 
     408         && !memcmp( p_session->id, key.data, key.size ) ) 
     409        { 
     410            gnutls_datum data; 
     411 
     412            data.size = p_session->i_datalen; 
     413 
     414            data.data = gnutls_malloc( data.size ); 
     415            if( data.data == NULL ) 
     416            { 
     417                vlc_mutex_unlock( &p_sys->cache_lock ); 
     418                return err_datum; 
     419            } 
     420 
     421            memcpy( data.data, p_session->data, data.size ); 
     422            vlc_mutex_unlock( &p_sys->cache_lock ); 
     423            return data; 
     424        } 
     425        p_session++; 
     426    } 
     427 
     428    vlc_mutex_unlock( &p_sys->cache_lock ); 
     429 
     430    return err_datum; 
     431} 
     432 
     433 
     434static int cb_delete( void *p_server, gnutls_datum key ) 
     435{ 
     436    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys; 
     437    saved_session_t *p_session, *p_end; 
     438 
     439    p_session = p_sys->p_cache; 
     440    p_end = p_session + p_sys->i_cache_size; 
     441 
     442    vlc_mutex_lock( &p_sys->cache_lock ); 
     443 
     444    while( p_session < p_end ) 
     445    { 
     446        if( ( p_session->i_idlen == key.size ) 
     447         && !memcmp( p_session->id, key.data, key.size ) ) 
     448        { 
     449            p_session->i_datalen = p_session->i_idlen = 0; 
     450            vlc_mutex_unlock( &p_sys->cache_lock ); 
     451            return 0; 
     452        } 
     453        p_session++; 
     454    } 
     455 
     456    vlc_mutex_unlock( &p_sys->cache_lock ); 
     457 
     458    return -1; 
     459} 
     460 
     461 
     462/***************************************************************************** 
    315463 * tls_ServerSessionPrepare: 
    316464 ***************************************************************************** 
     
    321469{ 
    322470    tls_session_t *p_session; 
    323     tls_session_sys_t *p_sys
     471    gnutls_session session
    324472    int i_val; 
    325     vlc_value_t bits; 
    326  
    327     p_sys = (tls_session_sys_t *)malloc( sizeof(struct tls_session_sys_t) ); 
    328     if( p_sys == NULL ) 
    329         return NULL; 
    330  
    331     i_val = gnutls_init( &p_sys->session, GNUTLS_SERVER ); 
     473 
     474    i_val = gnutls_init( &session, GNUTLS_SERVER ); 
    332475    if( i_val != 0 ) 
    333476    { 
    334477        msg_Err( p_server->p_tls, "Cannot initialize TLS session : %s", 
    335478                 gnutls_strerror( i_val ) ); 
    336         free( p_sys ); 
    337479        return NULL; 
    338480    } 
    339481    
    340     i_val = gnutls_set_default_priority( p_sys->session ); 
     482    i_val = gnutls_set_default_priority( session ); 
    341483    if( i_val < 0 ) 
    342484    { 
    343485        msg_Err( p_server->p_tls, "Cannot set ciphers priorities : %s", 
    344486                 gnutls_strerror( i_val ) ); 
    345         gnutls_deinit( p_sys->session ); 
    346         free( p_sys ); 
    347         return NULL; 
    348     } 
    349  
    350     i_val = gnutls_credentials_set( p_sys->session, GNUTLS_CRD_CERTIFICATE, 
     487        gnutls_deinit( session ); 
     488        return NULL; 
     489    } 
     490 
     491    i_val = gnutls_credentials_set( session, GNUTLS_CRD_CERTIFICATE, 
    351492                                    ((tls_server_sys_t *)(p_server->p_sys)) 
    352493                                    ->x509_cred ); 
     
    355496        msg_Err( p_server->p_tls, "Cannot set TLS session credentials : %s", 
    356497                 gnutls_strerror( i_val ) ); 
    357         gnutls_deinit( p_sys->session ); 
    358         free( p_sys ); 
     498        gnutls_deinit( session ); 
    359499        return NULL; 
    360500    } 
     
    364504                                           GNUTLS_CERT_REQUEST ); */ 
    365505 
    366     if( var_Get( p_server->p_tls, "dh-bits", &bits ) != VLC_SUCCESS ) 
    367     { 
    368         var_Create( p_server->p_tls, "dh-bits", 
    369                     VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
    370         var_Get( p_server->p_tls, "dh-bits", &bits ); 
    371     } 
    372  
    373     gnutls_dh_set_prime_bits( p_sys->session, bits.i_int ); 
     506    gnutls_dh_set_prime_bits( session, get_Int( p_server->p_tls, "dh-bits" ) ); 
     507 
     508    /* Session resumption support */ 
     509    gnutls_db_set_cache_expiration( session, get_Int( p_server->p_tls, 
     510                                    "tls-cache-expiration" ) ); 
     511    gnutls_db_set_retrieve_function( session, cb_fetch ); 
     512    gnutls_db_set_remove_function( session, cb_delete ); 
     513    gnutls_db_set_store_function( session, cb_store ); 
     514    gnutls_db_set_ptr( session, p_server ); 
    374515 
    375516    p_session = malloc( sizeof (struct tls_session_t) ); 
    376517    if( p_session == NULL ) 
    377518    { 
    378         gnutls_deinit( p_sys->session ); 
    379         free( p_sys ); 
    380         return NULL; 
    381     } 
     519        gnutls_deinit( session ); 
     520        return NULL; 
     521    } 
     522 
     523    p_session->p_sys = (tls_session_sys_t *)malloc( sizeof(struct tls_session_sys_t) ); 
     524    if( p_session->p_sys == NULL ) 
     525    { 
     526        gnutls_deinit( session ); 
     527        free( p_session ); 
     528        return NULL; 
     529    } 
     530 
     531    ((tls_session_sys_t *)p_session->p_sys)->session = session; 
    382532 
    383533    p_session->p_tls = p_server->p_tls; 
    384534    p_session->p_server = p_server; 
    385     p_session->p_sys = p_sys; 
    386535    p_session->sock.p_sys = p_session; 
    387536    p_session->sock.pf_send = gnutls_Send; 
     
    403552gnutls_ServerDelete( tls_server_t *p_server ) 
    404553{ 
    405     gnutls_certificate_free_credentials( 
    406                                        ((tls_server_sys_t *)(p_server->p_sys)) 
    407                                          ->x509_cred ); 
    408     free( p_server->p_sys ); 
     554    tls_server_sys_t *p_sys; 
     555 
     556    p_sys = (tls_server_sys_t *)p_server->p_sys; 
     557 
     558    gnutls_certificate_free_credentials( p_sys->x509_cred ); 
     559    free( p_sys->p_cache ); 
     560    vlc_mutex_destroy( &p_sys->cache_lock ); 
     561    free( p_sys ); 
    409562    free( p_server ); 
    410563} 
     
    489642        return NULL; 
    490643 
     644    p_server_sys->i_cache_size = get_Int( p_this, "tls-cache-size" ); 
     645    p_server_sys->p_cache = (struct saved_session_t *) 
     646                            calloc( p_server_sys->i_cache_size, 
     647                                    sizeof( struct saved_session_t ) ); 
     648    if( p_server_sys->p_cache == NULL ) 
     649    { 
     650        free( p_server_sys ); 
     651        return NULL; 
     652    } 
     653    p_server_sys->p_store = p_server_sys->p_cache; 
     654    /* FIXME: check for errors */ 
     655    vlc_mutex_init( p_this, &p_server_sys->cache_lock ); 
     656 
    491657    /* Sets server's credentials */ 
    492658    val = gnutls_certificate_allocate_credentials( &p_server_sys->x509_cred ); 
     
    511677    } 
    512678 
    513     /* FIXME: regenerate these regularly */ 
     679    /* FIXME: 
     680     * - regenerate these regularly 
     681     * - support other ciper suites 
     682     */ 
    514683    val = gnutls_dh_params_init( &p_server_sys->dh_params ); 
    515684    if( val >= 0 ) 
    516685    { 
    517         vlc_value_t bits; 
    518  
    519         if( var_Get( p_this, "dh-bits", &bits ) != VLC_SUCCESS ) 
    520         { 
    521             var_Create( p_this, "dh-bits", 
    522                         VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
    523             var_Get( p_this, "dh-bits", &bits ); 
    524         } 
    525  
    526686        msg_Dbg( p_this, "Computing Diffie Hellman ciphers parameters" ); 
    527687        val = gnutls_dh_params_generate2( p_server_sys->dh_params, 
    528                                           bits.i_int ); 
     688                                          get_Int( p_this, "dh-bits" ) ); 
    529689    } 
    530690    if( val < 0 ) 
     
    564724vlc_object_t *__p_gcry_data; 
    565725 
    566 static int gcry_vlc_mutex_init (void **p_sys
     726static int gcry_vlc_mutex_init( void **p_sys
    567727{ 
    568728    int i_val; 
    569     vlc_mutex_t *p_lock = (vlc_mutex_t *)malloc (sizeof (vlc_mutex_t)); 
     729    vlc_mutex_t *p_lock = (vlc_mutex_t *)malloc( sizeof( vlc_mutex_t ) ); 
    570730 
    571731    if( p_lock == NULL) 
    572732        return ENOMEM; 
    573733 
    574     i_val = vlc_mutex_init( __p_gcry_data, p_lock); 
    575     if (i_val
    576         free (p_lock); 
     734    i_val = vlc_mutex_init( __p_gcry_data, p_lock ); 
     735    if( i_val
     736        free( p_lock ); 
    577737    else 
    578738        *p_sys = p_lock; 
     
    580740} 
    581741 
    582 static int gcry_vlc_mutex_destroy (void **p_sys
     742static int gcry_vlc_mutex_destroy( void **p_sys
    583743{ 
    584744    int i_val; 
    585745    vlc_mutex_t *p_lock = (vlc_mutex_t *)*p_sys; 
    586746 
    587     i_val = vlc_mutex_destroy (p_lock); 
    588     free (p_lock); 
     747    i_val = vlc_mutex_destroy( p_lock ); 
     748    free( p_lock ); 
    589749    return i_val; 
    590750} 
    591751 
    592 static int gcry_vlc_mutex_lock (void **p_sys
    593 { 
    594     return vlc_mutex_lock ((vlc_mutex_t *)*p_sys); 
    595 } 
    596  
    597 static int gcry_vlc_mutex_unlock (void **lock
    598 { 
    599     return vlc_mutex_unlock ((vlc_mutex_t *)*lock); 
     752static int gcry_vlc_mutex_lock( void **p_sys
     753{ 
     754    return vlc_mutex_lock( (vlc_mutex_t *)*p_sys ); 
     755} 
     756 
     757static int gcry_vlc_mutex_unlock( void **lock
     758{ 
     759    return vlc_mutex_unlock( (vlc_mutex_t *)*lock ); 
    600760} 
    601761