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