* parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt,
[gnupg.git] / g10 / parse-packet.c
1 /* parse-packet.c  - read packets
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "packet.h"
29 #include "iobuf.h"
30 #include "mpi.h"
31 #include "util.h"
32 #include "cipher.h"
33 #include "memory.h"
34 #include "filter.h"
35 #include "photoid.h"
36 #include "options.h"
37 #include "main.h"
38 #include "i18n.h"
39
40 static int mpi_print_mode = 0;
41 static int list_mode = 0;
42
43 static int  parse( IOBUF inp, PACKET *pkt, int onlykeypkts,
44                   off_t *retpos, int *skip, IOBUF out, int do_skip
45 #ifdef DEBUG_PARSE_PACKET
46                    ,const char *dbg_w, const char *dbg_f, int dbg_l
47 #endif
48                  );
49 static int  copy_packet( IOBUF inp, IOBUF out, int pkttype,
50                          unsigned long pktlen, int partial );
51 static void skip_packet( IOBUF inp, int pkttype,
52                          unsigned long pktlen, int partial );
53 static void skip_rest( IOBUF inp, 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_signature( IOBUF inp, int pkttype, unsigned long pktlen,
60                                                          PKT_signature *sig );
61 static int  parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
62                                                         PKT_onepass_sig *ops );
63 static int  parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
64                                       byte *hdr, int hdrlen, PACKET *packet );
65 static int  parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
66                                                            PACKET *packet );
67 static int  parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen,
68                                                            PACKET *packet );
69 static int  parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
70                                                            PACKET *packet );
71 static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen,
72                                                            PACKET *packet );
73 static int  parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
74                              PACKET *packet, int new_ctb, int partial);
75 static int  parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
76                                                PACKET *packet, int new_ctb );
77 static int  parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
78                              PACKET *packet, int new_ctb, int partial);
79 static int  parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
80                                                PACKET *packet, int new_ctb);
81 static int  parse_gpg_control( IOBUF inp, int pkttype, unsigned long pktlen,
82                                PACKET *packet, int partial );
83
84 static unsigned short
85 read_16(IOBUF inp)
86 {
87     unsigned short a;
88     a = iobuf_get_noeof(inp) << 8;
89     a |= iobuf_get_noeof(inp);
90     return a;
91 }
92
93 static unsigned long
94 read_32(IOBUF inp)
95 {
96     unsigned long a;
97     a =  iobuf_get_noeof(inp) << 24;
98     a |= iobuf_get_noeof(inp) << 16;
99     a |= iobuf_get_noeof(inp) << 8;
100     a |= iobuf_get_noeof(inp);
101     return a;
102 }
103
104
105 int
106 set_packet_list_mode( int mode )
107 {
108     int old = list_mode;
109     list_mode = mode;
110     mpi_print_mode = DBG_MPI;
111     return old;
112 }
113
114 static void
115 unknown_pubkey_warning( int algo )
116 {
117     static byte unknown_pubkey_algos[256];
118
119     algo &= 0xff;
120     if( !unknown_pubkey_algos[algo] ) {
121         if( opt.verbose )
122             log_info(_("can't handle public key algorithm %d\n"), algo );
123         unknown_pubkey_algos[algo] = 1;
124     }
125 }
126
127 /****************
128  * Parse a Packet and return it in packet
129  * Returns: 0 := valid packet in pkt
130  *         -1 := no more packets
131  *         >0 := error
132  * Note: The function may return an error and a partly valid packet;
133  * caller must free this packet.
134  */
135 #ifdef DEBUG_PARSE_PACKET
136 int
137 dbg_parse_packet( IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l )
138 {
139     int skip, rc;
140
141     do {
142         rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l );
143     } while( skip );
144     return rc;
145 }
146 #else
147 int
148 parse_packet( IOBUF inp, PACKET *pkt )
149 {
150     int skip, rc;
151
152     do {
153         rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
154     } while( skip );
155     return rc;
156 }
157 #endif
158
159 /****************
160  * Like parse packet, but only return secret or public (sub)key packets.
161  */
162 #ifdef DEBUG_PARSE_PACKET
163 int
164 dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid,
165                    const char *dbg_f, int dbg_l )
166 {
167     int skip, rc;
168
169     do {
170         rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
171     } while( skip );
172     return rc;
173 }
174 #else
175 int
176 search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid )
177 {
178     int skip, rc;
179
180     do {
181         rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
182     } while( skip );
183     return rc;
184 }
185 #endif
186
187 /****************
188  * Copy all packets from INP to OUT, thereby removing unused spaces.
189  */
190 #ifdef DEBUG_PARSE_PACKET
191 int
192 dbg_copy_all_packets( IOBUF inp, IOBUF out,
193                    const char *dbg_f, int dbg_l )
194 {
195     PACKET pkt;
196     int skip, rc=0;
197     do {
198         init_packet(&pkt);
199     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l )));
200     return rc;
201 }
202 #else
203 int
204 copy_all_packets( IOBUF inp, IOBUF out )
205 {
206     PACKET pkt;
207     int skip, rc=0;
208     do {
209         init_packet(&pkt);
210     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
211     return rc;
212 }
213 #endif
214
215 /****************
216  * Copy some packets from INP to OUT, thereby removing unused spaces.
217  * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
218  */
219 #ifdef DEBUG_PARSE_PACKET
220 int
221 dbg_copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff,
222                    const char *dbg_f, int dbg_l )
223 {
224     PACKET pkt;
225     int skip, rc=0;
226     do {
227         if( iobuf_tell(inp) >= stopoff )
228             return 0;
229         init_packet(&pkt);
230     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0,
231                                      "some", dbg_f, dbg_l )) );
232     return rc;
233 }
234 #else
235 int
236 copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff )
237 {
238     PACKET pkt;
239     int skip, rc=0;
240     do {
241         if( iobuf_tell(inp) >= stopoff )
242             return 0;
243         init_packet(&pkt);
244     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
245     return rc;
246 }
247 #endif
248
249 /****************
250  * Skip over N packets
251  */
252 #ifdef DEBUG_PARSE_PACKET
253 int
254 dbg_skip_some_packets( IOBUF inp, unsigned n,
255                    const char *dbg_f, int dbg_l )
256 {
257     int skip, rc=0;
258     PACKET pkt;
259
260     for( ;n && !rc; n--) {
261         init_packet(&pkt);
262         rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l );
263     }
264     return rc;
265 }
266 #else
267 int
268 skip_some_packets( IOBUF inp, unsigned n )
269 {
270     int skip, rc=0;
271     PACKET pkt;
272
273     for( ;n && !rc; n--) {
274         init_packet(&pkt);
275         rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
276     }
277     return rc;
278 }
279 #endif
280
281
282 /****************
283  * Parse packet. Set the variable skip points to 1 if the packet
284  * should be skipped; this is the case if either ONLYKEYPKTS is set
285  * and the parsed packet isn't one or the
286  * packet-type is 0, indicating deleted stuff.
287  * if OUT is not NULL, a special copymode is used.
288  */
289 static int
290 parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
291        int *skip, IOBUF out, int do_skip
292 #ifdef DEBUG_PARSE_PACKET
293        ,const char *dbg_w, const char *dbg_f, int dbg_l
294 #endif
295      )
296 {
297     int rc=0, c, ctb, pkttype, lenbytes;
298     unsigned long pktlen;
299     byte hdr[8];
300     int hdrlen;
301     int new_ctb = 0, partial=0;
302     int with_uid = (onlykeypkts == 2);
303
304     *skip = 0;
305     assert( !pkt->pkt.generic );
306     if( retpos )
307         *retpos = iobuf_tell(inp);
308
309     if( (ctb = iobuf_get(inp)) == -1 ) {
310         rc = -1;
311         goto leave;
312     }
313     hdrlen=0;
314     hdr[hdrlen++] = ctb;
315     if( !(ctb & 0x80) ) {
316         log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb );
317         rc = G10ERR_INVALID_PACKET;
318         goto leave;
319     }
320     pktlen = 0;
321     new_ctb = !!(ctb & 0x40);
322     if( new_ctb ) {
323         pkttype = ctb & 0x3f;
324         if( (c = iobuf_get(inp)) == -1 ) {
325             log_error("%s: 1st length byte missing\n", iobuf_where(inp) );
326             rc = G10ERR_INVALID_PACKET;
327             goto leave;
328         }
329         if (pkttype == PKT_COMPRESSED) {
330              iobuf_set_partial_block_mode(inp, c & 0xff);
331              pktlen = 0;/* to indicate partial length */
332              partial=1;
333         }
334         else {
335              hdr[hdrlen++] = c;
336              if( c < 192 )
337                pktlen = c;
338              else if( c < 224 )
339                {
340                  pktlen = (c - 192) * 256;
341                  if( (c = iobuf_get(inp)) == -1 )
342                    {
343                      log_error("%s: 2nd length byte missing\n",
344                                iobuf_where(inp) );
345                      rc = G10ERR_INVALID_PACKET;
346                      goto leave;
347                    }
348                  hdr[hdrlen++] = c;
349                  pktlen += c + 192;
350                }
351              else if( c == 255 )
352                {
353                  pktlen  = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24;
354                  pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16;
355                  pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8;
356                  if( (c = iobuf_get(inp)) == -1 )
357                    {
358                      log_error("%s: 4 byte length invalid\n",
359                                iobuf_where(inp) );
360                      rc = G10ERR_INVALID_PACKET;
361                      goto leave;
362                    }
363                  pktlen |= (hdr[hdrlen++] = c );
364                }
365              else
366                {
367                  /* Partial body length.  Note that we handled
368                     PKT_COMPRESSED earlier. */
369                  if(pkttype==PKT_PLAINTEXT || pkttype==PKT_ENCRYPTED
370                     || pkttype==PKT_ENCRYPTED_MDC)
371                    {
372                      iobuf_set_partial_block_mode(inp, c & 0xff);
373                      pktlen = 0;/* to indicate partial length */
374                      partial=1;
375                    }
376                  else
377                    {
378                      log_error("%s: partial length for invalid"
379                                " packet type %d\n",iobuf_where(inp),pkttype);
380                      rc=G10ERR_INVALID_PACKET;
381                      goto leave;
382                    }
383                }
384         }
385     }
386     else
387       {
388         pkttype = (ctb>>2)&0xf;
389         lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
390         if( !lenbytes )
391           {
392             pktlen = 0; /* don't know the value */
393             /* This isn't really partial, but we can treat it the same
394                in a "read until the end" sort of way. */
395             partial=1;
396             if(pkttype!=PKT_ENCRYPTED && pkttype!=PKT_PLAINTEXT
397                && pkttype!=PKT_COMPRESSED)
398               {
399                 log_error ("%s: indeterminate length for invalid"
400                            " packet type %d\n", iobuf_where(inp), pkttype );
401                 rc = G10ERR_INVALID_PACKET;
402                 goto leave;
403               }
404           }
405         else
406           {
407             for( ; lenbytes; lenbytes-- )
408               {
409                 pktlen <<= 8;
410                 pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
411               }
412           }
413       }
414
415     if (pktlen == 0xffffffff) {
416         /* with a some probability this is caused by a problem in the
417          * the uncompressing layer - in some error cases it just loops
418          * and spits out 0xff bytes. */
419         log_error ("%s: garbled packet detected\n", iobuf_where(inp) );
420         g10_exit (2);
421     }
422
423     if( out && pkttype  ) {
424         if( iobuf_write( out, hdr, hdrlen ) == -1 )
425             rc = G10ERR_WRITE_FILE;
426         else
427             rc = copy_packet(inp, out, pkttype, pktlen, partial );
428         goto leave;
429     }
430
431     if (with_uid && pkttype == PKT_USER_ID)
432         ;
433     else if( do_skip 
434         || !pkttype
435         || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
436                         && pkttype != PKT_PUBLIC_KEY
437                         && pkttype != PKT_SECRET_SUBKEY
438                         && pkttype != PKT_SECRET_KEY  ) ) {
439         skip_rest(inp, pktlen, partial);
440         *skip = 1;
441         rc = 0;
442         goto leave;
443     }
444
445     if( DBG_PACKET ) {
446 #ifdef DEBUG_PARSE_PACKET
447         log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n",
448                    iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"",
449                     dbg_w, dbg_f, dbg_l );
450 #else
451         log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n",
452                    iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" );
453 #endif
454     }
455     pkt->pkttype = pkttype;
456     rc = G10ERR_UNKNOWN_PACKET; /* default error */
457     switch( pkttype ) {
458       case PKT_PUBLIC_KEY:
459       case PKT_PUBLIC_SUBKEY:
460         pkt->pkt.public_key = m_alloc_clear(sizeof *pkt->pkt.public_key );
461         rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
462         break;
463       case PKT_SECRET_KEY:
464       case PKT_SECRET_SUBKEY:
465         pkt->pkt.secret_key = m_alloc_clear(sizeof *pkt->pkt.secret_key );
466         rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
467         break;
468       case PKT_SYMKEY_ENC:
469         rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
470         break;
471       case PKT_PUBKEY_ENC:
472         rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
473         break;
474       case PKT_SIGNATURE:
475         pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
476         rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
477         break;
478       case PKT_ONEPASS_SIG:
479         pkt->pkt.onepass_sig = m_alloc_clear(sizeof *pkt->pkt.onepass_sig );
480         rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
481         break;
482       case PKT_USER_ID:
483         rc = parse_user_id(inp, pkttype, pktlen, pkt );
484         break;
485       case PKT_ATTRIBUTE:
486         pkt->pkttype = pkttype = PKT_USER_ID;  /* we store it in the userID */
487         rc = parse_attribute(inp, pkttype, pktlen, pkt);
488         break;
489       case PKT_OLD_COMMENT:
490       case PKT_COMMENT:
491         rc = parse_comment(inp, pkttype, pktlen, pkt);
492         break;
493       case PKT_RING_TRUST:
494         parse_trust(inp, pkttype, pktlen, pkt);
495         rc = 0;
496         break;
497       case PKT_PLAINTEXT:
498         rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb, partial );
499         break;
500       case PKT_COMPRESSED:
501         rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
502         break;
503       case PKT_ENCRYPTED:
504       case PKT_ENCRYPTED_MDC:
505         rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb, partial );
506         break;
507       case PKT_MDC:
508         rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
509         break;
510       case PKT_GPG_CONTROL:
511         rc = parse_gpg_control(inp, pkttype, pktlen, pkt, partial );
512         break;
513       default:
514         skip_packet(inp, pkttype, pktlen, partial);
515         break;
516     }
517
518   leave:
519     if( !rc && iobuf_error(inp) )
520         rc = G10ERR_INV_KEYRING;
521     return rc;
522 }
523
524 static void
525 dump_hex_line( int c, int *i )
526 {
527     if( *i && !(*i%8) ) {
528         if( *i && !(*i%24) )
529             printf("\n%4d:", *i );
530         else
531             putchar(' ');
532     }
533     if( c == -1 )
534         printf(" EOF" );
535     else
536         printf(" %02x", c );
537     ++*i;
538 }
539
540
541 static int
542 copy_packet( IOBUF inp, IOBUF out, int pkttype,
543              unsigned long pktlen, int partial )
544 {
545     int n;
546     char buf[100];
547
548     if( partial ) {
549         while( (n = iobuf_read( inp, buf, 100 )) != -1 )
550             if( iobuf_write(out, buf, n ) )
551                 return G10ERR_WRITE_FILE; /* write error */
552     }
553     else if( !pktlen && pkttype == PKT_COMPRESSED ) {
554         log_debug("copy_packet: compressed!\n");
555         /* compressed packet, copy till EOF */
556         while( (n = iobuf_read( inp, buf, 100 )) != -1 )
557             if( iobuf_write(out, buf, n ) )
558                 return G10ERR_WRITE_FILE; /* write error */
559     }
560     else {
561         for( ; pktlen; pktlen -= n ) {
562             n = pktlen > 100 ? 100 : pktlen;
563             n = iobuf_read( inp, buf, n );
564             if( n == -1 )
565                 return G10ERR_READ_FILE;
566             if( iobuf_write(out, buf, n ) )
567                 return G10ERR_WRITE_FILE; /* write error */
568         }
569     }
570     return 0;
571 }
572
573
574 static void
575 skip_packet( IOBUF inp, int pkttype, unsigned long pktlen, int partial )
576 {
577     if( list_mode ) {
578         if( pkttype == PKT_MARKER )
579             fputs(":marker packet:\n", stdout );
580         else
581             printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
582         if( pkttype ) {
583             int c, i=0 ;
584             if( pkttype != PKT_MARKER )
585                 fputs("dump:", stdout );
586             if( partial ) {
587                 while( (c=iobuf_get(inp)) != -1 )
588                     dump_hex_line(c, &i);
589             }
590             else {
591                 for( ; pktlen; pktlen-- )
592                     dump_hex_line(iobuf_get(inp), &i);
593             }
594             putchar('\n');
595             return;
596         }
597     }
598     skip_rest(inp,pktlen,partial);
599 }
600
601 static void
602 skip_rest( IOBUF inp, unsigned long pktlen, int partial )
603 {
604     if( partial ) {
605         while( iobuf_get(inp) != -1 )
606                 ;
607     }
608     else {
609         for( ; pktlen; pktlen-- )
610             if( iobuf_get(inp) == -1 )
611                 break;
612     }
613 }
614
615
616 static void *
617 read_rest( IOBUF inp, size_t pktlen, int partial )
618 {
619     byte *p;
620     int i;
621
622     if( partial ) {
623         log_error("read_rest: can't store stream data\n");
624         p = NULL;
625     }
626     else {
627         p = m_alloc( pktlen );
628         for(i=0; pktlen; pktlen--, i++ )
629             p[i] = iobuf_get(inp);
630     }
631     return p;
632 }
633
634
635
636 static int
637 parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
638 {
639     PKT_symkey_enc *k;
640     int rc = 0;
641     int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
642
643     if( pktlen < 4 ) {
644         log_error("packet(%d) too short\n", pkttype);
645         rc = G10ERR_INVALID_PACKET;
646         goto leave;
647     }
648     version = iobuf_get_noeof(inp); pktlen--;
649     if( version != 4 ) {
650         log_error("packet(%d) with unknown version %d\n", pkttype, version);
651         rc = G10ERR_INVALID_PACKET;
652         goto leave;
653     }
654     if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
655         log_error("packet(%d) too large\n", pkttype);
656         rc = G10ERR_INVALID_PACKET;
657         goto leave;
658     }
659     cipher_algo = iobuf_get_noeof(inp); pktlen--;
660     s2kmode = iobuf_get_noeof(inp); pktlen--;
661     hash_algo = iobuf_get_noeof(inp); pktlen--;
662     switch( s2kmode ) {
663       case 0:  /* simple s2k */
664         minlen = 0;
665         break;
666       case 1:  /* salted s2k */
667         minlen = 8;
668         break;
669       case 3:  /* iterated+salted s2k */
670         minlen = 9;
671         break;
672       default:
673         log_error("unknown S2K %d\n", s2kmode );
674         goto leave;
675     }
676     if( minlen > pktlen ) {
677         log_error("packet with S2K %d too short\n", s2kmode );
678         rc = G10ERR_INVALID_PACKET;
679         goto leave;
680     }
681     seskeylen = pktlen - minlen;
682     k = packet->pkt.symkey_enc = m_alloc_clear( sizeof *packet->pkt.symkey_enc
683                                                 + seskeylen - 1 );
684     k->version = version;
685     k->cipher_algo = cipher_algo;
686     k->s2k.mode = s2kmode;
687     k->s2k.hash_algo = hash_algo;
688     if( s2kmode == 1 || s2kmode == 3 ) {
689         for(i=0; i < 8 && pktlen; i++, pktlen-- )
690             k->s2k.salt[i] = iobuf_get_noeof(inp);
691     }
692     if( s2kmode == 3 ) {
693         k->s2k.count = iobuf_get(inp); pktlen--;
694     }
695     k->seskeylen = seskeylen;
696     if(k->seskeylen)
697       {
698         for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
699           k->seskey[i] = iobuf_get_noeof(inp);
700
701         /* What we're watching out for here is a session key decryptor
702            with no salt.  The RFC says that using salt for this is a
703            MUST. */
704         if(s2kmode!=1 && s2kmode!=3)
705           log_info(_("WARNING: potentially insecure symmetrically"
706                      " encrypted session key\n"));
707       }
708     assert( !pktlen );
709
710     if( list_mode ) {
711         printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d",
712                version, cipher_algo, s2kmode, hash_algo);
713         if(seskeylen)
714           printf(", seskey %d bits",(seskeylen-1)*8);
715         printf("\n");
716         if( s2kmode == 1 || s2kmode == 3 ) {
717             printf("\tsalt ");
718             for(i=0; i < 8; i++ )
719                 printf("%02x", k->s2k.salt[i]);
720             if( s2kmode == 3 )
721                 printf(", count %lu", (ulong)k->s2k.count );
722             printf("\n");
723         }
724     }
725
726   leave:
727     skip_rest(inp, pktlen, 0);
728     return rc;
729 }
730
731 static int
732 parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
733 {
734     unsigned int n;
735     int rc = 0;
736     int i, ndata;
737     PKT_pubkey_enc *k;
738
739     k = packet->pkt.pubkey_enc = m_alloc_clear(sizeof *packet->pkt.pubkey_enc);
740     if( pktlen < 12 ) {
741         log_error("packet(%d) too short\n", pkttype);
742         rc = G10ERR_INVALID_PACKET;
743         goto leave;
744     }
745     k->version = iobuf_get_noeof(inp); pktlen--;
746     if( k->version != 2 && k->version != 3 ) {
747         log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
748         rc = G10ERR_INVALID_PACKET;
749         goto leave;
750     }
751     k->keyid[0] = read_32(inp); pktlen -= 4;
752     k->keyid[1] = read_32(inp); pktlen -= 4;
753     k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
754     k->throw_keyid = 0; /* only used as flag for build_packet */
755     if( list_mode )
756         printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
757           k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
758
759     ndata = pubkey_get_nenc(k->pubkey_algo);
760     if( !ndata ) {
761         if( list_mode )
762             printf("\tunsupported algorithm %d\n", k->pubkey_algo );
763         unknown_pubkey_warning( k->pubkey_algo );
764         k->data[0] = NULL;  /* no need to store the encrypted data */
765     }
766     else {
767         for( i=0; i < ndata; i++ ) {
768             n = pktlen;
769             k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
770             if( list_mode ) {
771                 printf("\tdata: ");
772                 mpi_print(stdout, k->data[i], mpi_print_mode );
773                 putchar('\n');
774             }
775             if (!k->data[i])
776                 rc = G10ERR_INVALID_PACKET;
777         }
778     }
779
780   leave:
781     skip_rest(inp, pktlen, 0);
782     return rc;
783 }
784
785
786 static void
787 dump_sig_subpkt( int hashed, int type, int critical,
788                  const byte *buffer, size_t buflen, size_t length )
789 {
790     const char *p=NULL;
791     int i;
792
793     /* The CERT has warning out with explains how to use GNUPG to
794      * detect the ARRs - we print our old message here when it is a faked
795      * ARR and add an additional notice */
796     if ( type == SIGSUBPKT_ARR && !hashed ) {
797         printf("\tsubpkt %d len %u (additional recipient request)\n"
798                "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
799                "encrypt to this key and thereby reveal the plaintext to "
800                "the owner of this ARR key. Detailed info follows:\n",
801                type, (unsigned)length );
802     }
803     
804     buffer++;
805     length--;
806    
807     printf("\t%s%ssubpkt %d len %u (", /*)*/
808               critical ? "critical ":"",
809               hashed ? "hashed ":"", type, (unsigned)length );
810     if( length > buflen ) {
811         printf("too short: buffer is only %u)\n", (unsigned)buflen );
812         return;
813     }
814     switch( type ) {
815       case SIGSUBPKT_SIG_CREATED:
816         if( length >= 4 )
817             printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
818         break;
819       case SIGSUBPKT_SIG_EXPIRE:
820         if( length >= 4 )
821             printf("sig expires after %s",
822                                      strtimevalue( buffer_to_u32(buffer) ) );
823         break;
824       case SIGSUBPKT_EXPORTABLE:
825         if( length )
826             printf("%sexportable", *buffer? "":"not ");
827         break;
828       case SIGSUBPKT_TRUST:
829         if(length!=2)
830           p="[invalid trust subpacket]";
831         else
832           printf("trust signature of depth %d, value %d",buffer[0],buffer[1]);
833         break;
834       case SIGSUBPKT_REGEXP:
835         if(!length)
836           p="[invalid regexp subpacket]";
837         else
838           printf("regular expression: \"%s\"",buffer);
839         break;
840       case SIGSUBPKT_REVOCABLE:
841         if( length )
842             printf("%srevocable", *buffer? "":"not ");
843         break;
844       case SIGSUBPKT_KEY_EXPIRE:
845         if( length >= 4 )
846             printf("key expires after %s",
847                                     strtimevalue( buffer_to_u32(buffer) ) );
848         break;
849       case SIGSUBPKT_PREF_SYM:
850         fputs("pref-sym-algos:", stdout );
851         for( i=0; i < length; i++ )
852             printf(" %d", buffer[i] );
853         break;
854       case SIGSUBPKT_REV_KEY:
855         fputs("revocation key: ", stdout );
856         if( length < 22 )
857             p = "[too short]";
858         else {
859             printf("c=%02x a=%d f=", buffer[0], buffer[1] );
860             for( i=2; i < length; i++ )
861                 printf("%02X", buffer[i] );
862         }
863         break;
864       case SIGSUBPKT_ISSUER:
865         if( length >= 8 )
866             printf("issuer key ID %08lX%08lX",
867                       (ulong)buffer_to_u32(buffer),
868                       (ulong)buffer_to_u32(buffer+4) );
869         break;
870       case SIGSUBPKT_NOTATION:
871         {
872             fputs("notation: ", stdout );
873             if( length < 8 )
874                 p = "[too short]";
875             else {
876                 const byte *s = buffer;
877                 size_t n1, n2;
878
879                 n1 = (s[4] << 8) | s[5];
880                 n2 = (s[6] << 8) | s[7];
881                 s += 8;
882                 if( 8+n1+n2 != length )
883                     p = "[error]";
884                 else {
885                     print_string( stdout, s, n1, ')' );
886                     putc( '=', stdout );
887
888                     if( *buffer & 0x80 )
889                       print_string( stdout, s+n1, n2, ')' );
890                     else
891                       p = "[not human readable]";
892                 }
893             }
894         }
895         break;
896       case SIGSUBPKT_PREF_HASH:
897         fputs("pref-hash-algos:", stdout );
898         for( i=0; i < length; i++ )
899             printf(" %d", buffer[i] );
900         break;
901       case SIGSUBPKT_PREF_COMPR:
902         fputs("pref-zip-algos:", stdout );
903         for( i=0; i < length; i++ )
904             printf(" %d", buffer[i] );
905         break;
906       case SIGSUBPKT_KS_FLAGS:
907         fputs("key server preferences:",stdout);
908         for(i=0;i<length;i++)
909           printf(" %02X", buffer[i]);
910         break;
911       case SIGSUBPKT_PREF_KS:
912         fputs("preferred key server: ", stdout );
913         print_string( stdout, buffer, length, ')' );
914         break;
915       case SIGSUBPKT_PRIMARY_UID:
916         p = "primary user ID";
917         break;
918       case SIGSUBPKT_POLICY:
919         fputs("policy: ", stdout );
920         print_string( stdout, buffer, length, ')' );
921         break;
922       case SIGSUBPKT_KEY_FLAGS:
923         fputs ( "key flags:", stdout );
924         for( i=0; i < length; i++ )
925             printf(" %02X", buffer[i] );
926         break;
927       case SIGSUBPKT_SIGNERS_UID:
928         p = "signer's user ID";
929         break;
930       case SIGSUBPKT_REVOC_REASON:
931         if( length ) {
932             printf("revocation reason 0x%02x (", *buffer );
933             print_string( stdout, buffer+1, length-1, ')' );
934             p = ")";
935         }
936         break;
937       case SIGSUBPKT_ARR:
938         fputs("Big Brother's key (ignored): ", stdout );
939         if( length < 22 )
940             p = "[too short]";
941         else {
942             printf("c=%02x a=%d f=", buffer[0], buffer[1] );
943             for( i=2; i < length; i++ )
944                 printf("%02X", buffer[i] );
945         }
946         break;
947       case SIGSUBPKT_FEATURES:
948         fputs ( "features:", stdout );
949         for( i=0; i < length; i++ )
950             printf(" %02x", buffer[i] );
951         break;
952       case SIGSUBPKT_SIGNATURE:
953         fputs("signature: ",stdout);
954         if(length<17)
955           p="[too short]";
956         else
957           printf("v%d, class 0x%02X, algo %d, digest algo %d",
958                  buffer[0],
959                  buffer[0]==3?buffer[2]:buffer[1],
960                  buffer[0]==3?buffer[15]:buffer[2],
961                  buffer[0]==3?buffer[16]:buffer[3]);
962         break;
963       default:
964         if(type>=100 && type<=110)
965           p="experimental / private subpacket";
966         else
967           p = "?";
968         break;
969     }
970
971     printf("%s)\n", p? p: "");
972 }
973
974 /****************
975  * Returns: >= 0 offset into buffer
976  *          -1 unknown type
977  *          -2 unsupported type
978  *          -3 subpacket too short
979  */
980 int
981 parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
982 {
983   switch( type )
984     {
985     case SIGSUBPKT_REV_KEY:
986       if(n < 22)
987         break;
988       return 0;
989     case SIGSUBPKT_SIG_CREATED:
990     case SIGSUBPKT_SIG_EXPIRE:
991     case SIGSUBPKT_KEY_EXPIRE:
992       if( n < 4 )
993         break;
994       return 0;
995     case SIGSUBPKT_KEY_FLAGS:
996     case SIGSUBPKT_KS_FLAGS:
997     case SIGSUBPKT_PREF_SYM:
998     case SIGSUBPKT_PREF_HASH:
999     case SIGSUBPKT_PREF_COMPR:
1000     case SIGSUBPKT_POLICY:
1001     case SIGSUBPKT_PREF_KS:
1002     case SIGSUBPKT_FEATURES:
1003     case SIGSUBPKT_REGEXP:
1004       return 0;
1005     case SIGSUBPKT_SIGNATURE:
1006     case SIGSUBPKT_EXPORTABLE:
1007     case SIGSUBPKT_REVOCABLE:
1008     case SIGSUBPKT_REVOC_REASON:
1009       if( !n )
1010         break;
1011       return 0;
1012     case SIGSUBPKT_ISSUER: /* issuer key ID */
1013       if( n < 8 )
1014         break;
1015       return 0;
1016     case SIGSUBPKT_NOTATION:
1017       if( n < 8 ) /* minimum length needed */
1018         break;
1019       return 0;
1020     case SIGSUBPKT_PRIMARY_UID:
1021       if ( n != 1 )
1022         break;
1023       return 0;
1024     case SIGSUBPKT_TRUST:
1025       if ( n != 2 )
1026         break;
1027       return 0;
1028     default: return -1;
1029     }
1030   return -3;
1031 }
1032
1033
1034 static int
1035 can_handle_critical( const byte *buffer, size_t n, int type )
1036 {
1037   switch( type )
1038     {
1039     case SIGSUBPKT_NOTATION:
1040       if( n >= 8 && (*buffer & 0x80) )
1041         return 1; /* human readable is handled */
1042       return 0;
1043
1044     case SIGSUBPKT_SIGNATURE:
1045     case SIGSUBPKT_SIG_CREATED:
1046     case SIGSUBPKT_SIG_EXPIRE:
1047     case SIGSUBPKT_KEY_EXPIRE:
1048     case SIGSUBPKT_EXPORTABLE:
1049     case SIGSUBPKT_REVOCABLE:
1050     case SIGSUBPKT_REV_KEY:
1051     case SIGSUBPKT_ISSUER:/* issuer key ID */
1052     case SIGSUBPKT_PREF_SYM:
1053     case SIGSUBPKT_PREF_HASH:
1054     case SIGSUBPKT_PREF_COMPR:
1055     case SIGSUBPKT_KEY_FLAGS:
1056     case SIGSUBPKT_PRIMARY_UID:
1057     case SIGSUBPKT_FEATURES:
1058     case SIGSUBPKT_TRUST:
1059     case SIGSUBPKT_REGEXP:
1060       /* Is it enough to show the policy or keyserver? */
1061     case SIGSUBPKT_POLICY:
1062     case SIGSUBPKT_PREF_KS:
1063       return 1;
1064
1065     default:
1066       return 0;
1067     }
1068 }
1069
1070
1071 const byte *
1072 enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
1073                  size_t *ret_n, int *start, int *critical )
1074 {
1075     const byte *buffer;
1076     int buflen;
1077     int type;
1078     int critical_dummy;
1079     int offset;
1080     size_t n;
1081     int seq = 0;
1082     int reqseq = start? *start: 0;
1083
1084     if(!critical)
1085       critical=&critical_dummy;
1086
1087     if( !pktbuf || reqseq == -1 ) {
1088         /* return some value different from NULL to indicate that
1089          * there is no critical bit we do not understand.  The caller
1090          * will never use the value.  Yes I know, it is an ugly hack */
1091         return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
1092     }
1093     buffer = pktbuf->data;
1094     buflen = pktbuf->len;
1095     while( buflen ) {
1096         n = *buffer++; buflen--;
1097         if( n == 255 ) { /* 4 byte length header */
1098             if( buflen < 4 )
1099                 goto too_short;
1100             n = (buffer[0] << 24) | (buffer[1] << 16)
1101                 | (buffer[2] << 8) | buffer[3];
1102             buffer += 4;
1103             buflen -= 4;
1104         }
1105         else if( n >= 192 ) { /* 2 byte special encoded length header */
1106             if( buflen < 2 )
1107                 goto too_short;
1108             n = (( n - 192 ) << 8) + *buffer + 192;
1109             buffer++;
1110             buflen--;
1111         }
1112         if( buflen < n )
1113             goto too_short;
1114         type = *buffer;
1115         if( type & 0x80 ) {
1116             type &= 0x7f;
1117             *critical = 1;
1118         }
1119         else
1120             *critical = 0;
1121         if( !(++seq > reqseq) )
1122             ;
1123         else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
1124             if( *critical ) {
1125                 if( n-1 > buflen+1 )
1126                     goto too_short;
1127                 if( !can_handle_critical(buffer+1, n-1, type ) )
1128                   {
1129                     if(opt.verbose)
1130                       log_info(_("subpacket of type %d has "
1131                                  "critical bit set\n"),type);
1132                     if( start )
1133                       *start = seq;
1134                     return NULL; /* this is an error */
1135                   }
1136             }
1137         }
1138         else if( reqtype < 0 ) /* list packets */
1139             dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
1140                                     type, *critical, buffer, buflen, n );
1141         else if( type == reqtype ) { /* found */
1142             buffer++;
1143             n--;
1144             if( n > buflen )
1145                 goto too_short;
1146             if( ret_n )
1147                 *ret_n = n;
1148             offset = parse_one_sig_subpkt(buffer, n, type );
1149             switch( offset ) {
1150               case -3:
1151                 log_error("subpacket of type %d too short\n", type);
1152                 return NULL;
1153               case -2:
1154                 return NULL;
1155               case -1:
1156                 BUG(); /* not yet needed */
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 static 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         printf(":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             printf("\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                 printf("\tdata: ");
1423                 mpi_print(stdout, sig->data[i], mpi_print_mode );
1424                 putchar('\n');
1425             }
1426             if (!sig->data[i])
1427                 rc = G10ERR_INVALID_PACKET;
1428         }
1429     }
1430
1431   leave:
1432     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         printf(":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     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             printf(":rfc1991 comment packet: \"" );
1539             for( ; pktlen; pktlen-- ) {
1540                 int c;
1541                 c = iobuf_get_noeof(inp);
1542                 if( c >= ' ' && c <= 'z' )
1543                     putchar(c);
1544                 else
1545                     printf("\\x%02x", c );
1546             }
1547             printf("\"\n");
1548         }
1549         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         printf(":%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             printf("\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                 printf(  "\tskey[%d]: ", i);
1646                 mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1647                 putchar('\n');
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                             printf(  "\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 ) printf(  "\tsimple S2K" );
1699                     break;
1700                   case 1: if( list_mode ) printf(  "\tsalted S2K" );
1701                     break;
1702                   case 3: if( list_mode ) printf(  "\titer+salt S2K" );
1703                     break;
1704                   case 1001: if( list_mode ) printf(  "\tgnu-dummy S2K" );
1705                     break;
1706                   case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1707                     break;
1708                   default:
1709                     if( list_mode )
1710                         printf(  "\tunknown %sS2K %d\n",
1711                                  sk->protect.s2k.mode < 1000? "":"GNU ",
1712                                                    sk->protect.s2k.mode );
1713                     rc = G10ERR_INVALID_PACKET;
1714                     goto leave;
1715                 }
1716
1717                 if( list_mode ) {
1718                     printf(", algo: %d,%s hash: %d",
1719                                      sk->protect.algo,
1720                                      sk->protect.sha1chk?" SHA1 protection,"
1721                                                         :" simple checksum,",
1722                                      sk->protect.s2k.hash_algo );
1723                     if( sk->protect.s2k.mode == 1
1724                         || sk->protect.s2k.mode == 3 ) {
1725                         printf(", salt: ");
1726                         for(i=0; i < 8; i++ )
1727                             printf("%02x", sk->protect.s2k.salt[i]);
1728                     }
1729                     putchar('\n');
1730                 }
1731
1732                 if( sk->protect.s2k.mode == 3 ) {
1733                     if( pktlen < 1 ) {
1734                         rc = G10ERR_INVALID_PACKET;
1735                         goto leave;
1736                     }
1737                     sk->protect.s2k.count = iobuf_get(inp);
1738                     pktlen--;
1739                     if( list_mode )
1740                         printf("\tprotect count: %lu\n",
1741                                             (ulong)sk->protect.s2k.count);
1742                 }
1743                 else if( sk->protect.s2k.mode == 1002 ) {
1744                     /* Read the serial number. */
1745                     if (pktlen < 1) {
1746                       rc = G10ERR_INVALID_PACKET;
1747                         goto leave;
1748                     }
1749                     snlen = iobuf_get (inp);
1750                     pktlen--;
1751                     if (pktlen < snlen || snlen == -1) {
1752                         rc = G10ERR_INVALID_PACKET;
1753                         goto leave;
1754                     }
1755                 }
1756             }
1757             /* Note that a sk->protect.algo > 110 is illegal, but I'm
1758                not erroring on it here as otherwise there would be no
1759                way to delete such a key. */
1760             else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1761                 sk->protect.s2k.mode = 0;
1762                 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1763                 if( list_mode )
1764                     printf(  "\tprotect algo: %d  (hash algo: %d)\n",
1765                          sk->protect.algo, sk->protect.s2k.hash_algo );
1766             }
1767             /* It is really ugly that we don't know the size
1768              * of the IV here in cases we are not aware of the algorithm.
1769              * so a
1770              *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1771              * won't work.  The only solution I see is to hardwire it here.
1772              * NOTE: if you change the ivlen above 16, don't forget to
1773              * enlarge temp.
1774              */
1775             switch( sk->protect.algo ) {
1776               case 7: case 8: case 9: /* reserved for AES */
1777               case 10: /* Twofish */
1778                 sk->protect.ivlen = 16;
1779                 break;
1780               default:
1781                 sk->protect.ivlen = 8;
1782             }
1783             if( sk->protect.s2k.mode == 1001 )
1784                 sk->protect.ivlen = 0;
1785             else if( sk->protect.s2k.mode == 1002 )
1786                 sk->protect.ivlen = snlen < 16? snlen : 16;
1787
1788             if( pktlen < sk->protect.ivlen ) {
1789                 rc = G10ERR_INVALID_PACKET;
1790                 goto leave;
1791             }
1792             for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
1793                 temp[i] = iobuf_get_noeof(inp);
1794             if( list_mode ) {
1795                 printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
1796                                                     : "\tprotect IV: ");
1797                 for(i=0; i < sk->protect.ivlen; i++ )
1798                     printf(" %02x", temp[i] );
1799                 putchar('\n');
1800             }
1801             memcpy(sk->protect.iv, temp, sk->protect.ivlen );
1802         }
1803         else
1804             sk->is_protected = 0;
1805         /* It does not make sense to read it into secure memory.
1806          * If the user is so careless, not to protect his secret key,
1807          * we can assume, that he operates an open system :=(.
1808          * So we put the key into secure memory when we unprotect it. */
1809         if( sk->protect.s2k.mode == 1001 
1810             || sk->protect.s2k.mode == 1002 ) {
1811             /* better set some dummy stuff here */
1812             sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10);
1813             pktlen = 0;
1814         }
1815         else if( is_v4 && sk->is_protected ) {
1816             /* ugly; the length is encrypted too, so we read all
1817              * stuff up to the end of the packet into the first
1818              * skey element */
1819             sk->skey[npkey] = mpi_set_opaque(NULL,
1820                                              read_rest(inp, pktlen, 0),pktlen);
1821             pktlen = 0;
1822             if( list_mode ) {
1823                 printf("\tencrypted stuff follows\n");
1824             }
1825         }
1826         else { /* v3 method: the mpi length is not encrypted */
1827             for(i=npkey; i < nskey; i++ ) {
1828                 if ( sk->is_protected ) {
1829                     sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
1830                     if( list_mode ) 
1831                         printf(  "\tskey[%d]: [encrypted]\n", i);
1832                 }
1833                 else {
1834                     n = pktlen;
1835                     sk->skey[i] = mpi_read(inp, &n, 0 );
1836                     pktlen -=n;
1837                     if( list_mode ) {
1838                         printf(  "\tskey[%d]: ", i);
1839                         mpi_print(stdout, sk->skey[i], mpi_print_mode  );
1840                         putchar('\n');
1841                     }
1842                 }
1843
1844                 if (!sk->skey[i])
1845                     rc = G10ERR_INVALID_PACKET;
1846             }
1847             if (rc)
1848                 goto leave;
1849
1850             sk->csum = read_16(inp); pktlen -= 2;
1851             if( list_mode ) {
1852                 printf("\tchecksum: %04hx\n", sk->csum);
1853             }
1854         }
1855     }
1856     else {
1857         PKT_public_key *pk = pkt->pkt.public_key;
1858
1859         if( !npkey ) {
1860             pk->pkey[0] = mpi_set_opaque( NULL,
1861                                           read_rest(inp, pktlen, 0), pktlen );
1862             pktlen = 0;
1863             goto leave;
1864         }
1865
1866         for(i=0; i < npkey; i++ ) {
1867             n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1868             if( list_mode ) {
1869                 printf(  "\tpkey[%d]: ", i);
1870                 mpi_print(stdout, pk->pkey[i], mpi_print_mode  );
1871                 putchar('\n');
1872             }
1873             if (!pk->pkey[i])
1874                 rc = G10ERR_INVALID_PACKET;
1875         }
1876         if (rc)
1877             goto leave;
1878     }
1879
1880   leave:
1881     skip_rest(inp, pktlen, 0);
1882     return rc;
1883 }
1884
1885 /* Attribute subpackets have the same format as v4 signature
1886    subpackets.  This is not part of OpenPGP, but is done in several
1887    versions of PGP nevertheless. */
1888 int
1889 parse_attribute_subpkts(PKT_user_id *uid)
1890 {
1891   size_t n;
1892   int count=0;
1893   struct user_attribute *attribs=NULL;
1894   const byte *buffer=uid->attrib_data;
1895   int buflen=uid->attrib_len;
1896   byte type;
1897
1898   m_free(uid->attribs);
1899
1900   while(buflen)
1901     {
1902       n = *buffer++; buflen--;
1903       if( n == 255 ) { /* 4 byte length header */
1904         if( buflen < 4 )
1905           goto too_short;
1906         n = (buffer[0] << 24) | (buffer[1] << 16)
1907           | (buffer[2] << 8) | buffer[3];
1908         buffer += 4;
1909         buflen -= 4;
1910       }
1911       else if( n >= 192 ) { /* 2 byte special encoded length header */
1912         if( buflen < 2 )
1913           goto too_short;
1914         n = (( n - 192 ) << 8) + *buffer + 192;
1915         buffer++;
1916         buflen--;
1917       }
1918       if( buflen < n )
1919         goto too_short;
1920
1921       attribs=m_realloc(attribs,(count+1)*sizeof(struct user_attribute));
1922       memset(&attribs[count],0,sizeof(struct user_attribute));
1923
1924       type=*buffer;
1925       buffer++;
1926       buflen--;
1927       n--;
1928
1929       attribs[count].type=type;
1930       attribs[count].data=buffer;
1931       attribs[count].len=n;
1932       buffer+=n;
1933       buflen-=n;
1934       count++;
1935     }
1936
1937   uid->attribs=attribs;
1938   uid->numattribs=count;
1939   return count;
1940
1941  too_short:
1942   log_error("buffer shorter than attribute subpacket\n");
1943   uid->attribs=attribs;
1944   uid->numattribs=count;
1945   return count;
1946 }
1947
1948 static void setup_user_id(PACKET *packet)
1949 {
1950   packet->pkt.user_id->ref = 1;
1951   packet->pkt.user_id->attribs = NULL;
1952   packet->pkt.user_id->attrib_data = NULL;
1953   packet->pkt.user_id->attrib_len = 0;
1954   packet->pkt.user_id->is_primary = 0;
1955   packet->pkt.user_id->is_revoked = 0;
1956   packet->pkt.user_id->is_expired = 0;
1957   packet->pkt.user_id->expiredate = 0;
1958   packet->pkt.user_id->created = 0;
1959   packet->pkt.user_id->help_key_usage = 0;
1960   packet->pkt.user_id->help_key_expire = 0;
1961   packet->pkt.user_id->prefs = NULL;
1962   packet->pkt.user_id->namehash = NULL;
1963 }
1964
1965 static int
1966 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1967 {
1968     byte *p;
1969
1970     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen);
1971     packet->pkt.user_id->len = pktlen;
1972
1973     setup_user_id(packet);
1974
1975     p = packet->pkt.user_id->name;
1976     for( ; pktlen; pktlen--, p++ )
1977         *p = iobuf_get_noeof(inp);
1978     *p = 0;
1979
1980     if( list_mode ) {
1981         int n = packet->pkt.user_id->len;
1982         printf(":user ID packet: \"");
1983         /* fixme: Hey why don't we replace this with print_string?? */
1984         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1985             if( *p >= ' ' && *p <= 'z' )
1986                 putchar(*p);
1987             else
1988                 printf("\\x%02x", *p );
1989         }
1990         printf("\"\n");
1991     }
1992     return 0;
1993 }
1994
1995
1996 void
1997 make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
1998 {
1999   assert ( max_namelen > 70 );
2000   if(uid->numattribs<=0)
2001     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
2002   else if(uid->numattribs>1)
2003     sprintf(uid->name,"[%d attributes of size %lu]",
2004             uid->numattribs,uid->attrib_len);
2005   else
2006     {
2007       /* Only one attribute, so list it as the "user id" */
2008
2009       if(uid->attribs->type==ATTRIB_IMAGE)
2010         {
2011           u32 len;
2012           byte type;
2013
2014           if(parse_image_header(uid->attribs,&type,&len))
2015             sprintf(uid->name,"[%.20s image of size %lu]",
2016                     image_type_to_string(type,1),(ulong)len);
2017           else
2018             sprintf(uid->name,"[invalid image]");
2019         }
2020       else
2021         sprintf(uid->name,"[unknown attribute of size %lu]",
2022                 (ulong)uid->attribs->len);
2023     }
2024
2025   uid->len = strlen(uid->name);
2026 }
2027
2028 static int
2029 parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2030 {
2031     byte *p;
2032
2033 #define EXTRA_UID_NAME_SPACE 71
2034     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id
2035                                   + EXTRA_UID_NAME_SPACE);
2036
2037     setup_user_id(packet);
2038
2039     packet->pkt.user_id->attrib_data = m_alloc(pktlen);
2040     packet->pkt.user_id->attrib_len = pktlen;
2041     p = packet->pkt.user_id->attrib_data;
2042     for( ; pktlen; pktlen--, p++ )
2043         *p = iobuf_get_noeof(inp);
2044
2045     /* Now parse out the individual attribute subpackets.  This is
2046        somewhat pointless since there is only one currently defined
2047        attribute type (jpeg), but it is correct by the spec. */
2048     parse_attribute_subpkts(packet->pkt.user_id);
2049
2050     make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
2051
2052     if( list_mode ) {
2053         printf(":attribute packet: %s\n", packet->pkt.user_id->name );
2054     }
2055     return 0;
2056 }
2057
2058
2059 static int
2060 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
2061 {
2062     byte *p;
2063
2064     packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
2065     packet->pkt.comment->len = pktlen;
2066     p = packet->pkt.comment->data;
2067     for( ; pktlen; pktlen--, p++ )
2068         *p = iobuf_get_noeof(inp);
2069
2070     if( list_mode ) {
2071         int n = packet->pkt.comment->len;
2072         printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2073                                          "OpenPGP draft " : "" );
2074         for(p=packet->pkt.comment->data; n; p++, n-- ) {
2075             if( *p >= ' ' && *p <= 'z' )
2076                 putchar(*p);
2077             else
2078                 printf("\\x%02x", *p );
2079         }
2080         printf("\"\n");
2081     }
2082     return 0;
2083 }
2084
2085
2086 static void
2087 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2088 {
2089   int c;
2090
2091   if (pktlen)
2092     {
2093       c = iobuf_get_noeof(inp);
2094       pktlen--;
2095       pkt->pkt.ring_trust = m_alloc( sizeof *pkt->pkt.ring_trust );
2096       pkt->pkt.ring_trust->trustval = c;
2097       pkt->pkt.ring_trust->sigcache = 0;
2098       if (!c && pktlen==1)
2099         {
2100           c = iobuf_get_noeof (inp);
2101           pktlen--;
2102           /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2103           if ( !(c & 0x80) )
2104             pkt->pkt.ring_trust->sigcache = c;
2105         }
2106       if( list_mode )
2107         printf(":trust packet: flag=%02x sigcache=%02x\n",
2108                pkt->pkt.ring_trust->trustval,
2109                pkt->pkt.ring_trust->sigcache);
2110     }
2111   else
2112     {
2113       if( list_mode )
2114         printf(":trust packet: empty\n");
2115     }
2116   skip_rest (inp, pktlen, 0);
2117 }
2118
2119
2120 static int
2121 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
2122                  PACKET *pkt, int new_ctb, int partial )
2123 {
2124     int rc = 0;
2125     int mode, namelen;
2126     PKT_plaintext *pt;
2127     byte *p;
2128     int c, i;
2129
2130     if( !partial && pktlen < 6 ) {
2131         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2132         rc = G10ERR_INVALID_PACKET;
2133         goto leave;
2134     }
2135     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2136     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2137     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
2138     pt->new_ctb = new_ctb;
2139     pt->mode = mode;
2140     pt->namelen = namelen;
2141     pt->is_partial = partial;
2142     if( pktlen ) {
2143         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2144             pt->name[i] = iobuf_get_noeof(inp);
2145     }
2146     else {
2147         for( i=0; i < namelen; i++ )
2148             if( (c=iobuf_get(inp)) == -1 )
2149                 break;
2150             else
2151                 pt->name[i] = c;
2152     }
2153     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2154     pt->len = pktlen;
2155     pt->buf = inp;
2156     pktlen = 0;
2157
2158     if( list_mode ) {
2159         printf(":literal data packet:\n"
2160                "\tmode %c, created %lu, name=\"",
2161                     mode >= ' ' && mode <'z'? mode : '?',
2162                     (ulong)pt->timestamp );
2163         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2164             if( *p >= ' ' && *p <= 'z' )
2165                 putchar(*p);
2166             else
2167                 printf("\\x%02x", *p );
2168         }
2169         printf("\",\n\traw data: ");
2170         if(partial)
2171           printf("unknown length\n");
2172         else
2173           printf("%lu bytes\n", (ulong)pt->len );
2174     }
2175
2176   leave:
2177     return rc;
2178 }
2179
2180
2181 static int
2182 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
2183                   PACKET *pkt, int new_ctb )
2184 {
2185     PKT_compressed *zd;
2186
2187     /* pktlen is here 0, but data follows
2188      * (this should be the last object in a file or
2189      *  the compress algorithm should know the length)
2190      */
2191     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
2192     zd->algorithm = iobuf_get_noeof(inp);
2193     zd->len = 0; /* not used */ 
2194     zd->new_ctb = new_ctb;
2195     zd->buf = inp;
2196     if( list_mode )
2197         printf(":compressed packet: algo=%d\n", zd->algorithm);
2198     return 0;
2199 }
2200
2201
2202 static int
2203 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
2204                  PACKET *pkt, int new_ctb, int partial )
2205 {
2206     int rc = 0;
2207     PKT_encrypted *ed;
2208     unsigned long orig_pktlen = pktlen;
2209
2210     ed = pkt->pkt.encrypted =  m_alloc(sizeof *pkt->pkt.encrypted );
2211     ed->len = pktlen;
2212     /* we don't know the extralen which is (cipher_blocksize+2)
2213        because the algorithm ist not specified in this packet.
2214        However, it is only important to know this for some sanity
2215        checks on the packet length - it doesn't matter that we can't
2216        do it */
2217     ed->extralen = 0;
2218     ed->buf = NULL;
2219     ed->new_ctb = new_ctb;
2220     ed->is_partial = partial;
2221     ed->mdc_method = 0;
2222     if( pkttype == PKT_ENCRYPTED_MDC ) {
2223         /* fixme: add some pktlen sanity checks */
2224         int version;
2225
2226         version = iobuf_get_noeof(inp); 
2227         if (orig_pktlen)
2228             pktlen--;
2229         if( version != 1 ) {
2230             log_error("encrypted_mdc packet with unknown version %d\n",
2231                                                                 version);
2232             /*skip_rest(inp, pktlen); should we really do this? */
2233             rc = G10ERR_INVALID_PACKET;
2234             goto leave;
2235         }
2236         ed->mdc_method = DIGEST_ALGO_SHA1;
2237     }
2238     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2239         log_error("packet(%d) too short\n", pkttype);
2240         rc = G10ERR_INVALID_PACKET;
2241         skip_rest(inp, pktlen, partial);
2242         goto leave;
2243     }
2244     if( list_mode ) {
2245         if( orig_pktlen )
2246             printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2247         else
2248             printf(":encrypted data packet:\n\tlength: unknown\n");
2249         if( ed->mdc_method )
2250             printf("\tmdc_method: %d\n", ed->mdc_method );
2251     }
2252
2253     ed->buf = inp;
2254
2255   leave:
2256     return rc;
2257 }
2258
2259
2260 static int
2261 parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
2262                                    PACKET *pkt, int new_ctb )
2263 {
2264     int rc = 0;
2265     PKT_mdc *mdc;
2266     byte *p;
2267
2268     mdc = pkt->pkt.mdc=  m_alloc(sizeof *pkt->pkt.mdc );
2269     if( list_mode )
2270         printf(":mdc packet: length=%lu\n", pktlen);
2271     if( !new_ctb || pktlen != 20 ) {
2272         log_error("mdc_packet with invalid encoding\n");
2273         rc = G10ERR_INVALID_PACKET;
2274         goto leave;
2275     }
2276     p = mdc->hash;
2277     for( ; pktlen; pktlen--, p++ )
2278         *p = iobuf_get_noeof(inp);
2279
2280   leave:
2281     return rc;
2282 }
2283
2284
2285 /*
2286  * This packet is internally generated by PGG (by armor.c) to
2287  * transfer some information to the lower layer.  To make sure that
2288  * this packet is really a GPG faked one and not one comming from outside,
2289  * we first check that tehre is a unique tag in it.
2290  * The format of such a control packet is:
2291  *   n byte  session marker
2292  *   1 byte  control type CTRLPKT_xxxxx
2293  *   m byte  control data
2294  */
2295
2296 static int
2297 parse_gpg_control( IOBUF inp, int pkttype,
2298                    unsigned long pktlen, PACKET *packet, int partial )
2299 {
2300     byte *p;
2301     const byte *sesmark;
2302     size_t sesmarklen;
2303     int i;
2304
2305     if ( list_mode )
2306         printf(":packet 63: length %lu ",  pktlen);
2307
2308     sesmark = get_session_marker ( &sesmarklen );
2309     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2310         goto skipit;
2311     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2312         if ( sesmark[i] != iobuf_get_noeof(inp) )
2313             goto skipit;
2314     }
2315     if ( list_mode )
2316         puts ("- gpg control packet");
2317
2318     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2319                                       + pktlen - 1);
2320     packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
2321     packet->pkt.gpg_control->datalen = pktlen;
2322     p = packet->pkt.gpg_control->data;
2323     for( ; pktlen; pktlen--, p++ )
2324         *p = iobuf_get_noeof(inp);
2325
2326     return 0;
2327
2328  skipit:
2329     if ( list_mode ) {
2330         int c;
2331
2332         i=0;
2333         printf("- private (rest length %lu)\n",  pktlen);
2334         if( partial ) {
2335             while( (c=iobuf_get(inp)) != -1 )
2336                 dump_hex_line(c, &i);
2337         }
2338         else {
2339             for( ; pktlen; pktlen-- )
2340                 dump_hex_line(iobuf_get(inp), &i);
2341         }
2342         putchar('\n');
2343     }
2344     skip_rest(inp,pktlen, 0);
2345     return G10ERR_INVALID_PACKET;
2346 }
2347
2348 /* create a gpg control packet to be used internally as a placeholder */
2349 PACKET *
2350 create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
2351 {
2352     PACKET *packet;
2353     byte *p;
2354
2355     packet = m_alloc( sizeof *packet );
2356     init_packet(packet);
2357     packet->pkttype = PKT_GPG_CONTROL;
2358     packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control
2359                                       + datalen - 1);
2360     packet->pkt.gpg_control->control = type;
2361     packet->pkt.gpg_control->datalen = datalen;
2362     p = packet->pkt.gpg_control->data;
2363     for( ; datalen; datalen--, p++ )
2364         *p = *data++;
2365
2366     return packet;
2367 }