/[winpt]/trunk/Gnupg/parse-packet.c
ViewVC logotype

Annotation of /trunk/Gnupg/parse-packet.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 309 - (hide annotations)
Sat Apr 7 11:07:07 2007 UTC (17 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 74234 byte(s)


1 werner 46 /* parse-packet.c - read packets
2     * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3     *
4     * This file is part of GnuPG.
5     *
6     * GnuPG is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * GnuPG is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #ifdef HAVE_CONFIG_H
22     #include <config.h>
23     #endif
24    
25     #include <stdio.h>
26     #include <stdio.h>
27     #include <stdlib.h>
28     #include <string.h>
29     #include <time.h>
30     #include <assert.h>
31     #include <process.h>
32     #include <sys/types.h>
33    
34     #include "openpgp.h"
35     #include "packet.h"
36     #include "md.h"
37    
38     static int mpi_print_mode = 0;
39     static int list_mode = 0;
40    
41     static int parse( gpg_iobuf_t inp, PACKET *pkt, int onlykeypkts,
42     _off_t *retpos, int *skip, gpg_iobuf_t out, int do_skip );
43     static int copy_packet( gpg_iobuf_t inp, gpg_iobuf_t out, int pkttype,
44     unsigned long pktlen );
45     static void skip_packet( gpg_iobuf_t inp, int pkttype, unsigned long pktlen );
46     static void skip_rest( gpg_iobuf_t inp, unsigned long pktlen );
47     static void *read_rest( gpg_iobuf_t inp, size_t pktlen );
48     static int parse_symkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
49     PACKET *packet );
50     static int parse_pubkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
51     PACKET *packet );
52     static int parse_signature( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
53     PKT_signature *sig );
54     static int parse_onepass_sig( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
55     PKT_onepass_sig *ops );
56     static int parse_key( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
57     byte *hdr, int hdrlen, PACKET *packet );
58     static int parse_user_id( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
59     PACKET *packet );
60     static int parse_attribute( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
61     PACKET *packet );
62     static int parse_comment( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
63     PACKET *packet );
64     static void parse_trust( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
65     PACKET *packet );
66     static int parse_plaintext( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
67     PACKET *packet, int new_ctb);
68     static int parse_compressed( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
69     PACKET *packet, int new_ctb );
70     static int parse_encrypted( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
71     PACKET *packet, int new_ctb);
72     static int parse_mdc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
73     PACKET *packet, int new_ctb);
74     static int parse_gpg_control( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
75     PACKET *packet );
76    
77     static unsigned short
78     read_16(gpg_iobuf_t inp)
79     {
80     unsigned short a;
81     a = gpg_iobuf_get_noeof(inp) << 8;
82     a |= gpg_iobuf_get_noeof(inp);
83     return a;
84     }
85    
86     static unsigned long
87     read_32(gpg_iobuf_t inp)
88     {
89     unsigned long a;
90     a = gpg_iobuf_get_noeof(inp) << 24;
91     a |= gpg_iobuf_get_noeof(inp) << 16;
92     a |= gpg_iobuf_get_noeof(inp) << 8;
93     a |= gpg_iobuf_get_noeof(inp);
94     return a;
95     }
96    
97     static unsigned long
98     buffer_to_u32( const unsigned char *buffer )
99     {
100     unsigned long a;
101     a = *buffer << 24;
102     a |= buffer[1] << 16;
103     a |= buffer[2] << 8;
104     a |= buffer[3];
105     return a;
106     }
107    
108    
109 twoaday 2 static void
110 werner 46 unknown_pubkey_warning( int algo )
111     {
112     static byte unknown_pubkey_algos[256];
113    
114     algo &= 0xff;
115     if( !unknown_pubkey_algos[algo] ) {
116     unknown_pubkey_algos[algo] = 1;
117     }
118     }
119    
120     static const char *
121     strtimestamp( unsigned long stamp )
122     {
123     static char buffer[11+5];
124     struct tm *tp;
125     time_t atime = stamp;
126    
127     if (atime < 0) {
128     strcpy (buffer, "????" "-??" "-??");
129     }
130     else {
131     tp = gmtime( &atime );
132     sprintf(buffer,"%04d-%02d-%02d",
133     1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
134     }
135     return buffer;
136     }
137    
138     static const char *
139     strtimevalue( unsigned long value )
140     {
141     static char buffer[30];
142     unsigned int years, days, hours, minutes;
143    
144     value /= 60;
145     minutes = value % 60;
146     value /= 60;
147     hours = value % 24;
148     value /= 24;
149     days = value % 365;
150     value /= 365;
151     years = value;
152    
153     sprintf(buffer,"%uy%ud%uh%um", years, days, hours, minutes );
154     if( years )
155     return buffer;
156     if( days )
157     return strchr( buffer, 'y' ) + 1;
158     return strchr( buffer, 'd' ) + 1;
159     }
160    
161    
162     static gpg_mpi_t
163     mpi_read( gpg_iobuf_t inp, size_t *ret_n, int flags )
164     {
165     gpg_mpi_t a;
166     int i = 0, j = 0;
167     u32 t;
168     size_t n;
169    
170     a = calloc( 1, sizeof *a );
171     a->nbits = read_16( inp );
172     n = (a->nbits + 7) / 8;
173     a->alloced = n;
174     a->d = calloc( n, 4 );
175     i = 4 - n % 4;
176     i %= 4;
177     j = (n+4-1) / 4;
178     for( ; j > 0; j-- ) {
179     t = 0;
180     for( ; i < 4; i++ ) {
181     t <<= 8;
182     t |= gpg_iobuf_get( inp ) & 0xff;
183     }
184     i = 0;
185     a->d[j-1] = t;
186     }
187     if( *ret_n )
188     *ret_n = n + 2;
189    
190     return a;
191     }
192    
193     void
194     mpi_print( FILE *fp, gpg_mpi_t a, int mode )
195     {
196     int i;
197     for( i = 0; i < a->alloced / 4; i++ )
198     printf( "%08lx", a->d[i] );
199     }
200    
201     static void
202     mpi_set_protect_flag( gpg_mpi_t a )
203     {
204     a->flags = 1;
205     }
206    
207     static gpg_mpi_t
208     mpi_set_opaque( gpg_mpi_t a, void *p, int len )
209     {
210     if( !a ) {
211     a = calloc( 1, sizeof *a );
212     }
213    
214     if( a->flags & 4 )
215     safe_free( a->d );
216     else {
217     safe_free( a->d );
218     }
219    
220     a->d = p;
221     a->alloced = 0;
222     a->nlimbs = 0;
223     a->nbits = len;
224     a->flags = 4;
225     return a;
226     }
227    
228     void
229     free_symkey_enc( PKT_symkey_enc *enc )
230     {
231     safe_free(enc);
232     }
233    
234     void
235     free_pubkey_enc( PKT_pubkey_enc *enc )
236     {
237     int n, i;
238     n = pubkey_get_nenc( enc->pubkey_algo );
239     if( !n )
240     safe_free(enc->data[0]);
241     for(i=0; i < n; i++ )
242     safe_free( enc->data[i] );
243     safe_free(enc);
244     }
245    
246     void
247     free_seckey_enc( PKT_signature *sig )
248     {
249     int n, i;
250    
251     n = pubkey_get_nsig( sig->pubkey_algo );
252     if( !n )
253     safe_free(sig->data[0]);
254     for(i=0; i < n; i++ )
255     safe_free( sig->data[i] );
256    
257     safe_free(sig->revkey);
258     safe_free(sig->hashed);
259     safe_free(sig->unhashed);
260     safe_free(sig);
261     }
262    
263    
264    
265     void
266     release_public_key_parts( PKT_public_key *pk )
267     {
268     int n, i;
269     n = pubkey_get_npkey( pk->pubkey_algo );
270     if( !n )
271     safe_free(pk->pkey[0]);
272     for(i=0; i < n; i++ ) {
273     safe_free( pk->pkey[i] );
274     pk->pkey[i] = NULL;
275     }
276     if (pk->prefs) {
277     safe_free (pk->prefs);
278     pk->prefs = NULL;
279     }
280     if( pk->namehash ) {
281     safe_free(pk->namehash);
282     pk->namehash = NULL;
283     }
284     if (pk->user_id) {
285     free_user_id (pk->user_id);
286     pk->user_id = NULL;
287     }
288     if (pk->revkey) {
289     safe_free(pk->revkey);
290     pk->revkey=NULL;
291     pk->numrevkeys=0;
292     }
293     }
294    
295    
296     void
297     free_public_key( PKT_public_key *pk )
298     {
299     release_public_key_parts( pk );
300     safe_free(pk);
301     }
302    
303    
304     int
305     pubkey_get_nenc( int algo )
306     {
307     switch( algo ) {
308     case 1:
309     case 2:
310     case 3: return 1;
311     case 16:
312     case 20: return 2;
313     }
314     return 0;
315     }
316    
317     int
318     pubkey_get_nsig( algo )
319     {
320     switch( algo ) {
321     case 1:
322     case 2:
323     case 3: return 1;
324     case 17:
325     case 16:
326     case 20: return 2;
327     }
328     return 0;
329     }
330    
331     int
332     pubkey_get_npkey( int algo )
333     {
334     if( is_ELGAMAL( algo ) ) return 3;
335     else if ( algo == 17 ) return 4;
336     else if ( is_RSA( algo ) ) return 2;
337     return 0;
338 twoaday 309 }
339 werner 46
340     int
341     pubkey_get_nskey( int algo )
342     {
343     if ( is_ELGAMAL( algo ) ) return 4;
344     else if ( algo == 17 ) return 5;
345     else if ( is_RSA( algo ) )return 6;
346     return 0;
347 twoaday 133 }
348 werner 46
349    
350    
351     /*
352     * Return a copy of the preferences
353     */
354     prefitem_t *
355     copy_prefs (const prefitem_t *prefs)
356     {
357     size_t n;
358     prefitem_t *new;
359    
360     if (!prefs)
361     return NULL;
362    
363     for (n=0; prefs[n].type; n++)
364     ;
365     new = malloc ( sizeof (*new) * (n+1));
366     for (n=0; prefs[n].type; n++) {
367     new[n].type = prefs[n].type;
368     new[n].value = prefs[n].value;
369     }
370     new[n].type = PREFTYPE_NONE;
371     new[n].value = 0;
372    
373     return new;
374     }
375    
376     /****************
377     * Replace all common parts of a sk by the one from the public key.
378     * This is a hack and a better solution will be to just store the real secret
379     * parts somewhere and don't duplicate all the other stuff.
380     */
381     void
382     copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
383     {
384     sk->expiredate = pk->expiredate;
385     sk->pubkey_algo = pk->pubkey_algo;
386     sk->pubkey_usage= pk->pubkey_usage;
387     sk->req_usage = pk->req_usage;
388     sk->req_algo = pk->req_algo;
389     sk->has_expired = pk->has_expired;
390     sk->is_revoked = pk->is_revoked;
391     sk->is_valid = pk->is_valid;
392     sk->main_keyid[0]= pk->main_keyid[0];
393     sk->main_keyid[1]= pk->main_keyid[1];
394     sk->keyid[0] = pk->keyid[0];
395     sk->keyid[1] = pk->keyid[1];
396     }
397    
398     void
399     release_secret_key_parts( PKT_secret_key *sk )
400     {
401     int n, i;
402    
403     n = pubkey_get_nskey( sk->pubkey_algo );
404     if( !n )
405     safe_free(sk->skey[0]);
406     for(i=0; i < n; i++ ) {
407     safe_free( sk->skey[i] );
408     sk->skey[i] = NULL;
409     }
410     }
411    
412     void
413     free_secret_key( PKT_secret_key *sk )
414     {
415     release_secret_key_parts( sk );
416     safe_free(sk);
417     }
418    
419     void
420     free_comment( PKT_comment *rem )
421     {
422     safe_free(rem);
423     }
424    
425     void
426     free_attributes(PKT_user_id *uid)
427     {
428     safe_free(uid->attribs);
429     safe_free(uid->attrib_data);
430    
431     uid->attribs=NULL;
432     uid->attrib_data=NULL;
433     uid->attrib_len=0;
434     }
435    
436     void
437     free_user_id (PKT_user_id *uid)
438     {
439     assert (uid->ref > 0);
440     if (--uid->ref)
441     return;
442    
443     free_attributes(uid);
444    
445     if (uid->prefs)
446     safe_free (uid->prefs);
447     safe_free (uid);
448     }
449    
450     void
451     free_compressed( PKT_compressed *zd )
452     {
453     if( zd->buf ) { /* have to skip some bytes */
454     /* don't have any information about the length, so
455     * we assume this is the last packet */
456     while( gpg_iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
457     ;
458     }
459     safe_free(zd);
460     }
461    
462     void
463     free_encrypted( PKT_encrypted *ed )
464     {
465     if( ed->buf ) { /* have to skip some bytes */
466     if( gpg_iobuf_in_block_mode(ed->buf) ) {
467     while( gpg_iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
468     ;
469     }
470     else {
471     while( ed->len ) { /* skip the packet */
472     int n = gpg_iobuf_read( ed->buf, NULL, ed->len );
473     if( n == -1 )
474     ed->len = 0;
475     else
476     ed->len -= n;
477     }
478     }
479     }
480     safe_free(ed);
481     }
482    
483    
484     void
485     free_plaintext( PKT_plaintext *pt )
486     {
487     if( pt->buf ) { /* have to skip some bytes */
488     if( gpg_iobuf_in_block_mode(pt->buf) ) {
489     while( gpg_iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
490     ;
491     }
492     else {
493     while( pt->len ) { /* skip the packet */
494     int n = gpg_iobuf_read( pt->buf, NULL, pt->len );
495     if( n == -1 )
496     pt->len = 0;
497     else
498     pt->len -= n;
499     }
500     }
501     }
502     safe_free(pt);
503     }
504    
505     /****************
506     * Free the packet in pkt.
507     */
508     void
509     gpg_free_packet( PACKET *pkt )
510     {
511     if( !pkt || !pkt->pkt.generic )
512     return;
513    
514     switch( pkt->pkttype ) {
515     case PKT_SIGNATURE:
516     free_seckey_enc( pkt->pkt.signature );
517     break;
518     case PKT_PUBKEY_ENC:
519     free_pubkey_enc( pkt->pkt.pubkey_enc );
520     break;
521     case PKT_SYMKEY_ENC:
522     free_symkey_enc( pkt->pkt.symkey_enc );
523     break;
524     case PKT_PUBLIC_KEY:
525     case PKT_PUBLIC_SUBKEY:
526     free_public_key( pkt->pkt.public_key );
527     break;
528     case PKT_SECRET_KEY:
529     case PKT_SECRET_SUBKEY:
530     free_secret_key( pkt->pkt.secret_key );
531     break;
532     case PKT_COMMENT:
533     free_comment( pkt->pkt.comment );
534     break;
535     case PKT_USER_ID:
536     free_user_id( pkt->pkt.user_id );
537     break;
538     case PKT_COMPRESSED:
539     free_compressed( pkt->pkt.compressed);
540     break;
541     case PKT_ENCRYPTED:
542     case PKT_ENCRYPTED_MDC:
543     free_encrypted( pkt->pkt.encrypted );
544     break;
545     case PKT_PLAINTEXT:
546     free_plaintext( pkt->pkt.plaintext );
547     break;
548     default:
549     safe_free( pkt->pkt.generic );
550     break;
551     }
552     pkt->pkt.generic = NULL;
553     }
554    
555    
556    
557     /****************
558     * Parse a Packet and return it in packet
559     * Returns: 0 := valid packet in pkt
560     * -1 := no more packets
561     * >0 := error
562     * Note: The function may return an error and a partly valid packet;
563     * caller must free this packet.
564     */
565     int
566     gpg_parse_packet( gpg_iobuf_t inp, PACKET *pkt )
567     {
568     int skip, rc;
569    
570     do {
571     rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
572     } while( skip );
573     return rc;
574     }
575    
576     /****************
577     * Like parse packet, but only return secret or public (sub)key packets.
578     */
579     int
580     search_packet( gpg_iobuf_t inp, PACKET *pkt, _off_t *retpos, int with_uid )
581     {
582     int skip, rc;
583    
584     do {
585     rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
586     } while( skip );
587     return rc;
588     }
589    
590     /****************
591     * Copy all packets from INP to OUT, thereby removing unused spaces.
592     */
593     int
594     copy_all_packets( gpg_iobuf_t inp, gpg_iobuf_t out )
595     {
596     PACKET pkt;
597     int skip, rc=0;
598     do {
599     gpg_init_packet(&pkt);
600     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
601     return rc;
602     }
603    
604     /****************
605     * Copy some packets from INP to OUT, thereby removing unused spaces.
606     * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
607     */
608     int
609     copy_some_packets( gpg_iobuf_t inp, gpg_iobuf_t out, _off_t stopoff )
610     {
611     PACKET pkt;
612     int skip, rc=0;
613     do {
614     if( gpg_iobuf_tell(inp) >= stopoff )
615     return 0;
616     gpg_init_packet(&pkt);
617     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
618     return rc;
619     }
620    
621     /****************
622     * Skip over N packets
623     */
624     int
625     skip_some_packets( gpg_iobuf_t inp, unsigned n )
626     {
627     int skip, rc=0;
628     PACKET pkt;
629    
630     for( ;n && !rc; n--) {
631     gpg_init_packet(&pkt);
632     rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
633     }
634     return rc;
635     }
636    
637     /****************
638     * Parse packet. Set the variable skip points to 1 if the packet
639     * should be skipped; this is the case if either ONLYKEYPKTS is set
640     * and the parsed packet isn't one or the
641     * packet-type is 0, indicating deleted stuff.
642     * if OUT is not NULL, a special copymode is used.
643     */
644     static int
645     parse( gpg_iobuf_t inp, PACKET *pkt, int onlykeypkts, _off_t *retpos,
646     int *skip, gpg_iobuf_t out, int do_skip
647     )
648     {
649     int rc=0, c, ctb, pkttype, lenbytes;
650     unsigned long pktlen;
651     byte hdr[8];
652     int hdrlen;
653     int new_ctb = 0;
654     int with_uid = (onlykeypkts == 2);
655    
656     *skip = 0;
657     /*assert( !pkt->pkt.generic );*/
658     if( retpos )
659     *retpos = gpg_iobuf_tell(inp);
660    
661     if( (ctb = gpg_iobuf_get(inp)) == -1 ) {
662     rc = -1;
663     goto leave;
664     }
665     hdrlen=0;
666     hdr[hdrlen++] = ctb;
667     if( !(ctb & 0x80) ) {
668     printf("%s: invalid packet (ctb=%02x)\n", gpg_iobuf_where(inp), ctb );
669     rc = G10ERR_INVALID_PACKET;
670     goto leave;
671     }
672     pktlen = 0;
673     new_ctb = !!(ctb & 0x40);
674     if( new_ctb ) {
675     pkttype = ctb & 0x3f;
676     if( (c = gpg_iobuf_get(inp)) == -1 ) {
677     printf("%s: 1st length byte missing\n", gpg_iobuf_where(inp) );
678     rc = G10ERR_INVALID_PACKET;
679     goto leave;
680     }
681     if (pkttype == PKT_COMPRESSED) {
682     gpg_iobuf_set_partial_block_mode(inp, c & 0xff);
683     pktlen = 0;/* to indicate partial length */
684     }
685     else {
686     hdr[hdrlen++] = c;
687     if( c < 192 )
688     pktlen = c;
689     else if( c < 224 ) {
690     pktlen = (c - 192) * 256;
691     if( (c = gpg_iobuf_get(inp)) == -1 ) {
692     printf("%s: 2nd length byte missing\n",
693     gpg_iobuf_where(inp) );
694     rc = G10ERR_INVALID_PACKET;
695     goto leave;
696     }
697     hdr[hdrlen++] = c;
698     pktlen += c + 192;
699     }
700     else if( c == 255 ) {
701     pktlen = (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 24;
702     pktlen |= (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 16;
703     pktlen |= (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 8;
704     if( (c = gpg_iobuf_get(inp)) == -1 ) {
705     printf("%s: 4 byte length invalid\n",
706     gpg_iobuf_where(inp) );
707     rc = G10ERR_INVALID_PACKET;
708     goto leave;
709     }
710     pktlen |= (hdr[hdrlen++] = c );
711     }
712     else { /* partial body length */
713     gpg_iobuf_set_partial_block_mode(inp, c & 0xff);
714     pktlen = 0;/* to indicate partial length */
715     }
716     }
717     }
718     else {
719     pkttype = (ctb>>2)&0xf;
720     lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
721     if( !lenbytes ) {
722     pktlen = 0; /* don't know the value */
723     if( pkttype != PKT_COMPRESSED )
724     gpg_iobuf_set_block_mode(inp, 1);
725     }
726     else {
727     for( ; lenbytes; lenbytes-- ) {
728     pktlen <<= 8;
729     pktlen |= hdr[hdrlen++] = gpg_iobuf_get_noeof(inp);
730     }
731     }
732     }
733    
734     if (pktlen == 0xffffffff) {
735     /* with a some probability this is caused by a problem in the
736     * the uncompressing layer - in some error cases it just loops
737     * and spits out 0xff bytes. */
738 twoaday 214 /*printf ("%s: garbled packet detected\n", gpg_iobuf_where(inp));*/
739     rc = G10ERR_INVALID_PACKET;
740     goto leave;
741 werner 46 }
742    
743     if( out && pkttype ) {
744     if( gpg_iobuf_write( out, hdr, hdrlen ) == -1 )
745     rc = G10ERR_WRITE_FILE;
746     else
747     rc = copy_packet(inp, out, pkttype, pktlen );
748     goto leave;
749     }
750    
751     if (with_uid && pkttype == PKT_USER_ID)
752     ;
753     else if( do_skip
754     || !pkttype
755     || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
756     && pkttype != PKT_PUBLIC_KEY
757     && pkttype != PKT_SECRET_SUBKEY
758     && pkttype != PKT_SECRET_KEY ) ) {
759     skip_rest(inp, pktlen);
760     *skip = 1;
761     rc = 0;
762     goto leave;
763     }
764    
765     pkt->pkttype = pkttype;
766     rc = G10ERR_UNKNOWN_PACKET; /* default error */
767     switch( pkttype ) {
768     case PKT_PUBLIC_KEY:
769     case PKT_PUBLIC_SUBKEY:
770     pkt->pkt.public_key = calloc(1, sizeof *pkt->pkt.public_key );
771     rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
772     break;
773     case PKT_SECRET_KEY:
774     case PKT_SECRET_SUBKEY:
775     pkt->pkt.secret_key = calloc(1,sizeof *pkt->pkt.secret_key );
776     rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
777     break;
778     case PKT_SYMKEY_ENC:
779     rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
780     break;
781     case PKT_PUBKEY_ENC:
782     rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
783     break;
784     case PKT_SIGNATURE:
785     pkt->pkt.signature = calloc(1,sizeof *pkt->pkt.signature );
786     rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
787     break;
788     case PKT_ONEPASS_SIG:
789     pkt->pkt.onepass_sig = calloc(1,sizeof *pkt->pkt.onepass_sig );
790     rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
791     break;
792     case PKT_USER_ID:
793     rc = parse_user_id(inp, pkttype, pktlen, pkt );
794     break;
795     case PKT_ATTRIBUTE:
796     pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */
797     rc = parse_attribute(inp, pkttype, pktlen, pkt);
798     break;
799     case PKT_OLD_COMMENT:
800     case PKT_COMMENT:
801     rc = parse_comment(inp, pkttype, pktlen, pkt);
802     break;
803     case PKT_RING_TRUST:
804     parse_trust(inp, pkttype, pktlen, pkt);
805     rc = 0;
806     break;
807     case PKT_PLAINTEXT:
808     rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb );
809     break;
810     case PKT_COMPRESSED:
811     rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
812     break;
813     case PKT_ENCRYPTED:
814     case PKT_ENCRYPTED_MDC:
815     rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
816     break;
817     case PKT_MDC:
818     rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
819     break;
820     case PKT_GPG_CONTROL:
821     rc = parse_gpg_control(inp, pkttype, pktlen, pkt );
822     break;
823     default:
824     skip_packet(inp, pkttype, pktlen);
825     break;
826     }
827    
828     leave:
829     if( !rc && gpg_iobuf_error(inp) )
830     rc = G10ERR_INV_KEYRING;
831     return rc;
832     }
833    
834     static void
835     dump_hex_line( int c, int *i )
836     {
837     if( *i && !(*i%8) ) {
838     if( *i && !(*i%24) )
839     printf("\n%4d:", *i );
840     else
841     putchar(' ');
842     }
843     if( c == -1 )
844     printf(" EOF" );
845     else
846     printf(" %02x", c );
847     ++*i;
848     }
849    
850    
851     static int
852     copy_packet( gpg_iobuf_t inp, gpg_iobuf_t out, int pkttype, unsigned long pktlen )
853     {
854     int n;
855     char buf[100];
856    
857     if( gpg_iobuf_in_block_mode(inp) ) {
858     while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
859     if( gpg_iobuf_write(out, buf, n ) )
860     return G10ERR_WRITE_FILE; /* write error */
861     }
862     else if( !pktlen && pkttype == PKT_COMPRESSED ) {
863     printf("copy_packet: compressed!\n");
864     /* compressed packet, copy till EOF */
865     while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
866     if( gpg_iobuf_write(out, buf, n ) )
867     return G10ERR_WRITE_FILE; /* write error */
868     }
869     else {
870     for( ; pktlen; pktlen -= n ) {
871     n = pktlen > 100 ? 100 : pktlen;
872     n = gpg_iobuf_read( inp, buf, n );
873     if( n == -1 )
874     return G10ERR_READ_FILE;
875     if( gpg_iobuf_write(out, buf, n ) )
876     return G10ERR_WRITE_FILE; /* write error */
877     }
878     }
879     return 0;
880     }
881    
882    
883     static void
884     skip_packet( gpg_iobuf_t inp, int pkttype, unsigned long pktlen )
885     {
886     if( list_mode ) {
887     if( pkttype == PKT_MARKER )
888     fputs(":marker packet:\n", stdout );
889     else
890     printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
891     if( pkttype ) {
892     int c, i=0 ;
893     if( pkttype != PKT_MARKER )
894     fputs("dump:", stdout );
895     if( gpg_iobuf_in_block_mode(inp) ) {
896     while( (c=gpg_iobuf_get(inp)) != -1 )
897     dump_hex_line(c, &i);
898     }
899     else {
900     for( ; pktlen; pktlen-- )
901     dump_hex_line(gpg_iobuf_get(inp), &i);
902     }
903     putchar('\n');
904     return;
905     }
906     }
907     skip_rest(inp,pktlen);
908     }
909    
910     static void
911     skip_rest( gpg_iobuf_t inp, unsigned long pktlen )
912     {
913     if( gpg_iobuf_in_block_mode(inp) ) {
914     while( gpg_iobuf_get(inp) != -1 )
915     ;
916     }
917     else {
918     for( ; pktlen; pktlen-- )
919     if( gpg_iobuf_get(inp) == -1 )
920     break;
921     }
922     }
923    
924    
925     static void *
926     read_rest( gpg_iobuf_t inp, size_t pktlen )
927     {
928     byte *p;
929     int i;
930    
931     if( gpg_iobuf_in_block_mode(inp) ) {
932     printf("read_rest: can't store stream data\n");
933     p = NULL;
934     }
935     else {
936     p = malloc( pktlen );
937     for(i=0; pktlen; pktlen--, i++ )
938     p[i] = gpg_iobuf_get(inp);
939     }
940     return p;
941     }
942    
943    
944    
945     static int
946     parse_symkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
947     {
948     PKT_symkey_enc *k;
949     int rc = 0;
950     int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
951    
952     if( pktlen < 4 ) {
953     printf("packet(%d) too short\n", pkttype);
954     rc = G10ERR_INVALID_PACKET;
955     goto leave;
956     }
957     version = gpg_iobuf_get_noeof(inp); pktlen--;
958     if( version != 4 ) {
959     printf("packet(%d) with unknown version %d\n", pkttype, version);
960     rc = G10ERR_INVALID_PACKET;
961     goto leave;
962     }
963     if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
964     printf("packet(%d) too large\n", pkttype);
965     rc = G10ERR_INVALID_PACKET;
966     goto leave;
967     }
968     cipher_algo = gpg_iobuf_get_noeof(inp); pktlen--;
969     s2kmode = gpg_iobuf_get_noeof(inp); pktlen--;
970     hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
971     switch( s2kmode ) {
972     case 0: /* simple s2k */
973     minlen = 0;
974     break;
975     case 1: /* salted s2k */
976     minlen = 8;
977     break;
978     case 3: /* iterated+salted s2k */
979     minlen = 9;
980     break;
981     default:
982     printf("unknown S2K %d\n", s2kmode );
983     goto leave;
984     }
985     if( minlen > pktlen ) {
986     printf("packet with S2K %d too short\n", s2kmode );
987     rc = G10ERR_INVALID_PACKET;
988     goto leave;
989     }
990     seskeylen = pktlen - minlen;
991     k = packet->pkt.symkey_enc = calloc(1, sizeof *packet->pkt.symkey_enc
992     + seskeylen - 1 );
993     k->version = version;
994     k->cipher_algo = cipher_algo;
995     k->s2k.mode = s2kmode;
996     k->s2k.hash_algo = hash_algo;
997     if( s2kmode == 1 || s2kmode == 3 ) {
998     for(i=0; i < 8 && pktlen; i++, pktlen-- )
999     k->s2k.salt[i] = gpg_iobuf_get_noeof(inp);
1000     }
1001     if( s2kmode == 3 ) {
1002     k->s2k.count = gpg_iobuf_get(inp); pktlen--;
1003     }
1004     k->seskeylen = seskeylen;
1005     for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
1006     k->seskey[i] = gpg_iobuf_get_noeof(inp);
1007     assert( !pktlen );
1008    
1009     if( list_mode ) {
1010     printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
1011     version, cipher_algo, s2kmode, hash_algo);
1012     if( s2kmode == 1 || s2kmode == 3 ) {
1013     printf("\tsalt ");
1014     for(i=0; i < 8; i++ )
1015     printf("%02x", k->s2k.salt[i]);
1016     if( s2kmode == 3 )
1017     printf(", count %lu\n", (ulong)k->s2k.count );
1018     printf("\n");
1019     }
1020     }
1021    
1022     leave:
1023     skip_rest(inp, pktlen);
1024     return rc;
1025     }
1026    
1027     static int
1028     parse_pubkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
1029     {
1030     unsigned int n;
1031     int rc = 0;
1032     int i, ndata;
1033     PKT_pubkey_enc *k;
1034    
1035     k = packet->pkt.pubkey_enc = calloc(1, sizeof *packet->pkt.pubkey_enc);
1036     if( pktlen < 12 ) {
1037     printf("packet(%d) too short\n", pkttype);
1038     rc = G10ERR_INVALID_PACKET;
1039     goto leave;
1040     }
1041     k->version = gpg_iobuf_get_noeof(inp); pktlen--;
1042     if( k->version != 2 && k->version != 3 ) {
1043     printf("packet(%d) with unknown version %d\n", pkttype, k->version);
1044     rc = G10ERR_INVALID_PACKET;
1045     goto leave;
1046     }
1047     k->keyid[0] = read_32(inp); pktlen -= 4;
1048     k->keyid[1] = read_32(inp); pktlen -= 4;
1049     k->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1050     k->throw_keyid = 0; /* only used as flag for build_packet */
1051     if( list_mode )
1052     printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
1053     k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
1054    
1055     ndata = pubkey_get_nenc(k->pubkey_algo);
1056     if( !ndata ) {
1057     if( list_mode )
1058     printf("\tunsupported algorithm %d\n", k->pubkey_algo );
1059     unknown_pubkey_warning( k->pubkey_algo );
1060     k->data[0] = NULL; /* no need to store the encrypted data */
1061     }
1062     else {
1063     for( i=0; i < ndata; i++ ) {
1064     n = pktlen;
1065     k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
1066     if( list_mode ) {
1067     printf("\tdata: ");
1068     mpi_print(stdout, k->data[i], mpi_print_mode );
1069     putchar('\n');
1070     }
1071     if (!k->data[i])
1072     rc = G10ERR_INVALID_PACKET;
1073     }
1074     }
1075    
1076     leave:
1077     skip_rest(inp, pktlen);
1078     return rc;
1079     }
1080    
1081     static void
1082     dump_sig_subpkt( int hashed, int type, int critical,
1083     const byte *buffer, size_t buflen, size_t length )
1084     {
1085     const char *p=NULL;
1086     int i;
1087    
1088     /* The CERT has warning out with explains how to use GNUPG to
1089     * detect the ARRs - we print our old message here when it is a faked
1090     * ARR and add an additional notice */
1091     if ( type == SIGSUBPKT_ARR && !hashed ) {
1092     printf("\tsubpkt %d len %u (additional recipient request)\n"
1093     "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
1094     "encrypt to this key and thereby reveal the plaintext to "
1095     "the owner of this ARR key. Detailed info follows:\n",
1096     type, (unsigned)length );
1097     }
1098    
1099    
1100     printf("\t%s%ssubpkt %d len %u (", /*)*/
1101     critical ? "critical ":"",
1102     hashed ? "hashed ":"", type, (unsigned)length );
1103     buffer++;
1104     length--;
1105     if( length > buflen ) {
1106     printf("too short: buffer is only %u)\n", (unsigned)buflen );
1107     return;
1108     }
1109     switch( type ) {
1110     case SIGSUBPKT_SIG_CREATED:
1111     if( length >= 4 )
1112     printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
1113     break;
1114     case SIGSUBPKT_SIG_EXPIRE:
1115     if( length >= 4 )
1116     printf("sig expires after %s",
1117     strtimevalue( buffer_to_u32(buffer) ) );
1118     break;
1119     case SIGSUBPKT_EXPORTABLE:
1120     if( length )
1121     printf("%sexportable", *buffer? "":"not ");
1122     break;
1123     case SIGSUBPKT_TRUST:
1124     if(length!=2)
1125     p="[invalid trust signature]";
1126     else
1127     printf("trust signature of level %d, amount %d",buffer[0],buffer[1]);
1128     break;
1129     case SIGSUBPKT_REGEXP:
1130     if(!length)
1131     p="[invalid regexp]";
1132     else
1133     printf("regular expression: \"%s\"",buffer);
1134     break;
1135     case SIGSUBPKT_REVOCABLE:
1136     if( length )
1137     printf("%srevocable", *buffer? "":"not ");
1138     break;
1139     case SIGSUBPKT_KEY_EXPIRE:
1140     if( length >= 4 )
1141     printf("key expires after %s",
1142     strtimevalue( buffer_to_u32(buffer) ) );
1143     break;
1144     case SIGSUBPKT_PREF_SYM:
1145     fputs("pref-sym-algos:", stdout );
1146     for( i=0; i < length; i++ )
1147     printf(" %d", buffer[i] );
1148     break;
1149     case SIGSUBPKT_REV_KEY:
1150     fputs("revocation key: ", stdout );
1151     if( length < 22 )
1152     p = "[too short]";
1153     else {
1154     printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1155     for( i=2; i < length; i++ )
1156     printf("%02X", buffer[i] );
1157     }
1158     break;
1159     case SIGSUBPKT_ISSUER:
1160     if( length >= 8 )
1161     printf("issuer key ID %08lX%08lX",
1162     (ulong)buffer_to_u32(buffer),
1163     (ulong)buffer_to_u32(buffer+4) );
1164     break;
1165     case SIGSUBPKT_NOTATION:
1166     {
1167     fputs("notation: ", stdout );
1168     if( length < 8 )
1169     p = "[too short]";
1170     else if( !(*buffer & 0x80) )
1171     p = "[not human readable]";
1172     else {
1173     const byte *s = buffer;
1174     size_t n1, n2;
1175    
1176     n1 = (s[4] << 8) | s[5];
1177     n2 = (s[6] << 8) | s[7];
1178     s += 8;
1179     if( 8+n1+n2 != length )
1180     p = "[error]";
1181     else {
1182     print_string( stdout, s, n1, ')' );
1183     putc( '=', stdout );
1184     print_string( stdout, s+n1, n2, ')' );
1185     }
1186     }
1187     }
1188     break;
1189     case SIGSUBPKT_PREF_HASH:
1190     fputs("pref-hash-algos:", stdout );
1191     for( i=0; i < length; i++ )
1192     printf(" %d", buffer[i] );
1193     break;
1194     case SIGSUBPKT_PREF_COMPR:
1195     fputs("pref-zip-algos:", stdout );
1196     for( i=0; i < length; i++ )
1197     printf(" %d", buffer[i] );
1198     break;
1199     case SIGSUBPKT_KS_FLAGS:
1200     fputs("key server preferences:",stdout);
1201     for(i=0;i<length;i++)
1202     printf(" %02X", buffer[i]);
1203     break;
1204     case SIGSUBPKT_PREF_KS:
1205     p = "preferred key server";
1206     break;
1207     case SIGSUBPKT_PRIMARY_UID:
1208     p = "primary user ID";
1209     break;
1210     case SIGSUBPKT_POLICY:
1211     fputs("policy: ", stdout );
1212     print_string( stdout, buffer, length, ')' );
1213     break;
1214     case SIGSUBPKT_KEY_FLAGS:
1215     fputs ( "key flags:", stdout );
1216     for( i=0; i < length; i++ )
1217     printf(" %02X", buffer[i] );
1218     break;
1219     case SIGSUBPKT_SIGNERS_UID:
1220     p = "signer's user ID";
1221     break;
1222     case SIGSUBPKT_REVOC_REASON:
1223     if( length ) {
1224     printf("revocation reason 0x%02x (", *buffer );
1225     print_string( stdout, buffer+1, length-1, ')' );
1226     p = ")";
1227     }
1228     break;
1229     case SIGSUBPKT_ARR:
1230     fputs("Big Brother's key (ignored): ", stdout );
1231     if( length < 22 )
1232     p = "[too short]";
1233     else {
1234     printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1235     for( i=2; i < length; i++ )
1236     printf("%02X", buffer[i] );
1237     }
1238     break;
1239     case SIGSUBPKT_FEATURES:
1240     fputs ( "features:", stdout );
1241     for( i=0; i < length; i++ )
1242     printf(" %02x", buffer[i] );
1243     break;
1244     case SIGSUBPKT_PRIV_VERIFY_CACHE:
1245     p = "obsolete verification cache";
1246     break;
1247     default: p = "?"; break;
1248     }
1249    
1250     printf("%s)\n", p? p: "");
1251     }
1252    
1253     /****************
1254     * Returns: >= 0 offset into buffer
1255     * -1 unknown type
1256     * -2 unsupported type
1257     * -3 subpacket too short
1258     */
1259     int
1260     parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
1261     {
1262     switch( type ) {
1263     case SIGSUBPKT_REV_KEY:
1264     if(n < 22)
1265     break;
1266     return 0;
1267     case SIGSUBPKT_SIG_CREATED:
1268     case SIGSUBPKT_SIG_EXPIRE:
1269     case SIGSUBPKT_KEY_EXPIRE:
1270     if( n < 4 )
1271     break;
1272     return 0;
1273     case SIGSUBPKT_KEY_FLAGS:
1274     case SIGSUBPKT_KS_FLAGS:
1275     case SIGSUBPKT_PREF_SYM:
1276     case SIGSUBPKT_PREF_HASH:
1277     case SIGSUBPKT_PREF_COMPR:
1278     case SIGSUBPKT_POLICY:
1279     case SIGSUBPKT_FEATURES:
1280     return 0;
1281     case SIGSUBPKT_EXPORTABLE:
1282     case SIGSUBPKT_REVOCABLE:
1283     if( !n )
1284     break;
1285     return 0;
1286     case SIGSUBPKT_ISSUER: /* issuer key ID */
1287     if( n < 8 )
1288     break;
1289     return 0;
1290     case SIGSUBPKT_NOTATION:
1291     if( n < 8 ) /* minimum length needed */
1292     break;
1293     return 0;
1294     case SIGSUBPKT_REVOC_REASON:
1295     if( !n )
1296     break;
1297     return 0;
1298     case SIGSUBPKT_PRIMARY_UID:
1299     if ( n != 1 )
1300     break;
1301     return 0;
1302     case SIGSUBPKT_PRIV_VERIFY_CACHE:
1303     /* We used this in gpg 1.0.5 and 1.0.6 to cache signature
1304     * verification results - it is no longer used.
1305     * "GPG" 0x00 <mode> <stat>
1306     * where mode == 1: valid data, stat == 0: invalid signature
1307     * stat == 1: valid signature
1308     * (because we use private data, we check our marker) */
1309     if( n < 6 )
1310     break;
1311     if( buffer[0] != 'G' || buffer[1] != 'P'
1312     || buffer[2] != 'G' || buffer[3] )
1313     return -2;
1314     return 4;
1315     default: return -1;
1316     }
1317     return -3;
1318     }
1319    
1320    
1321     static int
1322     can_handle_critical( const byte *buffer, size_t n, int type )
1323     {
1324     switch( type ) {
1325     case SIGSUBPKT_NOTATION:
1326     if( n >= 8 && (*buffer & 0x80) )
1327     return 1; /* human readable is handled */
1328     return 0;
1329    
1330     case SIGSUBPKT_SIG_CREATED:
1331     case SIGSUBPKT_SIG_EXPIRE:
1332     case SIGSUBPKT_KEY_EXPIRE:
1333     case SIGSUBPKT_EXPORTABLE:
1334     case SIGSUBPKT_REVOCABLE:
1335     case SIGSUBPKT_REV_KEY:
1336     case SIGSUBPKT_ISSUER:/* issuer key ID */
1337     case SIGSUBPKT_PREF_SYM:
1338     case SIGSUBPKT_PREF_HASH:
1339     case SIGSUBPKT_PREF_COMPR:
1340     case SIGSUBPKT_KEY_FLAGS:
1341     case SIGSUBPKT_PRIMARY_UID:
1342     case SIGSUBPKT_FEATURES:
1343     case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
1344     return 1;
1345    
1346     default:
1347     return 0;
1348     }
1349     }
1350    
1351    
1352     const byte *
1353     enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
1354     size_t *ret_n, int *start, int *critical )
1355     {
1356     const byte *buffer;
1357     int buflen;
1358     int type;
1359     int critical_dummy;
1360     int offset;
1361     size_t n;
1362     int seq = 0;
1363     int reqseq = start? *start: 0;
1364    
1365     if(!critical)
1366     critical=&critical_dummy;
1367    
1368     if( !pktbuf || reqseq == -1 ) {
1369     /* return some value different from NULL to indicate that
1370     * there is no critical bit we do not understand. The caller
1371     * will never use the value. Yes I know, it is an ugly hack */
1372     return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
1373     }
1374     buffer = pktbuf->data;
1375     buflen = pktbuf->len;
1376     while( buflen ) {
1377     n = *buffer++; buflen--;
1378     if( n == 255 ) { /* 4 byte length header */
1379     if( buflen < 4 )
1380     goto too_short;
1381     n = (buffer[0] << 24) | (buffer[1] << 16)
1382     | (buffer[2] << 8) | buffer[3];
1383     buffer += 4;
1384     buflen -= 4;
1385     }
1386     else if( n >= 192 ) { /* 2 byte special encoded length header */
1387     if( buflen < 2 )
1388     goto too_short;
1389     n = (( n - 192 ) << 8) + *buffer + 192;
1390     buffer++;
1391     buflen--;
1392     }
1393     if( buflen < n )
1394     goto too_short;
1395     type = *buffer;
1396     if( type & 0x80 ) {
1397     type &= 0x7f;
1398     *critical = 1;
1399     }
1400     else
1401     *critical = 0;
1402     if( !(++seq > reqseq) )
1403     ;
1404     else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
1405     if( *critical ) {
1406     if( n-1 > buflen+1 )
1407     goto too_short;
1408     if( !can_handle_critical(buffer+1, n-1, type ) ) {
1409     printf("subpacket of type %d has critical bit set\n",
1410     type);
1411     if( start )
1412     *start = seq;
1413     return NULL; /* this is an error */
1414     }
1415     }
1416     }
1417     else if( reqtype < 0 ) /* list packets */
1418     dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
1419     type, *critical, buffer, buflen, n );
1420     else if( type == reqtype ) { /* found */
1421     buffer++;
1422     n--;
1423     if( n > buflen )
1424     goto too_short;
1425     if( ret_n )
1426     *ret_n = n;
1427     offset = parse_one_sig_subpkt(buffer, n, type );
1428     switch( offset ) {
1429     case -3:
1430     printf("subpacket of type %d too short\n", type);
1431     return NULL;
1432     case -2:
1433     return NULL;
1434     case -1:
1435     printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
1436     exit( -1 );
1437     default:
1438     break;
1439     }
1440     if( start )
1441     *start = seq;
1442     return buffer+offset;
1443     }
1444     buffer += n; buflen -=n;
1445     }
1446     if( reqtype == SIGSUBPKT_TEST_CRITICAL )
1447     return buffer; /* as value true to indicate that there is no */
1448     /* critical bit we don't understand */
1449     if( start )
1450     *start = -1;
1451     return NULL; /* end of packets; not found */
1452    
1453     too_short:
1454     printf("buffer shorter than subpacket\n");
1455     if( start )
1456     *start = -1;
1457     return NULL;
1458     }
1459    
1460    
1461     const byte *
1462     gpg_parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype,
1463     size_t *ret_n)
1464     {
1465     return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL );
1466     }
1467    
1468     const byte *
1469     gpg_parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
1470     size_t *ret_n )
1471     {
1472     const byte *p;
1473    
1474     p = gpg_parse_sig_subpkt (sig->hashed, reqtype, ret_n );
1475     if( !p )
1476     p = gpg_parse_sig_subpkt (sig->unhashed, reqtype, ret_n );
1477     return p;
1478     }
1479    
1480     /* Find all revocation keys. Look in hashed area only. */
1481     void parse_revkeys(PKT_signature *sig)
1482     {
1483     struct revocation_key *revkey;
1484     int seq=0;
1485     size_t len;
1486    
1487     if( sig->sig_class != 0x1F )
1488     return;
1489    
1490     while((revkey=
1491     (struct revocation_key *)enum_sig_subpkt(sig->hashed,
1492     SIGSUBPKT_REV_KEY,
1493     &len,&seq,NULL))) {
1494     if( len==sizeof(struct revocation_key) &&
1495     (revkey->rclass&0x80)) /* 0x80 bit must be set */ {
1496     sig->revkey=realloc(sig->revkey,
1497     sizeof(struct revocation_key *)*(sig->numrevkeys+1));
1498     sig->revkey[sig->numrevkeys]=revkey;
1499     sig->numrevkeys++;
1500     }
1501     }
1502     }
1503    
1504     static int
1505     parse_signature( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1506     PKT_signature *sig )
1507     {
1508     int md5_len=0;
1509     unsigned n;
1510     int is_v4=0;
1511     int rc=0;
1512     int i, ndata;
1513    
1514     if( pktlen < 16 ) {
1515     printf("packet(%d) too short\n", pkttype);
1516     goto leave;
1517     }
1518     sig->version = gpg_iobuf_get_noeof(inp); pktlen--;
1519     if( sig->version == 4 )
1520     is_v4=1;
1521     else if( sig->version != 2 && sig->version != 3 ) {
1522     printf("packet(%d) with unknown version %d\n", pkttype, sig->version);
1523     rc = G10ERR_INVALID_PACKET;
1524     goto leave;
1525     }
1526    
1527     if( !is_v4 ) {
1528     md5_len = gpg_iobuf_get_noeof(inp); pktlen--;
1529     }
1530     sig->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1531     if( !is_v4 ) {
1532     sig->timestamp = read_32(inp); pktlen -= 4;
1533     sig->keyid[0] = read_32(inp); pktlen -= 4;
1534     sig->keyid[1] = read_32(inp); pktlen -= 4;
1535     }
1536     sig->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1537     sig->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1538     sig->flags.exportable=1;
1539     sig->flags.revocable=1;
1540     if( is_v4 ) { /* read subpackets */
1541     n = read_16(inp); pktlen -= 2; /* length of hashed data */
1542     if( n > 10000 ) {
1543     printf("signature packet: hashed data too long\n");
1544     rc = G10ERR_INVALID_PACKET;
1545     goto leave;
1546     }
1547     if( n ) {
1548     sig->hashed = malloc (sizeof (*sig->hashed) + n - 1 );
1549     sig->hashed->size = n;
1550     sig->hashed->len = n;
1551     if( gpg_iobuf_read (inp, sig->hashed->data, n ) != n ) {
1552     printf ("premature eof while reading "
1553     "hashed signature data\n");
1554     rc = -1;
1555     goto leave;
1556     }
1557     pktlen -= n;
1558     }
1559     n = read_16(inp); pktlen -= 2; /* length of unhashed data */
1560     if( n > 10000 ) {
1561     printf("signature packet: unhashed data too long\n");
1562     rc = G10ERR_INVALID_PACKET;
1563     goto leave;
1564     }
1565     if( n ) {
1566     /* we add 8 extra bytes so that we have space for the signature
1567     * status cache. Well we are wastin this if there is a cache
1568     * packet already, but in the other case it avoids an realloc */
1569     sig->unhashed = malloc (sizeof(*sig->unhashed) + n + 8 - 1 );
1570     sig->unhashed->size = n + 8;
1571     sig->unhashed->len = n;
1572     if( gpg_iobuf_read(inp, sig->unhashed->data, n ) != n ) {
1573     printf("premature eof while reading "
1574     "unhashed signature data\n");
1575     rc = -1;
1576     goto leave;
1577     }
1578     pktlen -= n;
1579     }
1580     }
1581    
1582     if( pktlen < 5 ) { /* sanity check */
1583     printf("packet(%d) too short\n", pkttype);
1584     rc = G10ERR_INVALID_PACKET;
1585     goto leave;
1586     }
1587    
1588     sig->digest_start[0] = gpg_iobuf_get_noeof(inp); pktlen--;
1589     sig->digest_start[1] = gpg_iobuf_get_noeof(inp); pktlen--;
1590    
1591     if( is_v4 && sig->pubkey_algo ) { /*extract required information */
1592     const byte *p;
1593    
1594     /* set sig->flags.unknown_critical if there is a
1595     * critical bit set for packets which we do not understand */
1596     if( !gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
1597     || !gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
1598     NULL) )
1599     {
1600     sig->flags.unknown_critical = 1;
1601     }
1602    
1603     p = gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
1604     if( !p )
1605     printf("signature packet without timestamp\n");
1606     else
1607     sig->timestamp = buffer_to_u32(p);
1608     p = gpg_parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1609     if( !p )
1610     printf("signature packet without keyid\n");
1611     else {
1612     sig->keyid[0] = buffer_to_u32(p);
1613     sig->keyid[1] = buffer_to_u32(p+4);
1614     }
1615    
1616     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1617     if(p)
1618     sig->expiredate=sig->timestamp+buffer_to_u32(p);
1619     if(sig->expiredate && sig->expiredate<=time(NULL))
1620     sig->flags.expired=1;
1621    
1622     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1623     if(p)
1624     sig->flags.policy_url=1;
1625    
1626     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1627     if(p)
1628     sig->flags.notation=1;
1629    
1630     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1631     if(p && *p==0)
1632     sig->flags.revocable=0;
1633    
1634     /* We accept the exportable subpacket from either the hashed
1635     or unhashed areas as older versions of gpg put it in the
1636     unhashed area. In theory, anyway, we should never see this
1637     packet off of a local keyring. */
1638    
1639     p=gpg_parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1640     if(p && *p==0)
1641     sig->flags.exportable=0;
1642    
1643     /* Find all revocation keys. */
1644     if(sig->sig_class==0x1F)
1645     parse_revkeys(sig);
1646     }
1647    
1648     if( list_mode ) {
1649     printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1650     "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1651     "\tdigest algo %d, begin of digest %02x %02x\n",
1652     sig->pubkey_algo,
1653     (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1654     sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1655     sig->digest_algo,
1656     sig->digest_start[0], sig->digest_start[1] );
1657     if( is_v4 ) {
1658     gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL );
1659     gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1660     }
1661     }
1662    
1663     ndata = pubkey_get_nsig(sig->pubkey_algo);
1664     if( !ndata ) {
1665     if( list_mode )
1666     printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1667     unknown_pubkey_warning( sig->pubkey_algo );
1668     /* we store the plain material in data[0], so that we are able
1669     * to write it back with build_packet() */
1670     sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1671     pktlen = 0;
1672     }
1673     else {
1674     for( i=0; i < ndata; i++ ) {
1675     n = pktlen;
1676     sig->data[i] = mpi_read(inp, &n, 0 );
1677     pktlen -=n;
1678     if( list_mode ) {
1679     printf("\tdata: ");
1680     mpi_print(stdout, sig->data[i], mpi_print_mode );
1681     putchar('\n');
1682     }
1683     if (!sig->data[i])
1684     rc = G10ERR_INVALID_PACKET;
1685     }
1686     }
1687    
1688     leave:
1689     skip_rest(inp, pktlen);
1690     return rc;
1691     }
1692    
1693    
1694     static int
1695     parse_onepass_sig( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1696     PKT_onepass_sig *ops )
1697     {
1698     int version;
1699     int rc = 0;
1700    
1701     if( pktlen < 13 ) {
1702     printf("packet(%d) too short\n", pkttype);
1703     rc = G10ERR_INVALID_PACKET;
1704     goto leave;
1705     }
1706     version = gpg_iobuf_get_noeof(inp); pktlen--;
1707     if( version != 3 ) {
1708     printf("onepass_sig with unknown version %d\n", version);
1709     rc = G10ERR_INVALID_PACKET;
1710     goto leave;
1711     }
1712     ops->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1713     ops->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1714     ops->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1715     ops->keyid[0] = read_32(inp); pktlen -= 4;
1716     ops->keyid[1] = read_32(inp); pktlen -= 4;
1717     ops->last = gpg_iobuf_get_noeof(inp); pktlen--;
1718     if( list_mode )
1719     printf(":onepass_sig packet: keyid %08lX%08lX\n"
1720     "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1721     (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1722     version, ops->sig_class,
1723     ops->digest_algo, ops->pubkey_algo, ops->last );
1724    
1725    
1726     leave:
1727     skip_rest(inp, pktlen);
1728     return rc;
1729     }
1730    
1731    
1732     static int
1733     parse_key( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1734     byte *hdr, int hdrlen, PACKET *pkt )
1735     {
1736     int i, version, algorithm;
1737     unsigned n;
1738     unsigned long timestamp, expiredate, max_expiredate;
1739     int npkey, nskey;
1740     int is_v4=0;
1741     int rc=0;
1742    
1743     version = gpg_iobuf_get_noeof(inp); pktlen--;
1744     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1745     /* early versions of G10 use old PGP comments packets;
1746     * luckily all those comments are started by a hash */
1747     if( list_mode ) {
1748     printf(":rfc1991 comment packet: \"" );
1749     for( ; pktlen; pktlen-- ) {
1750     int c;
1751     c = gpg_iobuf_get_noeof(inp);
1752     if( c >= ' ' && c <= 'z' )
1753     putchar(c);
1754     else
1755     printf("\\x%02x", c );
1756     }
1757     printf("\"\n");
1758     }
1759     skip_rest(inp, pktlen);
1760     return 0;
1761     }
1762     else if( version == 4 )
1763     is_v4=1;
1764     else if( version != 2 && version != 3 ) {
1765     printf("packet(%d) with unknown version %d\n", pkttype, version);
1766     rc = G10ERR_INVALID_PACKET;
1767     goto leave;
1768     }
1769    
1770     if( pktlen < 11 ) {
1771     printf("packet(%d) too short\n", pkttype);
1772     rc = G10ERR_INVALID_PACKET;
1773     goto leave;
1774     }
1775    
1776     timestamp = read_32(inp); pktlen -= 4;
1777     if( is_v4 ) {
1778     expiredate = 0; /* have to get it from the selfsignature */
1779     max_expiredate = 0;
1780     }
1781     else {
1782     unsigned short ndays;
1783     ndays = read_16(inp); pktlen -= 2;
1784     if( ndays )
1785     expiredate = timestamp + ndays * 86400L;
1786     else
1787     expiredate = 0;
1788    
1789     max_expiredate=expiredate;
1790     }
1791     algorithm = gpg_iobuf_get_noeof(inp); pktlen--;
1792     if( list_mode )
1793     printf(":%s key packet:\n"
1794     "\tversion %d, algo %d, created %lu, expires %lu\n",
1795     pkttype == PKT_PUBLIC_KEY? "public" :
1796     pkttype == PKT_SECRET_KEY? "secret" :
1797     pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1798     pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1799     version, algorithm, timestamp, expiredate );
1800    
1801     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1802     PKT_secret_key *sk = pkt->pkt.secret_key;
1803    
1804     sk->timestamp = timestamp;
1805     sk->expiredate = expiredate;
1806     sk->max_expiredate = max_expiredate;
1807     sk->hdrbytes = hdrlen;
1808     sk->version = version;
1809     sk->is_primary = pkttype == PKT_SECRET_KEY;
1810     sk->pubkey_algo = algorithm;
1811     sk->req_usage = 0;
1812     sk->pubkey_usage = 0; /* not yet used */
1813     }
1814     else {
1815     PKT_public_key *pk = pkt->pkt.public_key;
1816    
1817     pk->timestamp = timestamp;
1818     pk->expiredate = expiredate;
1819     pk->max_expiredate = max_expiredate;
1820     pk->hdrbytes = hdrlen;
1821     pk->version = version;
1822     pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1823     pk->pubkey_algo = algorithm;
1824     pk->req_usage = 0;
1825     pk->pubkey_usage = 0; /* not yet used */
1826     pk->is_revoked = 0;
1827     pk->keyid[0] = 0;
1828     pk->keyid[1] = 0;
1829     }
1830     nskey = pubkey_get_nskey( algorithm );
1831     npkey = pubkey_get_npkey( algorithm );
1832     if( !npkey ) {
1833     if( list_mode )
1834     printf("\tunknown algorithm %d\n", algorithm );
1835     unknown_pubkey_warning( algorithm );
1836     }
1837    
1838    
1839     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1840     PKT_secret_key *sk = pkt->pkt.secret_key;
1841     byte temp[16];
1842     size_t snlen = 0;
1843    
1844     if( !npkey ) {
1845     sk->skey[0] = mpi_set_opaque( NULL,
1846     read_rest(inp, pktlen), pktlen );
1847     pktlen = 0;
1848     goto leave;
1849     }
1850    
1851     for(i=0; i < npkey; i++ ) {
1852     n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1853     if( list_mode ) {
1854     printf( "\tskey[%d]: ", i);
1855     mpi_print(stdout, sk->skey[i], mpi_print_mode );
1856     putchar('\n');
1857     }
1858     if (!sk->skey[i])
1859     rc = G10ERR_INVALID_PACKET;
1860     }
1861     if (rc) /* one of the MPIs were bad */
1862     goto leave;
1863     sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1864     sk->protect.sha1chk = 0;
1865     if( sk->protect.algo ) {
1866     sk->is_protected = 1;
1867     sk->protect.s2k.count = 0;
1868     if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1869     if( pktlen < 3 ) {
1870     rc = G10ERR_INVALID_PACKET;
1871     goto leave;
1872     }
1873     sk->protect.sha1chk = (sk->protect.algo == 254);
1874     sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1875     /* Note that a sk->protect.algo > 110 is illegal, but
1876     I'm not erroring on it here as otherwise there
1877     would be no way to delete such a key. */
1878     sk->protect.s2k.mode = gpg_iobuf_get_noeof(inp); pktlen--;
1879     sk->protect.s2k.hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1880     /* check for the special GNU extension */
1881     if( is_v4 && sk->protect.s2k.mode == 101 ) {
1882     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1883     temp[i] = gpg_iobuf_get_noeof(inp);
1884     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1885     if( list_mode )
1886     printf( "\tunknown S2K %d\n",
1887     sk->protect.s2k.mode );
1888     rc = G10ERR_INVALID_PACKET;
1889     goto leave;
1890     }
1891     /* here we know that it is a gnu extension
1892     * What follows is the GNU protection mode:
1893     * All values have special meanings
1894     * and they are mapped in the mode with a base of 1000.
1895     */
1896     sk->protect.s2k.mode = 1000 + temp[3];
1897     }
1898     switch( sk->protect.s2k.mode ) {
1899     case 1:
1900     case 3:
1901     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1902     temp[i] = gpg_iobuf_get_noeof(inp);
1903     memcpy(sk->protect.s2k.salt, temp, 8 );
1904     break;
1905     }
1906     switch( sk->protect.s2k.mode ) {
1907     case 0: if( list_mode ) printf( "\tsimple S2K" );
1908     break;
1909     case 1: if( list_mode ) printf( "\tsalted S2K" );
1910     break;
1911     case 3: if( list_mode ) printf( "\titer+salt S2K" );
1912     break;
1913     case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
1914     break;
1915     case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1916     break;
1917     default:
1918     if( list_mode )
1919     printf( "\tunknown %sS2K %d\n",
1920     sk->protect.s2k.mode < 1000? "":"GNU ",
1921     sk->protect.s2k.mode );
1922     rc = G10ERR_INVALID_PACKET;
1923     goto leave;
1924     }
1925    
1926     if( list_mode ) {
1927     printf(", algo: %d,%s hash: %d",
1928     sk->protect.algo,
1929     sk->protect.sha1chk?" SHA1 protection,"
1930     :" simple checksum,",
1931     sk->protect.s2k.hash_algo );
1932     if( sk->protect.s2k.mode == 1
1933     || sk->protect.s2k.mode == 3 ) {
1934     printf(", salt: ");
1935     for(i=0; i < 8; i++ )
1936     printf("%02x", sk->protect.s2k.salt[i]);
1937     }
1938     putchar('\n');
1939     }
1940    
1941     if( sk->protect.s2k.mode == 3 ) {
1942     if( pktlen < 1 ) {
1943     rc = G10ERR_INVALID_PACKET;
1944     goto leave;
1945     }
1946     sk->protect.s2k.count = gpg_iobuf_get(inp);
1947     pktlen--;
1948     if( list_mode )
1949     printf("\tprotect count: %lu\n",
1950     (ulong)sk->protect.s2k.count);
1951     }
1952     else if( sk->protect.s2k.mode == 1002 ) {
1953     /* Read the serial number. */
1954     if (pktlen < 1) {
1955     rc = G10ERR_INVALID_PACKET;
1956     goto leave;
1957     }
1958     snlen = gpg_iobuf_get (inp);
1959     pktlen--;
1960     if (pktlen < snlen || snlen == -1) {
1961     rc = G10ERR_INVALID_PACKET;
1962     goto leave;
1963     }
1964     }
1965     }
1966     /* Note that a sk->protect.algo > 110 is illegal, but I'm
1967     not erroring on it here as otherwise there would be no
1968     way to delete such a key. */
1969     else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1970     sk->protect.s2k.mode = 0;
1971     sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1972     if( list_mode )
1973     printf( "\tprotect algo: %d (hash algo: %d)\n",
1974     sk->protect.algo, sk->protect.s2k.hash_algo );
1975     }
1976     /* It is really ugly that we don't know the size
1977     * of the IV here in cases we are not aware of the algorithm.
1978     * so a
1979     * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1980     * won't work. The only solution I see is to hardwire it here.
1981     * NOTE: if you change the ivlen above 16, don't forget to
1982     * enlarge temp.
1983     */
1984     switch( sk->protect.algo ) {
1985     case 7: case 8: case 9: /* reserved for AES */
1986     case 10: /* Twofish */
1987     sk->protect.ivlen = 16;
1988     break;
1989     default:
1990     sk->protect.ivlen = 8;
1991     }
1992     if( sk->protect.s2k.mode == 1001 )
1993     sk->protect.ivlen = 0;
1994     else if( sk->protect.s2k.mode == 1002 )
1995     sk->protect.ivlen = snlen < 16? snlen : 16;
1996    
1997     if( pktlen < sk->protect.ivlen ) {
1998     rc = G10ERR_INVALID_PACKET;
1999     goto leave;
2000     }
2001     for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
2002     temp[i] = gpg_iobuf_get_noeof(inp);
2003     if( list_mode ) {
2004     printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
2005     : "\tprotect IV: ");
2006     for(i=0; i < sk->protect.ivlen; i++ )
2007     printf(" %02x", temp[i] );
2008     putchar('\n');
2009     }
2010     memcpy( sk->protect.iv, temp, sk->protect.ivlen );
2011     }
2012     else
2013     sk->is_protected = 0;
2014     /* It does not make sense to read it into secure memory.
2015     * If the user is so careless, not to protect his secret key,
2016     * we can assume, that he operates an open system :=(.
2017     * So we put the key into secure memory when we unprotect it. */
2018     if( sk->protect.s2k.mode == 1001
2019     || sk->protect.s2k.mode == 1002 ) {
2020     /* better set some dummy stuff here */
2021     sk->skey[npkey] = mpi_set_opaque(NULL, strdup("dummydata"), 10);
2022     pktlen = 0;
2023     }
2024     else if( is_v4 && sk->is_protected ) {
2025     /* ugly; the length is encrypted too, so we read all
2026     * stuff up to the end of the packet into the first
2027     * skey element */
2028     sk->skey[npkey] = mpi_set_opaque(NULL,
2029     read_rest(inp, pktlen), pktlen );
2030     pktlen = 0;
2031     if( list_mode ) {
2032     printf("\tencrypted stuff follows\n");
2033     }
2034     }
2035     else { /* v3 method: the mpi length is not encrypted */
2036     for(i=npkey; i < nskey; i++ ) {
2037     n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2038     if( sk->is_protected && sk->skey[i] )
2039     mpi_set_protect_flag(sk->skey[i]);
2040     if( list_mode ) {
2041     printf( "\tskey[%d]: ", i);
2042     if( sk->is_protected )
2043     printf( "[encrypted]\n");
2044     else {
2045     mpi_print(stdout, sk->skey[i], mpi_print_mode );
2046     putchar('\n');
2047     }
2048     }
2049     if (!sk->skey[i])
2050     rc = G10ERR_INVALID_PACKET;
2051     }
2052     if (rc)
2053     goto leave;
2054    
2055     sk->csum = read_16(inp); pktlen -= 2;
2056     if( list_mode ) {
2057     printf("\tchecksum: %04hx\n", sk->csum);
2058     }
2059     }
2060     }
2061     else {
2062     PKT_public_key *pk = pkt->pkt.public_key;
2063    
2064     if( !npkey ) {
2065     pk->pkey[0] = mpi_set_opaque( NULL,
2066     read_rest(inp, pktlen), pktlen );
2067     pktlen = 0;
2068     goto leave;
2069     }
2070    
2071     for(i=0; i < npkey; i++ ) {
2072     n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2073     if( list_mode ) {
2074     printf( "\tpkey[%d]: ", i);
2075     mpi_print(stdout, pk->pkey[i], mpi_print_mode );
2076     putchar('\n');
2077     }
2078     if (!pk->pkey[i])
2079     rc = G10ERR_INVALID_PACKET;
2080     }
2081     if (rc)
2082     goto leave;
2083     }
2084    
2085     leave:
2086     skip_rest(inp, pktlen);
2087     return rc;
2088     }
2089    
2090     /* Attribute subpackets have the same format as v4 signature
2091     subpackets. This is not part of OpenPGP, but is done in several
2092     versions of PGP nevertheless. */
2093     int
2094     parse_attribute_subpkts(PKT_user_id *uid)
2095     {
2096     size_t n;
2097     int count=0;
2098     struct user_attribute *attribs=NULL;
2099     const byte *buffer=uid->attrib_data;
2100     int buflen=uid->attrib_len;
2101     byte type;
2102    
2103     safe_free(uid->attribs);
2104    
2105     while(buflen) {
2106     n = *buffer++; buflen--;
2107     if( n == 255 ) { /* 4 byte length header */
2108     if( buflen < 4 )
2109     goto too_short;
2110     n = (buffer[0] << 24) | (buffer[1] << 16)
2111     | (buffer[2] << 8) | buffer[3];
2112     buffer += 4;
2113     buflen -= 4;
2114     }
2115     else if( n >= 192 ) { /* 2 byte special encoded length header */
2116     if( buflen < 2 )
2117     goto too_short;
2118     n = (( n - 192 ) << 8) + *buffer + 192;
2119     buffer++;
2120     buflen--;
2121     }
2122     if( buflen < n )
2123     goto too_short;
2124    
2125     attribs=realloc(attribs,(count+1)*sizeof(struct user_attribute));
2126     memset(&attribs[count],0,sizeof(struct user_attribute));
2127    
2128     type=*buffer;
2129     buffer++;
2130     buflen--;
2131     n--;
2132    
2133     attribs[count].type=type;
2134     attribs[count].data=buffer;
2135     attribs[count].len=n;
2136     buffer+=n;
2137     buflen-=n;
2138     count++;
2139     }
2140    
2141     uid->attribs=attribs;
2142     uid->numattribs=count;
2143     return count;
2144    
2145     too_short:
2146     printf("buffer shorter than attribute subpacket\n");
2147     uid->attribs=attribs;
2148     uid->numattribs=count;
2149     return count;
2150     }
2151    
2152     static void
2153     setup_user_id(PACKET *packet)
2154     {
2155     packet->pkt.user_id->ref = 1;
2156     packet->pkt.user_id->attribs = NULL;
2157     packet->pkt.user_id->attrib_data = NULL;
2158     packet->pkt.user_id->attrib_len = 0;
2159     packet->pkt.user_id->is_primary = 0;
2160     packet->pkt.user_id->is_revoked = 0;
2161     packet->pkt.user_id->is_expired = 0;
2162     packet->pkt.user_id->expiredate = 0;
2163     packet->pkt.user_id->created = 0;
2164     packet->pkt.user_id->help_key_usage = 0;
2165     packet->pkt.user_id->help_key_expire = 0;
2166     packet->pkt.user_id->prefs = NULL;
2167     }
2168    
2169     static int
2170     parse_user_id( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2171     {
2172     byte *p;
2173    
2174     packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + pktlen);
2175     packet->pkt.user_id->len = pktlen;
2176    
2177     setup_user_id(packet);
2178    
2179     p = packet->pkt.user_id->name;
2180     for( ; pktlen; pktlen--, p++ )
2181     *p = gpg_iobuf_get_noeof(inp);
2182     *p = 0;
2183    
2184     if( list_mode ) {
2185     int n = packet->pkt.user_id->len;
2186     printf(":user ID packet: \"");
2187     /* fixme: Hey why don't we replace this with print_string?? */
2188     for(p=packet->pkt.user_id->name; n; p++, n-- ) {
2189     if( *p >= ' ' && *p <= 'z' )
2190     putchar(*p);
2191     else
2192     printf("\\x%02x", *p );
2193     }
2194     printf("\"\n");
2195     }
2196     return 0;
2197     }
2198    
2199     /* Returns 0 for error, 1 for valid */
2200     int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
2201     {
2202     u16 headerlen;
2203    
2204     if(attr->len<3)
2205     return 0;
2206    
2207     /* For historical reasons (i.e. "oops!"), the header length is
2208     little endian. */
2209     headerlen=(attr->data[1]<<8) | attr->data[0];
2210    
2211     if(headerlen>attr->len)
2212     return 0;
2213    
2214     if(type && attr->len>=4)
2215     {
2216     if(attr->data[2]==1) /* header version 1 */
2217     *type=attr->data[3];
2218     else
2219     *type=0;
2220     }
2221    
2222     *len=attr->len-headerlen;
2223    
2224     if(*len==0)
2225     return 0;
2226    
2227     return 1;
2228     }
2229    
2230     /* style==0 for extension, 1 for name, 2 for MIME type. Remember that
2231     the "name" style string could be used in a user ID name field, so
2232     make sure it is not too big (see
2233     parse-packet.c:parse_attribute). */
2234     char *image_type_to_string(byte type,int style)
2235     {
2236     char *string;
2237    
2238     switch(type) {
2239     case 1: /* jpeg */
2240     if(style==0)
2241     string="jpg";
2242     else if(style==1)
2243     string="jpeg";
2244     else
2245     string="image/jpeg";
2246     break;
2247    
2248     default:
2249     if(style==0)
2250     string="bin";
2251     else if(style==1)
2252     string="unknown";
2253     else
2254     string="image/x-unknown";
2255     break;
2256     }
2257    
2258     return string;
2259     }
2260    
2261     void
2262     make_attribute_uidname(PKT_user_id *uid)
2263     {
2264     if(uid->numattribs<=0)
2265     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
2266     else if(uid->numattribs>1)
2267     sprintf(uid->name,"[%d attributes of size %lu]",
2268     uid->numattribs,uid->attrib_len);
2269     else {
2270     /* Only one attribute, so list it as the "user id" */
2271    
2272     if(uid->attribs->type==ATTRIB_IMAGE) {
2273     u32 len;
2274     byte type;
2275    
2276     if(parse_image_header(uid->attribs,&type,&len))
2277     sprintf(uid->name,"[%s image of size %lu]",
2278     image_type_to_string(type,1),(ulong)len);
2279     else
2280     sprintf(uid->name,"[invalid image]");
2281     }
2282     else
2283     sprintf(uid->name,"[unknown attribute of size %lu]",
2284     (ulong)uid->attribs->len);
2285     }
2286    
2287     uid->len = strlen(uid->name);
2288     }
2289    
2290     static int
2291     parse_attribute( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2292     {
2293     byte *p;
2294    
2295     packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + 70);
2296    
2297     setup_user_id(packet);
2298    
2299     packet->pkt.user_id->attrib_data = malloc(pktlen);
2300     packet->pkt.user_id->attrib_len = pktlen;
2301     p = packet->pkt.user_id->attrib_data;
2302     for( ; pktlen; pktlen--, p++ )
2303     *p = gpg_iobuf_get_noeof(inp);
2304    
2305     /* Now parse out the individual attribute subpackets. This is
2306     somewhat pointless since there is only one currently defined
2307     attribute type (jpeg), but it is correct by the spec. */
2308     parse_attribute_subpkts(packet->pkt.user_id);
2309    
2310     make_attribute_uidname(packet->pkt.user_id);
2311    
2312     if( list_mode ) {
2313     printf(":attribute packet: %s\n", packet->pkt.user_id->name );
2314     }
2315     return 0;
2316     }
2317    
2318    
2319     static int
2320     parse_comment( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2321     {
2322     byte *p;
2323    
2324     packet->pkt.comment = malloc(sizeof *packet->pkt.comment + pktlen - 1);
2325     packet->pkt.comment->len = pktlen;
2326     p = packet->pkt.comment->data;
2327     for( ; pktlen; pktlen--, p++ )
2328     *p = gpg_iobuf_get_noeof(inp);
2329    
2330     if( list_mode ) {
2331     int n = packet->pkt.comment->len;
2332     printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2333     "OpenPGP draft " : "" );
2334     for(p=packet->pkt.comment->data; n; p++, n-- ) {
2335     if( *p >= ' ' && *p <= 'z' )
2336     putchar(*p);
2337     else
2338     printf("\\x%02x", *p );
2339     }
2340     printf("\"\n");
2341     }
2342     return 0;
2343     }
2344    
2345    
2346     static void
2347     parse_trust( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2348     {
2349     int c;
2350    
2351     if (pktlen) {
2352     c = gpg_iobuf_get_noeof(inp);
2353     pktlen--;
2354     pkt->pkt.ring_trust = malloc( sizeof *pkt->pkt.ring_trust );
2355     pkt->pkt.ring_trust->trustval = c;
2356     pkt->pkt.ring_trust->sigcache = 0;
2357     if (!c && pktlen==1) {
2358     c = gpg_iobuf_get_noeof (inp);
2359     pktlen--;
2360     /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2361     if ( !(c & 0x80) )
2362     pkt->pkt.ring_trust->sigcache = c;
2363     }
2364     if( list_mode )
2365     printf(":trust packet: flag=%02x sigcache=%02x\n",
2366     pkt->pkt.ring_trust->trustval,
2367     pkt->pkt.ring_trust->sigcache);
2368     }
2369     else {
2370     if( list_mode )
2371     printf(":trust packet: empty\n");
2372     }
2373     skip_rest (inp, pktlen);
2374     }
2375    
2376    
2377     static int
2378     parse_plaintext( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2379     PACKET *pkt, int new_ctb )
2380     {
2381     int rc = 0;
2382     int mode, namelen, partial=0;
2383     PKT_plaintext *pt;
2384     byte *p;
2385     int c, i;
2386    
2387     if( pktlen && pktlen < 6 ) {
2388     printf("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2389     rc = G10ERR_INVALID_PACKET;
2390     goto leave;
2391     }
2392     /* A packet length of zero indicates partial body length. A zero
2393     data length isn't a zero length packet due to the header (mode,
2394     name, etc), so this is accurate. */
2395     if(pktlen==0)
2396     partial=1;
2397     mode = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2398     namelen = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2399     pt = pkt->pkt.plaintext = malloc(sizeof *pkt->pkt.plaintext + namelen -1);
2400     pt->new_ctb = new_ctb;
2401     pt->mode = mode;
2402     pt->namelen = namelen;
2403     pt->is_partial = partial;
2404     if( pktlen ) {
2405     for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2406     pt->name[i] = gpg_iobuf_get_noeof(inp);
2407     }
2408     else {
2409     for( i=0; i < namelen; i++ )
2410     if( (c=gpg_iobuf_get(inp)) == -1 )
2411     break;
2412     else
2413     pt->name[i] = c;
2414     }
2415     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2416     pt->len = pktlen;
2417     pt->buf = inp;
2418     pktlen = 0;
2419    
2420     if( list_mode ) {
2421     printf(":literal data packet:\n"
2422     "\tmode %c, created %lu, name=\"",
2423     mode >= ' ' && mode <'z'? mode : '?',
2424     (ulong)pt->timestamp );
2425     for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2426     if( *p >= ' ' && *p <= 'z' )
2427     putchar(*p);
2428     else
2429     printf("\\x%02x", *p );
2430     }
2431     printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2432     }
2433    
2434     leave:
2435     return rc;
2436     }
2437    
2438    
2439     static int
2440     parse_compressed( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2441     PACKET *pkt, int new_ctb )
2442     {
2443     PKT_compressed *zd;
2444    
2445     /* pktlen is here 0, but data follows
2446     * (this should be the last object in a file or
2447     * the compress algorithm should know the length)
2448     */
2449     zd = pkt->pkt.compressed = malloc(sizeof *pkt->pkt.compressed );
2450     zd->algorithm = gpg_iobuf_get_noeof(inp);
2451     zd->len = 0; /* not used */
2452     zd->new_ctb = new_ctb;
2453     zd->buf = inp;
2454     if( list_mode )
2455     printf(":compressed packet: algo=%d\n", zd->algorithm);
2456     return 0;
2457     }
2458    
2459    
2460     static int
2461     parse_encrypted( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2462     PACKET *pkt, int new_ctb )
2463     {
2464     int rc = 0;
2465     PKT_encrypted *ed;
2466     unsigned long orig_pktlen = pktlen;
2467    
2468     ed = pkt->pkt.encrypted = malloc(sizeof *pkt->pkt.encrypted );
2469     ed->len = pktlen;
2470     /* we don't know the extralen which is (cipher_blocksize+2)
2471     because the algorithm ist not specified in this packet.
2472     However, it is only important to know this for some sanity
2473     checks on the packet length - it doesn't matter that we can't
2474     do it */
2475     ed->extralen = 0;
2476     ed->buf = NULL;
2477     ed->new_ctb = new_ctb;
2478     ed->mdc_method = 0;
2479     if( pkttype == PKT_ENCRYPTED_MDC ) {
2480     /* fixme: add some pktlen sanity checks */
2481     int version;
2482    
2483     version = gpg_iobuf_get_noeof(inp);
2484     if (orig_pktlen)
2485     pktlen--;
2486     if( version != 1 ) {
2487     printf("encrypted_mdc packet with unknown version %d\n",
2488     version);
2489     /*skip_rest(inp, pktlen); should we really do this? */
2490     rc = G10ERR_INVALID_PACKET;
2491     goto leave;
2492     }
2493     ed->mdc_method = DIGEST_ALGO_SHA1;
2494     }
2495     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2496     printf("packet(%d) too short\n", pkttype);
2497     rc = G10ERR_INVALID_PACKET;
2498     skip_rest(inp, pktlen);
2499     goto leave;
2500     }
2501     if( list_mode ) {
2502     if( orig_pktlen )
2503     printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2504     else
2505     printf(":encrypted data packet:\n\tlength: unknown\n");
2506     if( ed->mdc_method )
2507     printf("\tmdc_method: %d\n", ed->mdc_method );
2508     }
2509    
2510     ed->buf = inp;
2511     pktlen = 0;
2512    
2513     leave:
2514     return rc;
2515     }
2516    
2517    
2518     static int
2519     parse_mdc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2520     PACKET *pkt, int new_ctb )
2521     {
2522     int rc = 0;
2523     PKT_mdc *mdc;
2524     byte *p;
2525    
2526     mdc = pkt->pkt.mdc= malloc(sizeof *pkt->pkt.mdc );
2527     if( list_mode )
2528     printf(":mdc packet: length=%lu\n", pktlen);
2529     if( !new_ctb || pktlen != 20 ) {
2530     printf("mdc_packet with invalid encoding\n");
2531     rc = G10ERR_INVALID_PACKET;
2532     goto leave;
2533     }
2534     p = mdc->hash;
2535     for( ; pktlen; pktlen--, p++ )
2536     *p = gpg_iobuf_get_noeof(inp);
2537    
2538     leave:
2539     return rc;
2540     }
2541    
2542    
2543     /*
2544     * This packet is internally generated by PGG (by armor.c) to
2545     * transfer some information to the lower layer. To make sure that
2546     * this packet is really a GPG faked one and not one comming from outside,
2547     * we first check that tehre is a unique tag in it.
2548     * The format of such a control packet is:
2549     * n byte session marker
2550     * 1 byte control type CTRLPKT_xxxxx
2551     * m byte control data
2552     */
2553    
2554     /* Return a string which is used as a kind of process ID */
2555     const byte *
2556     get_session_marker( size_t *rlen )
2557     {
2558     static byte marker[SIZEOF_UNSIGNED_LONG*2];
2559     static int initialized;
2560    
2561     if ( !initialized ) {
2562     volatile ulong aa, bb; /* we really want the uninitialized value */
2563     ulong a, b;
2564    
2565     initialized = 1;
2566     /* also this marker is guessable it is not easy to use this
2567     * for a faked control packet because an attacker does not
2568     * have enough control about the time the verification does
2569     * take place. Of course, we can add just more random but
2570     * than we need the random generator even for verification
2571     * tasks - which does not make sense. */
2572     a = aa ^ (ulong)getpid();
2573     b = bb ^ (ulong)time(NULL);
2574     memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
2575     memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
2576     }
2577     *rlen = sizeof(marker);
2578     return marker;
2579     }
2580    
2581     static int
2582     parse_gpg_control( gpg_iobuf_t inp,
2583     int pkttype, unsigned long pktlen, PACKET *packet )
2584     {
2585     byte *p;
2586     const byte *sesmark;
2587     size_t sesmarklen;
2588     int i;
2589    
2590     if ( list_mode )
2591     printf(":packet 63: length %lu ", pktlen);
2592    
2593     sesmark = get_session_marker ( &sesmarklen );
2594     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2595     goto skipit;
2596     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2597     if ( sesmark[i] != gpg_iobuf_get_noeof(inp) )
2598     goto skipit;
2599     }
2600     if ( list_mode )
2601     puts ("- gpg control packet");
2602    
2603     packet->pkt.gpg_control = malloc(sizeof *packet->pkt.gpg_control
2604     + pktlen - 1);
2605     packet->pkt.gpg_control->control = gpg_iobuf_get_noeof(inp); pktlen--;
2606     packet->pkt.gpg_control->datalen = pktlen;
2607     p = packet->pkt.gpg_control->data;
2608     for( ; pktlen; pktlen--, p++ )
2609     *p = gpg_iobuf_get_noeof(inp);
2610    
2611     return 0;
2612    
2613     skipit:
2614     if ( list_mode ) {
2615     int c;
2616    
2617     i=0;
2618     printf("- private (rest length %lu)\n", pktlen);
2619     if( gpg_iobuf_in_block_mode(inp) ) {
2620     while( (c=gpg_iobuf_get(inp)) != -1 )
2621     dump_hex_line(c, &i);
2622     }
2623     else {
2624     for( ; pktlen; pktlen-- )
2625     dump_hex_line(gpg_iobuf_get(inp), &i);
2626     }
2627     putchar('\n');
2628     }
2629     skip_rest(inp,pktlen);
2630     return G10ERR_INVALID_PACKET;
2631     }
2632    
2633    
2634     u32
2635     gpg_keyid_from_pk( PKT_public_key * pk, byte *fprint )
2636     {
2637     gpg_md_t md;
2638     int npkey, pktlen, i;
2639     const byte *mdbuf;
2640    
2641     if( pk->version == 3 && pk->pubkey_algo == PUBKEY_ALGO_RSA )
2642     return pk->pkey[0]->d[0];
2643     else {
2644     md = gpg_md_open( DIGEST_ALGO_SHA1 );
2645     gpg_md_putc( md, 0x99 );
2646     npkey = pubkey_get_npkey( pk->pubkey_algo );
2647     pktlen = 6;
2648     for( i = 0 ; i <npkey; i++ )
2649     pktlen = pktlen + 2 + pk->pkey[i]->alloced;
2650     gpg_md_putc( md, pktlen>>8 );
2651     gpg_md_putc( md, pktlen );
2652     gpg_md_putc( md, 4 );
2653     gpg_md_putc( md, pk->timestamp >> 24 );
2654     gpg_md_putc( md, pk->timestamp >> 16 );
2655     gpg_md_putc( md, pk->timestamp >> 8 );
2656     gpg_md_putc( md, pk->timestamp );
2657     gpg_md_putc( md, pk->pubkey_algo );
2658     for( i=0; i <npkey; i++ ) {
2659     const u32 * d = pk->pkey[i]->d;
2660     int nbits = pk->pkey[i]->nbits,
2661     n = pk->pkey[i]->alloced;
2662     gpg_md_putc( md, nbits >> 8 );
2663     gpg_md_putc( md, nbits );
2664     n = n>4? n/4 : n;
2665     while( n-- ) {
2666     if( pk->pkey[i]->alloced > 3 )
2667     gpg_md_putc( md, d[n] >> 24 );
2668     if( pk->pkey[i]->alloced > 2 )
2669     gpg_md_putc( md, d[n] >> 16 );
2670     if( pk->pkey[i]->alloced > 1 )
2671     gpg_md_putc( md, d[n] >> 8 );
2672     if( pk->pkey[i]->alloced > 0 )
2673     gpg_md_putc( md, d[n] );
2674     }
2675     }
2676     gpg_md_final( md );
2677     mdbuf = gpg_md_read( md );
2678     }
2679     if( mdbuf && fprint )
2680     memcpy( fprint, mdbuf, 20 );
2681     return mdbuf? mdbuf[16] << 24 | mdbuf[17] << 16 | mdbuf[18] << 8 | mdbuf[19] : 0;
2682     }
2683    
2684    
2685     u32
2686     gpg_keyid_from_sk( PKT_secret_key * sk, byte *fprint )
2687     {
2688     PKT_public_key pk;
2689     int npkey = pubkey_get_npkey( sk->pubkey_algo );
2690     int i;
2691    
2692     pk.pubkey_algo = sk->pubkey_algo;
2693     pk.version = sk->version;
2694     pk.timestamp = sk->timestamp;
2695     pk.expiredate = sk->expiredate;
2696     pk.pubkey_algo = sk->pubkey_algo;
2697     for( i=0; i < npkey; i++ )
2698     pk.pkey[i] = sk->skey[i];
2699     return gpg_keyid_from_pk( &pk, fprint );
2700     }
2701    
2702    
2703     /****************
2704     * Read the next keyblock from stream A.
2705     * PENDING_PKT should be initialzed to NULL
2706     * and not chnaged form the caller.
2707     * Retunr: 0 = okay, -1 no more blocks or another errorcode.
2708     */
2709     int
2710     gpg_read_keyblock( gpg_iobuf_t a, PACKET **pending_pkt, gpg_kbnode_t *ret_root )
2711     {
2712     int rc;
2713     PACKET *pkt;
2714     gpg_kbnode_t root = NULL;
2715     int in_cert;
2716    
2717     if( *pending_pkt ) {
2718     root = gpg_new_kbnode( *pending_pkt );
2719     *pending_pkt = NULL;
2720     in_cert = 1;
2721     }
2722     else
2723     in_cert = 0;
2724     pkt = malloc( sizeof *pkt );
2725     gpg_init_packet(pkt);
2726     while( (rc=gpg_parse_packet(a, pkt)) != -1 ) {
2727     if( rc ) { /* ignore errors */
2728     if( rc != G10ERR_UNKNOWN_PACKET ) {
2729     printf("read_block: read error: %d\n", rc );
2730     rc = G10ERR_INV_KEYRING;
2731     goto ready;
2732     }
2733     gpg_free_packet( pkt );
2734     gpg_init_packet(pkt);
2735     continue;
2736     }
2737    
2738     if( !root && pkt->pkttype == PKT_SIGNATURE
2739     && pkt->pkt.signature->sig_class == 0x20 ) {
2740     /* this is a revocation certificate which is handled
2741     * in a special way */
2742     root = gpg_new_kbnode( pkt );
2743     pkt = NULL;
2744     goto ready;
2745     }
2746    
2747     /* make a linked list of all packets */
2748     switch( pkt->pkttype ) {
2749     case PKT_RING_TRUST:
2750     /* skip those packets */
2751     gpg_free_packet( pkt );
2752     gpg_init_packet(pkt);
2753     break;
2754    
2755     case PKT_PUBLIC_KEY:
2756     case PKT_SECRET_KEY:
2757     if( in_cert ) { /* store this packet */
2758     *pending_pkt = pkt;
2759     pkt = NULL;
2760     goto ready;
2761     }
2762     in_cert = 1;
2763     default:
2764     if( in_cert ) {
2765     if( !root )
2766     root = gpg_new_kbnode( pkt );
2767     else
2768     gpg_add_kbnode( root, gpg_new_kbnode( pkt ) );
2769     pkt = malloc( sizeof *pkt );
2770     }
2771     gpg_init_packet(pkt);
2772     break;
2773     }
2774     }
2775     ready:
2776     if( rc == -1 && root )
2777     rc = 0;
2778    
2779     if( rc )
2780     gpg_release_kbnode( root );
2781     else
2782     *ret_root = root;
2783     gpg_free_packet( pkt );
2784     free( pkt );
2785     return rc;
2786     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26