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