summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-07-02 21:31:46 +0200
committerWerner Koch <wk@gnupg.org>1998-07-02 21:31:46 +0200
commit97090f1293d43f67e36850c76aeba23760954757 (patch)
treeed63e6c5e37edeb337048cdcc84b471aa405f503 /g10
parenttextual changes (diff)
downloadgnupg2-97090f1293d43f67e36850c76aeba23760954757.tar.xz
gnupg2-97090f1293d43f67e36850c76aeba23760954757.zip
partly added creation of OP partial length headers
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog17
-rw-r--r--g10/armor.c6
-rw-r--r--g10/build-packet.c44
-rw-r--r--g10/cipher.c57
-rw-r--r--g10/filter.h3
-rw-r--r--g10/free-packet.c52
-rw-r--r--g10/import.c4
-rw-r--r--g10/keyid.c34
-rw-r--r--g10/packet.h4
-rw-r--r--g10/parse-packet.c170
-rw-r--r--g10/ringedit.c8
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;