* packet.h, build-packet.c (build_sig_subpkt), export.c
[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     buffer++;
756     length--;
757    
758     printf("\t%s%ssubpkt %d len %u (", /*)*/
759               critical ? "critical ":"",
760               hashed ? "hashed ":"", type, (unsigned)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 subpacket]";
782         else
783           printf("trust signature of depth %d, value %d",buffer[0],buffer[1]);
784         break;
785       case SIGSUBPKT_REGEXP:
786         if(!length)
787           p="[invalid regexp subpacket]";
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 {
827                 const byte *s = buffer;
828                 size_t n1, n2;
829
830                 n1 = (s[4] << 8) | s[5];
831                 n2 = (s[6] << 8) | s[7];
832                 s += 8;
833                 if( 8+n1+n2 != length )
834                     p = "[error]";
835                 else {
836                     print_string( stdout, s, n1, ')' );
837                     putc( '=', stdout );
838
839                     if( *buffer & 0x80 )
840                       print_string( stdout, s+n1, n2, ')' );
841                     else
842                       p = "[not human readable]";
843                 }
844             }
845         }
846         break;
847       case SIGSUBPKT_PREF_HASH:
848         fputs("pref-hash-algos:", stdout );
849         for( i=0; i < length; i++ )
850             printf(" %d", buffer[i] );
851         break;
852       case SIGSUBPKT_PREF_COMPR:
853         fputs("pref-zip-algos:", stdout );
854         for( i=0; i < length; i++ )
855             printf(" %d", buffer[i] );
856         break;
857       case SIGSUBPKT_KS_FLAGS:
858         fputs("key server preferences:",stdout);
859         for(i=0;i<length;i++)
860           printf(" %02X", buffer[i]);
861         break;
862       case SIGSUBPKT_PREF_KS:
863         p = "preferred key server";
864         break;
865       case SIGSUBPKT_PRIMARY_UID:
866         p = "primary user ID";
867         break;
868       case SIGSUBPKT_POLICY:
869         fputs("policy: ", stdout );
870         print_string( stdout, buffer, length, ')' );
871         break;
872       case SIGSUBPKT_KEY_FLAGS:
873         fputs ( "key flags:", stdout );
874         for( i=0; i < length; i++ )
875             printf(" %02X", buffer[i] );
876         break;
877       case SIGSUBPKT_SIGNERS_UID:
878         p = "signer's user ID";
879         break;
880       case SIGSUBPKT_REVOC_REASON:
881         if( length ) {
882             printf("revocation reason 0x%02x (", *buffer );
883             print_string( stdout, buffer+1, length-1, ')' );
884             p = ")";
885         }
886         break;
887       case SIGSUBPKT_ARR:
888         fputs("Big Brother's key (ignored): ", stdout );
889         if( length < 22 )
890             p = "[too short]";
891         else {
892             printf("c=%02x a=%d f=", buffer[0], buffer[1] );
893             for( i=2; i < length; i++ )
894                 printf("%02X", buffer[i] );
895         }
896         break;
897       case SIGSUBPKT_FEATURES:
898         fputs ( "features:", stdout );
899         for( i=0; i < length; i++ )
900             printf(" %02x", buffer[i] );
901         break;
902       default:
903         if(type>=100 && type<=110)
904           p="experimental / private subpacket";
905         else
906           p = "?";
907         break;
908     }
909
910     printf("%s)\n", p? p: "");
911 }
912
913 /****************
914  * Returns: >= 0 offset into buffer
915  *          -1 unknown type
916  *          -2 unsupported type
917  *          -3 subpacket too short
918  */
919 int
920 parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
921 {
922     switch( type ) {
923       case SIGSUBPKT_REV_KEY:
924         if(n < 22)
925           break;
926         return 0;
927       case SIGSUBPKT_SIG_CREATED:
928       case SIGSUBPKT_SIG_EXPIRE:
929       case SIGSUBPKT_KEY_EXPIRE:
930         if( n < 4 )
931             break;
932         return 0;
933       case SIGSUBPKT_KEY_FLAGS:
934       case SIGSUBPKT_KS_FLAGS:
935       case SIGSUBPKT_PREF_SYM:
936       case SIGSUBPKT_PREF_HASH:
937       case SIGSUBPKT_PREF_COMPR:
938       case SIGSUBPKT_POLICY:
939       case SIGSUBPKT_FEATURES:
940       case SIGSUBPKT_REGEXP:
941         return 0;
942       case SIGSUBPKT_EXPORTABLE:
943       case SIGSUBPKT_REVOCABLE:
944         if( !n )
945             break;
946         return 0;
947       case SIGSUBPKT_ISSUER: /* issuer key ID */
948         if( n < 8 )
949             break;
950         return 0;
951       case SIGSUBPKT_NOTATION:
952         if( n < 8 ) /* minimum length needed */
953             break;
954         return 0;
955       case SIGSUBPKT_REVOC_REASON:
956         if( !n  )
957             break;
958         return 0;
959       case SIGSUBPKT_PRIMARY_UID:
960           if ( n != 1 )
961               break;
962           return 0;   
963       case SIGSUBPKT_TRUST:
964           if ( n != 2 )
965               break;
966           return 0;
967       default: return -1;
968     }
969     return -3;
970 }
971
972
973 static int
974 can_handle_critical( const byte *buffer, size_t n, int type )
975 {
976     switch( type ) {
977       case SIGSUBPKT_NOTATION:
978         if( n >= 8 && (*buffer & 0x80) )
979             return 1; /* human readable is handled */
980         return 0;
981
982       case SIGSUBPKT_SIG_CREATED:
983       case SIGSUBPKT_SIG_EXPIRE:
984       case SIGSUBPKT_KEY_EXPIRE:
985       case SIGSUBPKT_EXPORTABLE:
986       case SIGSUBPKT_REVOCABLE:
987       case SIGSUBPKT_REV_KEY:
988       case SIGSUBPKT_ISSUER:/* issuer key ID */
989       case SIGSUBPKT_PREF_SYM:
990       case SIGSUBPKT_PREF_HASH:
991       case SIGSUBPKT_PREF_COMPR:
992       case SIGSUBPKT_KEY_FLAGS:
993       case SIGSUBPKT_PRIMARY_UID:
994       case SIGSUBPKT_FEATURES:
995       case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
996       case SIGSUBPKT_TRUST:
997       case SIGSUBPKT_REGEXP:
998         return 1;
999
1000       default:
1001         return 0;
1002     }
1003 }
1004
1005
1006 const byte *
1007 enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
1008                  size_t *ret_n, int *start, int *critical )
1009 {
1010     const byte *buffer;
1011     int buflen;
1012     int type;
1013     int critical_dummy;
1014     int offset;
1015     size_t n;
1016     int seq = 0;
1017     int reqseq = start? *start: 0;
1018
1019     if(!critical)
1020       critical=&critical_dummy;
1021
1022     if( !pktbuf || reqseq == -1 ) {
1023         /* return some value different from NULL to indicate that
1024          * there is no critical bit we do not understand.  The caller
1025          * will never use the value.  Yes I know, it is an ugly hack */
1026         return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
1027     }
1028     buffer = pktbuf->data;
1029     buflen = pktbuf->len;
1030     while( buflen ) {
1031         n = *buffer++; buflen--;
1032         if( n == 255 ) { /* 4 byte length header */
1033             if( buflen < 4 )
1034                 goto too_short;
1035             n = (buffer[0] << 24) | (buffer[1] << 16)
1036                 | (buffer[2] << 8) | buffer[3];
1037             buffer += 4;
1038             buflen -= 4;
1039         }
1040         else if( n >= 192 ) { /* 2 byte special encoded length header */
1041             if( buflen < 2 )
1042                 goto too_short;
1043             n = (( n - 192 ) << 8) + *buffer + 192;
1044             buffer++;
1045             buflen--;
1046         }
1047         if( buflen < n )
1048             goto too_short;
1049         type = *buffer;
1050         if( type & 0x80 ) {
1051             type &= 0x7f;
1052             *critical = 1;
1053         }
1054         else
1055             *critical = 0;
1056         if( !(++seq > reqseq) )
1057             ;
1058         else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
1059             if( *critical ) {
1060                 if( n-1 > buflen+1 )
1061                     goto too_short;
1062                 if( !can_handle_critical(buffer+1, n-1, type ) )
1063                   {
1064                     if(opt.verbose)
1065                       log_info(_("subpacket of type %d has "
1066                                  "critical bit set\n"),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         size_t len;
1251
1252         /* set sig->flags.unknown_critical if there is a
1253          * critical bit set for packets which we do not understand */
1254         if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
1255            || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
1256                                                                         NULL) )
1257         {
1258             sig->flags.unknown_critical = 1;
1259         }
1260
1261         p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
1262         if( !p )
1263             log_error("signature packet without timestamp\n");
1264         else
1265             sig->timestamp = buffer_to_u32(p);
1266         p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1267         if( !p )
1268             log_error("signature packet without keyid\n");
1269         else {
1270             sig->keyid[0] = buffer_to_u32(p);
1271             sig->keyid[1] = buffer_to_u32(p+4);
1272         }
1273
1274         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1275         if(p)
1276           sig->expiredate=sig->timestamp+buffer_to_u32(p);
1277         if(sig->expiredate && sig->expiredate<=make_timestamp())
1278             sig->flags.expired=1;
1279
1280         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1281         if(p)
1282           sig->flags.policy_url=1;
1283
1284         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1285         if(p)
1286           sig->flags.notation=1;
1287
1288         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1289         if(p && *p==0)
1290           sig->flags.revocable=0;
1291
1292         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len);
1293         if(p && len==2)
1294           {
1295             sig->trust_depth=p[0];
1296             sig->trust_value=p[1];
1297
1298             /* Only look for a regexp if there is also a trust
1299                subpacket. */
1300             sig->trust_regexp=
1301               parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len);
1302
1303             /* If the regular expression is of 0 length, there is no
1304                regular expression. */
1305             if(len==0)
1306               sig->trust_regexp=NULL;
1307           }
1308
1309         /* We accept the exportable subpacket from either the hashed
1310            or unhashed areas as older versions of gpg put it in the
1311            unhashed area.  In theory, anyway, we should never see this
1312            packet off of a local keyring. */
1313
1314         p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1315         if(p && *p==0)
1316           sig->flags.exportable=0;
1317
1318         /* Find all revocation keys. */
1319         if(sig->sig_class==0x1F)
1320           parse_revkeys(sig);
1321     }
1322
1323     if( list_mode ) {
1324         printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1325                "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1326                "\tdigest algo %d, begin of digest %02x %02x\n",
1327                 sig->pubkey_algo,
1328                 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1329                 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1330                 sig->digest_algo,
1331                 sig->digest_start[0], sig->digest_start[1] );
1332         if( is_v4 ) {
1333             parse_sig_subpkt (sig->hashed,   SIGSUBPKT_LIST_HASHED, NULL );
1334             parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1335         }
1336     }
1337
1338     ndata = pubkey_get_nsig(sig->pubkey_algo);
1339     if( !ndata ) {
1340         if( list_mode )
1341             printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1342         unknown_pubkey_warning( sig->pubkey_algo );
1343         /* we store the plain material in data[0], so that we are able
1344          * to write it back with build_packet() */
1345         sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1346         pktlen = 0;
1347     }
1348     else {
1349         for( i=0; i < ndata; i++ ) {
1350             n = pktlen;
1351             sig->data[i] = mpi_read(inp, &n, 0 );
1352             pktlen -=n;
1353             if( list_mode ) {
1354                 printf("\tdata: ");
1355                 mpi_print(stdout, sig->data[i], mpi_print_mode );
1356                 putchar('\n');
1357             }
1358             if (!sig->data[i])
1359                 rc = G10ERR_INVALID_PACKET;
1360         }
1361     }
1362
1363   leave:
1364     skip_rest(inp, pktlen);
1365     return rc;
1366 }
1367
1368
1369 static int
1370 parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
1371                                              PKT_onepass_sig *ops )
1372 {
1373     int version;
1374     int rc = 0;
1375
1376     if( pktlen < 13 ) {
1377         log_error("packet(%d) too short\n", pkttype);
1378         rc = G10ERR_INVALID_PACKET;
1379         goto leave;
1380     }
1381     version = iobuf_get_noeof(inp); pktlen--;
1382     if( version != 3 ) {
1383         log_error("onepass_sig with unknown version %d\n", version);
1384         rc = G10ERR_INVALID_PACKET;
1385         goto leave;
1386     }
1387     ops->sig_class = iobuf_get_noeof(inp); pktlen--;
1388     ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
1389     ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
1390     ops->keyid[0] = read_32(inp); pktlen -= 4;
1391     ops->keyid[1] = read_32(inp); pktlen -= 4;
1392     ops->last = iobuf_get_noeof(inp); pktlen--;
1393     if( list_mode )
1394         printf(":onepass_sig packet: keyid %08lX%08lX\n"
1395                "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1396                 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1397                 version, ops->sig_class,
1398                 ops->digest_algo, ops->pubkey_algo, ops->last );
1399
1400
1401   leave:
1402     skip_rest(inp, pktlen);
1403     return rc;
1404 }
1405
1406
1407 static MPI
1408 read_protected_v3_mpi (IOBUF inp, unsigned long *length)
1409 {
1410   int c;
1411   unsigned int nbits, nbytes;
1412   unsigned char *buf, *p;
1413   MPI val;
1414
1415   if (*length < 2)
1416     {
1417       log_error ("mpi too small\n");
1418       return NULL;
1419     }
1420
1421   if ((c=iobuf_get (inp)) == -1)
1422     return NULL;
1423   --*length;
1424   nbits = c << 8;
1425   if ((c=iobuf_get(inp)) == -1)
1426     return NULL;
1427   --*length;
1428   nbits |= c;
1429
1430   if (nbits > 16384)
1431     {
1432       log_error ("mpi too large (%u bits)\n", nbits);
1433       return NULL;
1434     }
1435   nbytes = (nbits+7) / 8;
1436   buf = p = m_alloc (2 + nbytes);
1437   *p++ = nbits >> 8;
1438   *p++ = nbits;
1439   for (; nbytes && length; nbytes--, --*length)
1440     *p++ = iobuf_get (inp);
1441   if (nbytes)
1442     {
1443       log_error ("packet shorter tham mpi\n");
1444       m_free (buf);
1445       return NULL;
1446     }
1447
1448   /* convert buffer into an opaque MPI */
1449   val = mpi_set_opaque (NULL, buf, p-buf); 
1450   return val;
1451 }
1452
1453
1454 static int
1455 parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
1456                               byte *hdr, int hdrlen, PACKET *pkt )
1457 {
1458     int i, version, algorithm;
1459     unsigned n;
1460     unsigned long timestamp, expiredate, max_expiredate;
1461     int npkey, nskey;
1462     int is_v4=0;
1463     int rc=0;
1464
1465     version = iobuf_get_noeof(inp); pktlen--;
1466     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1467         /* early versions of G10 use old PGP comments packets;
1468          * luckily all those comments are started by a hash */
1469         if( list_mode ) {
1470             printf(":rfc1991 comment packet: \"" );
1471             for( ; pktlen; pktlen-- ) {
1472                 int c;
1473                 c = iobuf_get_noeof(inp);
1474                 if( c >= ' ' && c <= 'z' )
1475                     putchar(c);
1476                 else
1477                     printf("\\x%02x", c );
1478             }
1479             printf("\"\n");
1480         }
1481         skip_rest(inp, pktlen);
1482         return 0;
1483     }
1484     else if( version == 4 )
1485         is_v4=1;
1486     else if( version != 2 && version != 3 ) {
1487         log_error("packet(%d) with unknown version %d\n", pkttype, version);
1488         rc = G10ERR_INVALID_PACKET;
1489         goto leave;
1490     }
1491
1492     if( pktlen < 11 ) {
1493         log_error("packet(%d) too short\n", pkttype);
1494         rc = G10ERR_INVALID_PACKET;
1495         goto leave;
1496     }
1497
1498     timestamp = read_32(inp); pktlen -= 4;
1499     if( is_v4 ) {
1500         expiredate = 0; /* have to get it from the selfsignature */
1501         max_expiredate = 0;
1502     }
1503     else {
1504         unsigned short ndays;
1505         ndays = read_16(inp); pktlen -= 2;
1506         if( ndays )
1507             expiredate = timestamp + ndays * 86400L;
1508         else
1509             expiredate = 0;
1510
1511         max_expiredate=expiredate;
1512     }
1513     algorithm = iobuf_get_noeof(inp); pktlen--;
1514     if( list_mode )
1515         printf(":%s key packet:\n"
1516                "\tversion %d, algo %d, created %lu, expires %lu\n",
1517                 pkttype == PKT_PUBLIC_KEY? "public" :
1518                 pkttype == PKT_SECRET_KEY? "secret" :
1519                 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1520                 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1521                 version, algorithm, timestamp, expiredate );
1522
1523     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY )  {
1524         PKT_secret_key *sk = pkt->pkt.secret_key;
1525
1526         sk->timestamp = timestamp;
1527         sk->expiredate = expiredate;
1528         sk->max_expiredate = max_expiredate;
1529         sk->hdrbytes = hdrlen;
1530         sk->version = version;
1531         sk->is_primary = pkttype == PKT_SECRET_KEY;
1532         sk->pubkey_algo = algorithm;
1533         sk->req_usage = 0; 
1534         sk->pubkey_usage = 0; /* not yet used */
1535     }
1536     else {
1537         PKT_public_key *pk = pkt->pkt.public_key;
1538
1539         pk->timestamp = timestamp;
1540         pk->expiredate = expiredate;
1541         pk->max_expiredate = max_expiredate;
1542         pk->hdrbytes    = hdrlen;
1543         pk->version     = version;
1544         pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1545         pk->pubkey_algo = algorithm;
1546         pk->req_usage = 0; 
1547         pk->pubkey_usage = 0; /* not yet used */
1548         pk->is_revoked = 0;
1549         pk->keyid[0] = 0;
1550         pk->keyid[1] = 0;
1551     }
1552     nskey = pubkey_get_nskey( algorithm );
1553     npkey = pubkey_get_npkey( algorithm );
1554     if( !npkey ) {
1555         if( list_mode )
1556             printf("\tunknown algorithm %d\n", algorithm );
1557         unknown_pubkey_warning( algorithm );
1558     }
1559
1560
1561     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1562         PKT_secret_key *sk = pkt->pkt.secret_key;
1563         byte temp[16];
1564
1565         if( !npkey ) {
1566             sk->skey[0] = mpi_set_opaque( NULL,
1567                                           read_rest(inp, pktlen), pktlen );
1568             pktlen = 0;
1569             goto leave;
1570         }
1571
1572         for(i=0; i < npkey; i++ ) {
1573             n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1574             if( list_mode ) {
1575                 printf(  "\tskey[%d]: ", i);
1576                 mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1577                 putchar('\n');
1578             }
1579             if (!sk->skey[i])
1580                 rc = G10ERR_INVALID_PACKET;
1581         }
1582         if (rc) /* one of the MPIs were bad */
1583             goto leave;
1584         sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1585         sk->protect.sha1chk = 0;
1586         if( sk->protect.algo ) {
1587             sk->is_protected = 1;
1588             sk->protect.s2k.count = 0;
1589             if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1590                 if( pktlen < 3 ) {
1591                     rc = G10ERR_INVALID_PACKET;
1592                     goto leave;
1593                 }
1594                 sk->protect.sha1chk = (sk->protect.algo == 254);
1595                 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1596                 /* Note that a sk->protect.algo > 110 is illegal, but
1597                    I'm not erroring on it here as otherwise there
1598                    would be no way to delete such a key. */
1599                 sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
1600                 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1601                 /* check for the special GNU extension */
1602                 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1603                     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1604                         temp[i] = iobuf_get_noeof(inp);
1605                     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1606                         if( list_mode )
1607                             printf(  "\tunknown S2K %d\n",
1608                                                 sk->protect.s2k.mode );
1609                         rc = G10ERR_INVALID_PACKET;
1610                         goto leave;
1611                     }
1612                     /* here we know that it is a gnu extension
1613                      * What follows is the GNU protection mode:
1614                      * All values have special meanings
1615                      * and they are mapped in the mode with a base of 1000.
1616                      */
1617                     sk->protect.s2k.mode = 1000 + temp[3];
1618                 }
1619                 switch( sk->protect.s2k.mode ) {
1620                   case 1:
1621                   case 3:
1622                     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1623                         temp[i] = iobuf_get_noeof(inp);
1624                     memcpy(sk->protect.s2k.salt, temp, 8 );
1625                     break;
1626                 }
1627                 switch( sk->protect.s2k.mode ) {
1628                   case 0: if( list_mode ) printf(  "\tsimple S2K" );
1629                     break;
1630                   case 1: if( list_mode ) printf(  "\tsalted S2K" );
1631                     break;
1632                   case 3: if( list_mode ) printf(  "\titer+salt S2K" );
1633                     break;
1634                   case 1001: if( list_mode ) printf(  "\tgnu-dummy S2K" );
1635                     break;
1636                   default:
1637                     if( list_mode )
1638                         printf(  "\tunknown %sS2K %d\n",
1639                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1640                                                    sk->protect.s2k.mode );
1641                     rc = G10ERR_INVALID_PACKET;
1642                     goto leave;
1643                 }
1644
1645                 if( list_mode ) {
1646                     printf(", algo: %d,%s hash: %d",
1647                                      sk->protect.algo,
1648                                      sk->protect.sha1chk?" SHA1 protection,"
1649                                                         :" simple checksum,",
1650                                      sk->protect.s2k.hash_algo );
1651                     if( sk->protect.s2k.mode == 1
1652                         || sk->protect.s2k.mode == 3 ) {
1653                         printf(", salt: ");
1654                         for(i=0; i < 8; i++ )
1655                             printf("%02x", sk->protect.s2k.salt[i]);
1656                     }
1657                     putchar('\n');
1658                 }
1659
1660                 if( sk->protect.s2k.mode == 3 ) {
1661                     if( pktlen < 1 ) {
1662                         rc = G10ERR_INVALID_PACKET;
1663                         goto leave;
1664                     }
1665                     sk->protect.s2k.count = iobuf_get(inp);
1666                     pktlen--;
1667                     if( list_mode )
1668                         printf("\tprotect count: %lu\n",
1669                                             (ulong)sk->protect.s2k.count);
1670                 }
1671             }
1672             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1673                not erroring on it here as otherwise there would be no
1674                way to delete such a key. */
1675             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1676                 sk->protect.s2k.mode = 0;
1677                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1678                 if( list_mode )
1679                     printf(  "\tprotect algo: %d  (hash algo: %d)\n",
1680                          sk->protect.algo, sk->protect.s2k.hash_algo );
1681             }
1682             /* It is really ugly that we don't know the size
1683              * of the IV here in cases we are not aware of the algorithm.
1684              * so a
1685              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1686              * won't work.  The only solution I see is to hardwire it here.
1687              * NOTE: if you change the ivlen above 16, don't forget to
1688              * enlarge temp.
1689              */
1690             switch( sk->protect.algo ) {
1691               case 7: case 8: case 9: /* reserved for AES */
1692               case 10: /* Twofish */
1693                 sk->protect.ivlen = 16;
1694                 break;
1695               default:
1696                 sk->protect.ivlen = 8;
1697             }
1698             if( sk->protect.s2k.mode == 1001 )
1699                 sk->protect.ivlen = 0;
1700
1701             if( pktlen < sk->protect.ivlen ) {
1702                 rc = G10ERR_INVALID_PACKET;
1703                 goto leave;
1704             }
1705             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1706                 temp[i] = iobuf_get_noeof(inp);
1707             if( list_mode ) {
1708                 printf(  "\tprotect IV: ");
1709                 for(i=0; i < sk->protect.ivlen; i++ )
1710                     printf(" %02x", temp[i] );
1711                 putchar('\n');
1712             }
1713             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1714         }
1715         else
1716             sk->is_protected = 0;
1717         /* It does not make sense to read it into secure memory.
1718          * If the user is so careless, not to protect his secret key,
1719          * we can assume, that he operates an open system :=(.
1720          * So we put the key into secure memory when we unprotect it. */
1721         if( sk->protect.s2k.mode == 1001 ) {
1722             /* better set some dummy stuff here */
1723             sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10);
1724             pktlen = 0;
1725         }
1726         else if( is_v4 && sk->is_protected ) {
1727             /* ugly; the length is encrypted too, so we read all
1728              * stuff up to the end of the packet into the first
1729              * skey element */
1730             sk->skey[npkey] = mpi_set_opaque(NULL,
1731                                              read_rest(inp, pktlen), pktlen );
1732             pktlen = 0;
1733             if( list_mode ) {
1734                 printf("\tencrypted stuff follows\n");
1735             }
1736         }
1737         else { /* v3 method: the mpi length is not encrypted */
1738             for(i=npkey; i < nskey; i++ ) {
1739                 if ( sk->is_protected ) {
1740                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1741                     if( list_mode ) 
1742                         printf(  "\tskey[%d]: [encrypted]\n", i);
1743                 }
1744                 else {
1745                     n = pktlen;
1746                     sk->skey[i] = mpi_read(inp, &n, 0 );
1747                     pktlen -=n;
1748                     if( list_mode ) {
1749                         printf(  "\tskey[%d]: ", i);
1750                         mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1751                         putchar('\n');
1752                     }
1753                 }
1754
1755                 if (!sk->skey[i])
1756                     rc = G10ERR_INVALID_PACKET;
1757             }
1758             if (rc)
1759                 goto leave;
1760
1761             sk->csum = read_16(inp); pktlen -= 2;
1762             if( list_mode ) {
1763                 printf("\tchecksum: %04hx\n", sk->csum);
1764             }
1765         }
1766     }
1767     else {
1768         PKT_public_key *pk = pkt->pkt.public_key;
1769
1770         if( !npkey ) {
1771             pk->pkey[0] = mpi_set_opaque( NULL,
1772                                           read_rest(inp, pktlen), pktlen );
1773             pktlen = 0;
1774             goto leave;
1775         }
1776
1777         for(i=0; i < npkey; i++ ) {
1778             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1779             if( list_mode ) {
1780                 printf(  "\tpkey[%d]: ", i);
1781                 mpi_print(stdout, pk->pkey[i], mpi_print_mode  );
1782                 putchar('\n');
1783             }
1784             if (!pk->pkey[i])
1785                 rc = G10ERR_INVALID_PACKET;
1786         }
1787         if (rc)
1788             goto leave;
1789     }
1790
1791   leave:
1792     skip_rest(inp, pktlen);
1793     return rc;
1794 }
1795
1796 /* Attribute subpackets have the same format as v4 signature
1797    subpackets.  This is not part of OpenPGP, but is done in several
1798    versions of PGP nevertheless. */
1799 int
1800 parse_attribute_subpkts(PKT_user_id *uid)
1801 {
1802   size_t n;
1803   int count=0;
1804   struct user_attribute *attribs=NULL;
1805   const byte *buffer=uid->attrib_data;
1806   int buflen=uid->attrib_len;
1807   byte type;
1808
1809   m_free(uid->attribs);
1810
1811   while(buflen)
1812     {
1813       n = *buffer++; buflen--;
1814       if( n == 255 ) { /* 4 byte length header */
1815         if( buflen < 4 )
1816           goto too_short;
1817         n = (buffer[0] << 24) | (buffer[1] << 16)
1818           | (buffer[2] << 8) | buffer[3];
1819         buffer += 4;
1820         buflen -= 4;
1821       }
1822       else if( n >= 192 ) { /* 2 byte special encoded length header */
1823         if( buflen < 2 )
1824           goto too_short;
1825         n = (( n - 192 ) << 8) + *buffer + 192;
1826         buffer++;
1827         buflen--;
1828       }
1829       if( buflen < n )
1830         goto too_short;
1831
1832       attribs=m_realloc(attribs,(count+1)*sizeof(struct user_attribute));
1833       memset(&attribs[count],0,sizeof(struct user_attribute));
1834
1835       type=*buffer;
1836       buffer++;
1837       buflen--;
1838       n--;
1839
1840       attribs[count].type=type;
1841       attribs[count].data=buffer;
1842       attribs[count].len=n;
1843       buffer+=n;
1844       buflen-=n;
1845       count++;
1846     }
1847
1848   uid->attribs=attribs;
1849   uid->numattribs=count;
1850   return count;
1851
1852  too_short:
1853   log_error("buffer shorter than attribute subpacket\n");
1854   uid->attribs=attribs;
1855   uid->numattribs=count;
1856   return count;
1857 }
1858
1859 static void setup_user_id(PACKET *packet)
1860 {
1861   packet->pkt.user_id->ref = 1;
1862   packet->pkt.user_id->attribs = NULL;
1863   packet->pkt.user_id->attrib_data = NULL;
1864   packet->pkt.user_id->attrib_len = 0;
1865   packet->pkt.user_id->is_primary = 0;
1866   packet->pkt.user_id->is_revoked = 0;
1867   packet->pkt.user_id->is_expired = 0;
1868   packet->pkt.user_id->expiredate = 0;
1869   packet->pkt.user_id->created = 0;
1870   packet->pkt.user_id->help_key_usage = 0;
1871   packet->pkt.user_id->help_key_expire = 0;
1872   packet->pkt.user_id->prefs = NULL;
1873   packet->pkt.user_id->namehash = NULL;
1874 }
1875
1876 static int
1877 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1878 {
1879     byte *p;
1880
1881     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen);
1882     packet->pkt.user_id->len = pktlen;
1883
1884     setup_user_id(packet);
1885
1886     p = packet->pkt.user_id->name;
1887     for( ; pktlen; pktlen--, p++ )
1888         *p = iobuf_get_noeof(inp);
1889     *p = 0;
1890
1891     if( list_mode ) {
1892         int n = packet->pkt.user_id->len;
1893         printf(":user ID packet: \"");
1894         /* fixme: Hey why don't we replace this with print_string?? */
1895         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1896             if( *p >= ' ' && *p <= 'z' )
1897                 putchar(*p);
1898             else
1899                 printf("\\x%02x", *p );
1900         }
1901         printf("\"\n");
1902     }
1903     return 0;
1904 }
1905
1906
1907 void
1908 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
1909 {
1910   assert ( max_namelen > 70 );
1911   if(uid->numattribs<=0)
1912     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
1913   else if(uid->numattribs>1)
1914     sprintf(uid->name,"[%d attributes of size %lu]",
1915             uid->numattribs,uid->attrib_len);
1916   else
1917     {
1918       /* Only one attribute, so list it as the "user id" */
1919
1920       if(uid->attribs->type==ATTRIB_IMAGE)
1921         {
1922           u32 len;
1923           byte type;
1924
1925           if(parse_image_header(uid->attribs,&type,&len))
1926             sprintf(uid->name,"[%.20s image of size %lu]",
1927                     image_type_to_string(type,1),(ulong)len);
1928           else
1929             sprintf(uid->name,"[invalid image]");
1930         }
1931       else
1932         sprintf(uid->name,"[unknown attribute of size %lu]",
1933                 (ulong)uid->attribs->len);
1934     }
1935
1936   uid->len = strlen(uid->name);
1937 }
1938
1939 static int
1940 parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1941 {
1942     byte *p;
1943
1944 #define EXTRA_UID_NAME_SPACE 71
1945     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id
1946                                   + EXTRA_UID_NAME_SPACE);
1947
1948     setup_user_id(packet);
1949
1950     packet->pkt.user_id->attrib_data = m_alloc(pktlen);
1951     packet->pkt.user_id->attrib_len = pktlen;
1952     p = packet->pkt.user_id->attrib_data;
1953     for( ; pktlen; pktlen--, p++ )
1954         *p = iobuf_get_noeof(inp);
1955
1956     /* Now parse out the individual attribute subpackets.  This is
1957        somewhat pointless since there is only one currently defined
1958        attribute type (jpeg), but it is correct by the spec. */
1959     parse_attribute_subpkts(packet->pkt.user_id);
1960
1961     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
1962
1963     if( list_mode ) {
1964         printf(":attribute packet: %s\n", packet->pkt.user_id->name );
1965     }
1966     return 0;
1967 }
1968
1969
1970 static int
1971 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1972 {
1973     byte *p;
1974
1975     packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
1976     packet->pkt.comment->len = pktlen;
1977     p = packet->pkt.comment->data;
1978     for( ; pktlen; pktlen--, p++ )
1979         *p = iobuf_get_noeof(inp);
1980
1981     if( list_mode ) {
1982         int n = packet->pkt.comment->len;
1983         printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
1984                                          "OpenPGP draft " : "" );
1985         for(p=packet->pkt.comment->data; n; p++, n-- ) {
1986             if( *p >= ' ' && *p <= 'z' )
1987                 putchar(*p);
1988             else
1989                 printf("\\x%02x", *p );
1990         }
1991         printf("\"\n");
1992     }
1993     return 0;
1994 }
1995
1996
1997 static void
1998 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
1999 {
2000   int c;
2001
2002   if (pktlen)
2003     {
2004       c = iobuf_get_noeof(inp);
2005       pktlen--;
2006       pkt->pkt.ring_trust = m_alloc( sizeof *pkt->pkt.ring_trust );
2007       pkt->pkt.ring_trust->trustval = c;
2008       pkt->pkt.ring_trust->sigcache = 0;
2009       if (!c && pktlen==1)
2010         {
2011           c = iobuf_get_noeof (inp);
2012           pktlen--;
2013           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2014           if ( !(c & 0x80) )
2015             pkt->pkt.ring_trust->sigcache = c;
2016         }
2017       if( list_mode )
2018         printf(":trust packet: flag=%02x sigcache=%02x\n",
2019                pkt->pkt.ring_trust->trustval,
2020                pkt->pkt.ring_trust->sigcache);
2021     }
2022   else
2023     {
2024       if( list_mode )
2025         printf(":trust packet: empty\n");
2026     }
2027   skip_rest (inp, pktlen);
2028 }
2029
2030
2031 static int
2032 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
2033                                         PACKET *pkt, int new_ctb )
2034 {
2035     int rc = 0;
2036     int mode, namelen, partial=0;
2037     PKT_plaintext *pt;
2038     byte *p;
2039     int c, i;
2040
2041     if( pktlen && pktlen < 6 ) {
2042         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2043         rc = G10ERR_INVALID_PACKET;
2044         goto leave;
2045     }
2046     /* A packet length of zero indicates partial body length.  A zero
2047        data length isn't a zero length packet due to the header (mode,
2048        name, etc), so this is accurate. */
2049     if(pktlen==0)
2050       partial=1;
2051     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2052     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2053     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
2054     pt->new_ctb = new_ctb;
2055     pt->mode = mode;
2056     pt->namelen = namelen;
2057     pt->is_partial = partial;
2058     if( pktlen ) {
2059         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2060             pt->name[i] = iobuf_get_noeof(inp);
2061     }
2062     else {
2063         for( i=0; i < namelen; i++ )
2064             if( (c=iobuf_get(inp)) == -1 )
2065                 break;
2066             else
2067                 pt->name[i] = c;
2068     }
2069     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2070     pt->len = pktlen;
2071     pt->buf = inp;
2072     pktlen = 0;
2073
2074     if( list_mode ) {
2075         printf(":literal data packet:\n"
2076                "\tmode %c, created %lu, name=\"",
2077                     mode >= ' ' && mode <'z'? mode : '?',
2078                     (ulong)pt->timestamp );
2079         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2080             if( *p >= ' ' && *p <= 'z' )
2081                 putchar(*p);
2082             else
2083                 printf("\\x%02x", *p );
2084         }
2085         printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2086     }
2087
2088   leave:
2089     return rc;
2090 }
2091
2092
2093 static int
2094 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
2095                   PACKET *pkt, int new_ctb )
2096 {
2097     PKT_compressed *zd;
2098
2099     /* pktlen is here 0, but data follows
2100      * (this should be the last object in a file or
2101      *  the compress algorithm should know the length)
2102      */
2103     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
2104     zd->algorithm = iobuf_get_noeof(inp);
2105     zd->len = 0; /* not used */ 
2106     zd->new_ctb = new_ctb;
2107     zd->buf = inp;
2108     if( list_mode )
2109         printf(":compressed packet: algo=%d\n", zd->algorithm);
2110     return 0;
2111 }
2112
2113
2114 static int
2115 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
2116                                        PACKET *pkt, int new_ctb )
2117 {
2118     int rc = 0;
2119     PKT_encrypted *ed;
2120     unsigned long orig_pktlen = pktlen;
2121
2122     ed = pkt->pkt.encrypted =  m_alloc(sizeof *pkt->pkt.encrypted );
2123     ed->len = pktlen;
2124     /* we don't know the extralen which is (cipher_blocksize+2)
2125        because the algorithm ist not specified in this packet.
2126        However, it is only important to know this for some sanity
2127        checks on the packet length - it doesn't matter that we can't
2128        do it */
2129     ed->extralen = 0;
2130     ed->buf = NULL;
2131     ed->new_ctb = new_ctb;
2132     ed->mdc_method = 0;
2133     if( pkttype == PKT_ENCRYPTED_MDC ) {
2134         /* fixme: add some pktlen sanity checks */
2135         int version;
2136
2137         version = iobuf_get_noeof(inp); 
2138         if (orig_pktlen)
2139             pktlen--;
2140         if( version != 1 ) {
2141             log_error("encrypted_mdc packet with unknown version %d\n",
2142                                                                 version);
2143             /*skip_rest(inp, pktlen); should we really do this? */
2144             rc = G10ERR_INVALID_PACKET;
2145             goto leave;
2146         }
2147         ed->mdc_method = DIGEST_ALGO_SHA1;
2148     }
2149     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2150         log_error("packet(%d) too short\n", pkttype);
2151         rc = G10ERR_INVALID_PACKET;
2152         skip_rest(inp, pktlen);
2153         goto leave;
2154     }
2155     if( list_mode ) {
2156         if( orig_pktlen )
2157             printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2158         else
2159             printf(":encrypted data packet:\n\tlength: unknown\n");
2160         if( ed->mdc_method )
2161             printf("\tmdc_method: %d\n", ed->mdc_method );
2162     }
2163
2164     ed->buf = inp;
2165     pktlen = 0;
2166
2167   leave:
2168     return rc;
2169 }
2170
2171
2172 static int
2173 parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
2174                                    PACKET *pkt, int new_ctb )
2175 {
2176     int rc = 0;
2177     PKT_mdc *mdc;
2178     byte *p;
2179
2180     mdc = pkt->pkt.mdc=  m_alloc(sizeof *pkt->pkt.mdc );
2181     if( list_mode )
2182         printf(":mdc packet: length=%lu\n", pktlen);
2183     if( !new_ctb || pktlen != 20 ) {
2184         log_error("mdc_packet with invalid encoding\n");
2185         rc = G10ERR_INVALID_PACKET;
2186         goto leave;
2187     }
2188     p = mdc->hash;
2189     for( ; pktlen; pktlen--, p++ )
2190         *p = iobuf_get_noeof(inp);
2191
2192   leave:
2193     return rc;
2194 }
2195
2196
2197 /*
2198  * This packet is internally generated by PGG (by armor.c) to
2199  * transfer some information to the lower layer.  To make sure that
2200  * this packet is really a GPG faked one and not one comming from outside,
2201  * we first check that tehre is a unique tag in it.
2202  * The format of such a control packet is:
2203  *   n byte  session marker
2204  *   1 byte  control type CTRLPKT_xxxxx
2205  *   m byte  control data
2206  */
2207
2208 static int
2209 parse_gpg_control( IOBUF inp,
2210                    int pkttype, unsigned long pktlen, PACKET *packet )
2211 {
2212     byte *p;
2213     const byte *sesmark;
2214     size_t sesmarklen;
2215     int i;
2216
2217     if ( list_mode )
2218         printf(":packet 63: length %lu ",  pktlen);
2219
2220     sesmark = get_session_marker ( &sesmarklen );
2221     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2222         goto skipit;
2223     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2224         if ( sesmark[i] != iobuf_get_noeof(inp) )
2225             goto skipit;
2226     }
2227     if ( list_mode )
2228         puts ("- gpg control packet");
2229
2230     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2231                                       + pktlen - 1);
2232     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2233     packet->pkt.gpg_control->datalen = pktlen;
2234     p = packet->pkt.gpg_control->data;
2235     for( ; pktlen; pktlen--, p++ )
2236         *p = iobuf_get_noeof(inp);
2237
2238     return 0;
2239
2240  skipit:
2241     if ( list_mode ) {
2242         int c;
2243
2244         i=0;
2245         printf("- private (rest length %lu)\n",  pktlen);
2246         if( iobuf_in_block_mode(inp) ) {
2247             while( (c=iobuf_get(inp)) != -1 )
2248                 dump_hex_line(c, &i);
2249         }
2250         else {
2251             for( ; pktlen; pktlen-- )
2252                 dump_hex_line(iobuf_get(inp), &i);
2253         }
2254         putchar('\n');
2255     }
2256     skip_rest(inp,pktlen);
2257     return G10ERR_INVALID_PACKET;
2258 }
2259
2260 /* create a gpg control packet to be used internally as a placeholder */
2261 PACKET *
2262 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2263 {
2264     PACKET *packet;
2265     byte *p;
2266
2267     packet = m_alloc( sizeof *packet );
2268     init_packet(packet);
2269     packet->pkttype = PKT_GPG_CONTROL;
2270     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2271                                       + datalen - 1);
2272     packet->pkt.gpg_control->control = type;
2273     packet->pkt.gpg_control->datalen = datalen;
2274     p = packet->pkt.gpg_control->data;
2275     for( ; datalen; datalen--, p++ )
2276         *p = *data++;
2277
2278     return packet;
2279 }