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