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