* packet.h, sig-check.c (signature_check2, do_check, do_check_messages):
[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             sig->unhashed = m_alloc (sizeof(*sig->unhashed) + n - 1 );
1249             sig->unhashed->size = n;
1250             sig->unhashed->len = n;
1251             if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
1252                 log_error("premature eof while reading "
1253                           "unhashed signature data\n");
1254                 rc = -1;
1255                 goto leave;
1256             }
1257             pktlen -= n;
1258         }
1259     }
1260
1261     if( pktlen < 5 ) { /* sanity check */
1262         log_error("packet(%d) too short\n", pkttype);
1263         rc = G10ERR_INVALID_PACKET;
1264         goto leave;
1265     }
1266
1267     sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
1268     sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
1269
1270     if( is_v4 && sig->pubkey_algo ) { /*extract required information */
1271         const byte *p;
1272         size_t len;
1273
1274         /* set sig->flags.unknown_critical if there is a
1275          * critical bit set for packets which we do not understand */
1276         if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
1277            || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
1278                                                                         NULL) )
1279         {
1280             sig->flags.unknown_critical = 1;
1281         }
1282
1283         p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
1284         if(p)
1285           sig->timestamp = buffer_to_u32(p);
1286         else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
1287           log_error("signature packet without timestamp\n");
1288
1289         p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1290         if(p)
1291           {
1292             sig->keyid[0] = buffer_to_u32(p);
1293             sig->keyid[1] = buffer_to_u32(p+4);
1294           }
1295         else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
1296           log_error("signature packet without keyid\n");
1297
1298         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1299         if(p)
1300           sig->expiredate=sig->timestamp+buffer_to_u32(p);
1301         if(sig->expiredate && sig->expiredate<=make_timestamp())
1302             sig->flags.expired=1;
1303
1304         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1305         if(p)
1306           sig->flags.policy_url=1;
1307
1308         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1309         if(p)
1310           sig->flags.notation=1;
1311
1312         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1313         if(p && *p==0)
1314           sig->flags.revocable=0;
1315
1316         p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len);
1317         if(p && len==2)
1318           {
1319             sig->trust_depth=p[0];
1320             sig->trust_value=p[1];
1321
1322             /* Only look for a regexp if there is also a trust
1323                subpacket. */
1324             sig->trust_regexp=
1325               parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len);
1326
1327             /* If the regular expression is of 0 length, there is no
1328                regular expression. */
1329             if(len==0)
1330               sig->trust_regexp=NULL;
1331           }
1332
1333         /* We accept the exportable subpacket from either the hashed
1334            or unhashed areas as older versions of gpg put it in the
1335            unhashed area.  In theory, anyway, we should never see this
1336            packet off of a local keyring. */
1337
1338         p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1339         if(p && *p==0)
1340           sig->flags.exportable=0;
1341
1342         /* Find all revocation keys. */
1343         if(sig->sig_class==0x1F)
1344           parse_revkeys(sig);
1345     }
1346
1347     if( list_mode ) {
1348         printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1349                "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1350                "\tdigest algo %d, begin of digest %02x %02x\n",
1351                 sig->pubkey_algo,
1352                 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1353                 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1354                 sig->digest_algo,
1355                 sig->digest_start[0], sig->digest_start[1] );
1356         if( is_v4 ) {
1357             parse_sig_subpkt (sig->hashed,   SIGSUBPKT_LIST_HASHED, NULL );
1358             parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1359         }
1360     }
1361
1362     ndata = pubkey_get_nsig(sig->pubkey_algo);
1363     if( !ndata ) {
1364         if( list_mode )
1365             printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1366         unknown_pubkey_warning( sig->pubkey_algo );
1367         /* we store the plain material in data[0], so that we are able
1368          * to write it back with build_packet() */
1369         sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1370         pktlen = 0;
1371     }
1372     else {
1373         for( i=0; i < ndata; i++ ) {
1374             n = pktlen;
1375             sig->data[i] = mpi_read(inp, &n, 0 );
1376             pktlen -=n;
1377             if( list_mode ) {
1378                 printf("\tdata: ");
1379                 mpi_print(stdout, sig->data[i], mpi_print_mode );
1380                 putchar('\n');
1381             }
1382             if (!sig->data[i])
1383                 rc = G10ERR_INVALID_PACKET;
1384         }
1385     }
1386
1387   leave:
1388     skip_rest(inp, pktlen);
1389     return rc;
1390 }
1391
1392
1393 static int
1394 parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
1395                                              PKT_onepass_sig *ops )
1396 {
1397     int version;
1398     int rc = 0;
1399
1400     if( pktlen < 13 ) {
1401         log_error("packet(%d) too short\n", pkttype);
1402         rc = G10ERR_INVALID_PACKET;
1403         goto leave;
1404     }
1405     version = iobuf_get_noeof(inp); pktlen--;
1406     if( version != 3 ) {
1407         log_error("onepass_sig with unknown version %d\n", version);
1408         rc = G10ERR_INVALID_PACKET;
1409         goto leave;
1410     }
1411     ops->sig_class = iobuf_get_noeof(inp); pktlen--;
1412     ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
1413     ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
1414     ops->keyid[0] = read_32(inp); pktlen -= 4;
1415     ops->keyid[1] = read_32(inp); pktlen -= 4;
1416     ops->last = iobuf_get_noeof(inp); pktlen--;
1417     if( list_mode )
1418         printf(":onepass_sig packet: keyid %08lX%08lX\n"
1419                "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1420                 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1421                 version, ops->sig_class,
1422                 ops->digest_algo, ops->pubkey_algo, ops->last );
1423
1424
1425   leave:
1426     skip_rest(inp, pktlen);
1427     return rc;
1428 }
1429
1430
1431 static MPI
1432 read_protected_v3_mpi (IOBUF inp, unsigned long *length)
1433 {
1434   int c;
1435   unsigned int nbits, nbytes;
1436   unsigned char *buf, *p;
1437   MPI val;
1438
1439   if (*length < 2)
1440     {
1441       log_error ("mpi too small\n");
1442       return NULL;
1443     }
1444
1445   if ((c=iobuf_get (inp)) == -1)
1446     return NULL;
1447   --*length;
1448   nbits = c << 8;
1449   if ((c=iobuf_get(inp)) == -1)
1450     return NULL;
1451   --*length;
1452   nbits |= c;
1453
1454   if (nbits > 16384)
1455     {
1456       log_error ("mpi too large (%u bits)\n", nbits);
1457       return NULL;
1458     }
1459   nbytes = (nbits+7) / 8;
1460   buf = p = m_alloc (2 + nbytes);
1461   *p++ = nbits >> 8;
1462   *p++ = nbits;
1463   for (; nbytes && length; nbytes--, --*length)
1464     *p++ = iobuf_get (inp);
1465   if (nbytes)
1466     {
1467       log_error ("packet shorter tham mpi\n");
1468       m_free (buf);
1469       return NULL;
1470     }
1471
1472   /* convert buffer into an opaque MPI */
1473   val = mpi_set_opaque (NULL, buf, p-buf); 
1474   return val;
1475 }
1476
1477
1478 static int
1479 parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
1480                               byte *hdr, int hdrlen, PACKET *pkt )
1481 {
1482     int i, version, algorithm;
1483     unsigned n;
1484     unsigned long timestamp, expiredate, max_expiredate;
1485     int npkey, nskey;
1486     int is_v4=0;
1487     int rc=0;
1488
1489     version = iobuf_get_noeof(inp); pktlen--;
1490     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1491         /* early versions of G10 use old PGP comments packets;
1492          * luckily all those comments are started by a hash */
1493         if( list_mode ) {
1494             printf(":rfc1991 comment packet: \"" );
1495             for( ; pktlen; pktlen-- ) {
1496                 int c;
1497                 c = iobuf_get_noeof(inp);
1498                 if( c >= ' ' && c <= 'z' )
1499                     putchar(c);
1500                 else
1501                     printf("\\x%02x", c );
1502             }
1503             printf("\"\n");
1504         }
1505         skip_rest(inp, pktlen);
1506         return 0;
1507     }
1508     else if( version == 4 )
1509         is_v4=1;
1510     else if( version != 2 && version != 3 ) {
1511         log_error("packet(%d) with unknown version %d\n", pkttype, version);
1512         rc = G10ERR_INVALID_PACKET;
1513         goto leave;
1514     }
1515
1516     if( pktlen < 11 ) {
1517         log_error("packet(%d) too short\n", pkttype);
1518         rc = G10ERR_INVALID_PACKET;
1519         goto leave;
1520     }
1521
1522     timestamp = read_32(inp); pktlen -= 4;
1523     if( is_v4 ) {
1524         expiredate = 0; /* have to get it from the selfsignature */
1525         max_expiredate = 0;
1526     }
1527     else {
1528         unsigned short ndays;
1529         ndays = read_16(inp); pktlen -= 2;
1530         if( ndays )
1531             expiredate = timestamp + ndays * 86400L;
1532         else
1533             expiredate = 0;
1534
1535         max_expiredate=expiredate;
1536     }
1537     algorithm = iobuf_get_noeof(inp); pktlen--;
1538     if( list_mode )
1539         printf(":%s key packet:\n"
1540                "\tversion %d, algo %d, created %lu, expires %lu\n",
1541                 pkttype == PKT_PUBLIC_KEY? "public" :
1542                 pkttype == PKT_SECRET_KEY? "secret" :
1543                 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1544                 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1545                 version, algorithm, timestamp, expiredate );
1546
1547     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY )  {
1548         PKT_secret_key *sk = pkt->pkt.secret_key;
1549
1550         sk->timestamp = timestamp;
1551         sk->expiredate = expiredate;
1552         sk->max_expiredate = max_expiredate;
1553         sk->hdrbytes = hdrlen;
1554         sk->version = version;
1555         sk->is_primary = pkttype == PKT_SECRET_KEY;
1556         sk->pubkey_algo = algorithm;
1557         sk->req_usage = 0; 
1558         sk->pubkey_usage = 0; /* not yet used */
1559     }
1560     else {
1561         PKT_public_key *pk = pkt->pkt.public_key;
1562
1563         pk->timestamp = timestamp;
1564         pk->expiredate = expiredate;
1565         pk->max_expiredate = max_expiredate;
1566         pk->hdrbytes    = hdrlen;
1567         pk->version     = version;
1568         pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1569         pk->pubkey_algo = algorithm;
1570         pk->req_usage = 0; 
1571         pk->pubkey_usage = 0; /* not yet used */
1572         pk->is_revoked = 0;
1573         pk->is_disabled = 0;
1574         pk->keyid[0] = 0;
1575         pk->keyid[1] = 0;
1576     }
1577     nskey = pubkey_get_nskey( algorithm );
1578     npkey = pubkey_get_npkey( algorithm );
1579     if( !npkey ) {
1580         if( list_mode )
1581             printf("\tunknown algorithm %d\n", algorithm );
1582         unknown_pubkey_warning( algorithm );
1583     }
1584
1585
1586     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1587         PKT_secret_key *sk = pkt->pkt.secret_key;
1588         byte temp[16];
1589
1590         if( !npkey ) {
1591             sk->skey[0] = mpi_set_opaque( NULL,
1592                                           read_rest(inp, pktlen), pktlen );
1593             pktlen = 0;
1594             goto leave;
1595         }
1596
1597         for(i=0; i < npkey; i++ ) {
1598             n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1599             if( list_mode ) {
1600                 printf(  "\tskey[%d]: ", i);
1601                 mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1602                 putchar('\n');
1603             }
1604             if (!sk->skey[i])
1605                 rc = G10ERR_INVALID_PACKET;
1606         }
1607         if (rc) /* one of the MPIs were bad */
1608             goto leave;
1609         sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1610         sk->protect.sha1chk = 0;
1611         if( sk->protect.algo ) {
1612             sk->is_protected = 1;
1613             sk->protect.s2k.count = 0;
1614             if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1615                 if( pktlen < 3 ) {
1616                     rc = G10ERR_INVALID_PACKET;
1617                     goto leave;
1618                 }
1619                 sk->protect.sha1chk = (sk->protect.algo == 254);
1620                 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1621                 /* Note that a sk->protect.algo > 110 is illegal, but
1622                    I'm not erroring on it here as otherwise there
1623                    would be no way to delete such a key. */
1624                 sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
1625                 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1626                 /* check for the special GNU extension */
1627                 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1628                     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1629                         temp[i] = iobuf_get_noeof(inp);
1630                     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1631                         if( list_mode )
1632                             printf(  "\tunknown S2K %d\n",
1633                                                 sk->protect.s2k.mode );
1634                         rc = G10ERR_INVALID_PACKET;
1635                         goto leave;
1636                     }
1637                     /* here we know that it is a gnu extension
1638                      * What follows is the GNU protection mode:
1639                      * All values have special meanings
1640                      * and they are mapped in the mode with a base of 1000.
1641                      */
1642                     sk->protect.s2k.mode = 1000 + temp[3];
1643                 }
1644                 switch( sk->protect.s2k.mode ) {
1645                   case 1:
1646                   case 3:
1647                     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1648                         temp[i] = iobuf_get_noeof(inp);
1649                     memcpy(sk->protect.s2k.salt, temp, 8 );
1650                     break;
1651                 }
1652                 switch( sk->protect.s2k.mode ) {
1653                   case 0: if( list_mode ) printf(  "\tsimple S2K" );
1654                     break;
1655                   case 1: if( list_mode ) printf(  "\tsalted S2K" );
1656                     break;
1657                   case 3: if( list_mode ) printf(  "\titer+salt S2K" );
1658                     break;
1659                   case 1001: if( list_mode ) printf(  "\tgnu-dummy S2K" );
1660                     break;
1661                   default:
1662                     if( list_mode )
1663                         printf(  "\tunknown %sS2K %d\n",
1664                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1665                                                    sk->protect.s2k.mode );
1666                     rc = G10ERR_INVALID_PACKET;
1667                     goto leave;
1668                 }
1669
1670                 if( list_mode ) {
1671                     printf(", algo: %d,%s hash: %d",
1672                                      sk->protect.algo,
1673                                      sk->protect.sha1chk?" SHA1 protection,"
1674                                                         :" simple checksum,",
1675                                      sk->protect.s2k.hash_algo );
1676                     if( sk->protect.s2k.mode == 1
1677                         || sk->protect.s2k.mode == 3 ) {
1678                         printf(", salt: ");
1679                         for(i=0; i < 8; i++ )
1680                             printf("%02x", sk->protect.s2k.salt[i]);
1681                     }
1682                     putchar('\n');
1683                 }
1684
1685                 if( sk->protect.s2k.mode == 3 ) {
1686                     if( pktlen < 1 ) {
1687                         rc = G10ERR_INVALID_PACKET;
1688                         goto leave;
1689                     }
1690                     sk->protect.s2k.count = iobuf_get(inp);
1691                     pktlen--;
1692                     if( list_mode )
1693                         printf("\tprotect count: %lu\n",
1694                                             (ulong)sk->protect.s2k.count);
1695                 }
1696             }
1697             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1698                not erroring on it here as otherwise there would be no
1699                way to delete such a key. */
1700             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1701                 sk->protect.s2k.mode = 0;
1702                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1703                 if( list_mode )
1704                     printf(  "\tprotect algo: %d  (hash algo: %d)\n",
1705                          sk->protect.algo, sk->protect.s2k.hash_algo );
1706             }
1707             /* It is really ugly that we don't know the size
1708              * of the IV here in cases we are not aware of the algorithm.
1709              * so a
1710              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1711              * won't work.  The only solution I see is to hardwire it here.
1712              * NOTE: if you change the ivlen above 16, don't forget to
1713              * enlarge temp.
1714              */
1715             switch( sk->protect.algo ) {
1716               case 7: case 8: case 9: /* reserved for AES */
1717               case 10: /* Twofish */
1718                 sk->protect.ivlen = 16;
1719                 break;
1720               default:
1721                 sk->protect.ivlen = 8;
1722             }
1723             if( sk->protect.s2k.mode == 1001 )
1724                 sk->protect.ivlen = 0;
1725
1726             if( pktlen < sk->protect.ivlen ) {
1727                 rc = G10ERR_INVALID_PACKET;
1728                 goto leave;
1729             }
1730             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1731                 temp[i] = iobuf_get_noeof(inp);
1732             if( list_mode ) {
1733                 printf(  "\tprotect IV: ");
1734                 for(i=0; i < sk->protect.ivlen; i++ )
1735                     printf(" %02x", temp[i] );
1736                 putchar('\n');
1737             }
1738             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1739         }
1740         else
1741             sk->is_protected = 0;
1742         /* It does not make sense to read it into secure memory.
1743          * If the user is so careless, not to protect his secret key,
1744          * we can assume, that he operates an open system :=(.
1745          * So we put the key into secure memory when we unprotect it. */
1746         if( sk->protect.s2k.mode == 1001 ) {
1747             /* better set some dummy stuff here */
1748             sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10);
1749             pktlen = 0;
1750         }
1751         else if( is_v4 && sk->is_protected ) {
1752             /* ugly; the length is encrypted too, so we read all
1753              * stuff up to the end of the packet into the first
1754              * skey element */
1755             sk->skey[npkey] = mpi_set_opaque(NULL,
1756                                              read_rest(inp, pktlen), pktlen );
1757             pktlen = 0;
1758             if( list_mode ) {
1759                 printf("\tencrypted stuff follows\n");
1760             }
1761         }
1762         else { /* v3 method: the mpi length is not encrypted */
1763             for(i=npkey; i < nskey; i++ ) {
1764                 if ( sk->is_protected ) {
1765                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1766                     if( list_mode ) 
1767                         printf(  "\tskey[%d]: [encrypted]\n", i);
1768                 }
1769                 else {
1770                     n = pktlen;
1771                     sk->skey[i] = mpi_read(inp, &n, 0 );
1772                     pktlen -=n;
1773                     if( list_mode ) {
1774                         printf(  "\tskey[%d]: ", i);
1775                         mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1776                         putchar('\n');
1777                     }
1778                 }
1779
1780                 if (!sk->skey[i])
1781                     rc = G10ERR_INVALID_PACKET;
1782             }
1783             if (rc)
1784                 goto leave;
1785
1786             sk->csum = read_16(inp); pktlen -= 2;
1787             if( list_mode ) {
1788                 printf("\tchecksum: %04hx\n", sk->csum);
1789             }
1790         }
1791     }
1792     else {
1793         PKT_public_key *pk = pkt->pkt.public_key;
1794
1795         if( !npkey ) {
1796             pk->pkey[0] = mpi_set_opaque( NULL,
1797                                           read_rest(inp, pktlen), pktlen );
1798             pktlen = 0;
1799             goto leave;
1800         }
1801
1802         for(i=0; i < npkey; i++ ) {
1803             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1804             if( list_mode ) {
1805                 printf(  "\tpkey[%d]: ", i);
1806                 mpi_print(stdout, pk->pkey[i], mpi_print_mode  );
1807                 putchar('\n');
1808             }
1809             if (!pk->pkey[i])
1810                 rc = G10ERR_INVALID_PACKET;
1811         }
1812         if (rc)
1813             goto leave;
1814     }
1815
1816   leave:
1817     skip_rest(inp, pktlen);
1818     return rc;
1819 }
1820
1821 /* Attribute subpackets have the same format as v4 signature
1822    subpackets.  This is not part of OpenPGP, but is done in several
1823    versions of PGP nevertheless. */
1824 int
1825 parse_attribute_subpkts(PKT_user_id *uid)
1826 {
1827   size_t n;
1828   int count=0;
1829   struct user_attribute *attribs=NULL;
1830   const byte *buffer=uid->attrib_data;
1831   int buflen=uid->attrib_len;
1832   byte type;
1833
1834   m_free(uid->attribs);
1835
1836   while(buflen)
1837     {
1838       n = *buffer++; buflen--;
1839       if( n == 255 ) { /* 4 byte length header */
1840         if( buflen < 4 )
1841           goto too_short;
1842         n = (buffer[0] << 24) | (buffer[1] << 16)
1843           | (buffer[2] << 8) | buffer[3];
1844         buffer += 4;
1845         buflen -= 4;
1846       }
1847       else if( n >= 192 ) { /* 2 byte special encoded length header */
1848         if( buflen < 2 )
1849           goto too_short;
1850         n = (( n - 192 ) << 8) + *buffer + 192;
1851         buffer++;
1852         buflen--;
1853       }
1854       if( buflen < n )
1855         goto too_short;
1856
1857       attribs=m_realloc(attribs,(count+1)*sizeof(struct user_attribute));
1858       memset(&attribs[count],0,sizeof(struct user_attribute));
1859
1860       type=*buffer;
1861       buffer++;
1862       buflen--;
1863       n--;
1864
1865       attribs[count].type=type;
1866       attribs[count].data=buffer;
1867       attribs[count].len=n;
1868       buffer+=n;
1869       buflen-=n;
1870       count++;
1871     }
1872
1873   uid->attribs=attribs;
1874   uid->numattribs=count;
1875   return count;
1876
1877  too_short:
1878   log_error("buffer shorter than attribute subpacket\n");
1879   uid->attribs=attribs;
1880   uid->numattribs=count;
1881   return count;
1882 }
1883
1884 static void setup_user_id(PACKET *packet)
1885 {
1886   packet->pkt.user_id->ref = 1;
1887   packet->pkt.user_id->attribs = NULL;
1888   packet->pkt.user_id->attrib_data = NULL;
1889   packet->pkt.user_id->attrib_len = 0;
1890   packet->pkt.user_id->is_primary = 0;
1891   packet->pkt.user_id->is_revoked = 0;
1892   packet->pkt.user_id->is_expired = 0;
1893   packet->pkt.user_id->expiredate = 0;
1894   packet->pkt.user_id->created = 0;
1895   packet->pkt.user_id->help_key_usage = 0;
1896   packet->pkt.user_id->help_key_expire = 0;
1897   packet->pkt.user_id->prefs = NULL;
1898   packet->pkt.user_id->namehash = NULL;
1899 }
1900
1901 static int
1902 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1903 {
1904     byte *p;
1905
1906     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen);
1907     packet->pkt.user_id->len = pktlen;
1908
1909     setup_user_id(packet);
1910
1911     p = packet->pkt.user_id->name;
1912     for( ; pktlen; pktlen--, p++ )
1913         *p = iobuf_get_noeof(inp);
1914     *p = 0;
1915
1916     if( list_mode ) {
1917         int n = packet->pkt.user_id->len;
1918         printf(":user ID packet: \"");
1919         /* fixme: Hey why don't we replace this with print_string?? */
1920         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1921             if( *p >= ' ' && *p <= 'z' )
1922                 putchar(*p);
1923             else
1924                 printf("\\x%02x", *p );
1925         }
1926         printf("\"\n");
1927     }
1928     return 0;
1929 }
1930
1931
1932 void
1933 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
1934 {
1935   assert ( max_namelen > 70 );
1936   if(uid->numattribs<=0)
1937     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
1938   else if(uid->numattribs>1)
1939     sprintf(uid->name,"[%d attributes of size %lu]",
1940             uid->numattribs,uid->attrib_len);
1941   else
1942     {
1943       /* Only one attribute, so list it as the "user id" */
1944
1945       if(uid->attribs->type==ATTRIB_IMAGE)
1946         {
1947           u32 len;
1948           byte type;
1949
1950           if(parse_image_header(uid->attribs,&type,&len))
1951             sprintf(uid->name,"[%.20s image of size %lu]",
1952                     image_type_to_string(type,1),(ulong)len);
1953           else
1954             sprintf(uid->name,"[invalid image]");
1955         }
1956       else
1957         sprintf(uid->name,"[unknown attribute of size %lu]",
1958                 (ulong)uid->attribs->len);
1959     }
1960
1961   uid->len = strlen(uid->name);
1962 }
1963
1964 static int
1965 parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1966 {
1967     byte *p;
1968
1969 #define EXTRA_UID_NAME_SPACE 71
1970     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id
1971                                   + EXTRA_UID_NAME_SPACE);
1972
1973     setup_user_id(packet);
1974
1975     packet->pkt.user_id->attrib_data = m_alloc(pktlen);
1976     packet->pkt.user_id->attrib_len = pktlen;
1977     p = packet->pkt.user_id->attrib_data;
1978     for( ; pktlen; pktlen--, p++ )
1979         *p = iobuf_get_noeof(inp);
1980
1981     /* Now parse out the individual attribute subpackets.  This is
1982        somewhat pointless since there is only one currently defined
1983        attribute type (jpeg), but it is correct by the spec. */
1984     parse_attribute_subpkts(packet->pkt.user_id);
1985
1986     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
1987
1988     if( list_mode ) {
1989         printf(":attribute packet: %s\n", packet->pkt.user_id->name );
1990     }
1991     return 0;
1992 }
1993
1994
1995 static int
1996 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1997 {
1998     byte *p;
1999
2000     packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
2001     packet->pkt.comment->len = pktlen;
2002     p = packet->pkt.comment->data;
2003     for( ; pktlen; pktlen--, p++ )
2004         *p = iobuf_get_noeof(inp);
2005
2006     if( list_mode ) {
2007         int n = packet->pkt.comment->len;
2008         printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2009                                          "OpenPGP draft " : "" );
2010         for(p=packet->pkt.comment->data; n; p++, n-- ) {
2011             if( *p >= ' ' && *p <= 'z' )
2012                 putchar(*p);
2013             else
2014                 printf("\\x%02x", *p );
2015         }
2016         printf("\"\n");
2017     }
2018     return 0;
2019 }
2020
2021
2022 static void
2023 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2024 {
2025   int c;
2026
2027   if (pktlen)
2028     {
2029       c = iobuf_get_noeof(inp);
2030       pktlen--;
2031       pkt->pkt.ring_trust = m_alloc( sizeof *pkt->pkt.ring_trust );
2032       pkt->pkt.ring_trust->trustval = c;
2033       pkt->pkt.ring_trust->sigcache = 0;
2034       if (!c && pktlen==1)
2035         {
2036           c = iobuf_get_noeof (inp);
2037           pktlen--;
2038           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2039           if ( !(c & 0x80) )
2040             pkt->pkt.ring_trust->sigcache = c;
2041         }
2042       if( list_mode )
2043         printf(":trust packet: flag=%02x sigcache=%02x\n",
2044                pkt->pkt.ring_trust->trustval,
2045                pkt->pkt.ring_trust->sigcache);
2046     }
2047   else
2048     {
2049       if( list_mode )
2050         printf(":trust packet: empty\n");
2051     }
2052   skip_rest (inp, pktlen);
2053 }
2054
2055
2056 static int
2057 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
2058                                         PACKET *pkt, int new_ctb )
2059 {
2060     int rc = 0;
2061     int mode, namelen, partial=0;
2062     PKT_plaintext *pt;
2063     byte *p;
2064     int c, i;
2065
2066     if( pktlen && pktlen < 6 ) {
2067         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2068         rc = G10ERR_INVALID_PACKET;
2069         goto leave;
2070     }
2071     /* A packet length of zero indicates partial body length.  A zero
2072        data length isn't a zero length packet due to the header (mode,
2073        name, etc), so this is accurate. */
2074     if(pktlen==0)
2075       partial=1;
2076     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2077     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2078     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
2079     pt->new_ctb = new_ctb;
2080     pt->mode = mode;
2081     pt->namelen = namelen;
2082     pt->is_partial = partial;
2083     if( pktlen ) {
2084         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2085             pt->name[i] = iobuf_get_noeof(inp);
2086     }
2087     else {
2088         for( i=0; i < namelen; i++ )
2089             if( (c=iobuf_get(inp)) == -1 )
2090                 break;
2091             else
2092                 pt->name[i] = c;
2093     }
2094     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2095     pt->len = pktlen;
2096     pt->buf = inp;
2097     pktlen = 0;
2098
2099     if( list_mode ) {
2100         printf(":literal data packet:\n"
2101                "\tmode %c, created %lu, name=\"",
2102                     mode >= ' ' && mode <'z'? mode : '?',
2103                     (ulong)pt->timestamp );
2104         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2105             if( *p >= ' ' && *p <= 'z' )
2106                 putchar(*p);
2107             else
2108                 printf("\\x%02x", *p );
2109         }
2110         printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2111     }
2112
2113   leave:
2114     return rc;
2115 }
2116
2117
2118 static int
2119 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
2120                   PACKET *pkt, int new_ctb )
2121 {
2122     PKT_compressed *zd;
2123
2124     /* pktlen is here 0, but data follows
2125      * (this should be the last object in a file or
2126      *  the compress algorithm should know the length)
2127      */
2128     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
2129     zd->algorithm = iobuf_get_noeof(inp);
2130     zd->len = 0; /* not used */ 
2131     zd->new_ctb = new_ctb;
2132     zd->buf = inp;
2133     if( list_mode )
2134         printf(":compressed packet: algo=%d\n", zd->algorithm);
2135     return 0;
2136 }
2137
2138
2139 static int
2140 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
2141                                        PACKET *pkt, int new_ctb )
2142 {
2143     int rc = 0;
2144     PKT_encrypted *ed;
2145     unsigned long orig_pktlen = pktlen;
2146
2147     ed = pkt->pkt.encrypted =  m_alloc(sizeof *pkt->pkt.encrypted );
2148     ed->len = pktlen;
2149     /* we don't know the extralen which is (cipher_blocksize+2)
2150        because the algorithm ist not specified in this packet.
2151        However, it is only important to know this for some sanity
2152        checks on the packet length - it doesn't matter that we can't
2153        do it */
2154     ed->extralen = 0;
2155     ed->buf = NULL;
2156     ed->new_ctb = new_ctb;
2157     ed->mdc_method = 0;
2158     if( pkttype == PKT_ENCRYPTED_MDC ) {
2159         /* fixme: add some pktlen sanity checks */
2160         int version;
2161
2162         version = iobuf_get_noeof(inp); 
2163         if (orig_pktlen)
2164             pktlen--;
2165         if( version != 1 ) {
2166             log_error("encrypted_mdc packet with unknown version %d\n",
2167                                                                 version);
2168             /*skip_rest(inp, pktlen); should we really do this? */
2169             rc = G10ERR_INVALID_PACKET;
2170             goto leave;
2171         }
2172         ed->mdc_method = DIGEST_ALGO_SHA1;
2173     }
2174     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2175         log_error("packet(%d) too short\n", pkttype);
2176         rc = G10ERR_INVALID_PACKET;
2177         skip_rest(inp, pktlen);
2178         goto leave;
2179     }
2180     if( list_mode ) {
2181         if( orig_pktlen )
2182             printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2183         else
2184             printf(":encrypted data packet:\n\tlength: unknown\n");
2185         if( ed->mdc_method )
2186             printf("\tmdc_method: %d\n", ed->mdc_method );
2187     }
2188
2189     ed->buf = inp;
2190     pktlen = 0;
2191
2192   leave:
2193     return rc;
2194 }
2195
2196
2197 static int
2198 parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
2199                                    PACKET *pkt, int new_ctb )
2200 {
2201     int rc = 0;
2202     PKT_mdc *mdc;
2203     byte *p;
2204
2205     mdc = pkt->pkt.mdc=  m_alloc(sizeof *pkt->pkt.mdc );
2206     if( list_mode )
2207         printf(":mdc packet: length=%lu\n", pktlen);
2208     if( !new_ctb || pktlen != 20 ) {
2209         log_error("mdc_packet with invalid encoding\n");
2210         rc = G10ERR_INVALID_PACKET;
2211         goto leave;
2212     }
2213     p = mdc->hash;
2214     for( ; pktlen; pktlen--, p++ )
2215         *p = iobuf_get_noeof(inp);
2216
2217   leave:
2218     return rc;
2219 }
2220
2221
2222 /*
2223  * This packet is internally generated by PGG (by armor.c) to
2224  * transfer some information to the lower layer.  To make sure that
2225  * this packet is really a GPG faked one and not one comming from outside,
2226  * we first check that tehre is a unique tag in it.
2227  * The format of such a control packet is:
2228  *   n byte  session marker
2229  *   1 byte  control type CTRLPKT_xxxxx
2230  *   m byte  control data
2231  */
2232
2233 static int
2234 parse_gpg_control( IOBUF inp,
2235                    int pkttype, unsigned long pktlen, PACKET *packet )
2236 {
2237     byte *p;
2238     const byte *sesmark;
2239     size_t sesmarklen;
2240     int i;
2241
2242     if ( list_mode )
2243         printf(":packet 63: length %lu ",  pktlen);
2244
2245     sesmark = get_session_marker ( &sesmarklen );
2246     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2247         goto skipit;
2248     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2249         if ( sesmark[i] != iobuf_get_noeof(inp) )
2250             goto skipit;
2251     }
2252     if ( list_mode )
2253         puts ("- gpg control packet");
2254
2255     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2256                                       + pktlen - 1);
2257     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2258     packet->pkt.gpg_control->datalen = pktlen;
2259     p = packet->pkt.gpg_control->data;
2260     for( ; pktlen; pktlen--, p++ )
2261         *p = iobuf_get_noeof(inp);
2262
2263     return 0;
2264
2265  skipit:
2266     if ( list_mode ) {
2267         int c;
2268
2269         i=0;
2270         printf("- private (rest length %lu)\n",  pktlen);
2271         if( iobuf_in_block_mode(inp) ) {
2272             while( (c=iobuf_get(inp)) != -1 )
2273                 dump_hex_line(c, &i);
2274         }
2275         else {
2276             for( ; pktlen; pktlen-- )
2277                 dump_hex_line(iobuf_get(inp), &i);
2278         }
2279         putchar('\n');
2280     }
2281     skip_rest(inp,pktlen);
2282     return G10ERR_INVALID_PACKET;
2283 }
2284
2285 /* create a gpg control packet to be used internally as a placeholder */
2286 PACKET *
2287 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2288 {
2289     PACKET *packet;
2290     byte *p;
2291
2292     packet = m_alloc( sizeof *packet );
2293     init_packet(packet);
2294     packet->pkttype = PKT_GPG_CONTROL;
2295     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2296                                       + datalen - 1);
2297     packet->pkt.gpg_control->control = type;
2298     packet->pkt.gpg_control->datalen = datalen;
2299     p = packet->pkt.gpg_control->data;
2300     for( ; datalen; datalen--, p++ )
2301         *p = *data++;
2302
2303     return packet;
2304 }