⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnutls.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    {        msg_Err( session, "Certificate expired" );        goto crt_error;    }    if( gnutls_x509_crt_get_activation_time( cert ) > time ( NULL ) )    {        msg_Err( session, "Certificate not yet valid" );        goto crt_error;    }    gnutls_x509_crt_deinit( cert );    msg_Dbg( session, "TLS/x509 certificate verified" );    return 0;crt_error:    gnutls_x509_crt_deinit( cert );error:    session->pf_close( session );    return -1;}/** * Starts negociation of a TLS session. * * @param fd stream socket already connected with the peer. * @param psz_hostname if not NULL, hostname to mention as a Server Name. * * @return -1 on error (you need not and must not call tls_SessionClose), * 0 on succesful handshake completion, 1 if more would-be blocking recv is * needed, 2 if more would-be blocking send is required. */static intgnutls_BeginHandshake( tls_session_t *p_session, int fd,                       const char *psz_hostname ){    tls_session_sys_t *p_sys;    p_sys = (tls_session_sys_t *)(p_session->p_sys);    gnutls_transport_set_ptr (p_sys->session, (gnutls_transport_ptr)(intptr_t)fd);    if( psz_hostname != NULL )    {        gnutls_server_name_set( p_sys->session, GNUTLS_NAME_DNS, psz_hostname,                                strlen( psz_hostname ) );        if( get_Bool( p_session, "tls-check-hostname" ) )        {            p_sys->psz_hostname = strdup( psz_hostname );            if( p_sys->psz_hostname == NULL )            {                p_session->pf_close( p_session );                return -1;            }        }    }    return p_session->pf_handshake2( p_session );}/** * Terminates TLS session and releases session data. * You still have to close the socket yourself. */static voidgnutls_SessionClose( tls_session_t *p_session ){    tls_session_sys_t *p_sys;    p_sys = (tls_session_sys_t *)(p_session->p_sys);    if( p_sys->b_handshaked == VLC_TRUE )        gnutls_bye( p_sys->session, GNUTLS_SHUT_WR );    gnutls_deinit( p_sys->session );    if( p_sys->psz_hostname != NULL )        free( p_sys->psz_hostname );    vlc_object_detach( p_session );    vlc_object_destroy( p_session );    free( p_sys );}static voidgnutls_ClientDelete( tls_session_t *p_session ){    /* On the client-side, credentials are re-allocated per session */    gnutls_certificate_credentials x509_cred =                        ((tls_client_sys_t *)(p_session->p_sys))->x509_cred;    gnutls_SessionClose( p_session );    /* credentials must be free'd *after* gnutls_deinit() */    gnutls_certificate_free_credentials( x509_cred );}static intgnutls_Addx509File( vlc_object_t *p_this,                    gnutls_certificate_credentials cred,                    const char *psz_path, vlc_bool_t b_priv );static intgnutls_Addx509Directory( vlc_object_t *p_this,                         gnutls_certificate_credentials cred,                         const char *psz_dirname,                         vlc_bool_t b_priv ){    DIR* dir;    const char *psz_dirent;    if( *psz_dirname == '\0' )        psz_dirname = ".";    dir = utf8_opendir( psz_dirname );    if( dir == NULL )    {        msg_Warn( p_this, "cannot open directory (%s): %s", psz_dirname,                  strerror( errno ) );        return VLC_EGENERIC;    }#ifdef S_ISLNK    else    {        struct stat st1, st2;        int fd = dirfd( dir );        /*         * Gets stats for the directory path, checks that it is not a         * symbolic link (to avoid possibly infinite recursion), and verifies         * that the inode is still the same, to avoid TOCTOU race condition.         */        if( ( fd == -1)         || fstat( fd, &st1 ) || utf8_lstat( psz_dirname, &st2 )         || S_ISLNK( st2.st_mode ) || ( st1.st_ino != st2.st_ino ) )        {            vlc_closedir_wrapper( dir );            return VLC_EGENERIC;        }    }#endif    while( ( psz_dirent = utf8_readdir( dir ) ) != NULL )    {        char *psz_filename;        int check;        if( ( strcmp( ".", psz_dirent ) == 0 )         || ( strcmp( "..", psz_dirent ) == 0 ) )            continue;        check = asprintf( &psz_filename, "%s/%s", psz_dirname,                              psz_dirent );        LocaleFree( psz_dirent );        if( check == -1 )            continue;        gnutls_Addx509File( p_this, cred, psz_filename, b_priv );        free( psz_filename );    }    vlc_closedir_wrapper( dir );    return VLC_SUCCESS;}static intgnutls_Addx509File( vlc_object_t *p_this,                    gnutls_certificate_credentials cred,                    const char *psz_path, vlc_bool_t b_priv ){    struct stat st;    if( utf8_stat( psz_path, &st ) == 0 )    {        if( S_ISREG( st.st_mode ) )        {            char *psz_localname = ToLocale( psz_path );            int i = b_priv                    ? gnutls_certificate_set_x509_key_file( cred,                    psz_localname,  psz_localname, GNUTLS_X509_FMT_PEM )                : gnutls_certificate_set_x509_trust_file( cred,                        psz_localname, GNUTLS_X509_FMT_PEM );            LocaleFree( psz_localname );            if( i < 0 )            {                msg_Warn( p_this, "cannot add x509 credentials (%s): %s",                          psz_path, gnutls_strerror( i ) );                return VLC_EGENERIC;            }            else            {                msg_Dbg( p_this, "added x509 credentials (%s)",                         psz_path );                return VLC_SUCCESS;            }        }        else if( S_ISDIR( st.st_mode ) )        {            msg_Dbg( p_this,                     "looking recursively for x509 credentials in %s",                     psz_path );            return gnutls_Addx509Directory( p_this, cred, psz_path, b_priv);        }    }    else        msg_Warn( p_this, "cannot add x509 credentials (%s): %s",                  psz_path, strerror( errno ) );    return VLC_EGENERIC;}/** * Initializes a client-side TLS session. */static tls_session_t *gnutls_ClientCreate( tls_t *p_tls ){    tls_session_t *p_session = NULL;    tls_client_sys_t *p_sys = NULL;    int i_val;    const int cert_type_priority[3] =    {        GNUTLS_CRT_X509,        0    };    p_sys = (tls_client_sys_t *)malloc( sizeof(struct tls_client_sys_t) );    if( p_sys == NULL )        return NULL;    p_session = (struct tls_session_t *)vlc_object_create ( p_tls, sizeof(struct tls_session_t) );    if( p_session == NULL )    {        free( p_sys );        return NULL;    }    p_session->p_sys = p_sys;    p_session->sock.p_sys = p_session;    p_session->sock.pf_send = gnutls_Send;    p_session->sock.pf_recv = gnutls_Recv;    p_session->pf_handshake = gnutls_BeginHandshake;    p_session->pf_close = gnutls_ClientDelete;    p_sys->session.b_handshaked = VLC_FALSE;    p_sys->session.psz_hostname = NULL;    vlc_object_attach( p_session, p_tls );    i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred );    if( i_val != 0 )    {        msg_Err( p_tls, "cannot allocate X509 credentials: %s",                 gnutls_strerror( i_val ) );        goto error;    }    if( get_Bool( p_tls, "tls-check-cert" ) )    {        char *psz_path;        if( asprintf( &psz_path, "%s/"CONFIG_DIR"/ssl/certs",                      p_tls->p_vlc->psz_homedir ) != -1 )        {            gnutls_Addx509Directory( (vlc_object_t *)p_session,                                     p_sys->x509_cred, psz_path, VLC_FALSE );            free( psz_path );        }        if( asprintf( &psz_path, "%s/ca-certificates.crt",            config_GetDataDir ( (vlc_object_t *)p_session) ) != -1 )        {            gnutls_Addx509File( (vlc_object_t *)p_session,                                p_sys->x509_cred, psz_path, VLC_FALSE );            free( psz_path );        }        p_session->pf_handshake2 = gnutls_HandshakeAndValidate;    }    else        p_session->pf_handshake2 = gnutls_ContinueHandshake;    {        char *psz_path;        if( asprintf( &psz_path, "%s/"CONFIG_DIR"/ssl/private",                      p_tls->p_vlc->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 );    if( i_val != 0 )    {        msg_Err( p_tls, "cannot initialize TLS session: %s",                 gnutls_strerror( i_val ) );        gnutls_certificate_free_credentials( p_sys->x509_cred );        goto error;    }    i_val = gnutls_set_default_priority( p_sys->session.session );    if( i_val < 0 )    {        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,                                    GNUTLS_CRD_CERTIFICATE,                                    p_sys->x509_cred );    if( i_val < 0 )    {        msg_Err( p_tls, "cannot set TLS session credentials: %s",                 gnutls_strerror( i_val ) );        gnutls_deinit( p_sys->session.session );        gnutls_certificate_free_credentials( p_sys->x509_cred );        goto error;    }    return p_session;error:    vlc_object_detach( p_session );    vlc_object_destroy( p_session );    free( p_sys );    return NULL;}/** * TLS session resumption callbacks (server-side) */static int cb_store( void *p_server, gnutls_datum key, gnutls_datum data ){    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys;    if( ( p_sys->i_cache_size == 0 )     || ( key.size > MAX_SESSION_ID )     || ( data.size > MAX_SESSION_DATA ) )        return -1;    vlc_mutex_lock( &p_sys->cache_lock );    memcpy( p_sys->p_store->id, key.data, key.size);    memcpy( p_sys->p_store->data, data.data, data.size );    p_sys->p_store->i_idlen = key.size;    p_sys->p_store->i_datalen = data.size;    p_sys->p_store++;    if( ( p_sys->p_store - p_sys->p_cache ) == p_sys->i_cache_size )        p_sys->p_store = p_sys->p_cache;    vlc_mutex_unlock( &p_sys->cache_lock );    return 0;}static const gnutls_datum err_datum = { NULL, 0 };static gnutls_datum cb_fetch( void *p_server, gnutls_datum key ){    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys;    saved_session_t *p_session, *p_end;    p_session = p_sys->p_cache;    p_end = p_session + p_sys->i_cache_size;    vlc_mutex_lock( &p_sys->cache_lock );    while( p_session < p_end )    {        if( ( p_session->i_idlen == key.size )         && !memcmp( p_session->id, key.data, key.size ) )        {            gnutls_datum data;            data.size = p_session->i_datalen;            data.data = gnutls_malloc( data.size );            if( data.data == NULL )            {                vlc_mutex_unlock( &p_sys->cache_lock );                return err_datum;            }            memcpy( data.data, p_session->data, data.size );            vlc_mutex_unlock( &p_sys->cache_lock );            return data;        }        p_session++;    }    vlc_mutex_unlock( &p_sys->cache_lock );    return err_datum;}static int cb_delete( void *p_server, gnutls_datum key ){    tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys;    saved_session_t *p_session, *p_end;    p_session = p_sys->p_cache;    p_end = p_session + p_sys->i_cache_size;    vlc_mutex_lock( &p_sys->cache_lock );    while( p_session < p_end )    {        if( ( p_session->i_idlen == key.size )         && !memcmp( p_session->id, key.data, key.size ) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -