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