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