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