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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26