Ported changes from 1.4.
[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
1676     (void)hdr;
1677
1678     version = iobuf_get_noeof(inp); pktlen--;
1679     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1680         /* early versions of G10 use old PGP comments packets;
1681          * luckily all those comments are started by a hash */
1682         if( list_mode ) {
1683             fprintf (listfp, ":rfc1991 comment packet: \"" );
1684             for( ; pktlen; pktlen-- ) {
1685                 int c;
1686                 c = iobuf_get_noeof(inp);
1687                 if( c >= ' ' && c <= 'z' )
1688                     putc (c, listfp);
1689                 else
1690                     fprintf (listfp, "\\x%02x", c );
1691             }
1692             fprintf (listfp, "\"\n");
1693         }
1694         iobuf_skip_rest(inp, pktlen, 0);
1695         return 0;
1696     }
1697     else if( version == 4 )
1698         is_v4=1;
1699     else if( version != 2 && version != 3 ) {
1700         log_error("packet(%d) with unknown version %d\n", pkttype, version);
1701         rc = gpg_error (GPG_ERR_INV_PACKET);
1702         goto leave;
1703     }
1704
1705     if( pktlen < 11 ) {
1706         log_error("packet(%d) too short\n", pkttype);
1707         rc = gpg_error (GPG_ERR_INV_PACKET);
1708         goto leave;
1709     }
1710
1711     timestamp = read_32(inp); pktlen -= 4;
1712     if( is_v4 ) {
1713         expiredate = 0; /* have to get it from the selfsignature */
1714         max_expiredate = 0;
1715     }
1716     else {
1717         unsigned short ndays;
1718         ndays = read_16(inp); pktlen -= 2;
1719         if( ndays )
1720             expiredate = timestamp + ndays * 86400L;
1721         else
1722             expiredate = 0;
1723
1724         max_expiredate=expiredate;
1725     }
1726     algorithm = iobuf_get_noeof(inp); pktlen--;
1727     if( list_mode )
1728         fprintf (listfp, ":%s key packet:\n"
1729                "\tversion %d, algo %d, created %lu, expires %lu\n",
1730                 pkttype == PKT_PUBLIC_KEY? "public" :
1731                 pkttype == PKT_SECRET_KEY? "secret" :
1732                 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1733                 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1734                 version, algorithm, timestamp, expiredate );
1735
1736     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY )  {
1737         PKT_secret_key *sk = pkt->pkt.secret_key;
1738
1739         sk->timestamp = timestamp;
1740         sk->expiredate = expiredate;
1741         sk->max_expiredate = max_expiredate;
1742         sk->hdrbytes = hdrlen;
1743         sk->version = version;
1744         sk->is_primary = pkttype == PKT_SECRET_KEY;
1745         sk->pubkey_algo = algorithm;
1746         sk->req_usage = 0; 
1747         sk->pubkey_usage = 0; /* not yet used */
1748     }
1749     else {
1750         PKT_public_key *pk = pkt->pkt.public_key;
1751
1752         pk->timestamp = timestamp;
1753         pk->expiredate = expiredate;
1754         pk->max_expiredate = max_expiredate;
1755         pk->hdrbytes    = hdrlen;
1756         pk->version     = version;
1757         pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1758         pk->pubkey_algo = algorithm;
1759         pk->req_usage = 0; 
1760         pk->pubkey_usage = 0; /* not yet used */
1761         pk->is_revoked = 0;
1762         pk->is_disabled = 0;
1763         pk->keyid[0] = 0;
1764         pk->keyid[1] = 0;
1765     }
1766     nskey = pubkey_get_nskey( algorithm );
1767     npkey = pubkey_get_npkey( algorithm );
1768     if( !npkey ) {
1769         if( list_mode )
1770             fprintf (listfp, "\tunknown algorithm %d\n", algorithm );
1771         unknown_pubkey_warning( algorithm );
1772     }
1773
1774
1775     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1776         PKT_secret_key *sk = pkt->pkt.secret_key;
1777         byte temp[16];
1778         size_t snlen = 0;
1779
1780         if( !npkey ) {
1781             sk->skey[0] = gcry_mpi_set_opaque (NULL, read_rest(inp, pktlen, 0),
1782                                                pktlen*8 );
1783             pktlen = 0;
1784             goto leave;
1785         }
1786
1787         for(i=0; i < npkey; i++ ) {
1788             n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1789             if( list_mode ) {
1790                 fprintf (listfp,   "\tskey[%d]: ", i);
1791                 mpi_print(listfp, sk->skey[i], mpi_print_mode  );
1792                 putc ('\n', listfp);
1793             }
1794             if (!sk->skey[i])
1795                 rc = G10ERR_INVALID_PACKET;
1796         }
1797         if (rc) /* one of the MPIs were bad */
1798             goto leave;
1799         sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1800         sk->protect.sha1chk = 0;
1801         if( sk->protect.algo ) {
1802             sk->is_protected = 1;
1803             sk->protect.s2k.count = 0;
1804             if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1805                 if( pktlen < 3 ) {
1806                     rc = G10ERR_INVALID_PACKET;
1807                     goto leave;
1808                 }
1809                 sk->protect.sha1chk = (sk->protect.algo == 254);
1810                 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1811                 /* Note that a sk->protect.algo > 110 is illegal, but
1812                    I'm not erroring on it here as otherwise there
1813                    would be no way to delete such a key. */
1814                 sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
1815                 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1816                 /* check for the special GNU extension */
1817                 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1818                     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1819                         temp[i] = iobuf_get_noeof(inp);
1820                     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1821                         if( list_mode )
1822                             fprintf (listfp,   "\tunknown S2K %d\n",
1823                                                 sk->protect.s2k.mode );
1824                         rc = G10ERR_INVALID_PACKET;
1825                         goto leave;
1826                     }
1827                     /* here we know that it is a gnu extension
1828                      * What follows is the GNU protection mode:
1829                      * All values have special meanings
1830                      * and they are mapped in the mode with a base of 1000.
1831                      */
1832                     sk->protect.s2k.mode = 1000 + temp[3];
1833                 }
1834                 switch( sk->protect.s2k.mode ) {
1835                   case 1:
1836                   case 3:
1837                     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1838                         temp[i] = iobuf_get_noeof(inp);
1839                     memcpy(sk->protect.s2k.salt, temp, 8 );
1840                     break;
1841                 }
1842                 switch( sk->protect.s2k.mode ) {
1843                   case 0: if( list_mode ) fprintf (listfp, "\tsimple S2K" );
1844                     break;
1845                   case 1: if( list_mode ) fprintf (listfp, "\tsalted S2K" );
1846                     break;
1847                   case 3: if( list_mode ) fprintf (listfp, "\titer+salt S2K" );
1848                     break;
1849                   case 1001: if( list_mode ) fprintf (listfp,
1850                                                       "\tgnu-dummy S2K" );
1851                     break;
1852                   case 1002: if (list_mode) fprintf (listfp,
1853                                                   "\tgnu-divert-to-card S2K");
1854                     break;
1855                   default:
1856                     if( list_mode )
1857                         fprintf (listfp,   "\tunknown %sS2K %d\n",
1858                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1859                                                    sk->protect.s2k.mode );
1860                     rc = G10ERR_INVALID_PACKET;
1861                     goto leave;
1862                 }
1863
1864                 if( list_mode ) {
1865                     fprintf (listfp, ", algo: %d,%s hash: %d",
1866                                      sk->protect.algo,
1867                                      sk->protect.sha1chk?" SHA1 protection,"
1868                                                         :" simple checksum,",
1869                                      sk->protect.s2k.hash_algo );
1870                     if( sk->protect.s2k.mode == 1
1871                         || sk->protect.s2k.mode == 3 ) {
1872                         fprintf (listfp, ", salt: ");
1873                         for(i=0; i < 8; i++ )
1874                             fprintf (listfp, "%02x", sk->protect.s2k.salt[i]);
1875                     }
1876                     putc ('\n', listfp);
1877                 }
1878
1879                 if( sk->protect.s2k.mode == 3 ) {
1880                     if( pktlen < 1 ) {
1881                         rc = G10ERR_INVALID_PACKET;
1882                         goto leave;
1883                     }
1884                     sk->protect.s2k.count = iobuf_get(inp);
1885                     pktlen--;
1886                     if( list_mode )
1887                         fprintf (listfp, "\tprotect count: %lu\n",
1888                                             (ulong)sk->protect.s2k.count);
1889                 }
1890                 else if( sk->protect.s2k.mode == 1002 ) {
1891                     /* Read the serial number. */
1892                     if (pktlen < 1) {
1893                       rc = G10ERR_INVALID_PACKET;
1894                         goto leave;
1895                     }
1896                     snlen = iobuf_get (inp);
1897                     pktlen--;
1898                     if (pktlen < snlen || snlen == -1) {
1899                         rc = G10ERR_INVALID_PACKET;
1900                         goto leave;
1901                     }
1902                 }
1903             }
1904             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1905                not erroring on it here as otherwise there would be no
1906                way to delete such a key. */
1907             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1908                 sk->protect.s2k.mode = 0;
1909                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1910                 if( list_mode )
1911                     fprintf (listfp,   "\tprotect algo: %d  (hash algo: %d)\n",
1912                          sk->protect.algo, sk->protect.s2k.hash_algo );
1913             }
1914             /* It is really ugly that we don't know the size
1915              * of the IV here in cases we are not aware of the algorithm.
1916              * so a
1917              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1918              * won't work.  The only solution I see is to hardwire it.
1919              * NOTE: if you change the ivlen above 16, don't forget to
1920              * enlarge temp.
1921              */
1922             sk->protect.ivlen = openpgp_cipher_blocklen (sk->protect.algo);
1923             assert (sk->protect.ivlen <= sizeof (temp));
1924
1925             if( sk->protect.s2k.mode == 1001 )
1926                 sk->protect.ivlen = 0;
1927             else if( sk->protect.s2k.mode == 1002 )
1928                 sk->protect.ivlen = snlen < 16? snlen : 16;
1929
1930             if( pktlen < sk->protect.ivlen ) {
1931                 rc = G10ERR_INVALID_PACKET;
1932                 goto leave;
1933             }
1934             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1935                 temp[i] = iobuf_get_noeof(inp);
1936             if( list_mode ) {
1937                 fprintf (listfp,
1938                          sk->protect.s2k.mode == 1002? "\tserial-number: "
1939                                                      : "\tprotect IV: ");
1940                 for(i=0; i < sk->protect.ivlen; i++ )
1941                     fprintf (listfp, " %02x", temp[i] );
1942                 putc ('\n', listfp);
1943             }
1944             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1945         }
1946         else
1947             sk->is_protected = 0;
1948         /* It does not make sense to read it into secure memory.
1949          * If the user is so careless, not to protect his secret key,
1950          * we can assume, that he operates an open system :=(.
1951          * So we put the key into secure memory when we unprotect it. */
1952         if( sk->protect.s2k.mode == 1001 
1953             || sk->protect.s2k.mode == 1002 ) {
1954             /* better set some dummy stuff here */
1955             sk->skey[npkey] = gcry_mpi_set_opaque(NULL,
1956                                                   xstrdup("dummydata"), 10*8);
1957             pktlen = 0;
1958         }
1959         else if( is_v4 && sk->is_protected ) {
1960             /* ugly; the length is encrypted too, so we read all
1961              * stuff up to the end of the packet into the first
1962              * skey element */
1963             sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
1964                                                    read_rest(inp, pktlen, 0),
1965                                                    pktlen*8);
1966             pktlen = 0;
1967             if( list_mode ) {
1968                 fprintf (listfp, "\tencrypted stuff follows\n");
1969             }
1970         }
1971         else { /* v3 method: the mpi length is not encrypted */
1972             for(i=npkey; i < nskey; i++ ) {
1973                 if ( sk->is_protected ) {
1974                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1975                     if( list_mode ) 
1976                         fprintf (listfp,   "\tskey[%d]: [encrypted]\n", i);
1977                 }
1978                 else {
1979                     n = pktlen;
1980                     sk->skey[i] = mpi_read(inp, &n, 0 );
1981                     pktlen -=n;
1982                     if( list_mode ) {
1983                         fprintf (listfp,   "\tskey[%d]: ", i);
1984                         mpi_print(listfp, sk->skey[i], mpi_print_mode  );
1985                         putc ('\n', listfp);
1986                     }
1987                 }
1988
1989                 if (!sk->skey[i])
1990                     rc = G10ERR_INVALID_PACKET;
1991             }
1992             if (rc)
1993                 goto leave;
1994
1995             sk->csum = read_16(inp); pktlen -= 2;
1996             if( list_mode ) {
1997                 fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
1998             }
1999         }
2000     }
2001     else {
2002         PKT_public_key *pk = pkt->pkt.public_key;
2003
2004         if( !npkey ) {
2005             pk->pkey[0] = gcry_mpi_set_opaque ( NULL,
2006                                                 read_rest(inp, pktlen, 0),
2007                                                 pktlen*8 );
2008             pktlen = 0;
2009             goto leave;
2010         }
2011
2012         for(i=0; i < npkey; i++ ) {
2013             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2014             if( list_mode ) {
2015                 fprintf (listfp,   "\tpkey[%d]: ", i);
2016                 mpi_print(listfp, pk->pkey[i], mpi_print_mode  );
2017                 putc ('\n', listfp);
2018             }
2019             if (!pk->pkey[i])
2020                 rc = G10ERR_INVALID_PACKET;
2021         }
2022         if (rc)
2023             goto leave;
2024     }
2025
2026   leave:
2027     iobuf_skip_rest(inp, pktlen, 0);
2028     return rc;
2029 }
2030
2031 /* Attribute subpackets have the same format as v4 signature
2032    subpackets.  This is not part of OpenPGP, but is done in several
2033    versions of PGP nevertheless. */
2034 int
2035 parse_attribute_subpkts(PKT_user_id *uid)
2036 {
2037   size_t n;
2038   int count=0;
2039   struct user_attribute *attribs=NULL;
2040   const byte *buffer=uid->attrib_data;
2041   int buflen=uid->attrib_len;
2042   byte type;
2043
2044   xfree(uid->attribs);
2045
2046   while(buflen)
2047     {
2048       n = *buffer++; buflen--;
2049       if( n == 255 ) { /* 4 byte length header */
2050         if( buflen < 4 )
2051           goto too_short;
2052         n = (buffer[0] << 24) | (buffer[1] << 16)
2053           | (buffer[2] << 8) | buffer[3];
2054         buffer += 4;
2055         buflen -= 4;
2056       }
2057       else if( n >= 192 ) { /* 2 byte special encoded length header */
2058         if( buflen < 2 )
2059           goto too_short;
2060         n = (( n - 192 ) << 8) + *buffer + 192;
2061         buffer++;
2062         buflen--;
2063       }
2064       if( buflen < n )
2065         goto too_short;
2066
2067       attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute));
2068       memset(&attribs[count],0,sizeof(struct user_attribute));
2069
2070       type=*buffer;
2071       buffer++;
2072       buflen--;
2073       n--;
2074
2075       attribs[count].type=type;
2076       attribs[count].data=buffer;
2077       attribs[count].len=n;
2078       buffer+=n;
2079       buflen-=n;
2080       count++;
2081     }
2082
2083   uid->attribs=attribs;
2084   uid->numattribs=count;
2085   return count;
2086
2087  too_short:
2088   if(opt.verbose)
2089     log_info("buffer shorter than attribute subpacket\n");
2090   uid->attribs=attribs;
2091   uid->numattribs=count;
2092   return count;
2093 }
2094
2095
2096 static int
2097 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2098 {
2099     byte *p;
2100
2101     /* Cap the size of a user ID at 2k: a value absurdly large enough
2102        that there is no sane user ID string (which is printable text
2103        as of RFC2440bis) that won't fit in it, but yet small enough to
2104        avoid allocation problems.  A large pktlen may not be
2105        allocatable, and a very large pktlen could actually cause our
2106        allocation to wrap around in xmalloc to a small number. */
2107
2108     if (pktlen > 2048)
2109       {
2110         log_error ("packet(%d) too large\n", pkttype);
2111         iobuf_skip_rest(inp, pktlen, 0);
2112         return G10ERR_INVALID_PACKET;
2113       }
2114     
2115     packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen);
2116     packet->pkt.user_id->len = pktlen;
2117     packet->pkt.user_id->ref=1;
2118
2119     p = packet->pkt.user_id->name;
2120     for( ; pktlen; pktlen--, p++ )
2121         *p = iobuf_get_noeof(inp);
2122     *p = 0;
2123
2124     if( list_mode ) {
2125         int n = packet->pkt.user_id->len;
2126         fprintf (listfp, ":user ID packet: \"");
2127         /* fixme: Hey why don't we replace this with print_string?? */
2128         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
2129             if( *p >= ' ' && *p <= 'z' )
2130                 putc (*p, listfp);
2131             else
2132                 fprintf (listfp, "\\x%02x", *p );
2133         }
2134         fprintf (listfp, "\"\n");
2135     }
2136     return 0;
2137 }
2138
2139
2140 void
2141 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
2142 {
2143   assert ( max_namelen > 70 );
2144   if(uid->numattribs<=0)
2145     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
2146   else if(uid->numattribs>1)
2147     sprintf(uid->name,"[%d attributes of size %lu]",
2148             uid->numattribs,uid->attrib_len);
2149   else
2150     {
2151       /* Only one attribute, so list it as the "user id" */
2152
2153       if(uid->attribs->type==ATTRIB_IMAGE)
2154         {
2155           u32 len;
2156           byte type;
2157
2158           if(parse_image_header(uid->attribs,&type,&len))
2159             sprintf(uid->name,"[%.20s image of size %lu]",
2160                     image_type_to_string(type,1),(ulong)len);
2161           else
2162             sprintf(uid->name,"[invalid image]");
2163         }
2164       else
2165         sprintf(uid->name,"[unknown attribute of size %lu]",
2166                 (ulong)uid->attribs->len);
2167     }
2168
2169   uid->len = strlen(uid->name);
2170 }
2171
2172 static int
2173 parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2174 {
2175     byte *p;
2176
2177     (void)pkttype;
2178
2179 #define EXTRA_UID_NAME_SPACE 71
2180     packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id
2181                                         + EXTRA_UID_NAME_SPACE);
2182     packet->pkt.user_id->ref=1;
2183     packet->pkt.user_id->attrib_data = xmalloc(pktlen);
2184     packet->pkt.user_id->attrib_len = pktlen;
2185
2186     p = packet->pkt.user_id->attrib_data;
2187     for( ; pktlen; pktlen--, p++ )
2188         *p = iobuf_get_noeof(inp);
2189
2190     /* Now parse out the individual attribute subpackets.  This is
2191        somewhat pointless since there is only one currently defined
2192        attribute type (jpeg), but it is correct by the spec. */
2193     parse_attribute_subpkts(packet->pkt.user_id);
2194
2195     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
2196
2197     if( list_mode ) {
2198         fprintf (listfp, ":attribute packet: %s\n", packet->pkt.user_id->name );
2199     }
2200     return 0;
2201 }
2202
2203
2204 static int
2205 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2206 {
2207     byte *p;
2208
2209     /* Cap comment packet at a reasonable value to avoid an integer
2210        overflow in the malloc below.  Comment packets are actually not
2211        anymore define my OpenPGP and we even stopped to use our
2212        private comment packet. */
2213     if (pktlen>65536)
2214       {
2215         log_error ("packet(%d) too large\n", pkttype);
2216         iobuf_skip_rest (inp, pktlen, 0);
2217         return G10ERR_INVALID_PACKET;
2218       }
2219     packet->pkt.comment = xmalloc(sizeof *packet->pkt.comment + pktlen - 1);
2220     packet->pkt.comment->len = pktlen;
2221     p = packet->pkt.comment->data;
2222     for( ; pktlen; pktlen--, p++ )
2223         *p = iobuf_get_noeof(inp);
2224
2225     if( list_mode ) {
2226         int n = packet->pkt.comment->len;
2227         fprintf (listfp, ":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2228                                          "OpenPGP draft " : "" );
2229         for(p=packet->pkt.comment->data; n; p++, n-- ) {
2230             if( *p >= ' ' && *p <= 'z' )
2231                 putc (*p, listfp);
2232             else
2233                 fprintf (listfp, "\\x%02x", *p );
2234         }
2235         fprintf (listfp, "\"\n");
2236     }
2237     return 0;
2238 }
2239
2240
2241 static void
2242 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2243 {
2244   int c;
2245
2246   (void)pkttype;
2247
2248   if (pktlen)
2249     {
2250       c = iobuf_get_noeof(inp);
2251       pktlen--;
2252       pkt->pkt.ring_trust = xmalloc( sizeof *pkt->pkt.ring_trust );
2253       pkt->pkt.ring_trust->trustval = c;
2254       pkt->pkt.ring_trust->sigcache = 0;
2255       if (!c && pktlen==1)
2256         {
2257           c = iobuf_get_noeof (inp);
2258           pktlen--;
2259           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2260           if ( !(c & 0x80) )
2261             pkt->pkt.ring_trust->sigcache = c;
2262         }
2263       if( list_mode )
2264         fprintf (listfp, ":trust packet: flag=%02x sigcache=%02x\n",
2265                pkt->pkt.ring_trust->trustval,
2266                pkt->pkt.ring_trust->sigcache);
2267     }
2268   else
2269     {
2270       if( list_mode )
2271         fprintf (listfp, ":trust packet: empty\n");
2272     }
2273   iobuf_skip_rest (inp, pktlen, 0);
2274 }
2275
2276
2277 static int
2278 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
2279                  PACKET *pkt, int new_ctb, int partial )
2280 {
2281     int rc = 0;
2282     int mode, namelen;
2283     PKT_plaintext *pt;
2284     byte *p;
2285     int c, i;
2286
2287     if( !partial && pktlen < 6 ) {
2288         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2289         rc = gpg_error (GPG_ERR_INV_PACKET);
2290         goto leave;
2291     }
2292     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2293     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2294     /* Note that namelen will never exceed 255 bytes. */
2295     pt = pkt->pkt.plaintext = xmalloc(sizeof *pkt->pkt.plaintext + namelen -1);
2296     pt->new_ctb = new_ctb;
2297     pt->mode = mode;
2298     pt->namelen = namelen;
2299     pt->is_partial = partial;
2300     if( pktlen ) {
2301         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2302             pt->name[i] = iobuf_get_noeof(inp);
2303     }
2304     else {
2305         for( i=0; i < namelen; i++ )
2306             if( (c=iobuf_get(inp)) == -1 )
2307                 break;
2308             else
2309                 pt->name[i] = c;
2310     }
2311     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2312     pt->len = pktlen;
2313     pt->buf = inp;
2314     pktlen = 0;
2315
2316     if( list_mode ) {
2317         fprintf (listfp, ":literal data packet:\n"
2318                "\tmode %c (%X), created %lu, name=\"",
2319                     mode >= ' ' && mode <'z'? mode : '?', mode,
2320                     (ulong)pt->timestamp );
2321         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2322             if( *p >= ' ' && *p <= 'z' )
2323                 putc (*p, listfp);
2324             else
2325                 fprintf (listfp, "\\x%02x", *p );
2326         }
2327         fprintf (listfp, "\",\n\traw data: ");
2328         if(partial)
2329           fprintf (listfp, "unknown length\n");
2330         else
2331           fprintf (listfp, "%lu bytes\n", (ulong)pt->len );
2332     }
2333
2334   leave:
2335     return rc;
2336 }
2337
2338
2339 static int
2340 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
2341                   PACKET *pkt, int new_ctb )
2342 {
2343   PKT_compressed *zd;
2344   
2345   /* PKTLEN is here 0, but data follows (this should be the last
2346      object in a file or the compress algorithm should know the
2347      length).  */
2348   (void)pkttype;
2349   (void)pktlen;
2350
2351   zd = pkt->pkt.compressed = xmalloc (sizeof *pkt->pkt.compressed);
2352   zd->algorithm = iobuf_get_noeof(inp);
2353   zd->len = 0; /* not used */ 
2354   zd->new_ctb = new_ctb;
2355   zd->buf = inp;
2356   if (list_mode)
2357     fprintf (listfp, ":compressed packet: algo=%d\n", zd->algorithm);
2358   return 0;
2359 }
2360
2361
2362 static int
2363 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
2364                  PACKET *pkt, int new_ctb, int partial )
2365 {
2366     int rc = 0;
2367     PKT_encrypted *ed;
2368     unsigned long orig_pktlen = pktlen;
2369
2370     ed = pkt->pkt.encrypted =  xmalloc(sizeof *pkt->pkt.encrypted );
2371     ed->len = pktlen;
2372     /* we don't know the extralen which is (cipher_blocksize+2)
2373        because the algorithm ist not specified in this packet.
2374        However, it is only important to know this for some sanity
2375        checks on the packet length - it doesn't matter that we can't
2376        do it */
2377     ed->extralen = 0;
2378     ed->buf = NULL;
2379     ed->new_ctb = new_ctb;
2380     ed->is_partial = partial;
2381     ed->mdc_method = 0;
2382     if( pkttype == PKT_ENCRYPTED_MDC ) {
2383         /* fixme: add some pktlen sanity checks */
2384         int version;
2385
2386         version = iobuf_get_noeof(inp); 
2387         if (orig_pktlen)
2388             pktlen--;
2389         if( version != 1 ) {
2390             log_error("encrypted_mdc packet with unknown version %d\n",
2391                                                                 version);
2392             /*skip_rest(inp, pktlen); should we really do this? */
2393             rc = gpg_error (GPG_ERR_INV_PACKET);
2394             goto leave;
2395         }
2396         ed->mdc_method = DIGEST_ALGO_SHA1;
2397     }
2398     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2399         log_error("packet(%d) too short\n", pkttype);
2400         rc = G10ERR_INVALID_PACKET;
2401         iobuf_skip_rest(inp, pktlen, partial);
2402         goto leave;
2403     }
2404     if( list_mode ) {
2405         if( orig_pktlen )
2406             fprintf (listfp, ":encrypted data packet:\n\tlength: %lu\n",
2407                      orig_pktlen);
2408         else
2409             fprintf (listfp, ":encrypted data packet:\n\tlength: unknown\n");
2410         if( ed->mdc_method )
2411             fprintf (listfp, "\tmdc_method: %d\n", ed->mdc_method );
2412     }
2413
2414     ed->buf = inp;
2415
2416   leave:
2417     return rc;
2418 }
2419
2420
2421 /* Note, that this code is not anymore used in real life because now
2422    the MDC checking is done right after the encryption in
2423    decrypt_data. */
2424 static int
2425 parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen,
2426            PACKET *pkt, int new_ctb)
2427 {
2428   int rc = 0;
2429   PKT_mdc *mdc;
2430   byte *p;
2431
2432   (void)pkttype;
2433
2434   mdc = pkt->pkt.mdc = xmalloc(sizeof *pkt->pkt.mdc );
2435   if (list_mode)
2436     fprintf (listfp, ":mdc packet: length=%lu\n", pktlen);
2437   if (!new_ctb || pktlen != 20)
2438     {
2439       log_error("mdc_packet with invalid encoding\n");
2440       rc = gpg_error (GPG_ERR_INV_PACKET);
2441       goto leave;
2442     }
2443   p = mdc->hash;
2444   for (; pktlen; pktlen--, p++)
2445     *p = iobuf_get_noeof(inp);
2446   
2447  leave:
2448   return rc;
2449 }
2450
2451
2452 /*
2453  * This packet is internally generated by PGG (by armor.c) to
2454  * transfer some information to the lower layer.  To make sure that
2455  * this packet is really a GPG faked one and not one comming from outside,
2456  * we first check that tehre is a unique tag in it.
2457  * The format of such a control packet is:
2458  *   n byte  session marker
2459  *   1 byte  control type CTRLPKT_xxxxx
2460  *   m byte  control data
2461  */
2462
2463 static int
2464 parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen,
2465                    PACKET *packet, int partial)
2466 {
2467     byte *p;
2468     const byte *sesmark;
2469     size_t sesmarklen;
2470     int i;
2471
2472     (void)pkttype;
2473
2474     if ( list_mode )
2475         fprintf (listfp, ":packet 63: length %lu ",  pktlen);
2476
2477     sesmark = get_session_marker ( &sesmarklen );
2478     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2479         goto skipit;
2480     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2481         if ( sesmark[i] != iobuf_get_noeof(inp) )
2482             goto skipit;
2483     }
2484     if (pktlen > 4096)
2485       goto skipit; /* Definitely too large.  We skip it to avoid an
2486                       overflow in the malloc. */
2487     if ( list_mode )
2488         puts ("- gpg control packet");
2489
2490     packet->pkt.gpg_control = xmalloc(sizeof *packet->pkt.gpg_control
2491                                       + pktlen - 1);
2492     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2493     packet->pkt.gpg_control->datalen = pktlen;
2494     p = packet->pkt.gpg_control->data;
2495     for( ; pktlen; pktlen--, p++ )
2496         *p = iobuf_get_noeof(inp);
2497
2498     return 0;
2499
2500  skipit:
2501     if ( list_mode ) {
2502         int c;
2503
2504         i=0;
2505         fprintf (listfp, "- private (rest length %lu)\n",  pktlen);
2506         if( partial ) {
2507             while( (c=iobuf_get(inp)) != -1 )
2508                 dump_hex_line(c, &i);
2509         }
2510         else {
2511             for( ; pktlen; pktlen-- )
2512                 dump_hex_line(iobuf_get(inp), &i);
2513         }
2514         putc ('\n', listfp);
2515     }
2516     iobuf_skip_rest(inp,pktlen, 0);
2517     return gpg_error (GPG_ERR_INV_PACKET);
2518 }
2519
2520 /* create a gpg control packet to be used internally as a placeholder */
2521 PACKET *
2522 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2523 {
2524     PACKET *packet;
2525     byte *p;
2526
2527     packet = xmalloc( sizeof *packet );
2528     init_packet(packet);
2529     packet->pkttype = PKT_GPG_CONTROL;
2530     packet->pkt.gpg_control = xmalloc(sizeof *packet->pkt.gpg_control
2531                                       + datalen - 1);
2532     packet->pkt.gpg_control->control = type;
2533     packet->pkt.gpg_control->datalen = datalen;
2534     p = packet->pkt.gpg_control->data;
2535     for( ; datalen; datalen--, p++ )
2536         *p = *data++;
2537
2538     return packet;
2539 }