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