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