fc9e2559f189af35f613c20db12db385b9c2bf21
[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
1566         if( !npkey ) {
1567             sk->skey[0] = mpi_set_opaque( NULL,
1568                                           read_rest(inp, pktlen), pktlen );
1569             pktlen = 0;
1570             goto leave;
1571         }
1572
1573         for(i=0; i < npkey; i++ ) {
1574             n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1575             if( list_mode ) {
1576                 printf(  "\tskey[%d]: ", i);
1577                 mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1578                 putchar('\n');
1579             }
1580             if (!sk->skey[i])
1581                 rc = GPG_ERR_INV_PACKET;
1582         }
1583         if (rc) /* one of the MPIs were bad */
1584             goto leave;
1585         sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1586         sk->protect.sha1chk = 0;
1587         if( sk->protect.algo ) {
1588             sk->is_protected = 1;
1589             sk->protect.s2k.count = 0;
1590             if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1591                 if( pktlen < 3 ) {
1592                     rc = GPG_ERR_INV_PACKET;
1593                     goto leave;
1594                 }
1595                 sk->protect.sha1chk = (sk->protect.algo == 254);
1596                 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1597                 /* Note that a sk->protect.algo > 110 is illegal, but
1598                    I'm not erroring on it here as otherwise there
1599                    would be no way to delete such a key. */
1600                 sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
1601                 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1602                 /* check for the special GNU extension */
1603                 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1604                     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1605                         temp[i] = iobuf_get_noeof(inp);
1606                     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1607                         if( list_mode )
1608                             printf(  "\tunknown S2K %d\n",
1609                                                 sk->protect.s2k.mode );
1610                         rc = GPG_ERR_INV_PACKET;
1611                         goto leave;
1612                     }
1613                     /* here we know that it is a gnu extension
1614                      * What follows is the GNU protection mode:
1615                      * All values have special meanings
1616                      * and they are mapped in the mode with a base of 1000.
1617                      */
1618                     sk->protect.s2k.mode = 1000 + temp[3];
1619                 }
1620                 switch( sk->protect.s2k.mode ) {
1621                   case 1:
1622                   case 3:
1623                     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1624                         temp[i] = iobuf_get_noeof(inp);
1625                     memcpy(sk->protect.s2k.salt, temp, 8 );
1626                     break;
1627                 }
1628                 switch( sk->protect.s2k.mode ) {
1629                   case 0: if( list_mode ) printf(  "\tsimple S2K" );
1630                     break;
1631                   case 1: if( list_mode ) printf(  "\tsalted S2K" );
1632                     break;
1633                   case 3: if( list_mode ) printf(  "\titer+salt S2K" );
1634                     break;
1635                   case 1001: if( list_mode ) printf(  "\tgnu-dummy S2K" );
1636                     break;
1637                   case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1638                     break;
1639                   default:
1640                     if( list_mode )
1641                         printf(  "\tunknown %sS2K %d\n",
1642                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1643                                                    sk->protect.s2k.mode );
1644                     rc = GPG_ERR_INV_PACKET;
1645                     goto leave;
1646                 }
1647
1648                 if( list_mode ) {
1649                     printf(", algo: %d,%s hash: %d",
1650                                      sk->protect.algo,
1651                                      sk->protect.sha1chk?" SHA1 protection,"
1652                                                         :" simple checksum,",
1653                                      sk->protect.s2k.hash_algo );
1654                     if( sk->protect.s2k.mode == 1
1655                         || sk->protect.s2k.mode == 3 ) {
1656                         printf(", salt: ");
1657                         for(i=0; i < 8; i++ )
1658                             printf("%02x", sk->protect.s2k.salt[i]);
1659                     }
1660                     putchar('\n');
1661                 }
1662
1663                 if( sk->protect.s2k.mode == 3 ) {
1664                     if( pktlen < 1 ) {
1665                         rc = GPG_ERR_INV_PACKET;
1666                         goto leave;
1667                     }
1668                     sk->protect.s2k.count = iobuf_get(inp);
1669                     pktlen--;
1670                     if( list_mode )
1671                         printf("\tprotect count: %lu\n",
1672                                             (ulong)sk->protect.s2k.count);
1673                 }
1674                 else if( sk->protect.s2k.mode == 1002 ) {
1675                     size_t snlen;
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                     if( list_mode ) {
1689                       printf("\tserial-number: ");
1690                       for (;snlen; snlen--)
1691                         printf ("%02X", (unsigned int)iobuf_get_noeof (inp));
1692                       putchar ('\n');
1693                     }
1694                     else {
1695                       for (;snlen; snlen--)
1696                         iobuf_get_noeof (inp);
1697                     }
1698                 }
1699             }
1700             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1701                not erroring on it here as otherwise there would be no
1702                way to delete such a key. */
1703             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1704                 sk->protect.s2k.mode = 0;
1705                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1706                 if( list_mode )
1707                     printf(  "\tprotect algo: %d  (hash algo: %d)\n",
1708                          sk->protect.algo, sk->protect.s2k.hash_algo );
1709             }
1710             /* It is really ugly that we don't know the size
1711              * of the IV here in cases we are not aware of the algorithm.
1712              * so a
1713              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1714              * won't work.  The only solution I see is to hardwire it here.
1715              * NOTE: if you change the ivlen above 16, don't forget to
1716              * enlarge temp.
1717              */
1718             switch( sk->protect.algo ) {
1719               case 7: case 8: case 9: /* reserved for AES */
1720               case 10: /* Twofish */
1721                 sk->protect.ivlen = 16;
1722                 break;
1723               default:
1724                 sk->protect.ivlen = 8;
1725             }
1726             if( sk->protect.s2k.mode == 1001 )
1727                 sk->protect.ivlen = 0;
1728             else if( sk->protect.s2k.mode == 1002 )
1729                 sk->protect.ivlen = 0;
1730
1731             if( pktlen < sk->protect.ivlen ) {
1732                 rc = GPG_ERR_INV_PACKET;
1733                 goto leave;
1734             }
1735             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1736                 temp[i] = iobuf_get_noeof(inp);
1737             if( list_mode ) {
1738                 printf(  "\tprotect IV: ");
1739                 for(i=0; i < sk->protect.ivlen; i++ )
1740                     printf(" %02x", temp[i] );
1741                 putchar('\n');
1742             }
1743             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1744         }
1745         else
1746             sk->is_protected = 0;
1747         /* It does not make sense to read it into secure memory.
1748          * If the user is so careless, not to protect his secret key,
1749          * we can assume, that he operates an open system :=(.
1750          * So we put the key into secure memory when we unprotect it. */
1751         if( sk->protect.s2k.mode == 1001
1752             || sk->protect.s2k.mode == 1002 ) {
1753             /* better set some dummy stuff here */
1754             sk->skey[npkey] = mpi_set_opaque(NULL, xstrdup ("dummydata"), 10);
1755             pktlen = 0;
1756         }
1757         else if( is_v4 && sk->is_protected ) {
1758             /* ugly; the length is encrypted too, so we read all
1759              * stuff up to the end of the packet into the first
1760              * skey element */
1761             sk->skey[npkey] = mpi_set_opaque(NULL,
1762                                              read_rest(inp, pktlen), pktlen );
1763             pktlen = 0;
1764             if( list_mode ) {
1765                 printf("\tencrypted stuff follows\n");
1766             }
1767         }
1768         else { /* v3 method: the mpi length is not encrypted */
1769             for(i=npkey; i < nskey; i++ ) {
1770                 if ( sk->is_protected ) {
1771                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1772                     if( list_mode ) 
1773                         printf(  "\tskey[%d]: [encrypted]\n", i);
1774                 }
1775                 else {
1776                     n = pktlen;
1777                     sk->skey[i] = mpi_read(inp, &n, 0 );
1778                     pktlen -=n;
1779                     if( list_mode ) {
1780                         printf(  "\tskey[%d]: ", i);
1781                         mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1782                         putchar('\n');
1783                     }
1784                 }
1785
1786                 if (!sk->skey[i])
1787                     rc = GPG_ERR_INV_PACKET;
1788             }
1789             if (rc)
1790                 goto leave;
1791
1792             sk->csum = read_16(inp); pktlen -= 2;
1793             if( list_mode ) {
1794                 printf("\tchecksum: %04hx\n", sk->csum);
1795             }
1796         }
1797     }
1798     else {
1799         PKT_public_key *pk = pkt->pkt.public_key;
1800
1801         if( !npkey ) {
1802             pk->pkey[0] = mpi_set_opaque( NULL,
1803                                           read_rest(inp, pktlen), pktlen );
1804             pktlen = 0;
1805             goto leave;
1806         }
1807
1808         for(i=0; i < npkey; i++ ) {
1809             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1810             if( list_mode ) {
1811                 printf(  "\tpkey[%d]: ", i);
1812                 mpi_print(stdout, pk->pkey[i], mpi_print_mode  );
1813                 putchar('\n');
1814             }
1815             if (!pk->pkey[i])
1816                 rc = GPG_ERR_INV_PACKET;
1817         }
1818         if (rc)
1819             goto leave;
1820     }
1821
1822   leave:
1823     skip_rest(inp, pktlen);
1824     return rc;
1825 }
1826
1827 /* Attribute subpackets have the same format as v4 signature
1828    subpackets.  This is not part of OpenPGP, but is done in several
1829    versions of PGP nevertheless. */
1830 int
1831 parse_attribute_subpkts(PKT_user_id *uid)
1832 {
1833   size_t n;
1834   int count=0;
1835   struct user_attribute *attribs=NULL;
1836   const byte *buffer=uid->attrib_data;
1837   int buflen=uid->attrib_len;
1838   byte type;
1839
1840   xfree (uid->attribs);
1841
1842   while(buflen)
1843     {
1844       n = *buffer++; buflen--;
1845       if( n == 255 ) { /* 4 byte length header */
1846         if( buflen < 4 )
1847           goto too_short;
1848         n = (buffer[0] << 24) | (buffer[1] << 16)
1849           | (buffer[2] << 8) | buffer[3];
1850         buffer += 4;
1851         buflen -= 4;
1852       }
1853       else if( n >= 192 ) { /* 2 byte special encoded length header */
1854         if( buflen < 2 )
1855           goto too_short;
1856         n = (( n - 192 ) << 8) + *buffer + 192;
1857         buffer++;
1858         buflen--;
1859       }
1860       if( buflen < n )
1861         goto too_short;
1862
1863       attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute));
1864       memset(&attribs[count],0,sizeof(struct user_attribute));
1865
1866       type=*buffer;
1867       buffer++;
1868       buflen--;
1869       n--;
1870
1871       attribs[count].type=type;
1872       attribs[count].data=buffer;
1873       attribs[count].len=n;
1874       buffer+=n;
1875       buflen-=n;
1876       count++;
1877     }
1878
1879   uid->attribs=attribs;
1880   uid->numattribs=count;
1881   return count;
1882
1883  too_short:
1884   log_error("buffer shorter than attribute subpacket\n");
1885   uid->attribs=attribs;
1886   uid->numattribs=count;
1887   return count;
1888 }
1889
1890 static void setup_user_id(PACKET *packet)
1891 {
1892   packet->pkt.user_id->ref = 1;
1893   packet->pkt.user_id->attribs = NULL;
1894   packet->pkt.user_id->attrib_data = NULL;
1895   packet->pkt.user_id->attrib_len = 0;
1896   packet->pkt.user_id->is_primary = 0;
1897   packet->pkt.user_id->is_revoked = 0;
1898   packet->pkt.user_id->is_expired = 0;
1899   packet->pkt.user_id->expiredate = 0;
1900   packet->pkt.user_id->created = 0;
1901   packet->pkt.user_id->help_key_usage = 0;
1902   packet->pkt.user_id->help_key_expire = 0;
1903   packet->pkt.user_id->prefs = NULL;
1904   packet->pkt.user_id->namehash = NULL;
1905 }
1906
1907 static int
1908 parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
1909 {
1910     byte *p;
1911
1912     packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id  + pktlen);
1913     packet->pkt.user_id->len = pktlen;
1914
1915     setup_user_id(packet);
1916
1917     p = packet->pkt.user_id->name;
1918     for( ; pktlen; pktlen--, p++ )
1919         *p = iobuf_get_noeof(inp);
1920     *p = 0;
1921
1922     if( list_mode ) {
1923         int n = packet->pkt.user_id->len;
1924         printf(":user ID packet: \"");
1925         /* fixme: Hey why don't we replace this with print_string?? */
1926         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1927             if( *p >= ' ' && *p <= 'z' )
1928                 putchar(*p);
1929             else
1930                 printf("\\x%02x", *p );
1931         }
1932         printf("\"\n");
1933     }
1934     return 0;
1935 }
1936
1937
1938 void
1939 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
1940 {
1941   assert ( max_namelen > 70 );
1942   if(uid->numattribs<=0)
1943     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
1944   else if(uid->numattribs>1)
1945     sprintf(uid->name,"[%d attributes of size %lu]",
1946             uid->numattribs,uid->attrib_len);
1947   else
1948     {
1949       /* Only one attribute, so list it as the "user id" */
1950
1951       if(uid->attribs->type==ATTRIB_IMAGE)
1952         {
1953           u32 len;
1954           byte type;
1955
1956           if(parse_image_header(uid->attribs,&type,&len))
1957             sprintf(uid->name,"[%.20s image of size %lu]",
1958                     image_type_to_string(type,1),(ulong)len);
1959           else
1960             sprintf(uid->name,"[invalid image]");
1961         }
1962       else
1963         sprintf(uid->name,"[unknown attribute of size %lu]",
1964                 (ulong)uid->attribs->len);
1965     }
1966
1967   uid->len = strlen(uid->name);
1968 }
1969
1970 static int
1971 parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
1972 {
1973     byte *p;
1974
1975 #define EXTRA_UID_NAME_SPACE 71
1976     packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id
1977                                   + EXTRA_UID_NAME_SPACE);
1978
1979     setup_user_id(packet);
1980
1981     packet->pkt.user_id->attrib_data = xmalloc (pktlen);
1982     packet->pkt.user_id->attrib_len = pktlen;
1983     p = packet->pkt.user_id->attrib_data;
1984     for( ; pktlen; pktlen--, p++ )
1985         *p = iobuf_get_noeof(inp);
1986
1987     /* Now parse out the individual attribute subpackets.  This is
1988        somewhat pointless since there is only one currently defined
1989        attribute type (jpeg), but it is correct by the spec. */
1990     parse_attribute_subpkts(packet->pkt.user_id);
1991
1992     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
1993
1994     if( list_mode ) {
1995         printf(":attribute packet: %s\n", packet->pkt.user_id->name );
1996     }
1997     return 0;
1998 }
1999
2000
2001 static int
2002 parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2003 {
2004     byte *p;
2005
2006     packet->pkt.comment = xmalloc (sizeof *packet->pkt.comment + pktlen - 1);
2007     packet->pkt.comment->len = pktlen;
2008     p = packet->pkt.comment->data;
2009     for( ; pktlen; pktlen--, p++ )
2010         *p = iobuf_get_noeof(inp);
2011
2012     if( list_mode ) {
2013         int n = packet->pkt.comment->len;
2014         printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2015                                          "OpenPGP draft " : "" );
2016         for(p=packet->pkt.comment->data; n; p++, n-- ) {
2017             if( *p >= ' ' && *p <= 'z' )
2018                 putchar(*p);
2019             else
2020                 printf("\\x%02x", *p );
2021         }
2022         printf("\"\n");
2023     }
2024     return 0;
2025 }
2026
2027
2028 static void
2029 parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2030 {
2031   int c;
2032
2033   if (pktlen)
2034     {
2035       c = iobuf_get_noeof(inp);
2036       pktlen--;
2037       pkt->pkt.ring_trust = xmalloc ( sizeof *pkt->pkt.ring_trust );
2038       pkt->pkt.ring_trust->trustval = c;
2039       pkt->pkt.ring_trust->sigcache = 0;
2040       if (!c && pktlen==1)
2041         {
2042           c = iobuf_get_noeof (inp);
2043           pktlen--;
2044           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2045           if ( !(c & 0x80) )
2046             pkt->pkt.ring_trust->sigcache = c;
2047         }
2048       if( list_mode )
2049         printf(":trust packet: flag=%02x sigcache=%02x\n",
2050                pkt->pkt.ring_trust->trustval,
2051                pkt->pkt.ring_trust->sigcache);
2052     }
2053   else
2054     {
2055       if( list_mode )
2056         printf(":trust packet: empty\n");
2057     }
2058   skip_rest (inp, pktlen);
2059 }
2060
2061
2062 static int
2063 parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen,
2064                                         PACKET *pkt, int new_ctb )
2065 {
2066     int rc = 0;
2067     int mode, namelen, partial=0;
2068     PKT_plaintext *pt;
2069     byte *p;
2070     int c, i;
2071
2072     if( pktlen && pktlen < 6 ) {
2073         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2074         rc = GPG_ERR_INV_PACKET;
2075         goto leave;
2076     }
2077     /* A packet length of zero indicates partial body length.  A zero
2078        data length isn't a zero length packet due to the header (mode,
2079        name, etc), so this is accurate. */
2080     if(pktlen==0)
2081       partial=1;
2082     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2083     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2084     pt = pkt->pkt.plaintext = xmalloc (sizeof *pkt->pkt.plaintext + namelen -1);
2085     pt->new_ctb = new_ctb;
2086     pt->mode = mode;
2087     pt->namelen = namelen;
2088     pt->is_partial = partial;
2089     if( pktlen ) {
2090         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2091             pt->name[i] = iobuf_get_noeof(inp);
2092     }
2093     else {
2094         for( i=0; i < namelen; i++ )
2095             if( (c=iobuf_get(inp)) == -1 )
2096                 break;
2097             else
2098                 pt->name[i] = c;
2099     }
2100     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2101     pt->len = pktlen;
2102     pt->buf = inp;
2103     pktlen = 0;
2104
2105     if( list_mode ) {
2106         printf(":literal data packet:\n"
2107                "\tmode %c, created %lu, name=\"",
2108                     mode >= ' ' && mode <'z'? mode : '?',
2109                     (ulong)pt->timestamp );
2110         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2111             if( *p >= ' ' && *p <= 'z' )
2112                 putchar(*p);
2113             else
2114                 printf("\\x%02x", *p );
2115         }
2116         printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2117     }
2118
2119   leave:
2120     return rc;
2121 }
2122
2123
2124 static int
2125 parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen,
2126                   PACKET *pkt, int new_ctb )
2127 {
2128     PKT_compressed *zd;
2129
2130     /* pktlen is here 0, but data follows
2131      * (this should be the last object in a file or
2132      *  the compress algorithm should know the length)
2133      */
2134     zd = pkt->pkt.compressed =  xmalloc (sizeof *pkt->pkt.compressed );
2135     zd->algorithm = iobuf_get_noeof(inp);
2136     zd->len = 0; /* not used */ 
2137     zd->new_ctb = new_ctb;
2138     zd->buf = inp;
2139     if( list_mode )
2140         printf(":compressed packet: algo=%d\n", zd->algorithm);
2141     return 0;
2142 }
2143
2144
2145 static int
2146 parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen,
2147                                        PACKET *pkt, int new_ctb )
2148 {
2149     int rc = 0;
2150     PKT_encrypted *ed;
2151     unsigned long orig_pktlen = pktlen;
2152
2153     ed = pkt->pkt.encrypted =  xmalloc (sizeof *pkt->pkt.encrypted );
2154     ed->len = pktlen;
2155     /* we don't know the extralen which is (cipher_blocksize+2)
2156        because the algorithm ist not specified in this packet.
2157        However, it is only important to know this for some sanity
2158        checks on the packet length - it doesn't matter that we can't
2159        do it */
2160     ed->extralen = 0;
2161     ed->buf = NULL;
2162     ed->new_ctb = new_ctb;
2163     ed->mdc_method = 0;
2164     if( pkttype == PKT_ENCRYPTED_MDC ) {
2165         /* fixme: add some pktlen sanity checks */
2166         int version;
2167
2168         version = iobuf_get_noeof(inp); 
2169         if (orig_pktlen)
2170             pktlen--;
2171         if( version != 1 ) {
2172             log_error("encrypted_mdc packet with unknown version %d\n",
2173                                                                 version);
2174             /*skip_rest(inp, pktlen); should we really do this? */
2175             rc = GPG_ERR_INV_PACKET;
2176             goto leave;
2177         }
2178         ed->mdc_method = DIGEST_ALGO_SHA1;
2179     }
2180     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2181         log_error("packet(%d) too short\n", pkttype);
2182         rc = GPG_ERR_INV_PACKET;
2183         skip_rest(inp, pktlen);
2184         goto leave;
2185     }
2186     if( list_mode ) {
2187         if( orig_pktlen )
2188             printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2189         else
2190             printf(":encrypted data packet:\n\tlength: unknown\n");
2191         if( ed->mdc_method )
2192             printf("\tmdc_method: %d\n", ed->mdc_method );
2193     }
2194
2195     ed->buf = inp;
2196     pktlen = 0;
2197
2198   leave:
2199     return rc;
2200 }
2201
2202
2203 static int
2204 parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen,
2205                                    PACKET *pkt, int new_ctb )
2206 {
2207     int rc = 0;
2208     PKT_mdc *mdc;
2209     byte *p;
2210
2211     mdc = pkt->pkt.mdc=  xmalloc (sizeof *pkt->pkt.mdc );
2212     if( list_mode )
2213         printf(":mdc packet: length=%lu\n", pktlen);
2214     if( !new_ctb || pktlen != 20 ) {
2215         log_error("mdc_packet with invalid encoding\n");
2216         rc = GPG_ERR_INV_PACKET;
2217         goto leave;
2218     }
2219     p = mdc->hash;
2220     for( ; pktlen; pktlen--, p++ )
2221         *p = iobuf_get_noeof(inp);
2222
2223   leave:
2224     return rc;
2225 }
2226
2227
2228 /*
2229  * This packet is internally generated by PGG (by armor.c) to
2230  * transfer some information to the lower layer.  To make sure that
2231  * this packet is really a GPG faked one and not one comming from outside,
2232  * we first check that tehre is a unique tag in it.
2233  * The format of such a control packet is:
2234  *   n byte  session marker
2235  *   1 byte  control type CTRLPKT_xxxxx
2236  *   m byte  control data
2237  */
2238
2239 static int
2240 parse_gpg_control( iobuf_t inp,
2241                    int pkttype, unsigned long pktlen, PACKET *packet )
2242 {
2243     byte *p;
2244     const byte *sesmark;
2245     size_t sesmarklen;
2246     int i;
2247
2248     if ( list_mode )
2249         printf(":packet 63: length %lu ",  pktlen);
2250
2251     sesmark = get_session_marker ( &sesmarklen );
2252     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2253         goto skipit;
2254     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2255         if ( sesmark[i] != iobuf_get_noeof(inp) )
2256             goto skipit;
2257     }
2258     if ( list_mode )
2259         puts ("- gpg control packet");
2260
2261     packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
2262                                       + pktlen - 1);
2263     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2264     packet->pkt.gpg_control->datalen = pktlen;
2265     p = packet->pkt.gpg_control->data;
2266     for( ; pktlen; pktlen--, p++ )
2267         *p = iobuf_get_noeof(inp);
2268
2269     return 0;
2270
2271  skipit:
2272     if ( list_mode ) {
2273         int c;
2274
2275         i=0;
2276         printf("- private (rest length %lu)\n",  pktlen);
2277         if( iobuf_in_block_mode(inp) ) {
2278             while( (c=iobuf_get(inp)) != -1 )
2279                 dump_hex_line(c, &i);
2280         }
2281         else {
2282             for( ; pktlen; pktlen-- )
2283                 dump_hex_line(iobuf_get(inp), &i);
2284         }
2285         putchar('\n');
2286     }
2287     skip_rest(inp,pktlen);
2288     return GPG_ERR_INV_PACKET;
2289 }
2290
2291 /* create a gpg control packet to be used internally as a placeholder */
2292 PACKET *
2293 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2294 {
2295     PACKET *packet;
2296     byte *p;
2297
2298     packet = xmalloc ( sizeof *packet );
2299     init_packet(packet);
2300     packet->pkttype = PKT_GPG_CONTROL;
2301     packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
2302                                       + datalen - 1);
2303     packet->pkt.gpg_control->control = type;
2304     packet->pkt.gpg_control->datalen = datalen;
2305     p = packet->pkt.gpg_control->data;
2306     for( ; datalen; datalen--, p++ )
2307         *p = *data++;
2308
2309     return packet;
2310 }