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