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