Commit 82f9a191 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

- support for TLSv1.1

 - rationalize var_CreateGet*() and config_Get*() usage
parent b80738a2
...@@ -111,6 +111,23 @@ vlc_module_end(); ...@@ -111,6 +111,23 @@ vlc_module_end();
#define MAX_SESSION_ID 32 #define MAX_SESSION_ID 32
#define MAX_SESSION_DATA 1024 #define MAX_SESSION_DATA 1024
static const int proto_priority[] =
{
GNUTLS_TLS1_1,
GNUTLS_TLS1_0,
GNUTLS_SSL3,
0
};
static const int cert_type_priority[] =
{
GNUTLS_CRT_X509,
//GNUTLS_CRT_OPENPGP, TODO
0
};
typedef struct saved_session_t typedef struct saved_session_t
{ {
char id[MAX_SESSION_ID]; char id[MAX_SESSION_ID];
...@@ -150,38 +167,6 @@ typedef struct tls_client_sys_t ...@@ -150,38 +167,6 @@ typedef struct tls_client_sys_t
} tls_client_sys_t; } tls_client_sys_t;
static int
_get_Int( vlc_object_t *p_this, const char *var )
{
vlc_value_t value;
if( var_Get( p_this, var, &value ) != VLC_SUCCESS )
{
var_Create( p_this, var, VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_this, var, &value );
}
return value.i_int;
}
static int
_get_Bool( vlc_object_t *p_this, const char *var )
{
vlc_value_t value;
if( var_Get( p_this, var, &value ) != VLC_SUCCESS )
{
var_Create( p_this, var, VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_this, var, &value );
}
return value.b_bool;
}
#define get_Int( a, b ) _get_Int( (vlc_object_t *)(a), (b) )
#define get_Bool( a, b ) _get_Bool( (vlc_object_t *)(a), (b) )
/** /**
* Sends data through a TLS session. * Sends data through a TLS session.
*/ */
...@@ -402,7 +387,7 @@ gnutls_BeginHandshake( tls_session_t *p_session, int fd, ...@@ -402,7 +387,7 @@ gnutls_BeginHandshake( tls_session_t *p_session, int fd,
{ {
gnutls_server_name_set( p_sys->session, GNUTLS_NAME_DNS, psz_hostname, gnutls_server_name_set( p_sys->session, GNUTLS_NAME_DNS, psz_hostname,
strlen( psz_hostname ) ); strlen( psz_hostname ) );
if( get_Bool( p_session, "tls-check-hostname" ) ) if (var_CreateGetBool (p_session, "tls-check-hostname"))
{ {
p_sys->psz_hostname = strdup( psz_hostname ); p_sys->psz_hostname = strdup( psz_hostname );
if( p_sys->psz_hostname == NULL ) if( p_sys->psz_hostname == NULL )
...@@ -440,6 +425,40 @@ gnutls_SessionClose( tls_session_t *p_session ) ...@@ -440,6 +425,40 @@ gnutls_SessionClose( tls_session_t *p_session )
free( p_sys ); free( p_sys );
} }
static int
gnutls_SessionPrioritize (vlc_object_t *obj, gnutls_session_t session)
{
int val;
val = gnutls_set_default_priority (session);
if (val < 0)
{
msg_Err (obj, "cannot set TLS priorities: %s",
gnutls_strerror (val));
return VLC_EGENERIC;
}
val = gnutls_protocol_set_priority (session, proto_priority);
if (val < 0)
{
msg_Err (obj, "cannot set protocols priorities: %s",
gnutls_strerror (val));
return VLC_EGENERIC;
}
val = gnutls_certificate_type_set_priority (session, cert_type_priority);
if (val < 0)
{
msg_Err (obj, "cannot set certificate type priorities: %s",
gnutls_strerror (val));
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static void static void
gnutls_ClientDelete( tls_session_t *p_session ) gnutls_ClientDelete( tls_session_t *p_session )
{ {
...@@ -575,11 +594,6 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -575,11 +594,6 @@ gnutls_ClientCreate( tls_t *p_tls )
tls_session_t *p_session = NULL; tls_session_t *p_session = NULL;
tls_client_sys_t *p_sys = NULL; tls_client_sys_t *p_sys = NULL;
int i_val; int i_val;
static const int cert_type_priority[3] =
{
GNUTLS_CRT_X509,
0
};
p_sys = (tls_client_sys_t *)malloc( sizeof(struct tls_client_sys_t) ); p_sys = (tls_client_sys_t *)malloc( sizeof(struct tls_client_sys_t) );
if( p_sys == NULL ) if( p_sys == NULL )
...@@ -604,6 +618,13 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -604,6 +618,13 @@ gnutls_ClientCreate( tls_t *p_tls )
vlc_object_attach( p_session, p_tls ); vlc_object_attach( p_session, p_tls );
const char *homedir = p_tls->p_libvlc->psz_homedir,
*datadir = config_GetDataDir ((vlc_object_t *)p_session);
size_t l1 = strlen (homedir), l2 = strlen (datadir);
char path[((l1 > l2) ? l1 : l2) + sizeof ("/"CONFIG_DIR"/ssl/private")];
// > sizeof ("/"CONFIG_DIR"/ssl/certs")
// > sizeof ("/ca-certificates.crt")
i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred ); i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred );
if( i_val != 0 ) if( i_val != 0 )
{ {
...@@ -612,45 +633,23 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -612,45 +633,23 @@ gnutls_ClientCreate( tls_t *p_tls )
goto error; goto error;
} }
if( get_Bool( p_tls, "tls-check-cert" ) ) if (var_CreateGetBool (p_tls, "tls-check-cert"))
{
char *psz_path;
if( asprintf( &psz_path, "%s/"CONFIG_DIR"/ssl/certs",
p_tls->p_libvlc->psz_homedir ) != -1 )
{ {
gnutls_Addx509Directory( (vlc_object_t *)p_session, sprintf (path, "%s/"CONFIG_DIR"/ssl/certs", homedir);
p_sys->x509_cred, psz_path, VLC_FALSE ); gnutls_Addx509Directory ((vlc_object_t *)p_session,
free( psz_path ); p_sys->x509_cred, path, VLC_FALSE);
}
if( asprintf( &psz_path, "%s/ca-certificates.crt", sprintf (path, "%s/ca-certificates.crt", datadir);
config_GetDataDir ( (vlc_object_t *)p_session) ) != -1 ) gnutls_Addx509File ((vlc_object_t *)p_session,
{ p_sys->x509_cred, path, VLC_FALSE);
gnutls_Addx509File( (vlc_object_t *)p_session,
p_sys->x509_cred, psz_path, VLC_FALSE );
free( psz_path );
}
p_session->pf_handshake2 = gnutls_HandshakeAndValidate; p_session->pf_handshake2 = gnutls_HandshakeAndValidate;
} }
else else
p_session->pf_handshake2 = gnutls_ContinueHandshake; p_session->pf_handshake2 = gnutls_ContinueHandshake;
{ sprintf (path, "%s/"CONFIG_DIR"/ssl/private", homedir);
char *psz_path; gnutls_Addx509Directory ((vlc_object_t *)p_session, p_sys->x509_cred,
path, VLC_TRUE);
if( asprintf( &psz_path, "%s/"CONFIG_DIR"/ssl/private",
p_tls->p_libvlc->psz_homedir ) == -1 )
{
gnutls_certificate_free_credentials( p_sys->x509_cred );
goto error;
}
gnutls_Addx509Directory( (vlc_object_t *)p_session, p_sys->x509_cred,
psz_path, VLC_TRUE );
free( psz_path );
}
i_val = gnutls_init( &p_sys->session.session, GNUTLS_CLIENT ); i_val = gnutls_init( &p_sys->session.session, GNUTLS_CLIENT );
if( i_val != 0 ) if( i_val != 0 )
...@@ -661,26 +660,9 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -661,26 +660,9 @@ gnutls_ClientCreate( tls_t *p_tls )
goto error; goto error;
} }
i_val = gnutls_set_default_priority( p_sys->session.session ); if (gnutls_SessionPrioritize (VLC_OBJECT (p_session),
if( i_val < 0 ) p_sys->session.session))
{ goto s_error;
msg_Err( p_tls, "cannot set ciphers priorities: %s",
gnutls_strerror( i_val ) );
gnutls_deinit( p_sys->session.session );
gnutls_certificate_free_credentials( p_sys->x509_cred );
goto error;
}
i_val = gnutls_certificate_type_set_priority( p_sys->session.session,
cert_type_priority );
if( i_val < 0 )
{
msg_Err( p_tls, "cannot set certificate type priorities: %s",
gnutls_strerror( i_val ) );
gnutls_deinit( p_sys->session.session );
gnutls_certificate_free_credentials( p_sys->x509_cred );
goto error;
}
i_val = gnutls_credentials_set( p_sys->session.session, i_val = gnutls_credentials_set( p_sys->session.session,
GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE,
...@@ -689,13 +671,15 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -689,13 +671,15 @@ gnutls_ClientCreate( tls_t *p_tls )
{ {
msg_Err( p_tls, "cannot set TLS session credentials: %s", msg_Err( p_tls, "cannot set TLS session credentials: %s",
gnutls_strerror( i_val ) ); gnutls_strerror( i_val ) );
gnutls_deinit( p_sys->session.session ); goto s_error;
gnutls_certificate_free_credentials( p_sys->x509_cred );
goto error;
} }
return p_session; return p_session;
s_error:
gnutls_deinit( p_sys->session.session );
gnutls_certificate_free_credentials( p_sys->x509_cred );
error: error:
vlc_object_detach( p_session ); vlc_object_detach( p_session );
vlc_object_destroy( p_session ); vlc_object_destroy( p_session );
...@@ -849,10 +833,8 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server ) ...@@ -849,10 +833,8 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server )
((tls_session_sys_t *)p_session->p_sys)->session = session; ((tls_session_sys_t *)p_session->p_sys)->session = session;
i_val = gnutls_set_default_priority( session ); i_val = gnutls_set_default_priority( session );
if( i_val < 0 ) if (gnutls_SessionPrioritize (VLC_OBJECT (p_session), session))
{ {
msg_Err( p_server, "cannot set ciphers priorities: %s",
gnutls_strerror( i_val ) );
gnutls_deinit( session ); gnutls_deinit( session );
goto error; goto error;
} }
...@@ -870,11 +852,12 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server ) ...@@ -870,11 +852,12 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server )
if( p_session->pf_handshake2 == gnutls_HandshakeAndValidate ) if( p_session->pf_handshake2 == gnutls_HandshakeAndValidate )
gnutls_certificate_server_set_request( session, GNUTLS_CERT_REQUIRE ); gnutls_certificate_server_set_request( session, GNUTLS_CERT_REQUIRE );
gnutls_dh_set_prime_bits( session, get_Int( p_server, "gnutls-dh-bits" ) ); i_val = config_GetInt (p_server, "gnutls-dh-bits");
gnutls_dh_set_prime_bits (session, i_val);
/* Session resumption support */ /* Session resumption support */
gnutls_db_set_cache_expiration( session, get_Int( p_server, i_val = config_GetInt (p_server, "gnutls-cache-expiration");
"gnutls-cache-expiration" ) ); gnutls_db_set_cache_expiration (session, i_val);
gnutls_db_set_retrieve_function( session, cb_fetch ); gnutls_db_set_retrieve_function( session, cb_fetch );
gnutls_db_set_remove_function( session, cb_delete ); gnutls_db_set_remove_function( session, cb_delete );
gnutls_db_set_store_function( session, cb_store ); gnutls_db_set_store_function( session, cb_store );
...@@ -997,7 +980,7 @@ gnutls_ServerCreate( tls_t *p_tls, const char *psz_cert_path, ...@@ -997,7 +980,7 @@ gnutls_ServerCreate( tls_t *p_tls, const char *psz_cert_path,
if( p_sys == NULL ) if( p_sys == NULL )
return NULL; return NULL;
p_sys->i_cache_size = get_Int( p_tls, "gnutls-cache-size" ); p_sys->i_cache_size = config_GetInt (p_tls, "gnutls-cache-size");
p_sys->p_cache = (struct saved_session_t *)calloc( p_sys->i_cache_size, p_sys->p_cache = (struct saved_session_t *)calloc( p_sys->i_cache_size,
sizeof( struct saved_session_t ) ); sizeof( struct saved_session_t ) );
if( p_sys->p_cache == NULL ) if( p_sys->p_cache == NULL )
...@@ -1061,7 +1044,7 @@ gnutls_ServerCreate( tls_t *p_tls, const char *psz_cert_path, ...@@ -1061,7 +1044,7 @@ gnutls_ServerCreate( tls_t *p_tls, const char *psz_cert_path,
{ {
msg_Dbg( p_server, "computing Diffie Hellman ciphers parameters" ); msg_Dbg( p_server, "computing Diffie Hellman ciphers parameters" );
val = gnutls_dh_params_generate2( p_sys->dh_params, val = gnutls_dh_params_generate2( p_sys->dh_params,
get_Int( p_tls, "gnutls-dh-bits" ) ); config_GetInt( p_tls, "gnutls-dh-bits" ) );
} }
if( val < 0 ) if( val < 0 )
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment