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