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