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