📄 gnutls.c
字号:
p_session->pf_close = gnutls_SessionClose; ((tls_session_sys_t *)p_session->p_sys)->b_handshaked = VLC_FALSE; ((tls_session_sys_t *)p_session->p_sys)->psz_hostname = NULL; i_val = gnutls_init( &session, GNUTLS_SERVER ); if( i_val != 0 ) { msg_Err( p_server, "Cannot initialize TLS session : %s", gnutls_strerror( i_val ) ); goto error; } ((tls_session_sys_t *)p_session->p_sys)->session = session; i_val = gnutls_set_default_priority( session ); if( i_val < 0 ) { msg_Err( p_server, "Cannot set ciphers priorities : %s", gnutls_strerror( i_val ) ); gnutls_deinit( session ); goto error; } i_val = gnutls_credentials_set( session, GNUTLS_CRD_CERTIFICATE, p_server_sys->x509_cred ); if( i_val < 0 ) { msg_Err( p_server, "Cannot set TLS session credentials : %s", gnutls_strerror( i_val ) ); gnutls_deinit( session ); goto error; } if( p_session->pf_handshake2 == gnutls_HandshakeAndValidate ) gnutls_certificate_server_set_request( session, GNUTLS_CERT_REQUIRE ); gnutls_dh_set_prime_bits( session, get_Int( p_server, "dh-bits" ) ); /* Session resumption support */ gnutls_db_set_cache_expiration( session, get_Int( p_server, "tls-cache-expiration" ) ); gnutls_db_set_retrieve_function( session, cb_fetch ); gnutls_db_set_remove_function( session, cb_delete ); gnutls_db_set_store_function( session, cb_store ); gnutls_db_set_ptr( session, p_server ); return p_session;error: free( p_session->p_sys ); vlc_object_detach( p_session ); vlc_object_destroy( p_session ); return NULL;}/***************************************************************************** * tls_ServerDelete: ***************************************************************************** * Releases data allocated with tls_ServerCreate. *****************************************************************************/static voidgnutls_ServerDelete( tls_server_t *p_server ){ tls_server_sys_t *p_sys; p_sys = (tls_server_sys_t *)p_server->p_sys; vlc_mutex_destroy( &p_sys->cache_lock ); free( p_sys->p_cache ); vlc_object_detach( p_server ); vlc_object_destroy( p_server ); /* all sessions depending on the server are now deinitialized */ gnutls_certificate_free_credentials( p_sys->x509_cred ); gnutls_dh_params_deinit( p_sys->dh_params ); free( p_sys );}/***************************************************************************** * tls_ServerAddCA: ***************************************************************************** * Adds one or more certificate authorities. * Returns -1 on error, 0 on success. *****************************************************************************/static intgnutls_ServerAddCA( tls_server_t *p_server, const char *psz_ca_path ){ int val; tls_server_sys_t *p_sys; p_sys = (tls_server_sys_t *)(p_server->p_sys); val = gnutls_certificate_set_x509_trust_file( p_sys->x509_cred, psz_ca_path, GNUTLS_X509_FMT_PEM ); if( val < 0 ) { msg_Err( p_server, "Cannot add trusted CA (%s) : %s", psz_ca_path, gnutls_strerror( val ) ); return VLC_EGENERIC; } msg_Dbg( p_server, " %d trusted CA added (%s)", val, psz_ca_path ); /* enables peer's certificate verification */ p_sys->pf_handshake2 = gnutls_HandshakeAndValidate; return VLC_SUCCESS;}/***************************************************************************** * tls_ServerAddCRL: ***************************************************************************** * Adds a certificates revocation list to be sent to TLS clients. * Returns -1 on error, 0 on success. *****************************************************************************/static intgnutls_ServerAddCRL( tls_server_t *p_server, const char *psz_crl_path ){ int val; val = gnutls_certificate_set_x509_crl_file( ((tls_server_sys_t *) (p_server->p_sys))->x509_cred, psz_crl_path, GNUTLS_X509_FMT_PEM ); if( val < 0 ) { msg_Err( p_server, "Cannot add CRL (%s) : %s", psz_crl_path, gnutls_strerror( val ) ); return VLC_EGENERIC; } msg_Dbg( p_server, "%d CRL added (%s)", val, psz_crl_path ); return VLC_SUCCESS;} /***************************************************************************** * tls_ServerCreate: ***************************************************************************** * Allocates a whole server's TLS credentials. * Returns NULL on error. *****************************************************************************/static tls_server_t *gnutls_ServerCreate( tls_t *p_tls, const char *psz_cert_path, const char *psz_key_path ){ tls_server_t *p_server; tls_server_sys_t *p_sys; int val; msg_Dbg( p_tls, "Creating TLS server" ); p_sys = (tls_server_sys_t *)malloc( sizeof(struct tls_server_sys_t) ); if( p_sys == NULL ) return NULL; p_sys->i_cache_size = get_Int( p_tls, "tls-cache-size" ); p_sys->p_cache = (struct saved_session_t *)calloc( p_sys->i_cache_size, sizeof( struct saved_session_t ) ); if( p_sys->p_cache == NULL ) { free( p_sys ); return NULL; } p_sys->p_store = p_sys->p_cache; p_server = vlc_object_create( p_tls, sizeof(struct tls_server_t) ); if( p_server == NULL ) { free( p_sys->p_cache ); free( p_sys ); return NULL; } vlc_object_attach( p_server, p_tls ); p_server->p_sys = p_sys; p_server->pf_delete = gnutls_ServerDelete; p_server->pf_add_CA = gnutls_ServerAddCA; p_server->pf_add_CRL = gnutls_ServerAddCRL; p_server->pf_session_prepare = gnutls_ServerSessionPrepare; /* No certificate validation by default */ p_sys->pf_handshake2 = gnutls_ContinueHandshake; /* FIXME: check for errors */ vlc_mutex_init( p_server, &p_sys->cache_lock ); /* Sets server's credentials */ val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred ); if( val != 0 ) { msg_Err( p_server, "Cannot allocate X509 credentials : %s", gnutls_strerror( val ) ); goto error; } val = gnutls_certificate_set_x509_key_file( p_sys->x509_cred, psz_cert_path, psz_key_path, GNUTLS_X509_FMT_PEM ); if( val < 0 ) { msg_Err( p_server, "Cannot set certificate chain or private key : %s", gnutls_strerror( val ) ); gnutls_certificate_free_credentials( p_sys->x509_cred ); goto error; } /* FIXME: * - regenerate these regularly * - support other ciper suites */ val = gnutls_dh_params_init( &p_sys->dh_params ); if( val >= 0 ) { msg_Dbg( p_server, "Computing Diffie Hellman ciphers parameters" ); val = gnutls_dh_params_generate2( p_sys->dh_params, get_Int( p_tls, "dh-bits" ) ); } if( val < 0 ) { msg_Err( p_server, "Cannot initialize DH cipher suites : %s", gnutls_strerror( val ) ); gnutls_certificate_free_credentials( p_sys->x509_cred ); goto error; } msg_Dbg( p_server, "Ciphers parameters computed" ); gnutls_certificate_set_dh_params( p_sys->x509_cred, p_sys->dh_params); return p_server;error: vlc_mutex_destroy( &p_sys->cache_lock ); vlc_object_detach( p_server ); vlc_object_destroy( p_server ); free( p_sys ); return NULL;}/***************************************************************************** * gcrypt thread option VLC implementation: *****************************************************************************/vlc_object_t *__p_gcry_data;static int gcry_vlc_mutex_init( void **p_sys ){ int i_val; vlc_mutex_t *p_lock = (vlc_mutex_t *)malloc( sizeof( vlc_mutex_t ) ); if( p_lock == NULL) return ENOMEM; i_val = vlc_mutex_init( __p_gcry_data, p_lock ); if( i_val ) free( p_lock ); else *p_sys = p_lock; return i_val;}static int gcry_vlc_mutex_destroy( void **p_sys ){ int i_val; vlc_mutex_t *p_lock = (vlc_mutex_t *)*p_sys; i_val = vlc_mutex_destroy( p_lock ); free( p_lock ); return i_val;}static int gcry_vlc_mutex_lock( void **p_sys ){ return vlc_mutex_lock( (vlc_mutex_t *)*p_sys );}static int gcry_vlc_mutex_unlock( void **lock ){ return vlc_mutex_unlock( (vlc_mutex_t *)*lock );}static struct gcry_thread_cbs gcry_threads_vlc ={ GCRY_THREAD_OPTION_USER, NULL, gcry_vlc_mutex_init, gcry_vlc_mutex_destroy, gcry_vlc_mutex_lock, gcry_vlc_mutex_unlock};/***************************************************************************** * Module initialization *****************************************************************************/static intOpen( vlc_object_t *p_this ){ tls_t *p_tls = (tls_t *)p_this; vlc_value_t lock, count; var_Create( p_this->p_libvlc, "gnutls_mutex", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "gnutls_mutex", &lock ); vlc_mutex_lock( lock.p_address ); /* Initialize GnuTLS only once */ var_Create( p_this->p_libvlc, "gnutls_count", VLC_VAR_INTEGER ); var_Get( p_this->p_libvlc, "gnutls_count", &count); if( count.i_int == 0) { const char *psz_version; __p_gcry_data = VLC_OBJECT( p_this->p_vlc ); gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_vlc); if( gnutls_global_init( ) ) { msg_Warn( p_this, "cannot initialize GnuTLS" ); vlc_mutex_unlock( lock.p_address ); return VLC_EGENERIC; } /* * FIXME: in fact, we currently depends on 1.0.17, but it breaks on * Debian which as a patched 1.0.16 (which we can use). */ psz_version = gnutls_check_version( "1.0.16" ); if( psz_version == NULL ) { gnutls_global_deinit( ); vlc_mutex_unlock( lock.p_address ); msg_Err( p_this, "unsupported GnuTLS version" ); return VLC_EGENERIC; } msg_Dbg( p_this, "GnuTLS v%s initialized", psz_version ); } count.i_int++; var_Set( p_this->p_libvlc, "gnutls_count", count); vlc_mutex_unlock( lock.p_address ); p_tls->pf_server_create = gnutls_ServerCreate; p_tls->pf_client_create = gnutls_ClientCreate; return VLC_SUCCESS;}/***************************************************************************** * Module deinitialization *****************************************************************************/static voidClose( vlc_object_t *p_this ){ /*tls_t *p_tls = (tls_t *)p_this; tls_sys_t *p_sys = (tls_sys_t *)(p_this->p_sys);*/ vlc_value_t lock, count; var_Create( p_this->p_libvlc, "gnutls_mutex", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "gnutls_mutex", &lock ); vlc_mutex_lock( lock.p_address ); var_Create( p_this->p_libvlc, "gnutls_count", VLC_VAR_INTEGER ); var_Get( p_this->p_libvlc, "gnutls_count", &count); count.i_int--; var_Set( p_this->p_libvlc, "gnutls_count", count); if( count.i_int == 0 ) { gnutls_global_deinit( ); msg_Dbg( p_this, "GnuTLS deinitialized" ); } vlc_mutex_unlock( lock.p_address );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -