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