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