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