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