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