1 /* parse-packet.c - read packets
2 * Copyright (C) 1998 Free Software Foundation, Inc.
4 * This file is part of GNUPG.
6 * GNUPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36 static mpi_print_mode = 0;
39 static int parse( IOBUF inp, PACKET *pkt, int reqtype,
40 ulong *retpos, int *skip, IOBUF out, int do_skip );
41 static int copy_packet( IOBUF inp, IOBUF out, int pkttype,
42 unsigned long pktlen );
43 static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen );
44 static void skip_rest( IOBUF inp, unsigned long pktlen );
45 static int parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen,
47 static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
49 static int parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
50 PKT_onepass_sig *ops );
51 static int parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
52 byte *hdr, int hdrlen, PACKET *packet );
53 static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
55 static void parse_subkey( IOBUF inp, int pkttype, unsigned long pktlen );
56 static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
58 static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen );
59 static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
61 static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
63 static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
83 a = iobuf_get_noeof(inp) << 8;
84 a |= iobuf_get_noeof(inp);
92 a = iobuf_get_noeof(inp) << 24;
93 a |= iobuf_get_noeof(inp) << 16;
94 a |= iobuf_get_noeof(inp) << 8;
95 a |= iobuf_get_noeof(inp);
100 buffer_to_u32( const byte *buffer )
104 a |= buffer[1] << 16;
111 set_packet_list_mode( int mode )
115 mpi_print_mode = DBG_MPI;
120 * Parse a Packet and return it in packet
121 * Returns: 0 := valid packet in pkt
122 * -1 := no more packets
124 * Note: The function may return an error and a partly valid packet;
125 * caller must free this packet.
128 parse_packet( IOBUF inp, PACKET *pkt )
133 rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
139 * Like parse packet, but do only return packets of the given type.
142 search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos )
147 rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0 );
153 * Copy all packets from INP to OUT, thereby removing unused spaces.
156 copy_all_packets( IOBUF inp, IOBUF out )
162 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
167 * Copy some packets from INP to OUT, thereby removing unused spaces.
168 * Stop after at offset STOPoff (i.e. don't copy the packet at this offset)
171 copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff )
176 if( iobuf_tell(inp) >= stopoff )
179 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
184 * Skip over N packets
187 skip_some_packets( IOBUF inp, unsigned n )
192 for( ;n && !rc; n--) {
194 rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
200 * Parse packet. Set the variable skip points to to 1 if the packet
201 * should be skipped; this is the case if either there is a
202 * requested packet type and the parsed packet doesn't match or the
203 * packet-type is 0, indicating deleted stuff.
204 * if OUT is not NULL, a special copymode is used.
207 parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
208 int *skip, IOBUF out, int do_skip )
210 int rc, c, ctb, pkttype, lenbytes;
211 unsigned long pktlen;
217 assert( !pkt->pkt.generic );
219 *retpos = iobuf_tell(inp);
220 if( (ctb = iobuf_get(inp)) == -1 )
224 if( !(ctb & 0x80) ) {
225 log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb );
226 return G10ERR_INVALID_PACKET;
229 pgp3 = !!(ctb & 0x40);
231 pkttype = ctb & 0x3f;
232 if( (c = iobuf_get(inp)) == -1 ) {
233 log_error("%s: 1st length byte missing\n", iobuf_where(inp) );
234 return G10ERR_INVALID_PACKET;
240 pktlen = (c - 192) * 256;
241 if( (c = iobuf_get(inp)) == -1 ) {
242 log_error("%s: 2nd length byte missing\n", iobuf_where(inp) );
243 return G10ERR_INVALID_PACKET;
248 else { /* partial body length */
249 pktlen = 1 << (c & 0x1f);
250 log_debug("partial body length of %lu bytes\n", pktlen );
251 iobuf_set_partial_block_mode(inp, pktlen);
252 pktlen = 0;/* to indicate partial length */
256 pkttype = (ctb>>2)&0xf;
257 lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
259 pktlen = 0; /* don't know the value */
260 if( pkttype != PKT_COMPRESSED )
261 iobuf_set_block_mode(inp, 1);
264 for( ; lenbytes; lenbytes-- ) {
266 pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
271 if( out && pkttype ) {
272 if( iobuf_write( out, hdr, hdrlen ) == -1 )
273 rc = G10ERR_WRITE_FILE;
275 rc = copy_packet(inp, out, pkttype, pktlen );
279 if( do_skip || !pkttype || (reqtype && pkttype != reqtype) ) {
280 skip_packet(inp, pkttype, pktlen);
286 log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n",
287 iobuf_id(inp), pkttype, pktlen, pgp3?" (pgp3)":"" );
288 pkt->pkttype = pkttype;
289 rc = G10ERR_UNKNOWN_PACKET; /* default error */
291 case PKT_PUBLIC_CERT:
292 pkt->pkt.public_cert = m_alloc_clear(sizeof *pkt->pkt.public_cert );
293 rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
295 case PKT_SECRET_CERT:
296 case PKT_SECKEY_SUBCERT:
297 pkt->pkt.secret_cert = m_alloc_clear(sizeof *pkt->pkt.secret_cert );
298 rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
301 rc = parse_publickey(inp, pkttype, pktlen, pkt );
304 pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
305 rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
307 case PKT_ONEPASS_SIG:
308 pkt->pkt.onepass_sig = m_alloc_clear(sizeof *pkt->pkt.onepass_sig );
309 rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
312 rc = parse_user_id(inp, pkttype, pktlen, pkt );
314 case PKT_PUBKEY_SUBCERT:
315 parse_subkey(inp, pkttype, pktlen);
318 rc = parse_comment(inp, pkttype, pktlen, pkt);
321 parse_trust(inp, pkttype, pktlen);
324 rc = parse_plaintext(inp, pkttype, pktlen, pkt );
327 rc = parse_compressed(inp, pkttype, pktlen, pkt );
330 rc = parse_encrypted(inp, pkttype, pktlen, pkt );
333 skip_packet(inp, pkttype, pktlen);
341 dump_hex_line( int c, int *i )
343 if( *i && !(*i%8) ) {
345 printf("\n%4d:", *i );
358 copy_packet( IOBUF inp, IOBUF out, int pkttype, unsigned long pktlen )
363 if( iobuf_in_block_mode(inp) ) {
364 while( (n = iobuf_read( inp, buf, 100 )) != -1 )
365 if( iobuf_write(out, buf, n ) )
366 return G10ERR_WRITE_FILE; /* write error */
368 else if( !pktlen && pkttype == PKT_COMPRESSED ) {
369 /* compressed packet, copy till EOF */
370 while( (n = iobuf_read( inp, buf, 100 )) != -1 )
371 if( iobuf_write(out, buf, n ) )
372 return G10ERR_WRITE_FILE; /* write error */
375 for( ; pktlen; pktlen -= n ) {
376 n = pktlen > 100 ? 100 : pktlen;
377 n = iobuf_read( inp, buf, n );
379 return G10ERR_READ_FILE;
380 if( iobuf_write(out, buf, n ) )
381 return G10ERR_WRITE_FILE; /* write error */
389 skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
392 printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen );
396 if( iobuf_in_block_mode(inp) ) {
397 while( (c=iobuf_get(inp)) != -1 )
398 dump_hex_line(c, &i);
401 for( ; pktlen; pktlen-- )
402 dump_hex_line(iobuf_get(inp), &i);
408 skip_rest(inp,pktlen);
412 skip_rest( IOBUF inp, unsigned long pktlen )
414 if( iobuf_in_block_mode(inp) ) {
415 while( iobuf_get(inp) != -1 )
419 for( ; pktlen; pktlen-- )
426 parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
431 k = packet->pkt.pubkey_enc = m_alloc(sizeof *packet->pkt.pubkey_enc );
433 log_error("packet(%d) too short\n", pkttype);
436 k->version = iobuf_get_noeof(inp); pktlen--;
437 if( k->version != 2 && k->version != 3 ) {
438 log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
441 k->keyid[0] = read_32(inp); pktlen -= 4;
442 k->keyid[1] = read_32(inp); pktlen -= 4;
443 k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
445 printf(":public key encoded packet: version %d, keyid %08lX%08lX\n",
446 k->version, (ulong)k->keyid[0], (ulong)k->keyid[1]);
447 if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
449 k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
451 k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
454 mpi_print(stdout, k->d.elg.a, mpi_print_mode );
455 printf("\n\telg b: ");
456 mpi_print(stdout, k->d.elg.b, mpi_print_mode );
460 else if( k->pubkey_algo == PUBKEY_ALGO_RSA ) {
462 k->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
464 printf("\trsa integer: ");
465 mpi_print(stdout, k->d.rsa.rsa_integer, mpi_print_mode );
470 printf("\tunknown algorithm %d\n", k->pubkey_algo );
474 skip_rest(inp, pktlen);
480 parse_subpkt( const byte *buffer, int reqtype )
482 int buflen = (*buffer << 8) | buffer[1];
490 return NULL; /* end of packets; not found */
491 n = *buffer++; buflen--;
495 n = (( n - 192 ) << 8) + *buffer + 192;
507 if( reqtype < 0 ) { /* list packets */
508 printf("\t%ssubpacket %d of length %u (%s)\n",
509 reqtype == -1 ? "hashed ":"", type, n,
510 type == 2 ? "signature creation time"
511 : type == 3 ? "signature expiration time"
512 : type == 4 ? "exportable"
513 : type == 5 ? "trust signature"
514 : type == 6 ? "regular expression"
515 : type == 7 ? "revocable"
516 : type == 9 ? "key expiration time"
517 : type ==10 ? "additional recipient request"
518 : type ==11 ? "preferred symmetric algorithms"
519 : type ==12 ? "revocation key"
520 : type ==16 ? "issuer key ID"
521 : type ==20 ? "notation data"
522 : type ==21 ? "preferred hash algorithms"
523 : type ==22 ? "preferred compression algorithms"
524 : type ==23 ? "key server preferences"
525 : type ==24 ? "preferred key server"
528 else if( type == reqtype )
530 buffer += n; buflen -=n;
537 case 2: /* signature creation time */
541 case 16:/* issuer key ID */
545 case 3: /* signature expiration time */
546 case 4: /* exportable */
547 case 5: /* trust signature */
548 case 6: /* regular expression */
549 case 7: /* revocable */
550 case 9: /* key expiration time */
551 case 10:/* additional recipient request */
552 case 11:/* preferred symmetric algorithms */
553 case 12:/* revocation key */
554 case 20:/* notation data */
555 case 21:/* preferred hash algorithms */
556 case 22:/* preferred compression algorithms */
557 case 23:/* key server preferences */
558 case 24:/* preferred key server */
559 default: BUG(); /* not yet needed */
561 log_error("subpacket of type %d too short\n", type);
565 log_error("buffer shorter than subpacket\n");
571 parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
580 log_error("packet(%d) too short\n", pkttype);
583 sig->version = iobuf_get_noeof(inp); pktlen--;
584 if( sig->version == 4 )
586 else if( sig->version != 2 && sig->version != 3 ) {
587 log_error("packet(%d) with unknown version %d\n", pkttype, sig->version);
592 md5_len = iobuf_get_noeof(inp); pktlen--;
594 sig->sig_class = iobuf_get_noeof(inp); pktlen--;
596 sig->timestamp = read_32(inp); pktlen -= 4;
597 sig->keyid[0] = read_32(inp); pktlen -= 4;
598 sig->keyid[1] = read_32(inp); pktlen -= 4;
600 sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
601 sig->digest_algo = iobuf_get_noeof(inp); pktlen--;
602 if( is_v4 ) { /* read subpackets */
603 n = read_16(inp); pktlen -= 2; /* length of hashed data */
605 log_error("signature packet: hashed data too long\n");
606 rc = G10ERR_INVALID_PACKET;
610 sig->hashed_data = m_alloc( n + 2 );
611 sig->hashed_data[0] = n << 8;
612 sig->hashed_data[1] = n;
613 if( iobuf_read(inp, sig->hashed_data+2, n ) != n ) {
614 log_error("premature eof while reading hashed signature data\n");
620 n = read_16(inp); pktlen -= 2; /* length of unhashed data */
622 log_error("signature packet: unhashed data too long\n");
623 rc = G10ERR_INVALID_PACKET;
627 sig->unhashed_data = m_alloc( n + 2 );
628 sig->unhashed_data[0] = n << 8;
629 sig->unhashed_data[1] = n;
630 if( iobuf_read(inp, sig->unhashed_data+2, n ) != n ) {
631 log_error("premature eof while reading unhashed signature data\n");
639 if( pktlen < 5 ) { /* sanity check */
640 log_error("packet(%d) too short\n", pkttype);
641 rc = G10ERR_INVALID_PACKET;
645 sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
646 sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
648 if( is_v4 ) { /*extract required informations */
650 p = parse_subpkt( sig->hashed_data, 2 );
652 log_error("signature packet without timestamp\n");
654 sig->timestamp = buffer_to_u32(p);
655 p = parse_subpkt( sig->unhashed_data, 16 );
657 log_error("signature packet without keyid\n");
659 sig->keyid[0] = buffer_to_u32(p);
660 sig->keyid[1] = buffer_to_u32(p+4);
665 printf(":signature packet: keyid %08lX%08lX\n"
666 "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
667 "\tdigest algo %d, begin of digest %02x %02x\n",
668 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
669 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
671 sig->digest_start[0], sig->digest_start[1] );
673 parse_subpkt( sig->hashed_data, -1 );
674 parse_subpkt( sig->unhashed_data, -2 );
677 if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
679 sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n;
681 sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
684 mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
685 printf("\n\telg b: ");
686 mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
690 else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
692 sig->d.dsa.r = mpi_read(inp, &n, 0 ); pktlen -=n;
694 sig->d.dsa.s = mpi_read(inp, &n, 0 ); pktlen -=n;
697 mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
698 printf("\n\tdsa s: ");
699 mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
703 else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
705 sig->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
707 printf("\trsa integer: ");
708 mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
713 printf("\tunknown algorithm %d\n", sig->pubkey_algo );
717 skip_rest(inp, pktlen);
723 parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
724 PKT_onepass_sig *ops )
729 log_error("packet(%d) too short\n", pkttype);
732 version = iobuf_get_noeof(inp); pktlen--;
734 log_error("onepass_sig with unknown version %d\n", version);
737 ops->sig_class = iobuf_get_noeof(inp); pktlen--;
738 ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
739 ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
740 ops->keyid[0] = read_32(inp); pktlen -= 4;
741 ops->keyid[1] = read_32(inp); pktlen -= 4;
742 ops->last = iobuf_get_noeof(inp); pktlen--;
744 printf(":onepass_sig packet: keyid %08lX%08lX\n"
745 "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
746 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
747 version, ops->sig_class,
748 ops->digest_algo, ops->pubkey_algo, ops->last );
752 skip_rest(inp, pktlen);
760 parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
761 byte *hdr, int hdrlen, PACKET *pkt )
763 int i, version, algorithm;
765 unsigned long timestamp;
766 unsigned short valid_period;
772 log_error("packet(%d) too short\n", pkttype);
775 version = iobuf_get_noeof(inp); pktlen--;
778 else if( version != 2 && version != 3 ) {
779 log_error("packet(%d) with unknown version %d\n", pkttype, version);
783 timestamp = read_32(inp); pktlen -= 4;
787 valid_period = read_16(inp); pktlen -= 2;
789 algorithm = iobuf_get_noeof(inp); pktlen--;
791 printf(":%s key packet:\n"
792 "\tversion %d, created %lu, valid for %hu days\n",
793 pkttype == PKT_PUBLIC_CERT? "public" :
794 pkttype == PKT_SECRET_CERT? "secret" :
795 pkttype == PKT_PUBKEY_SUBCERT? "public sub" :
796 pkttype == PKT_SECKEY_SUBCERT? "secret sub" : "??",
797 version, timestamp, valid_period );
798 if( pkttype == PKT_SECRET_CERT ) {
799 pkt->pkt.secret_cert->timestamp = timestamp;
800 pkt->pkt.secret_cert->valid_days = valid_period;
801 pkt->pkt.secret_cert->hdrbytes = hdrlen;
802 pkt->pkt.secret_cert->version = version;
803 pkt->pkt.secret_cert->pubkey_algo = algorithm;
806 pkt->pkt.public_cert->timestamp = timestamp;
807 pkt->pkt.public_cert->valid_days = valid_period;
808 pkt->pkt.public_cert->hdrbytes = hdrlen;
809 pkt->pkt.public_cert->version = version;
810 pkt->pkt.public_cert->pubkey_algo = algorithm;
813 if( algorithm == PUBKEY_ALGO_ELGAMAL ) {
814 MPI elg_p, elg_g, elg_y;
815 n = pktlen; elg_p = mpi_read(inp, &n, 0 ); pktlen -=n;
816 n = pktlen; elg_g = mpi_read(inp, &n, 0 ); pktlen -=n;
817 n = pktlen; elg_y = mpi_read(inp, &n, 0 ); pktlen -=n;
819 printf( "\telg p: ");
820 mpi_print(stdout, elg_p, mpi_print_mode );
821 printf("\n\telg g: ");
822 mpi_print(stdout, elg_g, mpi_print_mode );
823 printf("\n\telg y: ");
824 mpi_print(stdout, elg_y, mpi_print_mode );
827 if( pkttype == PKT_PUBLIC_CERT ) {
828 pkt->pkt.public_cert->d.elg.p = elg_p;
829 pkt->pkt.public_cert->d.elg.g = elg_g;
830 pkt->pkt.public_cert->d.elg.y = elg_y;
833 PKT_secret_cert *cert = pkt->pkt.secret_cert;
836 pkt->pkt.secret_cert->d.elg.p = elg_p;
837 pkt->pkt.secret_cert->d.elg.g = elg_g;
838 pkt->pkt.secret_cert->d.elg.y = elg_y;
839 cert->d.elg.protect.algo = iobuf_get_noeof(inp); pktlen--;
840 if( cert->d.elg.protect.algo ) {
841 cert->d.elg.is_protected = 1;
842 cert->d.elg.protect.count = 0;
843 if( cert->d.elg.protect.algo == 255 ) {
845 rc = G10ERR_INVALID_PACKET;
848 cert->d.elg.protect.algo = iobuf_get_noeof(inp); pktlen--;
849 cert->d.elg.protect.s2k = iobuf_get_noeof(inp); pktlen--;
850 cert->d.elg.protect.hash = iobuf_get_noeof(inp); pktlen--;
851 switch( cert->d.elg.protect.s2k ) {
854 for(i=0; i < 8 && pktlen; i++, pktlen-- )
855 temp[i] = iobuf_get_noeof(inp);
856 memcpy(cert->d.elg.protect.salt, temp, 8 );
859 switch( cert->d.elg.protect.s2k ) {
860 case 0: if( list_mode ) printf( "\tsimple S2K" );
862 case 1: if( list_mode ) printf( "\tsalted S2K" );
864 case 3: if( list_mode ) printf( "\titer+salt S2K" );
868 printf( "\tunknown S2K %d\n",
869 cert->d.elg.protect.s2k );
870 rc = G10ERR_INVALID_PACKET;
875 printf(", algo: %d, hash: %d",
876 cert->d.elg.protect.algo,
877 cert->d.elg.protect.hash );
878 if( cert->d.elg.protect.s2k == 1
879 || cert->d.elg.protect.s2k == 3 ) {
881 for(i=0; i < 8; i++ )
882 printf("%02x", cert->d.elg.protect.salt[i]);
887 if( cert->d.elg.protect.s2k == 3 ) {
889 rc = G10ERR_INVALID_PACKET;
892 cert->d.elg.protect.count = iobuf_get_noeof(inp);
899 printf( "\tprotect algo: %d\n",
900 cert->d.elg.protect.algo);
901 /* old version, we don't have a S2K, so we fake one */
902 cert->d.elg.protect.s2k = 0;
903 /* We need this kludge to cope with old GNUPG versions */
904 cert->d.elg.protect.hash =
905 cert->d.elg.protect.algo == CIPHER_ALGO_BLOWFISH?
906 DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5;
909 rc = G10ERR_INVALID_PACKET;
912 for(i=0; i < 8 && pktlen; i++, pktlen-- )
913 temp[i] = iobuf_get_noeof(inp);
915 printf( "\tprotect IV: ");
916 for(i=0; i < 8; i++ )
917 printf(" %02x", temp[i] );
920 memcpy(cert->d.elg.protect.iv, temp, 8 );
923 cert->d.elg.is_protected = 0;
924 /* It does not make sense to read it into secure memory.
925 * If the user is so careless, not to protect his secret key,
926 * we can assume, that he operates an open system :=(.
927 * So we put the key into secure memory when we unprotect him. */
928 n = pktlen; cert->d.elg.x = mpi_read(inp, &n, 0 ); pktlen -=n;
930 cert->d.elg.csum = read_16(inp); pktlen -= 2;
932 printf("\t[secret value x is not shown]\n"
933 "\tchecksum: %04hx\n", cert->d.elg.csum);
935 /*log_mpidump("elg p=", cert->d.elg.p );
936 log_mpidump("elg g=", cert->d.elg.g );
937 log_mpidump("elg y=", cert->d.elg.y );
938 log_mpidump("elg x=", cert->d.elg.x ); */
941 else if( algorithm == PUBKEY_ALGO_DSA ) {
942 MPI dsa_p, dsa_q, dsa_g, dsa_y;
943 n = pktlen; dsa_p = mpi_read(inp, &n, 0 ); pktlen -=n;
944 n = pktlen; dsa_q = mpi_read(inp, &n, 0 ); pktlen -=n;
945 n = pktlen; dsa_g = mpi_read(inp, &n, 0 ); pktlen -=n;
946 n = pktlen; dsa_y = mpi_read(inp, &n, 0 ); pktlen -=n;
948 printf( "\tdsa p: ");
949 mpi_print(stdout, dsa_p, mpi_print_mode );
950 printf("\n\tdsa q: ");
951 mpi_print(stdout, dsa_q, mpi_print_mode );
952 printf("\n\tdsa g: ");
953 mpi_print(stdout, dsa_g, mpi_print_mode );
954 printf("\n\tdsa y: ");
955 mpi_print(stdout, dsa_y, mpi_print_mode );
958 if( pkttype == PKT_PUBLIC_CERT ) {
959 pkt->pkt.public_cert->d.dsa.p = dsa_p;
960 pkt->pkt.public_cert->d.dsa.q = dsa_q;
961 pkt->pkt.public_cert->d.dsa.g = dsa_g;
962 pkt->pkt.public_cert->d.dsa.y = dsa_y;
965 PKT_secret_cert *cert = pkt->pkt.secret_cert;
968 pkt->pkt.secret_cert->d.dsa.p = dsa_p;
969 pkt->pkt.secret_cert->d.dsa.q = dsa_q;
970 pkt->pkt.secret_cert->d.dsa.g = dsa_g;
971 pkt->pkt.secret_cert->d.dsa.y = dsa_y;
972 cert->d.dsa.protect.algo = iobuf_get_noeof(inp); pktlen--;
973 if( cert->d.dsa.protect.algo ) {
974 cert->d.dsa.is_protected = 1;
975 cert->d.dsa.protect.count = 0;
976 if( cert->d.dsa.protect.algo == 255 ) {
978 rc = G10ERR_INVALID_PACKET;
981 cert->d.dsa.protect.algo = iobuf_get_noeof(inp); pktlen--;
982 cert->d.dsa.protect.s2k = iobuf_get_noeof(inp); pktlen--;
983 cert->d.dsa.protect.hash = iobuf_get_noeof(inp); pktlen--;
984 switch( cert->d.dsa.protect.s2k ) {
987 for(i=0; i < 8 && pktlen; i++, pktlen-- )
988 temp[i] = iobuf_get_noeof(inp);
989 memcpy(cert->d.dsa.protect.salt, temp, 8 );
992 switch( cert->d.dsa.protect.s2k ) {
993 case 0: if( list_mode ) printf( "\tsimple S2K" );
995 case 1: if( list_mode ) printf( "\tsalted S2K" );
997 case 3: if( list_mode ) printf( "\titer+salt S2K" );
1001 printf( "\tunknown S2K %d\n",
1002 cert->d.dsa.protect.s2k );
1003 rc = G10ERR_INVALID_PACKET;
1008 printf(", algo: %d, hash: %d",
1009 cert->d.dsa.protect.algo,
1010 cert->d.dsa.protect.hash );
1011 if( cert->d.dsa.protect.s2k == 1
1012 || cert->d.dsa.protect.s2k == 3 ) {
1014 for(i=0; i < 8; i++ )
1015 printf("%02x", cert->d.dsa.protect.salt[i]);
1020 if( cert->d.dsa.protect.s2k == 3 ) {
1022 rc = G10ERR_INVALID_PACKET;
1025 cert->d.dsa.protect.count = iobuf_get_noeof(inp);
1032 printf( "\tprotect algo: %d\n",
1033 cert->d.dsa.protect.algo);
1034 /* old version, we don't have a S2K, so we fake one */
1035 cert->d.dsa.protect.s2k = 0;
1036 cert->d.dsa.protect.hash = DIGEST_ALGO_MD5;
1039 rc = G10ERR_INVALID_PACKET;
1042 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1043 temp[i] = iobuf_get_noeof(inp);
1045 printf( "\tprotect IV: ");
1046 for(i=0; i < 8; i++ )
1047 printf(" %02x", temp[i] );
1050 memcpy(cert->d.dsa.protect.iv, temp, 8 );
1053 cert->d.dsa.is_protected = 0;
1054 /* It does not make sense to read it into secure memory.
1055 * If the user is so careless, not to protect his secret key,
1056 * we can assume, that he operates an open system :=(.
1057 * So we put the key into secure memory when we unprotect him. */
1058 n = pktlen; cert->d.dsa.x = mpi_read(inp, &n, 0 ); pktlen -=n;
1060 cert->d.dsa.csum = read_16(inp); pktlen -= 2;
1062 printf("\t[secret value x is not shown]\n"
1063 "\tchecksum: %04hx\n", cert->d.dsa.csum);
1065 /*log_mpidump("dsa p=", cert->d.dsa.p );
1066 log_mpidump("dsa q=", cert->d.dsa.q );
1067 log_mpidump("dsa g=", cert->d.dsa.g );
1068 log_mpidump("dsa y=", cert->d.dsa.y );
1069 log_mpidump("dsa x=", cert->d.dsa.x ); */
1072 else if( algorithm == PUBKEY_ALGO_RSA ) {
1073 MPI rsa_pub_mod, rsa_pub_exp;
1075 n = pktlen; rsa_pub_mod = mpi_read(inp, &n, 0); pktlen -=n;
1076 n = pktlen; rsa_pub_exp = mpi_read(inp, &n, 0 ); pktlen -=n;
1078 printf( "\tpublic modulus n: ");
1079 mpi_print(stdout, rsa_pub_mod, mpi_print_mode );
1080 printf("\n\tpublic exponent e: ");
1081 mpi_print(stdout, rsa_pub_exp, mpi_print_mode );
1084 if( pkttype == PKT_PUBLIC_CERT ) {
1085 pkt->pkt.public_cert->d.rsa.rsa_n = rsa_pub_mod;
1086 pkt->pkt.public_cert->d.rsa.rsa_e = rsa_pub_exp;
1089 PKT_secret_cert *cert = pkt->pkt.secret_cert;
1092 pkt->pkt.secret_cert->d.rsa.rsa_n = rsa_pub_mod;
1093 pkt->pkt.secret_cert->d.rsa.rsa_e = rsa_pub_exp;
1094 cert->d.rsa.protect_algo = iobuf_get_noeof(inp); pktlen--;
1096 printf( "\tprotect algo: %d\n", cert->d.rsa.protect_algo);
1097 if( cert->d.rsa.protect_algo ) {
1098 cert->d.rsa.is_protected = 1;
1099 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1100 temp[i] = iobuf_get_noeof(inp);
1102 printf( "\tprotect IV: ");
1103 for(i=0; i < 8; i++ )
1104 printf(" %02x", temp[i] );
1107 if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
1108 memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
1111 cert->d.rsa.is_protected = 0;
1112 /* (See comments at the code for elg keys) */
1113 n = pktlen; cert->d.rsa.rsa_d = mpi_read(inp, &n, 0 ); pktlen -=n;
1114 n = pktlen; cert->d.rsa.rsa_p = mpi_read(inp, &n, 0 ); pktlen -=n;
1115 n = pktlen; cert->d.rsa.rsa_q = mpi_read(inp, &n, 0 ); pktlen -=n;
1116 n = pktlen; cert->d.rsa.rsa_u = mpi_read(inp, &n, 0 ); pktlen -=n;
1118 cert->d.rsa.csum = read_16(inp); pktlen -= 2;
1120 printf("\t[secret values d,p,q,u are not shown]\n"
1121 "\tchecksum: %04hx\n", cert->d.rsa.csum);
1123 /* log_mpidump("rsa n=", cert->d.rsa.rsa_n );
1124 log_mpidump("rsa e=", cert->d.rsa.rsa_e );
1125 log_mpidump("rsa d=", cert->d.rsa.rsa_d );
1126 log_mpidump("rsa p=", cert->d.rsa.rsa_p );
1127 log_mpidump("rsa q=", cert->d.rsa.rsa_q );
1128 log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */
1131 else if( list_mode )
1132 printf("\tunknown algorithm %d\n", algorithm );
1136 skip_rest(inp, pktlen);
1142 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1146 packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen - 1);
1147 packet->pkt.user_id->len = pktlen;
1148 p = packet->pkt.user_id->name;
1149 for( ; pktlen; pktlen--, p++ )
1150 *p = iobuf_get_noeof(inp);
1153 int n = packet->pkt.user_id->len;
1154 printf(":user id packet: \"");
1155 for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1156 if( *p >= ' ' && *p <= 'z' )
1159 printf("\\x%02x", *p );
1168 parse_subkey( IOBUF inp, int pkttype, unsigned long pktlen )
1172 version = iobuf_get_noeof(inp); pktlen--;
1173 if( pkttype == PKT_PUBKEY_SUBCERT && version == '#' ) {
1174 /* early versions of G10 use old comments packets; luckily all those
1175 * comments are started by a hash */
1177 printf(":old comment packet: \"" );
1178 for( ; pktlen; pktlen-- ) {
1180 c = iobuf_get_noeof(inp);
1181 if( c >= ' ' && c <= 'z' )
1184 printf("\\x%02x", c );
1188 skip_rest(inp, pktlen);
1193 printf(":public subkey packet: \"" );
1194 skip_rest(inp, pktlen);
1200 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1204 packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
1205 packet->pkt.comment->len = pktlen;
1206 p = packet->pkt.comment->data;
1207 for( ; pktlen; pktlen--, p++ )
1208 *p = iobuf_get_noeof(inp);
1211 int n = packet->pkt.comment->len;
1212 printf(":comment packet: \"");
1213 for(p=packet->pkt.comment->data; n; p++, n-- ) {
1214 if( *p >= ' ' && *p <= 'z' )
1217 printf("\\x%02x", *p );
1226 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
1230 c = iobuf_get_noeof(inp);
1232 printf(":trust packet: flag=%02x\n", c );
1237 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
1244 if( pktlen && pktlen < 6 ) {
1245 log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
1248 mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
1249 namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
1250 pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
1252 pt->namelen = namelen;
1254 for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
1255 pt->name[i] = iobuf_get_noeof(inp);
1258 for( i=0; i < namelen; i++ )
1259 if( (c=iobuf_get(inp)) == -1 )
1264 pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
1270 printf(":literal data packet:\n"
1271 "\tmode %c, created %lu, name=\"",
1272 mode >= ' ' && mode <'z'? mode : '?',
1273 (ulong)pt->timestamp );
1274 for(p=pt->name,i=0; i < namelen; p++, i++ ) {
1275 if( *p >= ' ' && *p <= 'z' )
1278 printf("\\x%02x", *p );
1280 printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
1289 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
1293 /* pktlen is here 0, but data follows
1294 * (this should be the last object in a file or
1295 * the compress algorithm should know the length)
1297 zd = pkt->pkt.compressed = m_alloc(sizeof *pkt->pkt.compressed );
1298 zd->len = 0; /* not yet used */
1299 zd->algorithm = iobuf_get_noeof(inp);
1302 printf(":compressed packet: algo=%d\n", zd->algorithm);
1308 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
1312 ed = pkt->pkt.encrypted = m_alloc(sizeof *pkt->pkt.encrypted );
1315 if( pktlen && pktlen < 10 ) {
1316 log_error("packet(%d) too short\n", pkttype);
1317 skip_rest(inp, pktlen);
1322 printf(":encrypted data packet:\n\tlength: %lu\n", pktlen-10);
1324 printf(":encrypted data packet:\n\tlength: unknown\n");