/*****************************************************************************
- * update_crypto.c: DSA/SHA1 related functions used for updating
+ * update_crypto.c: OpenPGP related functions used for updating
*****************************************************************************
- * Copyright © 2008-2009 the VideoLAN team
+ * Copyright © 2008-2009 VLC authors and VideoLAN
* $Id$
*
* Authors: Rafaël Carré <funman@videolanorg>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either release 2 of the License, or
* (at your option) any later release.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/**
#define packet_header_len( c ) ( ( c & 0x03 ) + 1 ) /* number of bytes in a packet header */
-static inline int scalar_number( uint8_t *p, int header_len )
+static inline int scalar_number( const uint8_t *p, int header_len )
{
assert( header_len == 1 || header_len == 2 || header_len == 4 );
/* number of data bytes in a MPI */
-#define mpi_len( mpi ) ( ( scalar_number( mpi, 2 ) + 7 ) / 8 )
+static int mpi_len(const uint8_t *mpi)
+{
+ return (scalar_number(mpi, 2) + 7) / 8;
+}
+
+static size_t read_mpi(uint8_t *dst, const uint8_t *buf, size_t buflen, size_t bits)
+{
+ if (buflen < 2)
+ return 0;
+
+ size_t n = mpi_len(buf);
+
+ if (n * 8 > bits)
+ return 0;
+ n += 2;
+
+ if (buflen < n)
+ return 0;
+
+ memcpy(dst, buf, n);
+ return n;
+}
+
+#define READ_MPI(d, bits) do { \
+ size_t n = read_mpi(d, p_buf, i_packet_len - i_read, bits); \
+ if (!n) goto error; \
+ p_buf += n; \
+ i_read += n; \
+} while(0)
/*
* fill a public_key_packet_t structure from public key packet data
- * verify that it is a version 4 public key packet, using DSA
+ * verify that it is a version 4 public key packet, using DSA or RSA
*/
-static int parse_public_key_packet( public_key_packet_t *p_key, uint8_t *p_buf,
- size_t i_packet_len )
+static int parse_public_key_packet( public_key_packet_t *p_key,
+ const uint8_t *p_buf, size_t i_packet_len )
{
-
- if( i_packet_len > 418 || i_packet_len < 6 )
+ if( i_packet_len < 6 )
return VLC_EGENERIC;
size_t i_read = 0;
memcpy( p_key->timestamp, p_buf, 4 ); p_buf += 4; i_read += 4;
p_key->algo = *p_buf++; i_read++;
- if( p_key->algo != PUBLIC_KEY_ALGO_DSA )
- return VLC_EGENERIC;
-
- /* read p */
- if( i_read + 2 > i_packet_len )
- return VLC_EGENERIC;
-
- int i_p_len = mpi_len( p_buf );
-
- if( i_p_len > 128 || i_read + 2 + i_p_len > i_packet_len )
- return VLC_EGENERIC;
-
- memcpy( p_key->p, p_buf, 2+i_p_len );
- p_buf += 2+i_p_len; i_read += 2+i_p_len;
-
- /* read q */
- if( i_read + 2 > i_packet_len )
- return VLC_EGENERIC;
-
- int i_q_len = mpi_len( p_buf );
-
- if( i_q_len > 20 || i_read+2+i_q_len > i_packet_len )
- return VLC_EGENERIC;
-
- memcpy( p_key->q, p_buf, 2+i_q_len );
- p_buf += 2+i_q_len; i_read += 2+i_q_len;
-
- /* read g */
- if( i_read + 2 > i_packet_len )
- return VLC_EGENERIC;
-
- int i_g_len = mpi_len( p_buf );
-
- if( i_g_len > 128 || i_read+2+i_g_len > i_packet_len )
+ if( p_key->algo == GCRY_PK_DSA ) {
+ READ_MPI(p_key->sig.dsa.p, 3072);
+ READ_MPI(p_key->sig.dsa.q, 256);
+ READ_MPI(p_key->sig.dsa.g, 3072);
+ READ_MPI(p_key->sig.dsa.y, 3072);
+ } else if ( p_key->algo == GCRY_PK_RSA ) {
+ READ_MPI(p_key->sig.rsa.n, 4096);
+ READ_MPI(p_key->sig.rsa.e, 4096);
+ } else
return VLC_EGENERIC;
- memcpy( p_key->g, p_buf, 2+i_g_len );
- p_buf += 2+i_g_len; i_read += 2+i_g_len;
+ if( i_read == i_packet_len )
+ return VLC_SUCCESS;
- /* read y */
- if( i_read + 2 > i_packet_len )
- return VLC_EGENERIC;
-
- int i_y_len = mpi_len( p_buf );
-
-
- if( i_y_len > 128 || i_read+2+i_y_len > i_packet_len )
- return VLC_EGENERIC;
-
- memcpy( p_key->y, p_buf, 2+i_y_len );
- i_read += 2+i_y_len;
-
- if( i_read != i_packet_len ) /* some extra data eh ? */
- return VLC_EGENERIC;
+ /* some extra data eh ? */
- return VLC_SUCCESS;
+error:
+ return VLC_EGENERIC;
}
static size_t parse_signature_v3_packet( signature_packet_t *p_sig,
- uint8_t *p_buf, size_t i_sig_len )
+ const uint8_t *p_buf, size_t i_sig_len )
{
size_t i_read = 1; /* we already read the version byte */
/*
* fill a signature_packet_v4_t from signature packet data
- * verify that it was used with a DSA public key, using SHA-1 digest
+ * verify that it was used with a DSA or RSA public key
*/
static size_t parse_signature_v4_packet( signature_packet_t *p_sig,
- uint8_t *p_buf, size_t i_sig_len )
+ const uint8_t *p_buf, size_t i_sig_len )
{
size_t i_read = 1; /* we already read the version byte */
p_sig->type = *p_buf++; i_read++;
p_sig->public_key_algo = *p_buf++; i_read++;
+ if (p_sig->public_key_algo != GCRY_PK_DSA && p_sig->public_key_algo != GCRY_PK_RSA )
+ return 0;
p_sig->digest_algo = *p_buf++; i_read++;
}
else
{
- if( p + 4 > max_pos )
+ if( ++p + 4 > max_pos )
return 0;
- i_subpacket_len = *++p << 24;
- i_subpacket_len += *++p << 16;
- i_subpacket_len += *++p << 8;
- i_subpacket_len += *++p;
+ i_subpacket_len = U32_AT(p);
+ p += 4;
}
if( *p == ISSUER_SUBPACKET )
static int parse_signature_packet( signature_packet_t *p_sig,
- uint8_t *p_buf, size_t i_sig_len )
+ const uint8_t *p_buf, size_t i_packet_len )
{
- if( !i_sig_len ) /* 1st sanity check, we need at least the version */
+ if( !i_packet_len ) /* 1st sanity check, we need at least the version */
return VLC_EGENERIC;
p_sig->version = *p_buf++;
switch( p_sig->version )
{
case 3:
- i_read = parse_signature_v3_packet( p_sig, p_buf, i_sig_len );
+ i_read = parse_signature_v3_packet( p_sig, p_buf, i_packet_len );
break;
case 4:
p_sig->specific.v4.hashed_data = NULL;
p_sig->specific.v4.unhashed_data = NULL;
- i_read = parse_signature_v4_packet( p_sig, p_buf, i_sig_len );
+ i_read = parse_signature_v4_packet( p_sig, p_buf, i_packet_len );
break;
default:
return VLC_EGENERIC;
if( i_read == 0 ) /* signature packet parsing has failed */
goto error;
- if( p_sig->public_key_algo != PUBLIC_KEY_ALGO_DSA )
- goto error;
-
- if( p_sig->digest_algo != DIGEST_ALGO_SHA1 )
+ if( p_sig->public_key_algo != GCRY_PK_DSA && p_sig->public_key_algo != GCRY_PK_RSA )
goto error;
switch( p_sig->type )
p_buf--; /* rewind to the version byte */
p_buf += i_read;
- if( i_read + 2 > i_sig_len )
+ if( p_sig->public_key_algo == GCRY_PK_DSA ) {
+ READ_MPI(p_sig->algo_specific.dsa.r, 256);
+ READ_MPI(p_sig->algo_specific.dsa.s, 256);
+ } else if ( p_sig->public_key_algo == GCRY_PK_RSA ) {
+ READ_MPI(p_sig->algo_specific.rsa.s, 4096);
+ } else
goto error;
- size_t i_r_len = mpi_len( p_buf ); i_read += 2;
- if( i_read + i_r_len > i_sig_len || i_r_len > 20 )
- goto error;
-
- memcpy( p_sig->r, p_buf, 2 + i_r_len );
- p_buf += 2 + i_r_len;
- i_read += i_r_len;
-
- if( i_read + 2 > i_sig_len )
- goto error;
-
- size_t i_s_len = mpi_len( p_buf ); i_read += 2;
- if( i_read + i_s_len > i_sig_len || i_s_len > 20 )
- goto error;
-
- memcpy( p_sig->s, p_buf, 2 + i_s_len );
- p_buf += 2 + i_s_len;
- i_read += i_s_len;
-
- assert( i_read == i_sig_len );
- if( i_read < i_sig_len ) /* some extra data, hm ? */
+ assert( i_read == i_packet_len );
+ if( i_read < i_packet_len ) /* some extra data, hm ? */
goto error;
return VLC_SUCCESS;
* 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,
+static int pgp_unarmor( const char *p_ibuf, size_t i_ibuf_len,
uint8_t *p_obuf, size_t i_obuf_len )
{
- char *p_ipos = p_ibuf;
+ const char *p_ipos = p_ibuf;
uint8_t *p_opos = p_obuf;
int i_end = 0;
int i_header_skipped = 0;
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 );
return l_crc2 == l_crc ? p_opos - p_obuf : 0;
}
+static int rsa_pkcs1_encode_sig(gcry_mpi_t *r_result, size_t size,
+ const uint8_t *hash, int algo)
+{
+ uint8_t asn[100];
+ uint8_t frame[4096/8];
+
+ size_t asnlen = sizeof(asn);
+ size_t hashlen = gcry_md_get_algo_dlen(algo);
+
+ if (gcry_md_algo_info(algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+ return VLC_EGENERIC;
+
+ if (!hashlen || hashlen + asnlen + 4 > size)
+ return VLC_EGENERIC;
+
+ frame[0] = 0;
+ frame[1] = 1; /* block type */
+ int pad = size - hashlen - asnlen - 3 ;
+ memset (&frame[2], 0xff, pad );
+ frame[2+pad] = 0;
+ memcpy(&frame[3+pad], asn, asnlen);
+ memcpy(&frame[3+pad+asnlen], hash, hashlen);
+
+ if (gcry_mpi_scan(r_result, GCRYMPI_FMT_USG, frame, size, &size))
+ return VLC_EGENERIC;
+ return VLC_SUCCESS;
+}
/*
- * Verify an OpenPGP signature made on some SHA-1 hash, with some DSA public key
+ * Verify an OpenPGP signature made with some RSA public key
*/
-int verify_signature( uint8_t *p_r, uint8_t *p_s, public_key_packet_t *p_key,
+static int verify_signature_rsa( signature_packet_t *sign, public_key_packet_t *p_key,
uint8_t *p_hash )
{
- /* the data to be verified (a SHA-1 hash) */
+ int ret = VLC_EGENERIC;
+ /* the data to be verified (a hash) */
+ const char *hash_sexp_s = "(data(flags raw)(value %m))";
+ /* the public key */
+ const char *key_sexp_s = "(public-key(rsa(n %m)(e %m)))";
+ /* the signature */
+ const char *sig_sexp_s = "(sig-val(rsa(s%m)))";
+
+ size_t erroff;
+ gcry_mpi_t n, e, s, hash;
+ n = e = s = hash = NULL;
+ gcry_sexp_t key_sexp, hash_sexp, sig_sexp;
+ key_sexp = hash_sexp = sig_sexp = NULL;
+
+ int i_n_len = mpi_len( p_key->sig.rsa.n );
+ int i_e_len = mpi_len( p_key->sig.rsa.e );
+ if( gcry_mpi_scan( &n, GCRYMPI_FMT_USG, p_key->sig.rsa.n + 2, i_n_len, NULL ) ||
+ gcry_mpi_scan( &e, GCRYMPI_FMT_USG, p_key->sig.rsa.e + 2, i_e_len, NULL ) ||
+ gcry_sexp_build( &key_sexp, &erroff, key_sexp_s, n, e ) )
+ goto out;
+
+ uint8_t *p_s = sign->algo_specific.rsa.s;
+ int i_s_len = mpi_len( p_s );
+ if( gcry_mpi_scan( &s, GCRYMPI_FMT_USG, p_s + 2, i_s_len, NULL ) ||
+ gcry_sexp_build( &sig_sexp, &erroff, sig_sexp_s, s ) )
+ goto out;
+
+ if( rsa_pkcs1_encode_sig (&hash, i_n_len, p_hash, sign->digest_algo) ||
+ gcry_sexp_build( &hash_sexp, &erroff, hash_sexp_s, hash ) )
+ goto out;
+
+ if( gcry_pk_verify( sig_sexp, hash_sexp, key_sexp ) )
+ goto out;
+
+ ret = VLC_SUCCESS;
+
+out:
+ if( n ) gcry_mpi_release( n );
+ if( e ) gcry_mpi_release( e );
+ 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 ret;
+}
+
+/*
+ * Verify an OpenPGP signature made with some DSA public key
+ */
+static int verify_signature_dsa( signature_packet_t *sign, public_key_packet_t *p_key,
+ uint8_t *p_hash )
+{
+ int ret = VLC_EGENERIC;
+
+ /* the data to be verified (a 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)))";
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 ) ||
+ int i_p_len = mpi_len( p_key->sig.dsa.p );
+ int i_q_len = mpi_len( p_key->sig.dsa.q );
+ int i_g_len = mpi_len( p_key->sig.dsa.g );
+ int i_y_len = mpi_len( p_key->sig.dsa.y );
+ if( gcry_mpi_scan( &p, GCRYMPI_FMT_USG, p_key->sig.dsa.p + 2, i_p_len, NULL ) ||
+ gcry_mpi_scan( &q, GCRYMPI_FMT_USG, p_key->sig.dsa.q + 2, i_q_len, NULL ) ||
+ gcry_mpi_scan( &g, GCRYMPI_FMT_USG, p_key->sig.dsa.g + 2, i_g_len, NULL ) ||
+ gcry_mpi_scan( &y, GCRYMPI_FMT_USG, p_key->sig.dsa.y + 2, i_y_len, NULL ) ||
gcry_sexp_build( &key_sexp, &erroff, key_sexp_s, p, q, g, y ) )
- goto problem;
+ goto out;
+ uint8_t *p_r = sign->algo_specific.dsa.r;
+ uint8_t *p_s = sign->algo_specific.dsa.s;
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;
+ goto out;
- int i_hash_len = 20;
+ int i_hash_len = gcry_md_get_algo_dlen (sign->digest_algo);
+ if (i_hash_len > i_q_len)
+ i_hash_len = i_q_len;
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;
+ goto out;
if( gcry_pk_verify( sig_sexp, hash_sexp, key_sexp ) )
- goto problem;
+ goto out;
- return VLC_SUCCESS;
+ ret = VLC_SUCCESS;
-problem:
+out:
if( p ) gcry_mpi_release( p );
if( q ) gcry_mpi_release( q );
if( g ) gcry_mpi_release( g );
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;
+
+ return ret;
+}
+
+/*
+ * Verify an OpenPGP signature made with some public key
+ */
+int verify_signature( signature_packet_t *sign, public_key_packet_t *p_key,
+ uint8_t *p_hash )
+{
+ if (sign->public_key_algo == GCRY_PK_DSA)
+ return verify_signature_dsa(sign, p_key, p_hash);
+ else if (sign->public_key_algo == GCRY_PK_RSA)
+ return verify_signature_rsa(sign, p_key, p_hash);
+ else
+ return VLC_EGENERIC;
}
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;
+ const uint8_t *pos = p_key_data;
+ const uint8_t *max_pos = pos + i_key_len;
int i_status = 0;
#define PUBLIC_KEY_FOUND 0x01
uint8_t buffer[4096];
size_t i_read;
- FILE *f = utf8_fopen( psz_file, "r" );
+ FILE *f = vlc_fopen( psz_file, "r" );
if( !f )
return -1;
gcry_md_final( hd );
- uint8_t *p_tmp = (uint8_t*) gcry_md_read( hd, GCRY_MD_SHA1);
- uint8_t *p_hash = malloc( 20 );
+ uint8_t *p_tmp = (uint8_t*) gcry_md_read( hd, p_sig->digest_algo) ;
+ unsigned int hash_len = gcry_md_get_algo_dlen (p_sig->digest_algo);
+ uint8_t *p_hash = malloc(hash_len);
if( p_hash )
- memcpy( p_hash, p_tmp, 20 );
+ memcpy(p_hash, p_tmp, hash_len);
gcry_md_close( hd );
return p_hash;
}
/*
- * return a sha1 hash of a text
+ * return a hash of a text
*/
-uint8_t *hash_sha1_from_text( const char *psz_string,
+uint8_t *hash_from_text( const char *psz_string,
signature_packet_t *p_sig )
{
gcry_md_hd_t hd;
- if( gcry_md_open( &hd, GCRY_MD_SHA1, 0 ) )
+ if( gcry_md_open( &hd, p_sig->digest_algo, 0 ) )
return NULL;
if( p_sig->type == TEXT_SIGNATURE )
while( *psz_string )
{
size_t i_len = strcspn( psz_string, "\r\n" );
- if( !i_len )
- break;
- gcry_md_write( hd, psz_string, i_len );
+ if( i_len )
+ {
+ gcry_md_write( hd, psz_string, i_len );
+ psz_string += i_len;
+ }
gcry_md_putc( hd, '\r' );
gcry_md_putc( hd, '\n' );
- psz_string += i_len;
- while( *psz_string == '\r' || *psz_string == '\n' )
+ if( *psz_string == '\r' )
+ psz_string++;
+ if( *psz_string == '\n' )
psz_string++;
}
else
/*
- * return a sha1 hash of a file
+ * return a hash of a file
*/
-uint8_t *hash_sha1_from_file( const char *psz_file, signature_packet_t *p_sig )
+uint8_t *hash_from_file( const char *psz_file, signature_packet_t *p_sig )
{
gcry_md_hd_t hd;
- if( gcry_md_open( &hd, GCRY_MD_SHA1, 0 ) )
+ if( gcry_md_open( &hd, p_sig->digest_algo, 0 ) )
return NULL;
if( hash_from_binary_file( psz_file, hd ) < 0 )
/*
- * Generate a SHA1 hash on a public key, to verify a signature made on that hash
+ * Generate a hash on a public key, to verify a signature made on that hash
* Note that we need the signature (v4) to compute the hash
*/
-uint8_t *hash_sha1_from_public_key( public_key_t *p_pkey )
+uint8_t *hash_from_public_key( public_key_t *p_pkey )
{
+ const uint8_t pk_algo = p_pkey->key.algo;
+ size_t i_size;
+ size_t i_p_len, i_g_len, i_q_len, i_y_len;
+ size_t i_n_len, i_e_len;
+
if( p_pkey->sig.version != 4 )
return NULL;
gcry_error_t error = 0;
gcry_md_hd_t hd;
- error = gcry_md_open( &hd, GCRY_MD_SHA1, 0 );
+ if (pk_algo == GCRY_PK_DSA) {
+ i_p_len = mpi_len( p_pkey->key.sig.dsa.p );
+ i_g_len = mpi_len( p_pkey->key.sig.dsa.g );
+ i_q_len = mpi_len( p_pkey->key.sig.dsa.q );
+ i_y_len = mpi_len( p_pkey->key.sig.dsa.y );
+
+ i_size = 6 + 2*4 + i_p_len + i_g_len + i_q_len + i_y_len;
+ } else if (pk_algo == GCRY_PK_RSA) {
+ i_n_len = mpi_len( p_pkey->key.sig.rsa.n );
+ i_e_len = mpi_len( p_pkey->key.sig.rsa.e );
+
+ i_size = 6 + 2*2 + i_n_len + i_e_len;
+ } else
+ return NULL;
+
+ error = gcry_md_open( &hd, p_pkey->sig.digest_algo, 0 );
if( error )
return NULL;
gcry_md_putc( hd, 0x99 );
- size_t i_p_len = mpi_len( p_pkey->key.p );
- size_t i_g_len = mpi_len( p_pkey->key.g );
- size_t i_q_len = mpi_len( p_pkey->key.q );
- size_t i_y_len = mpi_len( p_pkey->key.y );
-
- size_t i_size = 6 + 2*4 + i_p_len + i_g_len + i_q_len + i_y_len;
-
gcry_md_putc( hd, (i_size >> 8) & 0xff );
gcry_md_putc( hd, i_size & 0xff );
gcry_md_write( hd, p_pkey->key.timestamp, 4 );
gcry_md_putc( hd, p_pkey->key.algo );
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.p, 2 );
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.p + 2, i_p_len );
-
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.q, 2 );
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.q + 2, i_q_len );
-
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.g, 2 );
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.g + 2, i_g_len );
-
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.y, 2 );
- gcry_md_write( hd, (uint8_t*)&p_pkey->key.y + 2, i_y_len );
+ if (pk_algo == GCRY_PK_DSA) {
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.dsa.p, 2 + i_p_len );
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.dsa.q, 2 + i_q_len );
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.dsa.g, 2 + i_g_len );
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.dsa.y, 2 + i_y_len );
+ } else if (pk_algo == GCRY_PK_RSA) {
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.rsa.n, 2 + i_n_len );
+ gcry_md_write( hd, (uint8_t*)&p_pkey->key.sig.rsa.e, 2 + i_e_len );
+ }
gcry_md_putc( hd, 0xb4 );
p_hash[0] != p_pkey->sig.hash_verification[0] ||
p_hash[1] != p_pkey->sig.hash_verification[1] )
{
+ free(p_hash);
return NULL;
}
if( packet_type( *p_buf ) != SIGNATURE_PACKET )
{
- free( p_buf );
msg_Dbg( p_this, "Not a signature: %d", *p_buf );
+ free( p_buf );
return VLC_EGENERIC;
}