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