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