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

📄 update.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    return crc & 0xFFFFFFL;}/* * Transform an armored document in binary format * Used on public keys and signatures */static int pgp_unarmor( char *p_ibuf, size_t i_ibuf_len,                        uint8_t *p_obuf, size_t i_obuf_len ){    char *p_ipos = p_ibuf;    uint8_t *p_opos = p_obuf;    int i_end = 0;    int i_header_skipped = 0;    while( !i_end && p_ipos < p_ibuf + i_ibuf_len && *p_ipos != '=' )    {        if( *p_ipos == '\r' || *p_ipos == '\n' )        {            p_ipos++;            continue;        }        size_t i_line_len = strcspn( p_ipos, "\r\n" );        if( i_line_len == 0 )            continue;        if( !i_header_skipped )        {            if( !strncmp( p_ipos, "-----BEGIN PGP", 14 ) )                i_header_skipped = 1;            p_ipos += i_line_len + 1;            continue;        }        if( !strncmp( p_ipos, "Version:", 8 ) )        {            p_ipos += i_line_len + 1;            continue;        }        if( p_ipos[i_line_len - 1] == '=' )        {            i_end = 1;            p_ipos[i_line_len - 1] = '\0';        }        else            p_ipos[i_line_len] = '\0';        p_opos += vlc_b64_decode_binary_to_buffer(  p_opos,                        p_obuf - p_opos + i_obuf_len, p_ipos );        p_ipos += i_line_len + 1;    }    /* XXX: the CRC is OPTIONAL, really require it ? */    if( p_ipos + 5 > p_ibuf + i_ibuf_len || *p_ipos++ != '=' )        return 0;    uint8_t p_crc[3];    if( vlc_b64_decode_binary_to_buffer( p_crc, 3, p_ipos ) != 3 )        return 0;    long l_crc = crc_octets( p_obuf, p_opos - p_obuf );    long l_crc2 = ( 0 << 24 ) + ( p_crc[0] << 16 ) + ( p_crc[1] << 8 ) + p_crc[2];    return l_crc2 == l_crc ? p_opos - p_obuf : 0;}/* * Download the signature associated to a document or a binary file. * We're given the file's url, we just append ".asc" to it and download */static int download_signature(  vlc_object_t *p_this,                                signature_packet_t *p_sig,                                const char *psz_url ){    char *psz_sig = (char*) malloc( strlen( psz_url ) + 4 + 1 ); /* ".asc" + \0 */    if( !psz_sig )        return VLC_ENOMEM;    strcpy( psz_sig, psz_url );    strcat( psz_sig, ".asc" );    stream_t *p_stream = stream_UrlNew( p_this, psz_sig );    free( psz_sig );    if( !p_stream )        return VLC_ENOMEM;    int64_t i_size = stream_Size( p_stream );    msg_Dbg( p_this, "Downloading signature (%"PRId64" bytes)", i_size );    uint8_t *p_buf = (uint8_t*)malloc( i_size );    if( !p_buf )    {        stream_Delete( p_stream );        return VLC_ENOMEM;    }    int i_read = stream_Read( p_stream, p_buf, (int)i_size );    stream_Delete( p_stream );    if( i_read != (int)i_size )    {        msg_Dbg( p_this,            "Couldn't download full signature (only %d bytes)", i_read );        free( p_buf );        return VLC_EGENERIC;    }    if( (uint8_t)*p_buf < 0x80 ) /* ASCII */    {        msg_Dbg( p_this, "Unarmoring signature" );        uint8_t* p_unarmored = (uint8_t*) malloc( ( i_size * 3 ) / 4 + 1 );        if( !p_unarmored )        {            free( p_buf );            return VLC_EGENERIC;        }        int i_bytes = pgp_unarmor( (char*)p_buf, i_size, p_unarmored, i_size );        free( p_buf );        p_buf = p_unarmored;        i_size = i_bytes;        if( i_bytes < 2 )        {            free( p_buf );            msg_Dbg( p_this, "Unarmoring failed : corrupted signature ?" );            return VLC_EGENERIC;        }    }    if( packet_type( *p_buf ) != SIGNATURE_PACKET )    {        free( p_buf );        msg_Dbg( p_this, "Not a signature: %d", *p_buf );        return VLC_EGENERIC;    }    size_t i_header_len = packet_header_len( *p_buf );    if( ( i_header_len != 1 && i_header_len != 2 && i_header_len != 4 ) ||        i_header_len + 1 > (size_t)i_size )    {        free( p_buf );        msg_Dbg( p_this, "Invalid signature packet header" );        return VLC_EGENERIC;    }    size_t i_len = scalar_number( p_buf+1, i_header_len );    if( i_len + i_header_len + 1 != (size_t)i_size )    {        free( p_buf );        msg_Dbg( p_this, "Invalid signature packet" );        return VLC_EGENERIC;    }    int i_ret = parse_signature_packet( p_sig, p_buf+1+i_header_len, i_len );    free( p_buf );    if( i_ret != VLC_SUCCESS )    {        msg_Dbg( p_this, "Couldn't parse signature" );        return i_ret;    }    if( p_sig->type != BINARY_SIGNATURE && p_sig->type != TEXT_SIGNATURE )    {        msg_Dbg( p_this, "Invalid signature type: %d", p_sig->type );        if( p_sig->version == 4 )        {            free( p_sig->specific.v4.hashed_data );            free( p_sig->specific.v4.unhashed_data );        }        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/* * Verify an OpenPGP signature made on some SHA-1 hash, with some DSA public key */static int verify_signature( uint8_t *p_r, uint8_t *p_s,        public_key_packet_t *p_key, uint8_t *p_hash ){    /* the data to be verified (a SHA-1 hash) */    const char *hash_sexp_s = "(data(flags raw)(value %m))";    /* the public key */    const char *key_sexp_s = "(public-key(dsa(p %m)(q %m)(g %m)(y %m)))";    /* the signature */    const char *sig_sexp_s = "(sig-val(dsa(r %m )(s %m )))";    size_t erroff;    gcry_mpi_t p, q, g, y, r, s, hash;    p = q = g = y = r = s = hash = NULL;    gcry_sexp_t key_sexp, hash_sexp, sig_sexp;    key_sexp = hash_sexp = sig_sexp = NULL;    int i_p_len = mpi_len( p_key->p );    int i_q_len = mpi_len( p_key->q );    int i_g_len = mpi_len( p_key->g );    int i_y_len = mpi_len( p_key->y );    if( gcry_mpi_scan( &p, GCRYMPI_FMT_USG, p_key->p + 2, i_p_len, NULL ) ||        gcry_mpi_scan( &q, GCRYMPI_FMT_USG, p_key->q + 2, i_q_len, NULL ) ||        gcry_mpi_scan( &g, GCRYMPI_FMT_USG, p_key->g + 2, i_g_len, NULL ) ||        gcry_mpi_scan( &y, GCRYMPI_FMT_USG, p_key->y + 2, i_y_len, NULL ) ||        gcry_sexp_build( &key_sexp, &erroff, key_sexp_s, p, q, g, y ) )        goto problem;    int i_r_len = mpi_len( p_r );    int i_s_len = mpi_len( p_s );    if( gcry_mpi_scan( &r, GCRYMPI_FMT_USG, p_r + 2, i_r_len, NULL ) ||        gcry_mpi_scan( &s, GCRYMPI_FMT_USG, p_s + 2, i_s_len, NULL ) ||        gcry_sexp_build( &sig_sexp, &erroff, sig_sexp_s, r, s ) )        goto problem;    int i_hash_len = 20;    if( gcry_mpi_scan( &hash, GCRYMPI_FMT_USG, p_hash, i_hash_len, NULL ) ||        gcry_sexp_build( &hash_sexp, &erroff, hash_sexp_s, hash ) )        goto problem;    if( gcry_pk_verify( sig_sexp, hash_sexp, key_sexp ) )        goto problem;    return VLC_SUCCESS;problem:    if( p ) gcry_mpi_release( p );    if( q ) gcry_mpi_release( q );    if( g ) gcry_mpi_release( g );    if( y ) gcry_mpi_release( y );    if( r ) gcry_mpi_release( r );    if( s ) gcry_mpi_release( s );    if( hash ) gcry_mpi_release( hash );    if( key_sexp ) gcry_sexp_release( key_sexp );    if( sig_sexp ) gcry_sexp_release( sig_sexp );    if( hash_sexp ) gcry_sexp_release( hash_sexp );    return VLC_EGENERIC;}/* * fill a public_key_t with public key data, including: *   * public key packet *   * signature packet issued by key which long id is p_sig_issuer *   * user id packet */static int parse_public_key( const uint8_t *p_key_data, size_t i_key_len,                             public_key_t *p_key, const uint8_t *p_sig_issuer ){    uint8_t *pos = (uint8_t*) p_key_data;    uint8_t *max_pos = pos + i_key_len;    int i_status = 0;#define PUBLIC_KEY_FOUND    0x01#define USER_ID_FOUND       0x02#define SIGNATURE_FOUND     0X04    uint8_t *p_key_unarmored = NULL;    p_key->psz_username = NULL;    p_key->sig.specific.v4.hashed_data = NULL;    p_key->sig.specific.v4.unhashed_data = NULL;    if( !( *pos & 0x80 ) )    {   /* first byte is ASCII, unarmoring */        p_key_unarmored = (uint8_t*)malloc( i_key_len );        if( !p_key_unarmored )            return VLC_ENOMEM;        int i_len = pgp_unarmor( (char*)p_key_data, i_key_len,                                 p_key_unarmored, i_key_len );        if( i_len == 0 )            goto error;        pos = p_key_unarmored;        max_pos = pos + i_len;    }    while( pos < max_pos )    {        if( !(*pos & 0x80) || *pos & 0x40 )            goto error;        int i_type = packet_type( *pos );        int i_header_len = packet_header_len( *pos++ );        if( pos + i_header_len > max_pos ||            ( i_header_len != 1 && i_header_len != 2 && i_header_len != 4 ) )            goto error;        int i_packet_len = scalar_number( pos, i_header_len );        pos += i_header_len;        if( pos + i_packet_len > max_pos )            goto error;        switch( i_type )        {            case PUBLIC_KEY_PACKET:                i_status |= PUBLIC_KEY_FOUND;                if( parse_public_key_packet( &p_key->key, pos, i_packet_len ) != VLC_SUCCESS )                    goto error;                break;            case SIGNATURE_PACKET: /* we accept only v4 signatures here */                if( i_status & SIGNATURE_FOUND || !p_sig_issuer )                    break;                int i_ret = parse_signature_packet( &p_key->sig, pos,                                                    i_packet_len );                if( i_ret == VLC_SUCCESS )                {                    if( p_key->sig.version != 4 )                        break;                    if( memcmp( p_key->sig.issuer_longid, p_sig_issuer, 8 ) )                    {                        free( p_key->sig.specific.v4.hashed_data );                        free( p_key->sig.specific.v4.unhashed_data );                        p_key->sig.specific.v4.hashed_data = NULL;                        p_key->sig.specific.v4.unhashed_data = NULL;                        break;                    }                    i_status |= SIGNATURE_FOUND;                }                break;            case USER_ID_PACKET:                if( p_key->psz_username ) /* save only the first User ID */                    break;                i_status |= USER_ID_FOUND;                p_key->psz_username = (uint8_t*)malloc( i_packet_len + 1);                if( !p_key->psz_username )                    goto error;                memcpy( p_key->psz_username, pos, i_packet_len );                p_key->psz_username[i_packet_len] = '\0';                break;            default:                break;        }        pos += i_packet_len;    }    free( p_key_unarmored );    if( !( i_status & ( PUBLIC_KEY_FOUND | USER_ID_FOUND ) ) )        return VLC_EGENERIC;    if( p_sig_issuer && !( i_status & SIGNATURE_FOUND ) )        return VLC_EGENERIC;    return VLC_SUCCESS;error:    if( p_key->sig.version == 4 )    {        free( p_key->sig.specific.v4.hashed_data );        free( p_key->sig.specific.v4.unhashed_data );    }    free( p_key->psz_username );    free( p_key_unarmored );    return VLC_EGENERIC;}/* * return a sha1 hash of a file */static uint8_t *hash_sha1_from_file( const char *psz_file,                            signature_packet_t *p_sig ){    if( p_sig->type != BINARY_SIGNATURE && p_sig->type != TEXT_SIGNATURE )        return NULL;    FILE *f = utf8_fopen( psz_file, "r" );    if( !f )        return NULL;    uint8_t buffer[4096];    gcry_md_hd_t hd;    if( gcry_md_open( &hd, GCRY_MD_SHA1, 0 ) )    {        fclose( f );        return NULL;    }    size_t i_read;    while( ( i_read = fread( buffer, 1, sizeof(buffer), f ) ) > 0 )        gcry_md_write( hd, buffer, i_read );    if( p_sig->version == 3 )    {        gcry_md_putc( hd, p_sig->type );        gcry_md_write( hd, &p_sig->specific.v3.timestamp, 4 );    }    else if( p_sig->version == 4 )    {        gcry_md_putc( hd, p_sig->version );        gcry_md_putc( hd, p_sig->type );        gcry_md_putc( hd, p_sig->public_key_algo );        gcry_md_putc( hd, p_sig->digest_algo );        gcry_md_write( hd, p_sig->specific.v4.hashed_data_len, 2 );        size_t i_len = scalar_number( p_sig->specific.v4.hashed_data_len, 2 );        gcry_md_write( hd, p_sig->specific.v4.hashed_data, i_len );    }    else    {   /* RFC 4880 only tells about versions 3 and 4 */        gcry_md_close( hd );        return NULL;    }    fclose( f );    gcry_md_final( hd );    uint8_t *p_tmp = (uint8_t*) gcry_md_read( hd, GCRY_MD_SHA1);    uint8_t *p_hash = malloc( 20 );    if( p_hash )        memcpy( p_hash, p_tmp, 20 );    gcry_md_close( hd );    return p_hash;}/* * download a public key (the last one) from videolan server, and parse it */static public_key_t *download_key( vlc_object_t *p_this,                    const uint8_t *p_longid, const uint8_t *p_signature_issuer ){    char *psz_url;    if( asprintf( &psz_url, "http://download.videolan.org/pub/keys/%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X.asc",                    p_longid[0], p_longid[1], p_longid[2], p_longid[3],                    p_longid[4], p_longid[5], p_longid[6], p_longid[7] ) == -1 )        return NULL;    stream_t *p_stream = stream_UrlNew( p_this, psz_url );

⌨️ 快捷键说明

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