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