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