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