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