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