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