1 /*****************************************************************************
2 * update_crypto.c: OpenPGP related functions used for updating
3 *****************************************************************************
4 * Copyright © 2008-2009 VLC authors and VideoLAN
6 * Authors: Rafaël Carré <funman@videolanorg>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either release 2 of the License, or
11 * (at your option) any later release.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
25 * This file contains functions related to OpenPGP in VLC update management
28 /*****************************************************************************
30 *****************************************************************************/
40 #include "vlc_common.h"
41 #include <vlc_stream.h>
42 #include <vlc_strings.h>
48 /*****************************************************************************
50 *****************************************************************************/
52 #define packet_type( c ) ( ( c & 0x3c ) >> 2 ) /* 0x3C = 00111100 */
53 #define packet_header_len( c ) ( ( c & 0x03 ) + 1 ) /* number of bytes in a packet header */
56 static inline int scalar_number( const uint8_t *p
, int header_len
)
58 assert( header_len
== 1 || header_len
== 2 || header_len
== 4 );
62 else if( header_len
== 2 )
63 return( (p
[0] << 8) + p
[1] );
64 else if( header_len
== 4 )
65 return( (p
[0] << 24) + (p
[1] << 16) + (p
[2] << 8) + p
[3] );
71 /* number of data bytes in a MPI */
72 static int mpi_len(const uint8_t *mpi
)
74 return (scalar_number(mpi
, 2) + 7) / 8;
77 static size_t read_mpi(uint8_t *dst
, const uint8_t *buf
, size_t buflen
, size_t bits
)
82 size_t n
= mpi_len(buf
);
96 #define READ_MPI(d, bits) do { \
97 size_t n = read_mpi(d, p_buf, i_packet_len - i_read, bits); \
104 * fill a public_key_packet_t structure from public key packet data
105 * verify that it is a version 4 public key packet, using DSA or RSA
107 static int parse_public_key_packet( public_key_packet_t
*p_key
,
108 const uint8_t *p_buf
, size_t i_packet_len
)
110 if( i_packet_len
< 6 )
115 p_key
->version
= *p_buf
++; i_read
++;
116 if( p_key
->version
!= 4 )
119 /* XXX: warn when timestamp is > date ? */
120 memcpy( p_key
->timestamp
, p_buf
, 4 ); p_buf
+= 4; i_read
+= 4;
122 p_key
->algo
= *p_buf
++; i_read
++;
123 if( p_key
->algo
== GCRY_PK_DSA
) {
124 READ_MPI(p_key
->sig
.dsa
.p
, 3072);
125 READ_MPI(p_key
->sig
.dsa
.q
, 256);
126 READ_MPI(p_key
->sig
.dsa
.g
, 3072);
127 READ_MPI(p_key
->sig
.dsa
.y
, 3072);
128 } else if ( p_key
->algo
== GCRY_PK_RSA
) {
129 READ_MPI(p_key
->sig
.rsa
.n
, 4096);
130 READ_MPI(p_key
->sig
.rsa
.e
, 4096);
134 if( i_read
== i_packet_len
)
137 /* some extra data eh ? */
144 static size_t parse_signature_v3_packet( signature_packet_t
*p_sig
,
145 const uint8_t *p_buf
, size_t i_sig_len
)
147 size_t i_read
= 1; /* we already read the version byte */
149 if( i_sig_len
< 19 ) /* signature is at least 19 bytes + the 2 MPIs */
152 p_sig
->specific
.v3
.hashed_data_len
= *p_buf
++; i_read
++;
153 if( p_sig
->specific
.v3
.hashed_data_len
!= 5 )
156 p_sig
->type
= *p_buf
++; i_read
++;
158 memcpy( p_sig
->specific
.v3
.timestamp
, p_buf
, 4 );
159 p_buf
+= 4; i_read
+= 4;
161 memcpy( p_sig
->issuer_longid
, p_buf
, 8 );
162 p_buf
+= 8; i_read
+= 8;
164 p_sig
->public_key_algo
= *p_buf
++; i_read
++;
166 p_sig
->digest_algo
= *p_buf
++; i_read
++;
168 p_sig
->hash_verification
[0] = *p_buf
++; i_read
++;
169 p_sig
->hash_verification
[1] = *p_buf
++; i_read
++;
171 assert( i_read
== 19 );
178 * fill a signature_packet_v4_t from signature packet data
179 * verify that it was used with a DSA or RSA public key
181 static size_t parse_signature_v4_packet( signature_packet_t
*p_sig
,
182 const uint8_t *p_buf
, size_t i_sig_len
)
184 size_t i_read
= 1; /* we already read the version byte */
186 if( i_sig_len
< 10 ) /* signature is at least 10 bytes + the 2 MPIs */
189 p_sig
->type
= *p_buf
++; i_read
++;
191 p_sig
->public_key_algo
= *p_buf
++; i_read
++;
192 if (p_sig
->public_key_algo
!= GCRY_PK_DSA
&& p_sig
->public_key_algo
!= GCRY_PK_RSA
)
195 p_sig
->digest_algo
= *p_buf
++; i_read
++;
197 memcpy( p_sig
->specific
.v4
.hashed_data_len
, p_buf
, 2 );
198 p_buf
+= 2; i_read
+= 2;
200 size_t i_hashed_data_len
=
201 scalar_number( p_sig
->specific
.v4
.hashed_data_len
, 2 );
202 i_read
+= i_hashed_data_len
;
203 if( i_read
+ 4 > i_sig_len
)
206 p_sig
->specific
.v4
.hashed_data
= (uint8_t*) malloc( i_hashed_data_len
);
207 if( !p_sig
->specific
.v4
.hashed_data
)
209 memcpy( p_sig
->specific
.v4
.hashed_data
, p_buf
, i_hashed_data_len
);
210 p_buf
+= i_hashed_data_len
;
212 memcpy( p_sig
->specific
.v4
.unhashed_data_len
, p_buf
, 2 );
213 p_buf
+= 2; i_read
+= 2;
215 size_t i_unhashed_data_len
=
216 scalar_number( p_sig
->specific
.v4
.unhashed_data_len
, 2 );
217 i_read
+= i_unhashed_data_len
;
218 if( i_read
+ 2 > i_sig_len
)
221 p_sig
->specific
.v4
.unhashed_data
= (uint8_t*) malloc( i_unhashed_data_len
);
222 if( !p_sig
->specific
.v4
.unhashed_data
)
225 memcpy( p_sig
->specific
.v4
.unhashed_data
, p_buf
, i_unhashed_data_len
);
226 p_buf
+= i_unhashed_data_len
;
228 memcpy( p_sig
->hash_verification
, p_buf
, 2 );
229 p_buf
+= 2; i_read
+= 2;
231 uint8_t *p
, *max_pos
;
232 p
= p_sig
->specific
.v4
.unhashed_data
;
233 max_pos
= p
+ scalar_number( p_sig
->specific
.v4
.unhashed_data_len
, 2 );
240 size_t i_subpacket_len
;
243 if( p
+ 1 > max_pos
)
245 i_subpacket_len
= *p
++;
249 if( p
+ 2 > max_pos
)
251 i_subpacket_len
= (*p
++ - 192) << 8;
252 i_subpacket_len
+= *p
++ + 192;
256 if( ++p
+ 4 > max_pos
)
258 i_subpacket_len
= U32_AT(p
);
262 if( *p
== ISSUER_SUBPACKET
)
264 if( p
+ 9 > max_pos
)
267 memcpy( &p_sig
->issuer_longid
, p
+1, 8 );
272 p
+= i_subpacket_len
;
277 static int parse_signature_packet( signature_packet_t
*p_sig
,
278 const uint8_t *p_buf
, size_t i_packet_len
)
280 if( !i_packet_len
) /* 1st sanity check, we need at least the version */
283 p_sig
->version
= *p_buf
++;
286 switch( p_sig
->version
)
289 i_read
= parse_signature_v3_packet( p_sig
, p_buf
, i_packet_len
);
292 p_sig
->specific
.v4
.hashed_data
= NULL
;
293 p_sig
->specific
.v4
.unhashed_data
= NULL
;
294 i_read
= parse_signature_v4_packet( p_sig
, p_buf
, i_packet_len
);
300 if( i_read
== 0 ) /* signature packet parsing has failed */
303 if( p_sig
->public_key_algo
!= GCRY_PK_DSA
&& p_sig
->public_key_algo
!= GCRY_PK_RSA
)
306 switch( p_sig
->type
)
308 case BINARY_SIGNATURE
:
310 case GENERIC_KEY_SIGNATURE
:
311 case PERSONA_KEY_SIGNATURE
:
312 case CASUAL_KEY_SIGNATURE
:
313 case POSITIVE_KEY_SIGNATURE
:
319 p_buf
--; /* rewind to the version byte */
322 if( p_sig
->public_key_algo
== GCRY_PK_DSA
) {
323 READ_MPI(p_sig
->algo_specific
.dsa
.r
, 256);
324 READ_MPI(p_sig
->algo_specific
.dsa
.s
, 256);
325 } else if ( p_sig
->public_key_algo
== GCRY_PK_RSA
) {
326 READ_MPI(p_sig
->algo_specific
.rsa
.s
, 4096);
330 assert( i_read
== i_packet_len
);
331 if( i_read
< i_packet_len
) /* some extra data, hm ? */
338 if( p_sig
->version
== 4 )
340 free( p_sig
->specific
.v4
.hashed_data
);
341 free( p_sig
->specific
.v4
.unhashed_data
);
349 * crc_octets() was lamely copied from rfc 2440
350 * Copyright (C) The Internet Society (1998). All Rights Reserved.
352 #define CRC24_INIT 0xB704CEL
353 #define CRC24_POLY 0x1864CFBL
355 static long crc_octets( uint8_t *octets
, size_t len
)
357 long crc
= CRC24_INIT
;
361 crc
^= (*octets
++) << 16;
362 for (i
= 0; i
< 8; i
++)
369 return crc
& 0xFFFFFFL
;
374 * Transform an armored document in binary format
375 * Used on public keys and signatures
377 static int pgp_unarmor( const char *p_ibuf
, size_t i_ibuf_len
,
378 uint8_t *p_obuf
, size_t i_obuf_len
)
380 const char *p_ipos
= p_ibuf
;
381 uint8_t *p_opos
= p_obuf
;
383 int i_header_skipped
= 0;
385 while( !i_end
&& p_ipos
< p_ibuf
+ i_ibuf_len
&& *p_ipos
!= '=' )
387 if( *p_ipos
== '\r' || *p_ipos
== '\n' )
393 size_t i_line_len
= strcspn( p_ipos
, "\r\n" );
394 if( i_line_len
== 0 )
397 if( !i_header_skipped
)
399 if( !strncmp( p_ipos
, "-----BEGIN PGP", 14 ) )
400 i_header_skipped
= 1;
402 p_ipos
+= i_line_len
+ 1;
406 if( !strncmp( p_ipos
, "Version:", 8 ) )
408 p_ipos
+= i_line_len
+ 1;
412 if( p_ipos
[i_line_len
- 1] == '=' )
417 p_opos
+= vlc_b64_decode_binary_to_buffer( p_opos
,
418 p_obuf
- p_opos
+ i_obuf_len
, p_ipos
);
419 p_ipos
+= i_line_len
+ 1;
422 /* XXX: the CRC is OPTIONAL, really require it ? */
423 if( p_ipos
+ 5 > p_ibuf
+ i_ibuf_len
|| *p_ipos
++ != '=' )
427 if( vlc_b64_decode_binary_to_buffer( p_crc
, 3, p_ipos
) != 3 )
430 long l_crc
= crc_octets( p_obuf
, p_opos
- p_obuf
);
431 long l_crc2
= ( 0 << 24 ) + ( p_crc
[0] << 16 ) + ( p_crc
[1] << 8 ) + p_crc
[2];
433 return l_crc2
== l_crc
? p_opos
- p_obuf
: 0;
436 static int rsa_pkcs1_encode_sig(gcry_mpi_t
*r_result
, size_t size
,
437 const uint8_t *hash
, int algo
)
440 uint8_t frame
[4096/8];
442 size_t asnlen
= sizeof(asn
);
443 size_t hashlen
= gcry_md_get_algo_dlen(algo
);
445 if (gcry_md_algo_info(algo
, GCRYCTL_GET_ASNOID
, asn
, &asnlen
))
448 if (!hashlen
|| hashlen
+ asnlen
+ 4 > size
)
452 frame
[1] = 1; /* block type */
453 int pad
= size
- hashlen
- asnlen
- 3 ;
454 memset (&frame
[2], 0xff, pad
);
456 memcpy(&frame
[3+pad
], asn
, asnlen
);
457 memcpy(&frame
[3+pad
+asnlen
], hash
, hashlen
);
459 if (gcry_mpi_scan(r_result
, GCRYMPI_FMT_USG
, frame
, size
, &size
))
465 * Verify an OpenPGP signature made with some RSA public key
467 static int verify_signature_rsa( signature_packet_t
*sign
, public_key_packet_t
*p_key
,
470 int ret
= VLC_EGENERIC
;
471 /* the data to be verified (a hash) */
472 const char *hash_sexp_s
= "(data(flags raw)(value %m))";
474 const char *key_sexp_s
= "(public-key(rsa(n %m)(e %m)))";
476 const char *sig_sexp_s
= "(sig-val(rsa(s%m)))";
479 gcry_mpi_t n
, e
, s
, hash
;
480 n
= e
= s
= hash
= NULL
;
481 gcry_sexp_t key_sexp
, hash_sexp
, sig_sexp
;
482 key_sexp
= hash_sexp
= sig_sexp
= NULL
;
484 int i_n_len
= mpi_len( p_key
->sig
.rsa
.n
);
485 int i_e_len
= mpi_len( p_key
->sig
.rsa
.e
);
486 if( gcry_mpi_scan( &n
, GCRYMPI_FMT_USG
, p_key
->sig
.rsa
.n
+ 2, i_n_len
, NULL
) ||
487 gcry_mpi_scan( &e
, GCRYMPI_FMT_USG
, p_key
->sig
.rsa
.e
+ 2, i_e_len
, NULL
) ||
488 gcry_sexp_build( &key_sexp
, &erroff
, key_sexp_s
, n
, e
) )
491 uint8_t *p_s
= sign
->algo_specific
.rsa
.s
;
492 int i_s_len
= mpi_len( p_s
);
493 if( gcry_mpi_scan( &s
, GCRYMPI_FMT_USG
, p_s
+ 2, i_s_len
, NULL
) ||
494 gcry_sexp_build( &sig_sexp
, &erroff
, sig_sexp_s
, s
) )
497 if( rsa_pkcs1_encode_sig (&hash
, i_n_len
, p_hash
, sign
->digest_algo
) ||
498 gcry_sexp_build( &hash_sexp
, &erroff
, hash_sexp_s
, hash
) )
501 if( gcry_pk_verify( sig_sexp
, hash_sexp
, key_sexp
) )
507 if( n
) gcry_mpi_release( n
);
508 if( e
) gcry_mpi_release( e
);
509 if( s
) gcry_mpi_release( s
);
510 if( hash
) gcry_mpi_release( hash
);
511 if( key_sexp
) gcry_sexp_release( key_sexp
);
512 if( sig_sexp
) gcry_sexp_release( sig_sexp
);
513 if( hash_sexp
) gcry_sexp_release( hash_sexp
);
518 * Verify an OpenPGP signature made with some DSA public key
520 static int verify_signature_dsa( signature_packet_t
*sign
, public_key_packet_t
*p_key
,
523 int ret
= VLC_EGENERIC
;
525 /* the data to be verified (a hash) */
526 const char *hash_sexp_s
= "(data(flags raw)(value %m))";
528 const char *key_sexp_s
= "(public-key(dsa(p %m)(q %m)(g %m)(y %m)))";
530 const char *sig_sexp_s
= "(sig-val(dsa(r %m )(s %m )))";
533 gcry_mpi_t p
, q
, g
, y
, r
, s
, hash
;
534 p
= q
= g
= y
= r
= s
= hash
= NULL
;
535 gcry_sexp_t key_sexp
, hash_sexp
, sig_sexp
;
536 key_sexp
= hash_sexp
= sig_sexp
= NULL
;
538 int i_p_len
= mpi_len( p_key
->sig
.dsa
.p
);
539 int i_q_len
= mpi_len( p_key
->sig
.dsa
.q
);
540 int i_g_len
= mpi_len( p_key
->sig
.dsa
.g
);
541 int i_y_len
= mpi_len( p_key
->sig
.dsa
.y
);
542 if( gcry_mpi_scan( &p
, GCRYMPI_FMT_USG
, p_key
->sig
.dsa
.p
+ 2, i_p_len
, NULL
) ||
543 gcry_mpi_scan( &q
, GCRYMPI_FMT_USG
, p_key
->sig
.dsa
.q
+ 2, i_q_len
, NULL
) ||
544 gcry_mpi_scan( &g
, GCRYMPI_FMT_USG
, p_key
->sig
.dsa
.g
+ 2, i_g_len
, NULL
) ||
545 gcry_mpi_scan( &y
, GCRYMPI_FMT_USG
, p_key
->sig
.dsa
.y
+ 2, i_y_len
, NULL
) ||
546 gcry_sexp_build( &key_sexp
, &erroff
, key_sexp_s
, p
, q
, g
, y
) )
549 uint8_t *p_r
= sign
->algo_specific
.dsa
.r
;
550 uint8_t *p_s
= sign
->algo_specific
.dsa
.s
;
551 int i_r_len
= mpi_len( p_r
);
552 int i_s_len
= mpi_len( p_s
);
553 if( gcry_mpi_scan( &r
, GCRYMPI_FMT_USG
, p_r
+ 2, i_r_len
, NULL
) ||
554 gcry_mpi_scan( &s
, GCRYMPI_FMT_USG
, p_s
+ 2, i_s_len
, NULL
) ||
555 gcry_sexp_build( &sig_sexp
, &erroff
, sig_sexp_s
, r
, s
) )
558 int i_hash_len
= gcry_md_get_algo_dlen (sign
->digest_algo
);
559 if (i_hash_len
> i_q_len
)
560 i_hash_len
= i_q_len
;
561 if( gcry_mpi_scan( &hash
, GCRYMPI_FMT_USG
, p_hash
, i_hash_len
, NULL
) ||
562 gcry_sexp_build( &hash_sexp
, &erroff
, hash_sexp_s
, hash
) )
565 if( gcry_pk_verify( sig_sexp
, hash_sexp
, key_sexp
) )
571 if( p
) gcry_mpi_release( p
);
572 if( q
) gcry_mpi_release( q
);
573 if( g
) gcry_mpi_release( g
);
574 if( y
) gcry_mpi_release( y
);
575 if( r
) gcry_mpi_release( r
);
576 if( s
) gcry_mpi_release( s
);
577 if( hash
) gcry_mpi_release( hash
);
578 if( key_sexp
) gcry_sexp_release( key_sexp
);
579 if( sig_sexp
) gcry_sexp_release( sig_sexp
);
580 if( hash_sexp
) gcry_sexp_release( hash_sexp
);
586 * Verify an OpenPGP signature made with some public key
588 int verify_signature( signature_packet_t
*sign
, public_key_packet_t
*p_key
,
591 if (sign
->public_key_algo
== GCRY_PK_DSA
)
592 return verify_signature_dsa(sign
, p_key
, p_hash
);
593 else if (sign
->public_key_algo
== GCRY_PK_RSA
)
594 return verify_signature_rsa(sign
, p_key
, p_hash
);
601 * fill a public_key_t with public key data, including:
602 * * public key packet
603 * * signature packet issued by key which long id is p_sig_issuer
606 int parse_public_key( const uint8_t *p_key_data
, size_t i_key_len
,
607 public_key_t
*p_key
, const uint8_t *p_sig_issuer
)
609 const uint8_t *pos
= p_key_data
;
610 const uint8_t *max_pos
= pos
+ i_key_len
;
613 #define PUBLIC_KEY_FOUND 0x01
614 #define USER_ID_FOUND 0x02
615 #define SIGNATURE_FOUND 0X04
617 uint8_t *p_key_unarmored
= NULL
;
619 p_key
->psz_username
= NULL
;
620 p_key
->sig
.specific
.v4
.hashed_data
= NULL
;
621 p_key
->sig
.specific
.v4
.unhashed_data
= NULL
;
623 if( !( *pos
& 0x80 ) )
624 { /* first byte is ASCII, unarmoring */
625 p_key_unarmored
= (uint8_t*)malloc( i_key_len
);
626 if( !p_key_unarmored
)
628 int i_len
= pgp_unarmor( (char*)p_key_data
, i_key_len
,
629 p_key_unarmored
, i_key_len
);
634 pos
= p_key_unarmored
;
635 max_pos
= pos
+ i_len
;
638 while( pos
< max_pos
)
640 if( !(*pos
& 0x80) || *pos
& 0x40 )
643 int i_type
= packet_type( *pos
);
645 int i_header_len
= packet_header_len( *pos
++ );
646 if( pos
+ i_header_len
> max_pos
||
647 ( i_header_len
!= 1 && i_header_len
!= 2 && i_header_len
!= 4 ) )
650 int i_packet_len
= scalar_number( pos
, i_header_len
);
653 if( pos
+ i_packet_len
> max_pos
)
658 case PUBLIC_KEY_PACKET
:
659 i_status
|= PUBLIC_KEY_FOUND
;
660 if( parse_public_key_packet( &p_key
->key
, pos
, i_packet_len
) != VLC_SUCCESS
)
664 case SIGNATURE_PACKET
: /* we accept only v4 signatures here */
665 if( i_status
& SIGNATURE_FOUND
|| !p_sig_issuer
)
667 int i_ret
= parse_signature_packet( &p_key
->sig
, pos
,
669 if( i_ret
== VLC_SUCCESS
)
671 if( p_key
->sig
.version
!= 4 )
673 if( memcmp( p_key
->sig
.issuer_longid
, p_sig_issuer
, 8 ) )
675 free( p_key
->sig
.specific
.v4
.hashed_data
);
676 free( p_key
->sig
.specific
.v4
.unhashed_data
);
677 p_key
->sig
.specific
.v4
.hashed_data
= NULL
;
678 p_key
->sig
.specific
.v4
.unhashed_data
= NULL
;
681 i_status
|= SIGNATURE_FOUND
;
686 if( p_key
->psz_username
) /* save only the first User ID */
688 i_status
|= USER_ID_FOUND
;
689 p_key
->psz_username
= (uint8_t*)malloc( i_packet_len
+ 1);
690 if( !p_key
->psz_username
)
693 memcpy( p_key
->psz_username
, pos
, i_packet_len
);
694 p_key
->psz_username
[i_packet_len
] = '\0';
702 free( p_key_unarmored
);
704 if( !( i_status
& ( PUBLIC_KEY_FOUND
| USER_ID_FOUND
) ) )
707 if( p_sig_issuer
&& !( i_status
& SIGNATURE_FOUND
) )
713 if( p_key
->sig
.version
== 4 )
715 free( p_key
->sig
.specific
.v4
.hashed_data
);
716 free( p_key
->sig
.specific
.v4
.unhashed_data
);
718 free( p_key
->psz_username
);
719 free( p_key_unarmored
);
724 /* hash a binary file */
725 static int hash_from_binary_file( const char *psz_file
, gcry_md_hd_t hd
)
727 uint8_t buffer
[4096];
730 FILE *f
= vlc_fopen( psz_file
, "r" );
734 while( ( i_read
= fread( buffer
, 1, sizeof(buffer
), f
) ) > 0 )
735 gcry_md_write( hd
, buffer
, i_read
);
743 /* final part of the hash */
744 static uint8_t *hash_finish( gcry_md_hd_t hd
, signature_packet_t
*p_sig
)
746 if( p_sig
->version
== 3 )
748 gcry_md_putc( hd
, p_sig
->type
);
749 gcry_md_write( hd
, &p_sig
->specific
.v3
.timestamp
, 4 );
751 else if( p_sig
->version
== 4 )
753 gcry_md_putc( hd
, p_sig
->version
);
754 gcry_md_putc( hd
, p_sig
->type
);
755 gcry_md_putc( hd
, p_sig
->public_key_algo
);
756 gcry_md_putc( hd
, p_sig
->digest_algo
);
757 gcry_md_write( hd
, p_sig
->specific
.v4
.hashed_data_len
, 2 );
758 size_t i_len
= scalar_number( p_sig
->specific
.v4
.hashed_data_len
, 2 );
759 gcry_md_write( hd
, p_sig
->specific
.v4
.hashed_data
, i_len
);
761 gcry_md_putc( hd
, 0x04 );
762 gcry_md_putc( hd
, 0xFF );
764 i_len
+= 6; /* hashed data + 6 bytes header */
766 gcry_md_putc( hd
, (i_len
>> 24) & 0xff );
767 gcry_md_putc( hd
, (i_len
>> 16) & 0xff );
768 gcry_md_putc( hd
, (i_len
>> 8) & 0xff );
769 gcry_md_putc( hd
, (i_len
) & 0xff );
772 { /* RFC 4880 only tells about versions 3 and 4 */
778 uint8_t *p_tmp
= (uint8_t*) gcry_md_read( hd
, p_sig
->digest_algo
) ;
779 unsigned int hash_len
= gcry_md_get_algo_dlen (p_sig
->digest_algo
);
780 uint8_t *p_hash
= malloc(hash_len
);
782 memcpy(p_hash
, p_tmp
, hash_len
);
789 * return a hash of a text
791 uint8_t *hash_from_text( const char *psz_string
,
792 signature_packet_t
*p_sig
)
795 if( gcry_md_open( &hd
, p_sig
->digest_algo
, 0 ) )
798 if( p_sig
->type
== TEXT_SIGNATURE
)
801 size_t i_len
= strcspn( psz_string
, "\r\n" );
805 gcry_md_write( hd
, psz_string
, i_len
);
808 gcry_md_putc( hd
, '\r' );
809 gcry_md_putc( hd
, '\n' );
811 if( *psz_string
== '\r' )
813 if( *psz_string
== '\n' )
817 gcry_md_write( hd
, psz_string
, strlen( psz_string
) );
819 return hash_finish( hd
, p_sig
);
824 * return a hash of a file
826 uint8_t *hash_from_file( const char *psz_file
, signature_packet_t
*p_sig
)
829 if( gcry_md_open( &hd
, p_sig
->digest_algo
, 0 ) )
832 if( hash_from_binary_file( psz_file
, hd
) < 0 )
838 return hash_finish( hd
, p_sig
);
843 * Generate a hash on a public key, to verify a signature made on that hash
844 * Note that we need the signature (v4) to compute the hash
846 uint8_t *hash_from_public_key( public_key_t
*p_pkey
)
848 const uint8_t pk_algo
= p_pkey
->key
.algo
;
850 size_t i_p_len
, i_g_len
, i_q_len
, i_y_len
;
851 size_t i_n_len
, i_e_len
;
853 if( p_pkey
->sig
.version
!= 4 )
856 if( p_pkey
->sig
.type
< GENERIC_KEY_SIGNATURE
||
857 p_pkey
->sig
.type
> POSITIVE_KEY_SIGNATURE
)
860 if( p_pkey
->psz_username
== NULL
)
863 gcry_error_t error
= 0;
866 if (pk_algo
== GCRY_PK_DSA
) {
867 i_p_len
= mpi_len( p_pkey
->key
.sig
.dsa
.p
);
868 i_g_len
= mpi_len( p_pkey
->key
.sig
.dsa
.g
);
869 i_q_len
= mpi_len( p_pkey
->key
.sig
.dsa
.q
);
870 i_y_len
= mpi_len( p_pkey
->key
.sig
.dsa
.y
);
872 i_size
= 6 + 2*4 + i_p_len
+ i_g_len
+ i_q_len
+ i_y_len
;
873 } else if (pk_algo
== GCRY_PK_RSA
) {
874 i_n_len
= mpi_len( p_pkey
->key
.sig
.rsa
.n
);
875 i_e_len
= mpi_len( p_pkey
->key
.sig
.rsa
.e
);
877 i_size
= 6 + 2*2 + i_n_len
+ i_e_len
;
881 error
= gcry_md_open( &hd
, p_pkey
->sig
.digest_algo
, 0 );
885 gcry_md_putc( hd
, 0x99 );
887 gcry_md_putc( hd
, (i_size
>> 8) & 0xff );
888 gcry_md_putc( hd
, i_size
& 0xff );
890 gcry_md_putc( hd
, p_pkey
->key
.version
);
891 gcry_md_write( hd
, p_pkey
->key
.timestamp
, 4 );
892 gcry_md_putc( hd
, p_pkey
->key
.algo
);
894 if (pk_algo
== GCRY_PK_DSA
) {
895 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.dsa
.p
, 2 + i_p_len
);
896 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.dsa
.q
, 2 + i_q_len
);
897 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.dsa
.g
, 2 + i_g_len
);
898 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.dsa
.y
, 2 + i_y_len
);
899 } else if (pk_algo
== GCRY_PK_RSA
) {
900 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.rsa
.n
, 2 + i_n_len
);
901 gcry_md_write( hd
, (uint8_t*)&p_pkey
->key
.sig
.rsa
.e
, 2 + i_e_len
);
904 gcry_md_putc( hd
, 0xb4 );
906 size_t i_len
= strlen((char*)p_pkey
->psz_username
);
908 gcry_md_putc( hd
, (i_len
>> 24) & 0xff );
909 gcry_md_putc( hd
, (i_len
>> 16) & 0xff );
910 gcry_md_putc( hd
, (i_len
>> 8) & 0xff );
911 gcry_md_putc( hd
, (i_len
) & 0xff );
913 gcry_md_write( hd
, p_pkey
->psz_username
, i_len
);
915 uint8_t *p_hash
= hash_finish( hd
, &p_pkey
->sig
);
917 p_hash
[0] != p_pkey
->sig
.hash_verification
[0] ||
918 p_hash
[1] != p_pkey
->sig
.hash_verification
[1] )
929 * download a public key (the last one) from videolan server, and parse it
931 public_key_t
*download_key( vlc_object_t
*p_this
,
932 const uint8_t *p_longid
, const uint8_t *p_signature_issuer
)
935 if( asprintf( &psz_url
, "http://download.videolan.org/pub/keys/%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X.asc",
936 p_longid
[0], p_longid
[1], p_longid
[2], p_longid
[3],
937 p_longid
[4], p_longid
[5], p_longid
[6], p_longid
[7] ) == -1 )
940 stream_t
*p_stream
= vlc_stream_NewURL( p_this
, psz_url
);
946 if( vlc_stream_GetSize( p_stream
, &i_size
) || i_size
> INT_MAX
)
948 vlc_stream_Delete( p_stream
);
952 uint8_t *p_buf
= (uint8_t*)malloc( i_size
);
955 vlc_stream_Delete( p_stream
);
959 int i_read
= vlc_stream_Read( p_stream
, p_buf
, (int)i_size
);
960 vlc_stream_Delete( p_stream
);
962 if( i_read
!= (int)i_size
)
964 msg_Dbg( p_this
, "Couldn't read full GPG key" );
969 public_key_t
*p_pkey
= (public_key_t
*) malloc( sizeof( public_key_t
) );
976 memcpy( p_pkey
->longid
, p_longid
, 8 );
978 int i_error
= parse_public_key( p_buf
, i_read
, p_pkey
, p_signature_issuer
);
981 if( i_error
!= VLC_SUCCESS
)
983 msg_Dbg( p_this
, "Couldn't parse GPG key" );
993 * Download the signature associated to a document or a binary file.
994 * We're given the file's url, we just append ".asc" to it and download
996 int download_signature( vlc_object_t
*p_this
, signature_packet_t
*p_sig
,
997 const char *psz_url
)
999 char *psz_sig
= (char*) malloc( strlen( psz_url
) + 4 + 1 ); /* ".asc" + \0 */
1003 strcpy( psz_sig
, psz_url
);
1004 strcat( psz_sig
, ".asc" );
1006 stream_t
*p_stream
= vlc_stream_NewURL( p_this
, psz_sig
);
1013 if( vlc_stream_GetSize( p_stream
, &i_size
) || i_size
> INT_MAX
)
1015 vlc_stream_Delete( p_stream
);
1016 return VLC_EGENERIC
;
1019 msg_Dbg( p_this
, "Downloading signature (%"PRIu64
" bytes)", i_size
);
1020 uint8_t *p_buf
= (uint8_t*)malloc( i_size
);
1023 vlc_stream_Delete( p_stream
);
1027 int i_read
= vlc_stream_Read( p_stream
, p_buf
, (int)i_size
);
1029 vlc_stream_Delete( p_stream
);
1031 if( i_read
!= (int)i_size
)
1034 "Couldn't download full signature (only %d bytes)", i_read
);
1036 return VLC_EGENERIC
;
1039 if( (uint8_t)*p_buf
< 0x80 ) /* ASCII */
1041 msg_Dbg( p_this
, "Unarmoring signature" );
1043 uint8_t* p_unarmored
= (uint8_t*) malloc( ( i_size
* 3 ) / 4 + 1 );
1047 return VLC_EGENERIC
;
1050 int i_bytes
= pgp_unarmor( (char*)p_buf
, i_size
, p_unarmored
, i_size
);
1053 p_buf
= p_unarmored
;
1059 msg_Dbg( p_this
, "Unarmoring failed : corrupted signature ?" );
1060 return VLC_EGENERIC
;
1064 if( packet_type( *p_buf
) != SIGNATURE_PACKET
)
1066 msg_Dbg( p_this
, "Not a signature: %d", *p_buf
);
1068 return VLC_EGENERIC
;
1071 size_t i_header_len
= packet_header_len( *p_buf
);
1072 if( ( i_header_len
!= 1 && i_header_len
!= 2 && i_header_len
!= 4 ) ||
1073 i_header_len
+ 1 > (size_t)i_size
)
1076 msg_Dbg( p_this
, "Invalid signature packet header" );
1077 return VLC_EGENERIC
;
1080 size_t i_len
= scalar_number( p_buf
+1, i_header_len
);
1081 if( i_len
+ i_header_len
+ 1 != (size_t)i_size
)
1084 msg_Dbg( p_this
, "Invalid signature packet" );
1085 return VLC_EGENERIC
;
1088 int i_ret
= parse_signature_packet( p_sig
, p_buf
+1+i_header_len
, i_len
);
1090 if( i_ret
!= VLC_SUCCESS
)
1092 msg_Dbg( p_this
, "Couldn't parse signature" );
1096 if( p_sig
->type
!= BINARY_SIGNATURE
&& p_sig
->type
!= TEXT_SIGNATURE
)
1098 msg_Dbg( p_this
, "Invalid signature type: %d", p_sig
->type
);
1099 if( p_sig
->version
== 4 )
1101 free( p_sig
->specific
.v4
.hashed_data
);
1102 free( p_sig
->specific
.v4
.unhashed_data
);
1104 return VLC_EGENERIC
;