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