* keygen.c (do_add_key_flags, parse_parameter_usage): Add support
[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           sig->timestamp = buffer_to_u32(p);
1286         else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
1287           log_error("signature packet without timestamp\n");
1288
1289         p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1290         if(p)
1291           {
1292             sig->keyid[0] = buffer_to_u32(p);
1293             sig->keyid[1] = buffer_to_u32(p+4);
1294           }
1295         else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
1296           log_error("signature packet without keyid\n");
1297
1298         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1299         if(p)
1300           sig->expiredate=sig->timestamp+buffer_to_u32(p);
1301         if(sig->expiredate && sig->expiredate<=make_timestamp())
1302             sig->flags.expired=1;
1303
1304         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1305         if(p)
1306           sig->flags.policy_url=1;
1307
1308         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
1309         if(p)
1310           sig->flags.pref_ks=1;
1311
1312         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1313         if(p)
1314           sig->flags.notation=1;
1315
1316         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1317         if(p && *p==0)
1318           sig->flags.revocable=0;
1319
1320         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len);
1321         if(p && len==2)
1322           {
1323             sig->trust_depth=p[0];
1324             sig->trust_value=p[1];
1325
1326             /* Only look for a regexp if there is also a trust
1327                subpacket. */
1328             sig->trust_regexp=
1329               parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len);
1330
1331             /* If the regular expression is of 0 length, there is no
1332                regular expression. */
1333             if(len==0)
1334               sig->trust_regexp=NULL;
1335           }
1336
1337         /* We accept the exportable subpacket from either the hashed
1338            or unhashed areas as older versions of gpg put it in the
1339            unhashed area.  In theory, anyway, we should never see this
1340            packet off of a local keyring. */
1341
1342         p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1343         if(p && *p==0)
1344           sig->flags.exportable=0;
1345
1346         /* Find all revocation keys. */
1347         if(sig->sig_class==0x1F)
1348           parse_revkeys(sig);
1349     }
1350
1351     if( list_mode ) {
1352         printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1353                "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1354                "\tdigest algo %d, begin of digest %02x %02x\n",
1355                 sig->pubkey_algo,
1356                 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1357                 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1358                 sig->digest_algo,
1359                 sig->digest_start[0], sig->digest_start[1] );
1360         if( is_v4 ) {
1361             parse_sig_subpkt (sig->hashed,   SIGSUBPKT_LIST_HASHED, NULL );
1362             parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1363         }
1364     }
1365
1366     ndata = pubkey_get_nsig(sig->pubkey_algo);
1367     if( !ndata ) {
1368         if( list_mode )
1369             printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1370         unknown_pubkey_warning( sig->pubkey_algo );
1371         /* we store the plain material in data[0], so that we are able
1372          * to write it back with build_packet() */
1373         sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1374         pktlen = 0;
1375     }
1376     else {
1377         for( i=0; i < ndata; i++ ) {
1378             n = pktlen;
1379             sig->data[i] = mpi_read(inp, &n, 0 );
1380             pktlen -=n;
1381             if( list_mode ) {
1382                 printf("\tdata: ");
1383                 mpi_print(stdout, sig->data[i], mpi_print_mode );
1384                 putchar('\n');
1385             }
1386             if (!sig->data[i])
1387                 rc = G10ERR_INVALID_PACKET;
1388         }
1389     }
1390
1391   leave:
1392     skip_rest(inp, pktlen);
1393     return rc;
1394 }
1395
1396
1397 static int
1398 parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
1399                                              PKT_onepass_sig *ops )
1400 {
1401     int version;
1402     int rc = 0;
1403
1404     if( pktlen < 13 ) {
1405         log_error("packet(%d) too short\n", pkttype);
1406         rc = G10ERR_INVALID_PACKET;
1407         goto leave;
1408     }
1409     version = iobuf_get_noeof(inp); pktlen--;
1410     if( version != 3 ) {
1411         log_error("onepass_sig with unknown version %d\n", version);
1412         rc = G10ERR_INVALID_PACKET;
1413         goto leave;
1414     }
1415     ops->sig_class = iobuf_get_noeof(inp); pktlen--;
1416     ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
1417     ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
1418     ops->keyid[0] = read_32(inp); pktlen -= 4;
1419     ops->keyid[1] = read_32(inp); pktlen -= 4;
1420     ops->last = iobuf_get_noeof(inp); pktlen--;
1421     if( list_mode )
1422         printf(":onepass_sig packet: keyid %08lX%08lX\n"
1423                "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1424                 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1425                 version, ops->sig_class,
1426                 ops->digest_algo, ops->pubkey_algo, ops->last );
1427
1428
1429   leave:
1430     skip_rest(inp, pktlen);
1431     return rc;
1432 }
1433
1434
1435 static MPI
1436 read_protected_v3_mpi (IOBUF inp, unsigned long *length)
1437 {
1438   int c;
1439   unsigned int nbits, nbytes;
1440   unsigned char *buf, *p;
1441   MPI val;
1442
1443   if (*length < 2)
1444     {
1445       log_error ("mpi too small\n");
1446       return NULL;
1447     }
1448
1449   if ((c=iobuf_get (inp)) == -1)
1450     return NULL;
1451   --*length;
1452   nbits = c << 8;
1453   if ((c=iobuf_get(inp)) == -1)
1454     return NULL;
1455   --*length;
1456   nbits |= c;
1457
1458   if (nbits > 16384)
1459     {
1460       log_error ("mpi too large (%u bits)\n", nbits);
1461       return NULL;
1462     }
1463   nbytes = (nbits+7) / 8;
1464   buf = p = m_alloc (2 + nbytes);
1465   *p++ = nbits >> 8;
1466   *p++ = nbits;
1467   for (; nbytes && length; nbytes--, --*length)
1468     *p++ = iobuf_get (inp);
1469   if (nbytes)
1470     {
1471       log_error ("packet shorter tham mpi\n");
1472       m_free (buf);
1473       return NULL;
1474     }
1475
1476   /* convert buffer into an opaque MPI */
1477   val = mpi_set_opaque (NULL, buf, p-buf); 
1478   return val;
1479 }
1480
1481
1482 static int
1483 parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
1484                               byte *hdr, int hdrlen, PACKET *pkt )
1485 {
1486     int i, version, algorithm;
1487     unsigned n;
1488     unsigned long timestamp, expiredate, max_expiredate;
1489     int npkey, nskey;
1490     int is_v4=0;
1491     int rc=0;
1492
1493     version = iobuf_get_noeof(inp); pktlen--;
1494     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1495         /* early versions of G10 use old PGP comments packets;
1496          * luckily all those comments are started by a hash */
1497         if( list_mode ) {
1498             printf(":rfc1991 comment packet: \"" );
1499             for( ; pktlen; pktlen-- ) {
1500                 int c;
1501                 c = iobuf_get_noeof(inp);
1502                 if( c >= ' ' && c <= 'z' )
1503                     putchar(c);
1504                 else
1505                     printf("\\x%02x", c );
1506             }
1507             printf("\"\n");
1508         }
1509         skip_rest(inp, pktlen);
1510         return 0;
1511     }
1512     else if( version == 4 )
1513         is_v4=1;
1514     else if( version != 2 && version != 3 ) {
1515         log_error("packet(%d) with unknown version %d\n", pkttype, version);
1516         rc = G10ERR_INVALID_PACKET;
1517         goto leave;
1518     }
1519
1520     if( pktlen < 11 ) {
1521         log_error("packet(%d) too short\n", pkttype);
1522         rc = G10ERR_INVALID_PACKET;
1523         goto leave;
1524     }
1525
1526     timestamp = read_32(inp); pktlen -= 4;
1527     if( is_v4 ) {
1528         expiredate = 0; /* have to get it from the selfsignature */
1529         max_expiredate = 0;
1530     }
1531     else {
1532         unsigned short ndays;
1533         ndays = read_16(inp); pktlen -= 2;
1534         if( ndays )
1535             expiredate = timestamp + ndays * 86400L;
1536         else
1537             expiredate = 0;
1538
1539         max_expiredate=expiredate;
1540     }
1541     algorithm = iobuf_get_noeof(inp); pktlen--;
1542     if( list_mode )
1543         printf(":%s key packet:\n"
1544                "\tversion %d, algo %d, created %lu, expires %lu\n",
1545                 pkttype == PKT_PUBLIC_KEY? "public" :
1546                 pkttype == PKT_SECRET_KEY? "secret" :
1547                 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1548                 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1549                 version, algorithm, timestamp, expiredate );
1550
1551     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY )  {
1552         PKT_secret_key *sk = pkt->pkt.secret_key;
1553
1554         sk->timestamp = timestamp;
1555         sk->expiredate = expiredate;
1556         sk->max_expiredate = max_expiredate;
1557         sk->hdrbytes = hdrlen;
1558         sk->version = version;
1559         sk->is_primary = pkttype == PKT_SECRET_KEY;
1560         sk->pubkey_algo = algorithm;
1561         sk->req_usage = 0; 
1562         sk->pubkey_usage = 0; /* not yet used */
1563     }
1564     else {
1565         PKT_public_key *pk = pkt->pkt.public_key;
1566
1567         pk->timestamp = timestamp;
1568         pk->expiredate = expiredate;
1569         pk->max_expiredate = max_expiredate;
1570         pk->hdrbytes    = hdrlen;
1571         pk->version     = version;
1572         pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1573         pk->pubkey_algo = algorithm;
1574         pk->req_usage = 0; 
1575         pk->pubkey_usage = 0; /* not yet used */
1576         pk->is_revoked = 0;
1577         pk->is_disabled = 0;
1578         pk->keyid[0] = 0;
1579         pk->keyid[1] = 0;
1580     }
1581     nskey = pubkey_get_nskey( algorithm );
1582     npkey = pubkey_get_npkey( algorithm );
1583     if( !npkey ) {
1584         if( list_mode )
1585             printf("\tunknown algorithm %d\n", algorithm );
1586         unknown_pubkey_warning( algorithm );
1587     }
1588
1589
1590     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1591         PKT_secret_key *sk = pkt->pkt.secret_key;
1592         byte temp[16];
1593         size_t snlen = 0;
1594
1595         if( !npkey ) {
1596             sk->skey[0] = mpi_set_opaque( NULL,
1597                                           read_rest(inp, pktlen), pktlen );
1598             pktlen = 0;
1599             goto leave;
1600         }
1601
1602         for(i=0; i < npkey; i++ ) {
1603             n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1604             if( list_mode ) {
1605                 printf(  "\tskey[%d]: ", i);
1606                 mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1607                 putchar('\n');
1608             }
1609             if (!sk->skey[i])
1610                 rc = G10ERR_INVALID_PACKET;
1611         }
1612         if (rc) /* one of the MPIs were bad */
1613             goto leave;
1614         sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1615         sk->protect.sha1chk = 0;
1616         if( sk->protect.algo ) {
1617             sk->is_protected = 1;
1618             sk->protect.s2k.count = 0;
1619             if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1620                 if( pktlen < 3 ) {
1621                     rc = G10ERR_INVALID_PACKET;
1622                     goto leave;
1623                 }
1624                 sk->protect.sha1chk = (sk->protect.algo == 254);
1625                 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1626                 /* Note that a sk->protect.algo > 110 is illegal, but
1627                    I'm not erroring on it here as otherwise there
1628                    would be no way to delete such a key. */
1629                 sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
1630                 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1631                 /* check for the special GNU extension */
1632                 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1633                     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1634                         temp[i] = iobuf_get_noeof(inp);
1635                     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1636                         if( list_mode )
1637                             printf(  "\tunknown S2K %d\n",
1638                                                 sk->protect.s2k.mode );
1639                         rc = G10ERR_INVALID_PACKET;
1640                         goto leave;
1641                     }
1642                     /* here we know that it is a gnu extension
1643                      * What follows is the GNU protection mode:
1644                      * All values have special meanings
1645                      * and they are mapped in the mode with a base of 1000.
1646                      */
1647                     sk->protect.s2k.mode = 1000 + temp[3];
1648                 }
1649                 switch( sk->protect.s2k.mode ) {
1650                   case 1:
1651                   case 3:
1652                     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1653                         temp[i] = iobuf_get_noeof(inp);
1654                     memcpy(sk->protect.s2k.salt, temp, 8 );
1655                     break;
1656                 }
1657                 switch( sk->protect.s2k.mode ) {
1658                   case 0: if( list_mode ) printf(  "\tsimple S2K" );
1659                     break;
1660                   case 1: if( list_mode ) printf(  "\tsalted S2K" );
1661                     break;
1662                   case 3: if( list_mode ) printf(  "\titer+salt S2K" );
1663                     break;
1664                   case 1001: if( list_mode ) printf(  "\tgnu-dummy S2K" );
1665                     break;
1666                   case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1667                     break;
1668                   default:
1669                     if( list_mode )
1670                         printf(  "\tunknown %sS2K %d\n",
1671                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1672                                                    sk->protect.s2k.mode );
1673                     rc = G10ERR_INVALID_PACKET;
1674                     goto leave;
1675                 }
1676
1677                 if( list_mode ) {
1678                     printf(", algo: %d,%s hash: %d",
1679                                      sk->protect.algo,
1680                                      sk->protect.sha1chk?" SHA1 protection,"
1681                                                         :" simple checksum,",
1682                                      sk->protect.s2k.hash_algo );
1683                     if( sk->protect.s2k.mode == 1
1684                         || sk->protect.s2k.mode == 3 ) {
1685                         printf(", salt: ");
1686                         for(i=0; i < 8; i++ )
1687                             printf("%02x", sk->protect.s2k.salt[i]);
1688                     }
1689                     putchar('\n');
1690                 }
1691
1692                 if( sk->protect.s2k.mode == 3 ) {
1693                     if( pktlen < 1 ) {
1694                         rc = G10ERR_INVALID_PACKET;
1695                         goto leave;
1696                     }
1697                     sk->protect.s2k.count = iobuf_get(inp);
1698                     pktlen--;
1699                     if( list_mode )
1700                         printf("\tprotect count: %lu\n",
1701                                             (ulong)sk->protect.s2k.count);
1702                 }
1703                 else if( sk->protect.s2k.mode == 1002 ) {
1704                     /* Read the serial number. */
1705                     if (pktlen < 1) {
1706                       rc = G10ERR_INVALID_PACKET;
1707                         goto leave;
1708                     }
1709                     snlen = iobuf_get (inp);
1710                     pktlen--;
1711                     if (pktlen < snlen || snlen == -1) {
1712                         rc = G10ERR_INVALID_PACKET;
1713                         goto leave;
1714                     }
1715                 }
1716             }
1717             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1718                not erroring on it here as otherwise there would be no
1719                way to delete such a key. */
1720             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1721                 sk->protect.s2k.mode = 0;
1722                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1723                 if( list_mode )
1724                     printf(  "\tprotect algo: %d  (hash algo: %d)\n",
1725                          sk->protect.algo, sk->protect.s2k.hash_algo );
1726             }
1727             /* It is really ugly that we don't know the size
1728              * of the IV here in cases we are not aware of the algorithm.
1729              * so a
1730              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1731              * won't work.  The only solution I see is to hardwire it here.
1732              * NOTE: if you change the ivlen above 16, don't forget to
1733              * enlarge temp.
1734              */
1735             switch( sk->protect.algo ) {
1736               case 7: case 8: case 9: /* reserved for AES */
1737               case 10: /* Twofish */
1738                 sk->protect.ivlen = 16;
1739                 break;
1740               default:
1741                 sk->protect.ivlen = 8;
1742             }
1743             if( sk->protect.s2k.mode == 1001 )
1744                 sk->protect.ivlen = 0;
1745             else if( sk->protect.s2k.mode == 1002 )
1746                 sk->protect.ivlen = snlen < 16? snlen : 16;
1747
1748             if( pktlen < sk->protect.ivlen ) {
1749                 rc = G10ERR_INVALID_PACKET;
1750                 goto leave;
1751             }
1752             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1753                 temp[i] = iobuf_get_noeof(inp);
1754             if( list_mode ) {
1755                 printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
1756                                                     : "\tprotect IV: ");
1757                 for(i=0; i < sk->protect.ivlen; i++ )
1758                     printf(" %02x", temp[i] );
1759                 putchar('\n');
1760             }
1761             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1762         }
1763         else
1764             sk->is_protected = 0;
1765         /* It does not make sense to read it into secure memory.
1766          * If the user is so careless, not to protect his secret key,
1767          * we can assume, that he operates an open system :=(.
1768          * So we put the key into secure memory when we unprotect it. */
1769         if( sk->protect.s2k.mode == 1001 
1770             || sk->protect.s2k.mode == 1002 ) {
1771             /* better set some dummy stuff here */
1772             sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10);
1773             pktlen = 0;
1774         }
1775         else if( is_v4 && sk->is_protected ) {
1776             /* ugly; the length is encrypted too, so we read all
1777              * stuff up to the end of the packet into the first
1778              * skey element */
1779             sk->skey[npkey] = mpi_set_opaque(NULL,
1780                                              read_rest(inp, pktlen), pktlen );
1781             pktlen = 0;
1782             if( list_mode ) {
1783                 printf("\tencrypted stuff follows\n");
1784             }
1785         }
1786         else { /* v3 method: the mpi length is not encrypted */
1787             for(i=npkey; i < nskey; i++ ) {
1788                 if ( sk->is_protected ) {
1789                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1790                     if( list_mode ) 
1791                         printf(  "\tskey[%d]: [encrypted]\n", i);
1792                 }
1793                 else {
1794                     n = pktlen;
1795                     sk->skey[i] = mpi_read(inp, &n, 0 );
1796                     pktlen -=n;
1797                     if( list_mode ) {
1798                         printf(  "\tskey[%d]: ", i);
1799                         mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1800                         putchar('\n');
1801                     }
1802                 }
1803
1804                 if (!sk->skey[i])
1805                     rc = G10ERR_INVALID_PACKET;
1806             }
1807             if (rc)
1808                 goto leave;
1809
1810             sk->csum = read_16(inp); pktlen -= 2;
1811             if( list_mode ) {
1812                 printf("\tchecksum: %04hx\n", sk->csum);
1813             }
1814         }
1815     }
1816     else {
1817         PKT_public_key *pk = pkt->pkt.public_key;
1818
1819         if( !npkey ) {
1820             pk->pkey[0] = mpi_set_opaque( NULL,
1821                                           read_rest(inp, pktlen), pktlen );
1822             pktlen = 0;
1823             goto leave;
1824         }
1825
1826         for(i=0; i < npkey; i++ ) {
1827             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1828             if( list_mode ) {
1829                 printf(  "\tpkey[%d]: ", i);
1830                 mpi_print(stdout, pk->pkey[i], mpi_print_mode  );
1831                 putchar('\n');
1832             }
1833             if (!pk->pkey[i])
1834                 rc = G10ERR_INVALID_PACKET;
1835         }
1836         if (rc)
1837             goto leave;
1838     }
1839
1840   leave:
1841     skip_rest(inp, pktlen);
1842     return rc;
1843 }
1844
1845 /* Attribute subpackets have the same format as v4 signature
1846    subpackets.  This is not part of OpenPGP, but is done in several
1847    versions of PGP nevertheless. */
1848 int
1849 parse_attribute_subpkts(PKT_user_id *uid)
1850 {
1851   size_t n;
1852   int count=0;
1853   struct user_attribute *attribs=NULL;
1854   const byte *buffer=uid->attrib_data;
1855   int buflen=uid->attrib_len;
1856   byte type;
1857
1858   m_free(uid->attribs);
1859
1860   while(buflen)
1861     {
1862       n = *buffer++; buflen--;
1863       if( n == 255 ) { /* 4 byte length header */
1864         if( buflen < 4 )
1865           goto too_short;
1866         n = (buffer[0] << 24) | (buffer[1] << 16)
1867           | (buffer[2] << 8) | buffer[3];
1868         buffer += 4;
1869         buflen -= 4;
1870       }
1871       else if( n >= 192 ) { /* 2 byte special encoded length header */
1872         if( buflen < 2 )
1873           goto too_short;
1874         n = (( n - 192 ) << 8) + *buffer + 192;
1875         buffer++;
1876         buflen--;
1877       }
1878       if( buflen < n )
1879         goto too_short;
1880
1881       attribs=m_realloc(attribs,(count+1)*sizeof(struct user_attribute));
1882       memset(&attribs[count],0,sizeof(struct user_attribute));
1883
1884       type=*buffer;
1885       buffer++;
1886       buflen--;
1887       n--;
1888
1889       attribs[count].type=type;
1890       attribs[count].data=buffer;
1891       attribs[count].len=n;
1892       buffer+=n;
1893       buflen-=n;
1894       count++;
1895     }
1896
1897   uid->attribs=attribs;
1898   uid->numattribs=count;
1899   return count;
1900
1901  too_short:
1902   log_error("buffer shorter than attribute subpacket\n");
1903   uid->attribs=attribs;
1904   uid->numattribs=count;
1905   return count;
1906 }
1907
1908 static void setup_user_id(PACKET *packet)
1909 {
1910   packet->pkt.user_id->ref = 1;
1911   packet->pkt.user_id->attribs = NULL;
1912   packet->pkt.user_id->attrib_data = NULL;
1913   packet->pkt.user_id->attrib_len = 0;
1914   packet->pkt.user_id->is_primary = 0;
1915   packet->pkt.user_id->is_revoked = 0;
1916   packet->pkt.user_id->is_expired = 0;
1917   packet->pkt.user_id->expiredate = 0;
1918   packet->pkt.user_id->created = 0;
1919   packet->pkt.user_id->help_key_usage = 0;
1920   packet->pkt.user_id->help_key_expire = 0;
1921   packet->pkt.user_id->prefs = NULL;
1922   packet->pkt.user_id->namehash = NULL;
1923 }
1924
1925 static int
1926 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1927 {
1928     byte *p;
1929
1930     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen);
1931     packet->pkt.user_id->len = pktlen;
1932
1933     setup_user_id(packet);
1934
1935     p = packet->pkt.user_id->name;
1936     for( ; pktlen; pktlen--, p++ )
1937         *p = iobuf_get_noeof(inp);
1938     *p = 0;
1939
1940     if( list_mode ) {
1941         int n = packet->pkt.user_id->len;
1942         printf(":user ID packet: \"");
1943         /* fixme: Hey why don't we replace this with print_string?? */
1944         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1945             if( *p >= ' ' && *p <= 'z' )
1946                 putchar(*p);
1947             else
1948                 printf("\\x%02x", *p );
1949         }
1950         printf("\"\n");
1951     }
1952     return 0;
1953 }
1954
1955
1956 void
1957 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
1958 {
1959   assert ( max_namelen > 70 );
1960   if(uid->numattribs<=0)
1961     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
1962   else if(uid->numattribs>1)
1963     sprintf(uid->name,"[%d attributes of size %lu]",
1964             uid->numattribs,uid->attrib_len);
1965   else
1966     {
1967       /* Only one attribute, so list it as the "user id" */
1968
1969       if(uid->attribs->type==ATTRIB_IMAGE)
1970         {
1971           u32 len;
1972           byte type;
1973
1974           if(parse_image_header(uid->attribs,&type,&len))
1975             sprintf(uid->name,"[%.20s image of size %lu]",
1976                     image_type_to_string(type,1),(ulong)len);
1977           else
1978             sprintf(uid->name,"[invalid image]");
1979         }
1980       else
1981         sprintf(uid->name,"[unknown attribute of size %lu]",
1982                 (ulong)uid->attribs->len);
1983     }
1984
1985   uid->len = strlen(uid->name);
1986 }
1987
1988 static int
1989 parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1990 {
1991     byte *p;
1992
1993 #define EXTRA_UID_NAME_SPACE 71
1994     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id
1995                                   + EXTRA_UID_NAME_SPACE);
1996
1997     setup_user_id(packet);
1998
1999     packet->pkt.user_id->attrib_data = m_alloc(pktlen);
2000     packet->pkt.user_id->attrib_len = pktlen;
2001     p = packet->pkt.user_id->attrib_data;
2002     for( ; pktlen; pktlen--, p++ )
2003         *p = iobuf_get_noeof(inp);
2004
2005     /* Now parse out the individual attribute subpackets.  This is
2006        somewhat pointless since there is only one currently defined
2007        attribute type (jpeg), but it is correct by the spec. */
2008     parse_attribute_subpkts(packet->pkt.user_id);
2009
2010     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
2011
2012     if( list_mode ) {
2013         printf(":attribute packet: %s\n", packet->pkt.user_id->name );
2014     }
2015     return 0;
2016 }
2017
2018
2019 static int
2020 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2021 {
2022     byte *p;
2023
2024     packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
2025     packet->pkt.comment->len = pktlen;
2026     p = packet->pkt.comment->data;
2027     for( ; pktlen; pktlen--, p++ )
2028         *p = iobuf_get_noeof(inp);
2029
2030     if( list_mode ) {
2031         int n = packet->pkt.comment->len;
2032         printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2033                                          "OpenPGP draft " : "" );
2034         for(p=packet->pkt.comment->data; n; p++, n-- ) {
2035             if( *p >= ' ' && *p <= 'z' )
2036                 putchar(*p);
2037             else
2038                 printf("\\x%02x", *p );
2039         }
2040         printf("\"\n");
2041     }
2042     return 0;
2043 }
2044
2045
2046 static void
2047 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2048 {
2049   int c;
2050
2051   if (pktlen)
2052     {
2053       c = iobuf_get_noeof(inp);
2054       pktlen--;
2055       pkt->pkt.ring_trust = m_alloc( sizeof *pkt->pkt.ring_trust );
2056       pkt->pkt.ring_trust->trustval = c;
2057       pkt->pkt.ring_trust->sigcache = 0;
2058       if (!c && pktlen==1)
2059         {
2060           c = iobuf_get_noeof (inp);
2061           pktlen--;
2062           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2063           if ( !(c & 0x80) )
2064             pkt->pkt.ring_trust->sigcache = c;
2065         }
2066       if( list_mode )
2067         printf(":trust packet: flag=%02x sigcache=%02x\n",
2068                pkt->pkt.ring_trust->trustval,
2069                pkt->pkt.ring_trust->sigcache);
2070     }
2071   else
2072     {
2073       if( list_mode )
2074         printf(":trust packet: empty\n");
2075     }
2076   skip_rest (inp, pktlen);
2077 }
2078
2079
2080 static int
2081 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
2082                                         PACKET *pkt, int new_ctb )
2083 {
2084     int rc = 0;
2085     int mode, namelen, partial=0;
2086     PKT_plaintext *pt;
2087     byte *p;
2088     int c, i;
2089
2090     if( pktlen && pktlen < 6 ) {
2091         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2092         rc = G10ERR_INVALID_PACKET;
2093         goto leave;
2094     }
2095     /* A packet length of zero indicates partial body length.  A zero
2096        data length isn't a zero length packet due to the header (mode,
2097        name, etc), so this is accurate. */
2098     if(pktlen==0)
2099       partial=1;
2100     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2101     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2102     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
2103     pt->new_ctb = new_ctb;
2104     pt->mode = mode;
2105     pt->namelen = namelen;
2106     pt->is_partial = partial;
2107     if( pktlen ) {
2108         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2109             pt->name[i] = iobuf_get_noeof(inp);
2110     }
2111     else {
2112         for( i=0; i < namelen; i++ )
2113             if( (c=iobuf_get(inp)) == -1 )
2114                 break;
2115             else
2116                 pt->name[i] = c;
2117     }
2118     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2119     pt->len = pktlen;
2120     pt->buf = inp;
2121     pktlen = 0;
2122
2123     if( list_mode ) {
2124         printf(":literal data packet:\n"
2125                "\tmode %c, created %lu, name=\"",
2126                     mode >= ' ' && mode <'z'? mode : '?',
2127                     (ulong)pt->timestamp );
2128         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2129             if( *p >= ' ' && *p <= 'z' )
2130                 putchar(*p);
2131             else
2132                 printf("\\x%02x", *p );
2133         }
2134         printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2135     }
2136
2137   leave:
2138     return rc;
2139 }
2140
2141
2142 static int
2143 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
2144                   PACKET *pkt, int new_ctb )
2145 {
2146     PKT_compressed *zd;
2147
2148     /* pktlen is here 0, but data follows
2149      * (this should be the last object in a file or
2150      *  the compress algorithm should know the length)
2151      */
2152     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
2153     zd->algorithm = iobuf_get_noeof(inp);
2154     zd->len = 0; /* not used */ 
2155     zd->new_ctb = new_ctb;
2156     zd->buf = inp;
2157     if( list_mode )
2158         printf(":compressed packet: algo=%d\n", zd->algorithm);
2159     return 0;
2160 }
2161
2162
2163 static int
2164 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
2165                                        PACKET *pkt, int new_ctb )
2166 {
2167     int rc = 0;
2168     PKT_encrypted *ed;
2169     unsigned long orig_pktlen = pktlen;
2170
2171     ed = pkt->pkt.encrypted =  m_alloc(sizeof *pkt->pkt.encrypted );
2172     ed->len = pktlen;
2173     /* we don't know the extralen which is (cipher_blocksize+2)
2174        because the algorithm ist not specified in this packet.
2175        However, it is only important to know this for some sanity
2176        checks on the packet length - it doesn't matter that we can't
2177        do it */
2178     ed->extralen = 0;
2179     ed->buf = NULL;
2180     ed->new_ctb = new_ctb;
2181     ed->mdc_method = 0;
2182     if( pkttype == PKT_ENCRYPTED_MDC ) {
2183         /* fixme: add some pktlen sanity checks */
2184         int version;
2185
2186         version = iobuf_get_noeof(inp); 
2187         if (orig_pktlen)
2188             pktlen--;
2189         if( version != 1 ) {
2190             log_error("encrypted_mdc packet with unknown version %d\n",
2191                                                                 version);
2192             /*skip_rest(inp, pktlen); should we really do this? */
2193             rc = G10ERR_INVALID_PACKET;
2194             goto leave;
2195         }
2196         ed->mdc_method = DIGEST_ALGO_SHA1;
2197     }
2198     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2199         log_error("packet(%d) too short\n", pkttype);
2200         rc = G10ERR_INVALID_PACKET;
2201         skip_rest(inp, pktlen);
2202         goto leave;
2203     }
2204     if( list_mode ) {
2205         if( orig_pktlen )
2206             printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2207         else
2208             printf(":encrypted data packet:\n\tlength: unknown\n");
2209         if( ed->mdc_method )
2210             printf("\tmdc_method: %d\n", ed->mdc_method );
2211     }
2212
2213     ed->buf = inp;
2214     pktlen = 0;
2215
2216   leave:
2217     return rc;
2218 }
2219
2220
2221 static int
2222 parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
2223                                    PACKET *pkt, int new_ctb )
2224 {
2225     int rc = 0;
2226     PKT_mdc *mdc;
2227     byte *p;
2228
2229     mdc = pkt->pkt.mdc=  m_alloc(sizeof *pkt->pkt.mdc );
2230     if( list_mode )
2231         printf(":mdc packet: length=%lu\n", pktlen);
2232     if( !new_ctb || pktlen != 20 ) {
2233         log_error("mdc_packet with invalid encoding\n");
2234         rc = G10ERR_INVALID_PACKET;
2235         goto leave;
2236     }
2237     p = mdc->hash;
2238     for( ; pktlen; pktlen--, p++ )
2239         *p = iobuf_get_noeof(inp);
2240
2241   leave:
2242     return rc;
2243 }
2244
2245
2246 /*
2247  * This packet is internally generated by PGG (by armor.c) to
2248  * transfer some information to the lower layer.  To make sure that
2249  * this packet is really a GPG faked one and not one comming from outside,
2250  * we first check that tehre is a unique tag in it.
2251  * The format of such a control packet is:
2252  *   n byte  session marker
2253  *   1 byte  control type CTRLPKT_xxxxx
2254  *   m byte  control data
2255  */
2256
2257 static int
2258 parse_gpg_control( IOBUF inp,
2259                    int pkttype, unsigned long pktlen, PACKET *packet )
2260 {
2261     byte *p;
2262     const byte *sesmark;
2263     size_t sesmarklen;
2264     int i;
2265
2266     if ( list_mode )
2267         printf(":packet 63: length %lu ",  pktlen);
2268
2269     sesmark = get_session_marker ( &sesmarklen );
2270     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2271         goto skipit;
2272     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2273         if ( sesmark[i] != iobuf_get_noeof(inp) )
2274             goto skipit;
2275     }
2276     if ( list_mode )
2277         puts ("- gpg control packet");
2278
2279     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2280                                       + pktlen - 1);
2281     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2282     packet->pkt.gpg_control->datalen = pktlen;
2283     p = packet->pkt.gpg_control->data;
2284     for( ; pktlen; pktlen--, p++ )
2285         *p = iobuf_get_noeof(inp);
2286
2287     return 0;
2288
2289  skipit:
2290     if ( list_mode ) {
2291         int c;
2292
2293         i=0;
2294         printf("- private (rest length %lu)\n",  pktlen);
2295         if( iobuf_in_block_mode(inp) ) {
2296             while( (c=iobuf_get(inp)) != -1 )
2297                 dump_hex_line(c, &i);
2298         }
2299         else {
2300             for( ; pktlen; pktlen-- )
2301                 dump_hex_line(iobuf_get(inp), &i);
2302         }
2303         putchar('\n');
2304     }
2305     skip_rest(inp,pktlen);
2306     return G10ERR_INVALID_PACKET;
2307 }
2308
2309 /* create a gpg control packet to be used internally as a placeholder */
2310 PACKET *
2311 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2312 {
2313     PACKET *packet;
2314     byte *p;
2315
2316     packet = m_alloc( sizeof *packet );
2317     init_packet(packet);
2318     packet->pkttype = PKT_GPG_CONTROL;
2319     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2320                                       + datalen - 1);
2321     packet->pkt.gpg_control->control = type;
2322     packet->pkt.gpg_control->datalen = datalen;
2323     p = packet->pkt.gpg_control->data;
2324     for( ; datalen; datalen--, p++ )
2325         *p = *data++;
2326
2327     return packet;
2328 }