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
38 static int mpi_print_mode = 0;
39 static int list_mode = 0;
41 static int parse( IOBUF inp, PACKET *pkt, int reqtype,
42 ulong *retpos, int *skip, IOBUF out, int do_skip
43 #ifdef DEBUG_PARSE_PACKET
44 ,const char *dbg_w, const char *dbg_f, int dbg_l
47 static int copy_packet( IOBUF inp, IOBUF out, int pkttype,
48 unsigned long pktlen );
49 static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen );
50 static void skip_rest( IOBUF inp, unsigned long pktlen );
51 static void *read_rest( IOBUF inp, ulong *r_pktlen );
52 static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
54 static int parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
56 static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
58 static int parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
59 PKT_onepass_sig *ops );
60 static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
61 byte *hdr, int hdrlen, PACKET *packet );
62 static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
64 static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
66 static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen );
67 static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
68 PACKET *packet, int new_ctb);
69 static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
70 PACKET *packet, int new_ctb );
71 static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
72 PACKET *packet, int new_ctb);
79 a = iobuf_get_noeof(inp) << 8;
80 a |= iobuf_get_noeof(inp);
88 a = iobuf_get_noeof(inp) << 24;
89 a |= iobuf_get_noeof(inp) << 16;
90 a |= iobuf_get_noeof(inp) << 8;
91 a |= iobuf_get_noeof(inp);
97 set_packet_list_mode( int mode )
101 mpi_print_mode = DBG_MPI;
106 unknown_pubkey_warning( int algo )
108 static byte unknown_pubkey_algos[256];
111 if( !unknown_pubkey_algos[algo] ) {
113 log_info(_("can't handle public key algorithm %d\n"), algo );
114 unknown_pubkey_algos[algo] = 1;
119 * Parse a Packet and return it in packet
120 * Returns: 0 := valid packet in pkt
121 * -1 := no more packets
123 * Note: The function may return an error and a partly valid packet;
124 * caller must free this packet.
126 #ifdef DEBUG_PARSE_PACKET
128 dbg_parse_packet( IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l )
133 rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l );
139 parse_packet( IOBUF inp, PACKET *pkt )
144 rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
151 * Like parse packet, but only return packets of the given type.
153 #ifdef DEBUG_PARSE_PACKET
155 dbg_search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos,
156 const char *dbg_f, int dbg_l )
161 rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
167 search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos )
172 rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0 );
179 * Copy all packets from INP to OUT, thereby removing unused spaces.
181 #ifdef DEBUG_PARSE_PACKET
183 dbg_copy_all_packets( IOBUF inp, IOBUF out,
184 const char *dbg_f, int dbg_l )
190 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l )));
195 copy_all_packets( IOBUF inp, IOBUF out )
201 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
207 * Copy some packets from INP to OUT, thereby removing unused spaces.
208 * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
210 #ifdef DEBUG_PARSE_PACKET
212 dbg_copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff,
213 const char *dbg_f, int dbg_l )
218 if( iobuf_tell(inp) >= stopoff )
221 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0,
222 "some", dbg_f, dbg_l )) );
227 copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff )
232 if( iobuf_tell(inp) >= stopoff )
235 } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
241 * Skip over N packets
243 #ifdef DEBUG_PARSE_PACKET
245 dbg_skip_some_packets( IOBUF inp, unsigned n,
246 const char *dbg_f, int dbg_l )
251 for( ;n && !rc; n--) {
253 rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l );
259 skip_some_packets( IOBUF inp, unsigned n )
264 for( ;n && !rc; n--) {
266 rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
274 * Parse packet. Set the variable skip points to to 1 if the packet
275 * should be skipped; this is the case if either there is a
276 * requested packet type and the parsed packet doesn't match or the
277 * packet-type is 0, indicating deleted stuff.
278 * if OUT is not NULL, a special copymode is used.
281 parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
282 int *skip, IOBUF out, int do_skip
283 #ifdef DEBUG_PARSE_PACKET
284 ,const char *dbg_w, const char *dbg_f, int dbg_l
288 int rc=0, c, ctb, pkttype, lenbytes;
289 unsigned long pktlen;
295 assert( !pkt->pkt.generic );
297 *retpos = iobuf_tell(inp);
299 if( (ctb = iobuf_get(inp)) == -1 ) {
305 if( !(ctb & 0x80) ) {
306 log_error("%s: invalid packet (ctb=%02x) near %lu\n",
307 iobuf_where(inp), ctb, iobuf_tell(inp) );
308 rc = G10ERR_INVALID_PACKET;
312 new_ctb = !!(ctb & 0x40);
314 pkttype = ctb & 0x3f;
315 if( (c = iobuf_get(inp)) == -1 ) {
316 log_error("%s: 1st length byte missing\n", iobuf_where(inp) );
317 rc = G10ERR_INVALID_PACKET;
324 pktlen = (c - 192) * 256;
325 if( (c = iobuf_get(inp)) == -1 ) {
326 log_error("%s: 2nd length byte missing\n", iobuf_where(inp) );
327 rc = G10ERR_INVALID_PACKET;
333 else if( c == 255 ) {
334 pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24;
335 pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16;
336 pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8;
337 if( (c = iobuf_get(inp)) == -1 ) {
338 log_error("%s: 4 byte length invalid\n", iobuf_where(inp) );
339 rc = G10ERR_INVALID_PACKET;
342 pktlen |= (hdr[hdrlen++] = c );
344 else { /* partial body length */
345 iobuf_set_partial_block_mode(inp, c & 0xff);
346 pktlen = 0;/* to indicate partial length */
350 pkttype = (ctb>>2)&0xf;
351 lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
353 pktlen = 0; /* don't know the value */
354 if( pkttype != PKT_COMPRESSED )
355 iobuf_set_block_mode(inp, 1);
358 for( ; lenbytes; lenbytes-- ) {
360 pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
365 if( out && pkttype ) {
366 if( iobuf_write( out, hdr, hdrlen ) == -1 )
367 rc = G10ERR_WRITE_FILE;
369 rc = copy_packet(inp, out, pkttype, pktlen );
373 if( do_skip || !pkttype || (reqtype && pkttype != reqtype) ) {
374 skip_rest(inp, pktlen);
381 #ifdef DEBUG_PARSE_PACKET
382 log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n",
383 iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"",
384 dbg_w, dbg_f, dbg_l );
386 log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n",
387 iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" );
390 pkt->pkttype = pkttype;
391 rc = G10ERR_UNKNOWN_PACKET; /* default error */
394 case PKT_PUBLIC_SUBKEY:
395 pkt->pkt.public_key = m_alloc_clear(sizeof *pkt->pkt.public_key );
396 rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
399 case PKT_SECRET_SUBKEY:
400 pkt->pkt.secret_key = m_alloc_clear(sizeof *pkt->pkt.secret_key );
401 rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
404 rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
407 rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
410 pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
411 rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
413 case PKT_ONEPASS_SIG:
414 pkt->pkt.onepass_sig = m_alloc_clear(sizeof *pkt->pkt.onepass_sig );
415 rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
418 rc = parse_user_id(inp, pkttype, pktlen, pkt );
420 case PKT_OLD_COMMENT:
422 rc = parse_comment(inp, pkttype, pktlen, pkt);
425 parse_trust(inp, pkttype, pktlen);
426 rc = G10ERR_UNKNOWN_PACKET;
429 rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb );
432 rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
435 rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
438 skip_packet(inp, pkttype, pktlen);
443 if( !rc && iobuf_error(inp) )
444 rc = G10ERR_INV_KEYRING;
449 dump_hex_line( int c, int *i )
451 if( *i && !(*i%8) ) {
453 printf("\n%4d:", *i );
466 copy_packet( IOBUF inp, IOBUF out, int pkttype, unsigned long pktlen )
471 if( iobuf_in_block_mode(inp) ) {
472 while( (n = iobuf_read( inp, buf, 100 )) != -1 )
473 if( iobuf_write(out, buf, n ) )
474 return G10ERR_WRITE_FILE; /* write error */
476 else if( !pktlen && pkttype == PKT_COMPRESSED ) {
477 log_debug("copy_packet: compressed!\n");
478 /* compressed packet, copy till EOF */
479 while( (n = iobuf_read( inp, buf, 100 )) != -1 )
480 if( iobuf_write(out, buf, n ) )
481 return G10ERR_WRITE_FILE; /* write error */
484 for( ; pktlen; pktlen -= n ) {
485 n = pktlen > 100 ? 100 : pktlen;
486 n = iobuf_read( inp, buf, n );
488 return G10ERR_READ_FILE;
489 if( iobuf_write(out, buf, n ) )
490 return G10ERR_WRITE_FILE; /* write error */
498 skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
501 if( pkttype == PKT_MARKER )
502 fputs(":marker packet:\n", stdout );
504 printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
507 if( pkttype != PKT_MARKER )
508 fputs("dump:", stdout );
509 if( iobuf_in_block_mode(inp) ) {
510 while( (c=iobuf_get(inp)) != -1 )
511 dump_hex_line(c, &i);
514 for( ; pktlen; pktlen-- )
515 dump_hex_line(iobuf_get(inp), &i);
521 skip_rest(inp,pktlen);
525 skip_rest( IOBUF inp, unsigned long pktlen )
527 if( iobuf_in_block_mode(inp) ) {
528 while( iobuf_get(inp) != -1 )
532 for( ; pktlen; pktlen-- )
533 if( iobuf_get(inp) == -1 )
539 read_rest( IOBUF inp, ulong *r_pktlen )
543 size_t pktlen = *r_pktlen;
545 if( iobuf_in_block_mode(inp) ) {
546 log_error("read_rest: can't store stream data\n");
550 p = m_alloc( pktlen + 2 );
552 p[1] = pktlen & 0xff;
553 for(i=2; pktlen; pktlen--, i++ )
554 p[i] = iobuf_get(inp);
561 read_rest2( IOBUF inp, size_t pktlen )
566 if( iobuf_in_block_mode(inp) ) {
567 log_error("read_rest: can't store stream data\n");
571 p = m_alloc( pktlen );
572 for(i=0; pktlen; pktlen--, i++ )
573 p[i] = iobuf_get(inp);
581 parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
584 int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
587 log_error("packet(%d) too short\n", pkttype);
590 version = iobuf_get_noeof(inp); pktlen--;
592 log_error("packet(%d) with unknown version %d\n", pkttype, version);
595 if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
596 log_error("packet(%d) too large\n", pkttype);
599 cipher_algo = iobuf_get_noeof(inp); pktlen--;
600 s2kmode = iobuf_get_noeof(inp); pktlen--;
601 hash_algo = iobuf_get_noeof(inp); pktlen--;
603 case 0: /* simple s2k */
606 case 1: /* salted s2k */
609 case 3: /* iterated+salted s2k */
613 log_error("unknown S2K %d\n", s2kmode );
616 if( minlen > pktlen ) {
617 log_error("packet with S2K %d too short\n", s2kmode );
620 seskeylen = pktlen - minlen;
621 k = packet->pkt.symkey_enc = m_alloc_clear( sizeof *packet->pkt.symkey_enc
623 k->version = version;
624 k->cipher_algo = cipher_algo;
625 k->s2k.mode = s2kmode;
626 k->s2k.hash_algo = hash_algo;
627 if( s2kmode == 1 || s2kmode == 3 ) {
628 for(i=0; i < 8 && pktlen; i++, pktlen-- )
629 k->s2k.salt[i] = iobuf_get_noeof(inp);
632 k->s2k.count = iobuf_get(inp); pktlen--;
634 k->seskeylen = seskeylen;
635 for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
636 k->seskey[i] = iobuf_get_noeof(inp);
640 printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
641 version, cipher_algo, s2kmode, hash_algo);
642 if( s2kmode == 1 || s2kmode == 3 ) {
644 for(i=0; i < 8; i++ )
645 printf("%02x", k->s2k.salt[i]);
647 printf(", count %lu\n", (ulong)k->s2k.count );
653 skip_rest(inp, pktlen);
658 parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
664 k = packet->pkt.pubkey_enc = m_alloc(sizeof *packet->pkt.pubkey_enc );
666 log_error("packet(%d) too short\n", pkttype);
669 k->version = iobuf_get_noeof(inp); pktlen--;
670 if( k->version != 2 && k->version != 3 ) {
671 log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
674 k->keyid[0] = read_32(inp); pktlen -= 4;
675 k->keyid[1] = read_32(inp); pktlen -= 4;
676 k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
677 k->throw_keyid = 0; /* only used as flag for build_packet */
679 printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
680 k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
682 ndata = pubkey_get_nenc(k->pubkey_algo);
685 printf("\tunsupported algorithm %d\n", k->pubkey_algo );
686 unknown_pubkey_warning( k->pubkey_algo );
687 k->data[0] = NULL; /* no need to store the encrypted data */
690 for( i=0; i < ndata; i++ ) {
692 k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
695 mpi_print(stdout, k->data[i], mpi_print_mode );
702 skip_rest(inp, pktlen);
708 dump_sig_subpkt( int hashed, int type, int critical,
709 const byte *buffer, size_t buflen, size_t length )
714 printf("\t%s%ssubpkt %d len %u (", /*)*/
715 critical ? "critical ":"",
716 hashed ? "hashed ":"", type, (unsigned)length );
719 if( length > buflen ) {
720 printf("too short: buffer is only %u)\n", (unsigned)buflen );
724 case SIGSUBPKT_SIG_CREATED:
726 printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
728 case SIGSUBPKT_SIG_EXPIRE:
730 printf("sig expires after %s",
731 strtimevalue( buffer_to_u32(buffer) ) );
733 case SIGSUBPKT_EXPORTABLE:
735 printf("%sexportable", *buffer? "":"not ");
737 case SIGSUBPKT_TRUST:
738 p = "trust signature";
740 case SIGSUBPKT_REGEXP:
741 p = "regular expression";
743 case SIGSUBPKT_REVOCABLE:
746 case SIGSUBPKT_KEY_EXPIRE:
748 printf("key expires after %s",
749 strtimevalue( buffer_to_u32(buffer) ) );
752 p = "additional recipient request";
754 case SIGSUBPKT_PREF_SYM:
755 fputs("pref-sym-algos:", stdout );
756 for( i=0; i < length; i++ )
757 printf(" %d", buffer[i] );
759 case SIGSUBPKT_REV_KEY:
760 p = "revocation key";
762 case SIGSUBPKT_ISSUER:
764 printf("issuer key ID %08lX%08lX",
765 (ulong)buffer_to_u32(buffer),
766 (ulong)buffer_to_u32(buffer+4) );
768 case SIGSUBPKT_NOTATION:
771 case SIGSUBPKT_PREF_HASH:
772 fputs("pref-hash-algos:", stdout );
773 for( i=0; i < length; i++ )
774 printf(" %d", buffer[i] );
776 case SIGSUBPKT_PREF_COMPR:
777 fputs("pref-zip-algos:", stdout );
778 for( i=0; i < length; i++ )
779 printf(" %d", buffer[i] );
781 case SIGSUBPKT_KS_FLAGS:
782 p = "key server preferences";
784 case SIGSUBPKT_PREF_KS:
785 p = "preferred key server";
787 case SIGSUBPKT_PRIMARY_UID:
788 p = "primary user id";
790 case SIGSUBPKT_POLICY:
793 case SIGSUBPKT_KEY_FLAGS:
796 case SIGSUBPKT_SIGNERS_UID:
797 p = "signer's user id";
799 case SIGSUBPKT_PRIV_ADD_SIG:
800 p = "signs additional user id";
802 default: p = "?"; break;
805 printf("%s)\n", p? p: "");
809 * Returns: >= 0 offset into buffer
811 * -2 unsupported type
812 * -3 subpacket too short
815 parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
818 case SIGSUBPKT_SIG_CREATED:
819 case SIGSUBPKT_SIG_EXPIRE:
820 case SIGSUBPKT_KEY_EXPIRE:
824 case SIGSUBPKT_EXPORTABLE:
828 case SIGSUBPKT_ISSUER:/* issuer key ID */
832 case SIGSUBPKT_PREF_SYM:
833 case SIGSUBPKT_PREF_HASH:
834 case SIGSUBPKT_PREF_COMPR:
836 case SIGSUBPKT_PRIV_ADD_SIG:
837 /* because we use private data, we check the GNUPG marker */
840 if( buffer[0] != 'G' || buffer[1] != 'P' || buffer[2] != 'G' )
849 parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
859 buflen = (*buffer << 8) | buffer[1];
862 n = *buffer++; buflen--;
866 n = (buffer[0] << 24) | (buffer[1] << 16)
867 | (buffer[2] << 8) | buffer[3];
872 else if( n >= 192 ) {
875 n = (( n - 192 ) << 8) + *buffer + 192;
887 if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
891 if( parse_one_sig_subpkt(buffer+1, n-1, type ) < 0 ) {
892 log_info(_("subpacket of type %d has critical bit set\n"),
894 return NULL; /* this is an error */
898 else if( reqtype < 0 ) /* list packets */
899 dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
900 type, critical, buffer, buflen, n );
901 else if( type == reqtype ) { /* found */
908 offset = parse_one_sig_subpkt(buffer, n, type );
911 log_error("subpacket of type %d too short\n", type);
916 BUG(); /* not yet needed */
920 return buffer+offset;
922 buffer += n; buflen -=n;
924 if( reqtype == SIGSUBPKT_TEST_CRITICAL )
925 return buffer; /* as value true to indicate that there is no */
926 /* critical bit we don't understand */
927 return NULL; /* end of packets; not found */
930 log_error("buffer shorter than subpacket\n");
936 parse_sig_subpkt2( PKT_signature *sig, sigsubpkttype_t reqtype, size_t *ret_n )
940 p = parse_sig_subpkt( sig->hashed_data, reqtype, ret_n );
942 p = parse_sig_subpkt( sig->unhashed_data, reqtype, ret_n );
949 parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
959 log_error("packet(%d) too short\n", pkttype);
962 sig->version = iobuf_get_noeof(inp); pktlen--;
963 if( sig->version == 4 )
965 else if( sig->version != 2 && sig->version != 3 ) {
966 log_error("packet(%d) with unknown version %d\n", pkttype, sig->version);
971 md5_len = iobuf_get_noeof(inp); pktlen--;
973 sig->sig_class = iobuf_get_noeof(inp); pktlen--;
975 sig->timestamp = read_32(inp); pktlen -= 4;
976 sig->keyid[0] = read_32(inp); pktlen -= 4;
977 sig->keyid[1] = read_32(inp); pktlen -= 4;
979 sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
980 sig->digest_algo = iobuf_get_noeof(inp); pktlen--;
981 if( is_v4 ) { /* read subpackets */
982 n = read_16(inp); pktlen -= 2; /* length of hashed data */
984 log_error("signature packet: hashed data too long\n");
985 rc = G10ERR_INVALID_PACKET;
989 sig->hashed_data = m_alloc( n + 2 );
990 sig->hashed_data[0] = n << 8;
991 sig->hashed_data[1] = n;
992 if( iobuf_read(inp, sig->hashed_data+2, n ) != n ) {
993 log_error("premature eof while reading hashed signature data\n");
999 n = read_16(inp); pktlen -= 2; /* length of unhashed data */
1001 log_error("signature packet: unhashed data too long\n");
1002 rc = G10ERR_INVALID_PACKET;
1006 sig->unhashed_data = m_alloc( n + 2 );
1007 sig->unhashed_data[0] = n << 8;
1008 sig->unhashed_data[1] = n;
1009 if( iobuf_read(inp, sig->unhashed_data+2, n ) != n ) {
1010 log_error("premature eof while reading unhashed signature data\n");
1018 if( pktlen < 5 ) { /* sanity check */
1019 log_error("packet(%d) too short\n", pkttype);
1020 rc = G10ERR_INVALID_PACKET;
1024 sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
1025 sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
1027 if( is_v4 ) { /*extract required information */
1030 /* set sig->flags.unknown_critical if there is a
1031 * critical bit set for packets which we do not understand */
1032 if( !parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_TEST_CRITICAL, NULL)
1033 || !parse_sig_subpkt( sig->unhashed_data, SIGSUBPKT_TEST_CRITICAL,
1036 sig->flags.unknown_critical = 1;
1039 p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_SIG_CREATED, NULL );
1041 log_error("signature packet without timestamp\n");
1043 sig->timestamp = buffer_to_u32(p);
1044 p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1046 log_error("signature packet without keyid\n");
1048 sig->keyid[0] = buffer_to_u32(p);
1049 sig->keyid[1] = buffer_to_u32(p+4);
1054 printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1055 "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1056 "\tdigest algo %d, begin of digest %02x %02x\n",
1058 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1059 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1061 sig->digest_start[0], sig->digest_start[1] );
1063 parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_LIST_HASHED, NULL );
1064 parse_sig_subpkt( sig->unhashed_data,SIGSUBPKT_LIST_UNHASHED, NULL);
1068 ndata = pubkey_get_nsig(sig->pubkey_algo);
1071 printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1072 unknown_pubkey_warning( sig->pubkey_algo );
1073 /* we store the plain material in data[0], so that we are able
1074 * to write it back with build_packet() */
1075 sig->data[0] = read_rest(inp, &pktlen );
1078 for( i=0; i < ndata; i++ ) {
1080 sig->data[i] = mpi_read(inp, &n, 0 );
1084 mpi_print(stdout, sig->data[i], mpi_print_mode );
1092 skip_rest(inp, pktlen);
1098 parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
1099 PKT_onepass_sig *ops )
1104 log_error("packet(%d) too short\n", pkttype);
1107 version = iobuf_get_noeof(inp); pktlen--;
1108 if( version != 3 ) {
1109 log_error("onepass_sig with unknown version %d\n", version);
1112 ops->sig_class = iobuf_get_noeof(inp); pktlen--;
1113 ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
1114 ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
1115 ops->keyid[0] = read_32(inp); pktlen -= 4;
1116 ops->keyid[1] = read_32(inp); pktlen -= 4;
1117 ops->last = iobuf_get_noeof(inp); pktlen--;
1119 printf(":onepass_sig packet: keyid %08lX%08lX\n"
1120 "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1121 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1122 version, ops->sig_class,
1123 ops->digest_algo, ops->pubkey_algo, ops->last );
1127 skip_rest(inp, pktlen);
1135 parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
1136 byte *hdr, int hdrlen, PACKET *pkt )
1138 int i, version, algorithm;
1140 unsigned long timestamp, expiredate;
1145 version = iobuf_get_noeof(inp); pktlen--;
1146 if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1147 /* early versions of G10 use old PGP comments packets;
1148 * luckily all those comments are started by a hash */
1150 printf(":rfc1991 comment packet: \"" );
1151 for( ; pktlen; pktlen-- ) {
1153 c = iobuf_get_noeof(inp);
1154 if( c >= ' ' && c <= 'z' )
1157 printf("\\x%02x", c );
1161 skip_rest(inp, pktlen);
1164 else if( version == 4 )
1166 else if( version != 2 && version != 3 ) {
1167 log_error("packet(%d) with unknown version %d\n", pkttype, version);
1172 log_error("packet(%d) too short\n", pkttype);
1176 timestamp = read_32(inp); pktlen -= 4;
1178 expiredate = 0; /* have to get it from the selfsignature */
1180 unsigned short ndays;
1181 ndays = read_16(inp); pktlen -= 2;
1183 expiredate = timestamp + ndays * 86400L;
1187 algorithm = iobuf_get_noeof(inp); pktlen--;
1189 printf(":%s key packet:\n"
1190 "\tversion %d, algo %d, created %lu, expires %lu\n",
1191 pkttype == PKT_PUBLIC_KEY? "public" :
1192 pkttype == PKT_SECRET_KEY? "secret" :
1193 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1194 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1195 version, algorithm, timestamp, expiredate );
1197 if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1198 PKT_secret_key *sk = pkt->pkt.secret_key;
1200 sk->timestamp = timestamp;
1201 sk->expiredate = expiredate;
1202 sk->hdrbytes = hdrlen;
1203 sk->version = version;
1204 sk->is_primary = pkttype == PKT_SECRET_KEY;
1205 sk->pubkey_algo = algorithm;
1206 sk->pubkey_usage = 0; /* not yet used */
1209 PKT_public_key *pk = pkt->pkt.public_key;
1211 pk->timestamp = timestamp;
1212 pk->expiredate = expiredate;
1213 pk->hdrbytes = hdrlen;
1214 pk->version = version;
1215 pk->pubkey_algo = algorithm;
1216 pk->pubkey_usage = 0; /* not yet used */
1220 nskey = pubkey_get_nskey( algorithm );
1221 npkey = pubkey_get_npkey( algorithm );
1224 printf("\tunknown algorithm %d\n", algorithm );
1225 unknown_pubkey_warning( algorithm );
1229 if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1230 PKT_secret_key *sk = pkt->pkt.secret_key;
1234 sk->skey[0] = read_rest( inp, &pktlen );
1238 for(i=0; i < npkey; i++ ) {
1239 n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1241 printf( "\tskey[%d]: ", i);
1242 mpi_print(stdout, sk->skey[i], mpi_print_mode );
1246 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1247 if( sk->protect.algo ) {
1248 sk->is_protected = 1;
1249 sk->protect.s2k.count = 0;
1250 if( sk->protect.algo == 255 ) {
1252 rc = G10ERR_INVALID_PACKET;
1255 sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
1256 sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
1257 sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
1258 switch( sk->protect.s2k.mode ) {
1261 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1262 temp[i] = iobuf_get_noeof(inp);
1263 memcpy(sk->protect.s2k.salt, temp, 8 );
1266 switch( sk->protect.s2k.mode ) {
1267 case 0: if( list_mode ) printf( "\tsimple S2K" );
1269 case 1: if( list_mode ) printf( "\tsalted S2K" );
1271 case 3: if( list_mode ) printf( "\titer+salt S2K" );
1275 printf( "\tunknown S2K %d\n",
1276 sk->protect.s2k.mode );
1277 rc = G10ERR_INVALID_PACKET;
1282 printf(", algo: %d, hash: %d",
1284 sk->protect.s2k.hash_algo );
1285 if( sk->protect.s2k.mode == 1
1286 || sk->protect.s2k.mode == 3 ) {
1288 for(i=0; i < 8; i++ )
1289 printf("%02x", sk->protect.s2k.salt[i]);
1294 if( sk->protect.s2k.mode == 3 ) {
1296 rc = G10ERR_INVALID_PACKET;
1299 sk->protect.s2k.count = iobuf_get(inp);
1302 printf("\tprotect count: %lu\n",
1303 (ulong)sk->protect.s2k.count);
1306 else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1307 sk->protect.s2k.mode = 0;
1308 /* We need a kludge to cope with old GNUPG versions */
1309 sk->protect.s2k.hash_algo =
1310 ( sk->protect.algo == CIPHER_ALGO_BLOWFISH160
1311 && algorithm == PUBKEY_ALGO_ELGAMAL_E ) ?
1312 DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5;
1314 printf( "\tprotect algo: %d (hash algo: %d)\n",
1315 sk->protect.algo, sk->protect.s2k.hash_algo );
1318 rc = G10ERR_INVALID_PACKET;
1321 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1322 temp[i] = iobuf_get_noeof(inp);
1324 printf( "\tprotect IV: ");
1325 for(i=0; i < 8; i++ )
1326 printf(" %02x", temp[i] );
1329 memcpy(sk->protect.iv, temp, 8 );
1332 sk->is_protected = 0;
1333 /* It does not make sense to read it into secure memory.
1334 * If the user is so careless, not to protect his secret key,
1335 * we can assume, that he operates an open system :=(.
1336 * So we put the key into secure memory when we unprotect it. */
1337 if( is_v4 && sk->is_protected ){
1338 /* ugly; the length is encrypted too, so we read all
1339 * stuff up to the end of the packet into the first
1341 sk->skey[npkey] = mpi_set_opaque(NULL,
1342 read_rest2(inp, pktlen), pktlen );
1345 printf("\tencrypted stuff follows\n");
1348 else { /* v3 method: the mpi length is not encrypted */
1349 for(i=npkey; i < nskey; i++ ) {
1350 n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1351 if( sk->is_protected )
1352 mpi_set_protect_flag(sk->skey[i]);
1354 printf( "\tskey[%d]: ", i);
1355 if( sk->is_protected )
1356 printf( "[encrypted]\n");
1358 mpi_print(stdout, sk->skey[i], mpi_print_mode );
1364 sk->csum = read_16(inp); pktlen -= 2;
1366 printf("\tchecksum: %04hx\n", sk->csum);
1371 PKT_public_key *pk = pkt->pkt.public_key;
1374 pk->pkey[0] = read_rest( inp, &pktlen );
1378 for(i=0; i < npkey; i++ ) {
1379 n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1381 printf( "\tpkey[%d]: ", i);
1382 mpi_print(stdout, pk->pkey[i], mpi_print_mode );
1389 skip_rest(inp, pktlen);
1395 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1399 packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen);
1400 packet->pkt.user_id->len = pktlen;
1401 p = packet->pkt.user_id->name;
1402 for( ; pktlen; pktlen--, p++ )
1403 *p = iobuf_get_noeof(inp);
1407 int n = packet->pkt.user_id->len;
1408 printf(":user id packet: \"");
1409 /* fixme: Hey why don't we replace this wioth print_string?? */
1410 for(p=packet->pkt.user_id->name; n; p++, n-- ) {
1411 if( *p >= ' ' && *p <= 'z' )
1414 printf("\\x%02x", *p );
1424 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
1428 packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
1429 packet->pkt.comment->len = pktlen;
1430 p = packet->pkt.comment->data;
1431 for( ; pktlen; pktlen--, p++ )
1432 *p = iobuf_get_noeof(inp);
1435 int n = packet->pkt.comment->len;
1436 printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
1437 "OpenPGP draft " : "" );
1438 for(p=packet->pkt.comment->data; n; p++, n-- ) {
1439 if( *p >= ' ' && *p <= 'z' )
1442 printf("\\x%02x", *p );
1451 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
1455 c = iobuf_get_noeof(inp);
1457 printf(":trust packet: flag=%02x\n", c );
1462 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
1463 PACKET *pkt, int new_ctb )
1470 if( pktlen && pktlen < 6 ) {
1471 log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
1474 mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
1475 namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
1476 pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
1477 pt->new_ctb = new_ctb;
1479 pt->namelen = namelen;
1481 for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
1482 pt->name[i] = iobuf_get_noeof(inp);
1485 for( i=0; i < namelen; i++ )
1486 if( (c=iobuf_get(inp)) == -1 )
1491 pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
1497 printf(":literal data packet:\n"
1498 "\tmode %c, created %lu, name=\"",
1499 mode >= ' ' && mode <'z'? mode : '?',
1500 (ulong)pt->timestamp );
1501 for(p=pt->name,i=0; i < namelen; p++, i++ ) {
1502 if( *p >= ' ' && *p <= 'z' )
1505 printf("\\x%02x", *p );
1507 printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
1516 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
1517 PACKET *pkt, int new_ctb )
1521 /* pktlen is here 0, but data follows
1522 * (this should be the last object in a file or
1523 * the compress algorithm should know the length)
1525 zd = pkt->pkt.compressed = m_alloc(sizeof *pkt->pkt.compressed );
1526 zd->len = 0; /* not yet used */
1527 zd->algorithm = iobuf_get_noeof(inp);
1528 zd->new_ctb = new_ctb;
1531 printf(":compressed packet: algo=%d\n", zd->algorithm);
1537 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
1538 PACKET *pkt, int new_ctb )
1542 ed = pkt->pkt.encrypted = m_alloc(sizeof *pkt->pkt.encrypted );
1545 ed->new_ctb = new_ctb;
1546 if( pktlen && pktlen < 10 ) {
1547 log_error("packet(%d) too short\n", pkttype);
1548 skip_rest(inp, pktlen);
1553 printf(":encrypted data packet:\n\tlength: %lu\n", pktlen-10);
1555 printf(":encrypted data packet:\n\tlength: unknown\n");