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