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