diff options
author | Werner Koch <wk@gnupg.org> | 1998-07-02 21:31:46 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1998-07-02 21:31:46 +0200 |
commit | 97090f1293d43f67e36850c76aeba23760954757 (patch) | |
tree | ed63e6c5e37edeb337048cdcc84b471aa405f503 /g10 | |
parent | textual changes (diff) | |
download | gnupg2-97090f1293d43f67e36850c76aeba23760954757.tar.xz gnupg2-97090f1293d43f67e36850c76aeba23760954757.zip |
partly added creation of OP partial length headers
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 17 | ||||
-rw-r--r-- | g10/armor.c | 6 | ||||
-rw-r--r-- | g10/build-packet.c | 44 | ||||
-rw-r--r-- | g10/cipher.c | 57 | ||||
-rw-r--r-- | g10/filter.h | 3 | ||||
-rw-r--r-- | g10/free-packet.c | 52 | ||||
-rw-r--r-- | g10/import.c | 4 | ||||
-rw-r--r-- | g10/keyid.c | 34 | ||||
-rw-r--r-- | g10/packet.h | 4 | ||||
-rw-r--r-- | g10/parse-packet.c | 170 | ||||
-rw-r--r-- | g10/ringedit.c | 8 |
11 files changed, 273 insertions, 126 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index ccee5b99f..7094ed601 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +Thu Jul 2 21:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) + + * parse-packet.c: Now is able sto store data of unknown + algorithms. + * free-packet.c: Support for this. + * build-packet.c: Can write data of packet with unknown algos. + +Thu Jul 2 11:46:36 1998 Werner Koch (wk@isil.d.shuttle.de) + + * parse-packet.c (parse): fixed 4 byte length header + +Wed Jul 1 12:36:55 1998 Werner Koch (wk@isil.d.shuttle.de) + + * packet.h (new_ctb): New field for some packets + * build-packet.c (build_packet): Support for new_ctb + * parse-packet.c (parse): Ditto. + Mon Jun 29 12:54:45 1998 Werner Koch (wk@isil.d.shuttle.de) * packet.h: changed all "_cert" to "_key", "subcert" to "subkey". diff --git a/g10/armor.c b/g10/armor.c index 82b240f75..7fe2f8172 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -87,8 +87,9 @@ static char *head_strings[] = { "BEGIN PGP PUBLIC KEY BLOCK", "BEGIN PGP SIGNATURE", "BEGIN PGP SIGNED MESSAGE", - "BEGIN PGP ARMORED FILE", - "BEGIN PGP SECRET KEY BLOCK", + "BEGIN PGP ARMORED FILE", /* gnupg extension */ + "BEGIN PGP PRIVATE KEY BLOCK", + "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */ NULL }; static char *tail_strings[] = { @@ -97,6 +98,7 @@ static char *tail_strings[] = { "END PGP SIGNATURE", "END dummy", "END PGP ARMORED FILE", + "END PGP PRIVATE KEY BLOCK", "END PGP SECRET KEY BLOCK", NULL }; diff --git a/g10/build-packet.c b/g10/build-packet.c index cb08275ec..b8acc577e 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -64,14 +64,21 @@ static int write_version( IOBUF out, int ctb ); int build_packet( IOBUF out, PACKET *pkt ) { - int rc=0, ctb; + int new_ctb=0, rc=0, ctb; if( DBG_PACKET ) log_debug("build_packet() type=%d\n", pkt->pkttype ); - if( pkt->pkttype == PKT_OLD_COMMENT ) - pkt->pkttype = PKT_COMMENT; assert( pkt->pkt.generic ); - if( pkt->pkttype > 15 ) /* new format */ + + switch( pkt->pkttype ) { + case PKT_OLD_COMMENT: pkt->pkttype = PKT_COMMENT; break; + case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break; + case PKT_ENCRYPTED: new_ctb = pkt->pkt.encrypted->new_ctb; break; + case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break; + default: break; + } + + if( new_ctb || pkt->pkttype > 15 ) /* new format */ ctb = 0xc0 | (pkt->pkttype & 0x3f); else ctb = 0x80 | ((pkt->pkttype & 15)<<2); @@ -152,6 +159,19 @@ calc_packet_length( PACKET *pkt ) return n; } +static void +write_fake_data( IOBUF out, MPI a ) +{ + byte *s; + u16 len; + + if( a ) { + s = (byte*)a; + len = (s[0] << 8) | s[1]; + iobuf_write( out, s+2, len ); + } +} + static int do_comment( IOBUF out, int ctb, PKT_comment *rem ) @@ -189,6 +209,8 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk ) write_16(a, pk->valid_days ); iobuf_put(a, pk->pubkey_algo ); n = pubkey_get_npkey( pk->pubkey_algo ); + if( !n ) + write_fake_data( a, pk->pkey[0] ); for(i=0; i < n; i++ ) mpi_write(a, pk->pkey[i] ); @@ -259,6 +281,10 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) iobuf_put(a, sk->pubkey_algo ); nskey = pubkey_get_nskey( sk->pubkey_algo ); npkey = pubkey_get_npkey( sk->pubkey_algo ); + if( npkey ) { + write_fake_data( a, sk->skey[0] ); + goto leave; + } assert( npkey < nskey ); for(i=0; i < npkey; i++ ) @@ -287,6 +313,7 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) mpi_write(a, sk->skey[i] ); write_16(a, sk->csum ); + leave: write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 ); if( iobuf_write_temp( out, a ) ) rc = G10ERR_WRITE_FILE; @@ -326,6 +353,9 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) return rc; } + + + static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) { @@ -338,6 +368,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) write_32(a, enc->keyid[1] ); iobuf_put(a,enc->pubkey_algo ); n = pubkey_get_nenc( enc->pubkey_algo ); + if( !n ) + write_fake_data( a, enc->data[0] ); for(i=0; i < n; i++ ) mpi_write(a, enc->data[i] ); @@ -632,6 +664,8 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) iobuf_put(a, sig->digest_start[0] ); iobuf_put(a, sig->digest_start[1] ); n = pubkey_get_nsig( sig->pubkey_algo ); + if( !n ) + write_fake_data( a, sig->data[0] ); for(i=0; i < n; i++ ) mpi_write(a, sig->data[i] ); @@ -772,7 +806,7 @@ write_new_header( IOBUF out, int ctb, u32 len, int hdrlen ) if( iobuf_put(out, ctb ) ) return -1; if( !len ) { - log_bug("can't write partial headers yet\n"); + iobuf_set_partial_block_mode(out, 512 ); } else { if( len < 192 ) { diff --git a/g10/cipher.c b/g10/cipher.c index c6a43c6b4..b975d26f1 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -34,6 +34,34 @@ #include "options.h" +#define MIN_PARTIAL_SIZE 512 + + +static void +write_header( cipher_filter_context_t *cfx, IOBUF a ) +{ + PACKET pkt; + PKT_encrypted ed; + byte temp[10]; + + memset( &ed, 0, sizeof ed ); + ed.len = cfx->datalen; + init_packet( &pkt ); + pkt.pkttype = PKT_ENCRYPTED; + pkt.pkt.encrypted = &ed; + if( build_packet( a, &pkt )) + log_bug("build_packet(ENCR_DATA) failed\n"); + randomize_buffer( temp, 8, 1 ); + temp[8] = temp[6]; + temp[9] = temp[7]; + cfx->cipher_hd = cipher_open( cfx->dek->algo, CIPHER_MODE_AUTO_CFB, 1 ); + cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen ); + cipher_setiv( cfx->cipher_hd, NULL ); + cipher_encrypt( cfx->cipher_hd, temp, temp, 10); + cipher_sync( cfx->cipher_hd ); + iobuf_write(a, temp, 10); + cfx->header=1; +} /**************** @@ -53,35 +81,20 @@ cipher_filter( void *opaque, int control, else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ assert(a); if( !cfx->header ) { - PACKET pkt; - PKT_encrypted ed; - byte temp[10]; - - memset( &ed, 0, sizeof ed ); - ed.len = cfx->datalen; - init_packet( &pkt ); - pkt.pkttype = PKT_ENCRYPTED; - pkt.pkt.encrypted = &ed; - if( build_packet( a, &pkt )) - log_bug("build_packet(ENCR_DATA) failed\n"); - randomize_buffer( temp, 8, 1 ); - temp[8] = temp[6]; - temp[9] = temp[7]; - cfx->cipher_hd = cipher_open( cfx->dek->algo, - CIPHER_MODE_AUTO_CFB, 1 ); - cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen ); - cipher_setiv( cfx->cipher_hd, NULL ); - cipher_encrypt( cfx->cipher_hd, temp, temp, 10); - cipher_sync( cfx->cipher_hd ); - iobuf_write(a, temp, 10); - cfx->header=1; + write_header( cfx, a ); } cipher_encrypt( cfx->cipher_hd, buf, buf, size); if( iobuf_write( a, buf, size ) ) rc = G10ERR_WRITE_FILE; } else if( control == IOBUFCTRL_FREE ) { + #if 0 + if( cfx->new_partial && cfx->cfx->la_buffer ) { + + } + #endif cipher_close(cfx->cipher_hd); + m_free(cfx->la_buffer); cfx->la_buffer = NULL; } else if( control == IOBUFCTRL_DESC ) { *(char**)buf = "cipher_filter"; diff --git a/g10/filter.h b/g10/filter.h index 2dc8a3e87..108e64c0e 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -61,6 +61,9 @@ typedef struct { typedef struct { DEK *dek; u32 datalen; + int new_partial; /* use Openpgp partial packets header */ + char *la_buffer; /* help buffer for OP partial stuff */ + size_t la_buflen; /* and its used length */ CIPHER_HANDLE cipher_hd; int header; } cipher_filter_context_t; diff --git a/g10/free-packet.c b/g10/free-packet.c index 6b3b7686e..9d623ec30 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -42,6 +42,10 @@ free_pubkey_enc( PKT_pubkey_enc *enc ) { int n, i; n = pubkey_get_nenc( enc->pubkey_algo ); + if( !n ) { + m_free(enc->data[0]); + enc->data[0] = NULL; + } for(i=0; i < n; i++ ) mpi_free( enc->data[i] ); m_free(enc); @@ -52,6 +56,10 @@ free_seckey_enc( PKT_signature *sig ) { int n, i; n = pubkey_get_nenc( sig->pubkey_algo ); + if( !n ) { + m_free(sig->data[0]); + sig->data[0] = NULL; + } for(i=0; i < n; i++ ) mpi_free( sig->data[i] ); m_free(sig->hashed_data); @@ -66,6 +74,10 @@ release_public_key_parts( PKT_public_key *pk ) { int n, i; n = pubkey_get_npkey( pk->pubkey_algo ); + if( !n ) { + m_free(pk->pkey[0]); + pk->pkey[0] = NULL; + } for(i=0; i < n; i++ ) { mpi_free( pk->pkey[i] ); pk->pkey[i] = NULL; @@ -80,6 +92,22 @@ free_public_key( PKT_public_key *pk ) m_free(pk); } +static void * +cp_fake_data( MPI a ) +{ + byte *d, *s; + u16 len; + + if( !a ) + return NULL; + s = (byte*)a; + len = (s[0] << 8) | s[1]; + d = m_alloc( len+2 ); + memcpy(d, s, len+2); + return d; +} + + PKT_public_key * copy_public_key( PKT_public_key *d, PKT_public_key *s ) { @@ -89,8 +117,12 @@ copy_public_key( PKT_public_key *d, PKT_public_key *s ) d = m_alloc(sizeof *d); memcpy( d, s, sizeof *d ); n = pubkey_get_npkey( s->pubkey_algo ); - for(i=0; i < n; i++ ) - d->pkey[i] = mpi_copy( s->pkey[i] ); + if( !n ) + d->pkey[0] = cp_fake_data(s->pkey[0]); + else { + for(i=0; i < n; i++ ) + d->pkey[i] = mpi_copy( s->pkey[i] ); + } return d; } @@ -100,6 +132,10 @@ release_secret_key_parts( PKT_secret_key *sk ) int n, i; n = pubkey_get_nskey( sk->pubkey_algo ); + if( !n ) { + m_free(sk->skey[0]); + sk->skey[0] = NULL; + } for(i=0; i < n; i++ ) { mpi_free( sk->skey[i] ); sk->skey[i] = NULL; @@ -122,8 +158,12 @@ copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ) d = m_alloc(sizeof *d); memcpy( d, s, sizeof *d ); n = pubkey_get_nskey( s->pubkey_algo ); - for(i=0; i < n; i++ ) - d->skey[i] = mpi_copy( s->skey[i] ); + if( !n ) + d->skey[0] = cp_fake_data(s->skey[0]); + else { + for(i=0; i < n; i++ ) + d->skey[i] = mpi_copy( s->skey[i] ); + } return d; } @@ -254,6 +294,8 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) return -1; n = pubkey_get_npkey( b->pubkey_algo ); + if( !n ) + return -1; /* can't compare due to unknown algorithm */ for(i=0; i < n; i++ ) { if( mpi_cmp( a->pkey[i], b->pkey[i] ) ) return -1; @@ -278,6 +320,8 @@ cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ) return -1; n = pubkey_get_npkey( pk->pubkey_algo ); + if( !n ) + return -1; /* can't compare due to unknown algorithm */ for(i=0; i < n; i++ ) { if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) ) return -1; diff --git a/g10/import.c b/g10/import.c index 719a8e8e2..1467f092f 100644 --- a/g10/import.c +++ b/g10/import.c @@ -159,9 +159,7 @@ read_block( IOBUF a, compress_filter_context_t *cfx, init_packet(pkt); while( (rc=parse_packet(a, pkt)) != -1 ) { if( rc ) { /* ignore errors */ - if( rc == G10ERR_PUBKEY_ALGO ) - parse_pubkey_warning( pkt ); - else if( rc != G10ERR_UNKNOWN_PACKET ) { + if( rc != G10ERR_UNKNOWN_PACKET ) { log_error("read_block: read error: %s\n", g10_errstr(rc) ); rc = G10ERR_INV_KEYRING; goto ready; diff --git a/g10/keyid.c b/g10/keyid.c index 499c8928d..74bbf8c2c 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -130,7 +130,8 @@ keyid_from_sk( PKT_secret_key *sk, u32 *keyid ) keyid = dummy_keyid; if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) { - lowbits = mpi_get_keyid( sk->skey[0], keyid ); /* take n */ + lowbits = pubkey_get_npkey(sk->pubkey_algo) ? + mpi_get_keyid( sk->skey[0], keyid ) : 0; /* take n */ } else { const byte *dp; @@ -161,7 +162,8 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid ) keyid = dummy_keyid; if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) { - lowbits = mpi_get_keyid( pk->pkey[0], keyid ); /* from n */ + lowbits = pubkey_get_npkey(pk->pubkey_algo) ? + mpi_get_keyid( pk->pkey[0], keyid ) : 0 ; /* from n */ } else { const byte *dp; @@ -267,12 +269,14 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len ) MD_HANDLE md; md = md_open( DIGEST_ALGO_MD5, 0); - p = buf = mpi_get_buffer( pk->pkey[0], &n, NULL ); - md_write( md, p, n ); - m_free(buf); - p = buf = mpi_get_buffer( pk->pkey[1], &n, NULL ); - md_write( md, p, n ); - m_free(buf); + if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) { + p = buf = mpi_get_buffer( pk->pkey[0], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( pk->pkey[1], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + } md_final(md); array = m_alloc( 16 ); len = 16; @@ -306,12 +310,14 @@ fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len ) MD_HANDLE md; md = md_open( DIGEST_ALGO_MD5, 0); - p = buf = mpi_get_buffer( sk->skey[1], &n, NULL ); - md_write( md, p, n ); - m_free(buf); - p = buf = mpi_get_buffer( sk->skey[0], &n, NULL ); - md_write( md, p, n ); - m_free(buf); + if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) { + p = buf = mpi_get_buffer( sk->skey[1], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( sk->skey[0], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + } md_final(md); array = m_alloc( 16 ); len = 16; diff --git a/g10/packet.h b/g10/packet.h index b3a9d7507..4524328c6 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -145,18 +145,21 @@ typedef struct { typedef struct { u32 len; /* reserved */ + byte new_ctb; byte algorithm; IOBUF buf; /* IOBUF reference */ } PKT_compressed; typedef struct { u32 len; /* length of encrypted data */ + byte new_ctb; IOBUF buf; /* IOBUF reference */ } PKT_encrypted; typedef struct { u32 len; /* length of encrypted data */ IOBUF buf; /* IOBUF reference */ + byte new_ctb; int mode; u32 timestamp; int namelen; @@ -224,7 +227,6 @@ int list_packets( IOBUF a ); int set_packet_list_mode( int mode ); int search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos ); int parse_packet( IOBUF inp, PACKET *ret_pkt); -void parse_pubkey_warning( PACKET *pkt ); int copy_all_packets( IOBUF inp, IOBUF out ); int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff ); int skip_some_packets( IOBUF inp, unsigned n ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 153c4bcfa..20afd4163 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -43,6 +43,7 @@ static int copy_packet( IOBUF inp, IOBUF out, int pkttype, unsigned long pktlen ); static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen ); static void skip_rest( IOBUF inp, unsigned long pktlen ); +static void *read_rest( IOBUF inp, ulong *r_pktlen ); static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ); static int parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, @@ -59,11 +60,11 @@ static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ); static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen ); static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *pkt ); + PACKET *packet, int new_ctb); static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); + PACKET *packet, int new_ctb ); static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); + PACKET *packet, int new_ctb); static unsigned short @@ -96,6 +97,19 @@ set_packet_list_mode( int mode ) return old; } +static void +unknown_pubkey_warning( int algo ) +{ + static byte unknown_pubkey_algos[256]; + + algo &= 0xff; + if( !unknown_pubkey_algos[algo] ) { + if( opt.verbose ) + log_info("can't handle public key algorithm %d\n", algo ); + unknown_pubkey_algos[algo] = 1; + } +} + /**************** * Parse a Packet and return it in packet * Returns: 0 := valid packet in pkt @@ -177,36 +191,6 @@ skip_some_packets( IOBUF inp, unsigned n ) } -void -parse_pubkey_warning( PACKET *pkt ) -{ - static byte unknown_pubkey_algos[256]; - int unk=0, uns=0; - - if( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY ) - unk = pkt->pkt.public_key->pubkey_algo & 0xff; - else if( pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY ) - unk = pkt->pkt.secret_key->pubkey_algo & 0xff; - else if( pkt->pkttype == PKT_SIGNATURE ) - uns = pkt->pkt.signature->pubkey_algo & 0xff; - - if( unk ) { - if( !(unknown_pubkey_algos[unk]&1) ) { - log_info("can't handle key " - "with public key algorithm %d\n", unk ); - unknown_pubkey_algos[unk] |= 1; - } - } - else if( uns ) { - if( !(unknown_pubkey_algos[unk]&2) ) { - log_info("can't handle signature " - "with public key algorithm %d\n", uns ); - unknown_pubkey_algos[unk] |= 2; - } - } -} /**************** * Parse packet. Set the variable skip points to to 1 if the packet @@ -223,7 +207,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, unsigned long pktlen; byte hdr[8]; int hdrlen; - int pgp3 = 0; + int new_ctb = 0; *skip = 0; assert( !pkt->pkt.generic ); @@ -238,8 +222,8 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, return G10ERR_INVALID_PACKET; } pktlen = 0; - pgp3 = !!(ctb & 0x40); - if( pgp3 ) { + new_ctb = !!(ctb & 0x40); + if( new_ctb ) { pkttype = ctb & 0x3f; if( (c = iobuf_get(inp)) == -1 ) { log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); @@ -257,7 +241,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, hdr[hdrlen++] = c; pktlen += c + 192; } - else if( c < 255 ) { + else if( c == 255 ) { pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; @@ -268,8 +252,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, pktlen |= (hdr[hdrlen++] = c ); } else { /* partial body length */ - log_debug("partial body length of %lu bytes\n", pktlen ); - iobuf_set_partial_block_mode(inp, pktlen); + iobuf_set_partial_block_mode(inp, c & 0xff); pktlen = 0;/* to indicate partial length */ } } @@ -305,7 +288,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, if( DBG_PACKET ) log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n", - iobuf_id(inp), pkttype, pktlen, pgp3?" (pgp3)":"" ); + iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" ); pkt->pkttype = pkttype; rc = G10ERR_UNKNOWN_PACKET; /* default error */ switch( pkttype ) { @@ -345,13 +328,13 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, rc = G10ERR_UNKNOWN_PACKET; break; case PKT_PLAINTEXT: - rc = parse_plaintext(inp, pkttype, pktlen, pkt ); + rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb ); break; case PKT_COMPRESSED: - rc = parse_compressed(inp, pkttype, pktlen, pkt ); + rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb ); break; case PKT_ENCRYPTED: - rc = parse_encrypted(inp, pkttype, pktlen, pkt ); + rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb ); break; default: skip_packet(inp, pkttype, pktlen); @@ -445,6 +428,28 @@ skip_rest( IOBUF inp, unsigned long pktlen ) } } +static void * +read_rest( IOBUF inp, ulong *r_pktlen ) +{ + byte *p; + int i; + size_t pktlen = *r_pktlen; + + if( iobuf_in_block_mode(inp) ) { + log_error("read_rest: can't store stream data\n"); + p = NULL; + } + else { + p = m_alloc( pktlen + 2 ); + p[0] = pktlen >> 8; + p[1] = pktlen & 0xff; + for(i=2; pktlen; pktlen--, i++ ) + p[i] = iobuf_get(inp); + } + *r_pktlen = 0; + return p; +} + static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) @@ -548,16 +553,21 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]); ndata = pubkey_get_nenc(k->pubkey_algo); - if( !ndata && list_mode ) - printf("\tunsupported algorithm %d\n", k->pubkey_algo ); - - for( i=0; i < ndata; i++ ) { - n = pktlen; - k->data[i] = mpi_read(inp, &n, 0); pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, k->data[i], mpi_print_mode ); - putchar('\n'); + if( !ndata ) { + if( list_mode ) + printf("\tunsupported algorithm %d\n", k->pubkey_algo ); + unknown_pubkey_warning( k->pubkey_algo ); + k->data[0] = NULL; /* no need to store the encrypted data */ + } + else { + for( i=0; i < ndata; i++ ) { + n = pktlen; + k->data[i] = mpi_read(inp, &n, 0); pktlen -=n; + if( list_mode ) { + printf("\tdata: "); + mpi_print(stdout, k->data[i], mpi_print_mode ); + putchar('\n'); + } } } @@ -783,17 +793,24 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, } ndata = pubkey_get_nsig(sig->pubkey_algo); - if( !ndata && list_mode ) - printf("\tunknown algorithm %d\n", sig->pubkey_algo ); - - for( i=0; i < ndata; i++ ) { - n = pktlen; - sig->data[i] = mpi_read(inp, &n, 0 ); - pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, sig->data[i], mpi_print_mode ); - putchar('\n'); + if( !ndata ) { + if( list_mode ) + printf("\tunknown algorithm %d\n", sig->pubkey_algo ); + unknown_pubkey_warning( sig->pubkey_algo ); + /* we store the plain material in data[0], so that we are able + * to write it back with build_packet() */ + sig->data[0] = read_rest(inp, &pktlen ); + } + else { + for( i=0; i < ndata; i++ ) { + n = pktlen; + sig->data[i] = mpi_read(inp, &n, 0 ); + pktlen -=n; + if( list_mode ) { + printf("\tdata: "); + mpi_print(stdout, sig->data[i], mpi_print_mode ); + putchar('\n'); + } } } @@ -923,8 +940,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, if( !npkey ) { if( list_mode ) printf("\tunknown algorithm %d\n", algorithm ); - rc = G10ERR_PUBKEY_ALGO; - goto leave; + unknown_pubkey_warning( algorithm ); } @@ -932,6 +948,11 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, PKT_secret_key *sk = pkt->pkt.secret_key; byte temp[8]; + if( !npkey ) { + sk->skey[0] = read_rest( inp, &pktlen ); + goto leave; + } + for(i=0; i < npkey; i++ ) { n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; if( list_mode ) { @@ -1053,6 +1074,11 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, else { PKT_public_key *pk = pkt->pkt.public_key; + if( !npkey ) { + pk->pkey[0] = read_rest( inp, &pktlen ); + goto leave; + } + for(i=0; i < npkey; i++ ) { n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; if( list_mode ) { @@ -1135,7 +1161,8 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen ) static int -parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) +parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, + PACKET *pkt, int new_ctb ) { int mode, namelen; PKT_plaintext *pt; @@ -1149,6 +1176,7 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--; namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--; pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1); + pt->new_ctb = new_ctb; pt->mode = mode; pt->namelen = namelen; if( pktlen ) { @@ -1187,7 +1215,8 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) static int -parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) +parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, + PACKET *pkt, int new_ctb ) { PKT_compressed *zd; @@ -1198,6 +1227,7 @@ parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) zd = pkt->pkt.compressed = m_alloc(sizeof *pkt->pkt.compressed ); zd->len = 0; /* not yet used */ zd->algorithm = iobuf_get_noeof(inp); + zd->new_ctb = new_ctb; zd->buf = inp; if( list_mode ) printf(":compressed packet: algo=%d\n", zd->algorithm); @@ -1206,13 +1236,15 @@ parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) static int -parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) +parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, + PACKET *pkt, int new_ctb ) { PKT_encrypted *ed; ed = pkt->pkt.encrypted = m_alloc(sizeof *pkt->pkt.encrypted ); ed->len = pktlen; ed->buf = NULL; + ed->new_ctb = new_ctb; if( pktlen && pktlen < 10 ) { log_error("packet(%d) too short\n", pkttype); skip_rest(inp, pktlen); diff --git a/g10/ringedit.c b/g10/ringedit.c index 42509759e..876247000 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -575,9 +575,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root ) kbpos->count=0; while( (rc=parse_packet(a, pkt)) != -1 ) { if( rc ) { /* ignore errors */ - if( rc == G10ERR_PUBKEY_ALGO ) - parse_pubkey_warning( pkt ); - else if( rc != G10ERR_UNKNOWN_PACKET ) { + if( rc != G10ERR_UNKNOWN_PACKET ) { log_error("read_keyblock: read error: %s\n", g10_errstr(rc) ); rc = G10ERR_INV_KEYRING; goto ready; @@ -640,9 +638,7 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) init_packet(pkt); while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) { if( rc ) { /* ignore errors */ - if( rc == G10ERR_PUBKEY_ALGO ) - parse_pubkey_warning( pkt ); - else if( rc != G10ERR_UNKNOWN_PACKET ) { + if( rc != G10ERR_UNKNOWN_PACKET ) { log_error("read_keyblock: read error: %s\n", g10_errstr(rc) ); rc = G10ERR_INV_KEYRING; goto ready; |