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