summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--g10/ChangeLog11
-rw-r--r--g10/build-packet.c51
-rw-r--r--g10/free-packet.c8
-rw-r--r--g10/keydb.h4
-rw-r--r--g10/keyedit.c17
-rw-r--r--g10/keygen.c35
-rw-r--r--g10/mainproc.c53
-rw-r--r--g10/packet.h24
-rw-r--r--g10/parse-packet.c165
-rw-r--r--g10/passphrase.c58
-rw-r--r--g10/seckey-cert.c4
-rw-r--r--zlib/Makefile2
13 files changed, 307 insertions, 127 deletions
diff --git a/TODO b/TODO
index 3e39c0886..7eea85eeb 100644
--- a/TODO
+++ b/TODO
@@ -49,3 +49,5 @@
* add multi-user-id-sigs handling to import.c
+ * add tag 3 packet support to "-c"
+
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 2402a59c1..b4a74ab72 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,14 @@
+Fri May 1 12:44:39 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * packet.h (count): Chnaged s2k count from byte to u32.
+ * seckey-cert.c (do_check): Changed s2k algo 3 to 4, changed
+ reading of count.
+ * build-packet.c (do_secret_cert): ditto.
+ * parse-packet.c (parse_certificate): ditto.
+
+ * parse-packet.c (parse_symkeyenc): New.
+ * build-packet.c (do_symkey_enc): New.
+
Thu Apr 30 16:33:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* sign.c (clearsign_file): Fixed "Hash: " armor line.
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 8d897ca88..384957515 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -38,6 +38,7 @@ static int do_comment( IOBUF out, int ctb, PKT_comment *rem );
static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
static int do_public_cert( IOBUF out, int ctb, PKT_public_cert *pk );
static int do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *pk );
+static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
static u32 calc_plaintext( PKT_plaintext *pt );
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
@@ -85,6 +86,9 @@ build_packet( IOBUF out, PACKET *pkt )
case PKT_SECRET_CERT:
rc = do_secret_cert( out, ctb, pkt->pkt.secret_cert );
break;
+ case PKT_SYMKEY_ENC:
+ rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
+ break;
case PKT_PUBKEY_ENC:
rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
break;
@@ -129,6 +133,7 @@ calc_packet_length( PACKET *pkt )
case PKT_COMMENT:
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
+ case PKT_SYMKEY_ENC:
case PKT_PUBKEY_ENC:
case PKT_ENCRYPTED:
case PKT_SIGNATURE:
@@ -270,13 +275,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
if( skc->is_protected ) {
iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo );
- iobuf_put(a, skc->protect.s2k );
- iobuf_put(a, skc->protect.hash );
- if( skc->protect.s2k == 1
- || skc->protect.s2k == 3 )
- iobuf_write(a, skc->protect.salt, 8 );
- if( skc->protect.s2k == 3 )
- iobuf_put(a, skc->protect.count );
+ iobuf_put(a, skc->protect.s2k.mode );
+ iobuf_put(a, skc->protect.s2k.hash_algo );
+ if( skc->protect.s2k.mode == 1
+ || skc->protect.s2k.mode == 4 )
+ iobuf_write(a, skc->protect.s2k.salt, 8 );
+ if( skc->protect.s2k.mode == 4 )
+ write_32(a, skc->protect.s2k.count );
iobuf_write(a, skc->protect.iv, 8 );
}
else
@@ -315,6 +320,37 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
}
static int
+do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
+{
+ int rc = 0;
+ IOBUF a = iobuf_temp();
+
+ assert( enc->version == 4 );
+ switch( enc->s2k.mode ) {
+ case 0: case 1: case 4: break;
+ default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
+ }
+ iobuf_put( a, enc->version );
+ iobuf_put( a, enc->cipher_algo );
+ iobuf_put( a, enc->s2k.mode );
+ iobuf_put( a, enc->s2k.hash_algo );
+ if( enc->s2k.mode == 1 || enc->s2k.mode == 4 ) {
+ iobuf_write(a, enc->s2k.salt, 8 );
+ if( enc->s2k.mode == 4 )
+ write_32(a, enc->s2k.count);
+ }
+ if( enc->seskeylen )
+ iobuf_write(a, enc->seskey, enc->seskeylen );
+
+ write_header(out, ctb, iobuf_get_temp_length(a) );
+ if( iobuf_write_temp( out, a ) )
+ rc = G10ERR_WRITE_FILE;
+
+ iobuf_close(a);
+ return rc;
+}
+
+static int
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
{
int rc = 0;
@@ -348,7 +384,6 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
-
static u32
calc_plaintext( PKT_plaintext *pt )
{
diff --git a/g10/free-packet.c b/g10/free-packet.c
index 09971c4cf..d998ce29d 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -31,6 +31,11 @@
#include "cipher.h"
#include "memory.h"
+void
+free_symkey_enc( PKT_symkey_enc *enc )
+{
+ m_free(enc);
+}
void
free_pubkey_enc( PKT_pubkey_enc *enc )
@@ -277,6 +282,9 @@ free_packet( PACKET *pkt )
case PKT_PUBKEY_ENC:
free_pubkey_enc( pkt->pkt.pubkey_enc );
break;
+ case PKT_SYMKEY_ENC:
+ free_symkey_enc( pkt->pkt.symkey_enc );
+ break;
case PKT_PUBLIC_CERT:
free_public_cert( pkt->pkt.public_cert );
break;
diff --git a/g10/keydb.h b/g10/keydb.h
index d1a7e4571..96dc652df 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -97,8 +97,8 @@ int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list,
/*-- passphrase.h --*/
void set_passphrase_fd( int fd );
int get_passphrase_fd(void);
-DEK *get_passphrase_hash( u32 *keyid, char *text, byte *salt );
-int make_dek_from_passphrase( DEK *dek, int mode, byte *salt );
+DEK *get_passphrase_hash( u32 *keyid, char *text, STRING2KEY *s2k );
+int make_dek_from_passphrase( DEK *dek, int mode, STRING2KEY *s2k );
/*-- getkey.c --*/
void add_keyring( const char *name );
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 634baa1c6..37824d84d 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -624,15 +624,16 @@ change_passphrase( const char *username )
if( rc )
tty_printf("Can't edit this key: %s\n", g10_errstr(rc));
else {
- DEK *dek = m_alloc_secure( sizeof *dek + 8 );
- byte *salt = (byte*)dek + sizeof( *dek );
+ DEK *dek = m_alloc_secure( sizeof *dek );
+ STRING2KEY *s2k = m_alloc_secure( sizeof *s2k );
tty_printf( "Enter the new passphrase for this secret key.\n\n" );
for(;;) {
dek->algo = CIPHER_ALGO_BLOWFISH;
- randomize_buffer(salt, 8, 1);
- rc = make_dek_from_passphrase( dek , 2, salt );
+ s2k->mode = 1;
+ s2k->hash_algo = DIGEST_ALGO_RMD160;
+ rc = make_dek_from_passphrase( dek , 2, s2k );
if( rc == -1 ) {
rc = 0;
tty_printf( "You don't want a passphrase -"
@@ -653,11 +654,8 @@ change_passphrase( const char *username )
break;
}
else { /* okay */
- skc->protect.algo = CIPHER_ALGO_BLOWFISH;
- skc->protect.s2k = 1;
- skc->protect.hash = DIGEST_ALGO_RMD160;
- memcpy(skc->protect.salt, salt, 8);
- randomize_buffer(skc->protect.iv, 8, 1);
+ skc->protect.algo = dek->algo;
+ skc->protect.s2k = *s2k;
rc = protect_secret_key( skc, dek );
if( rc )
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
@@ -666,6 +664,7 @@ change_passphrase( const char *username )
break;
}
}
+ m_free(s2k);
m_free(dek);
}
diff --git a/g10/keygen.c b/g10/keygen.c
index a4addfc25..1d3f9004e 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -95,7 +95,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
static int
gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
- byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
+ STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days )
{
int rc;
int i;
@@ -128,11 +128,8 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
*ret_skc = copy_secret_cert( NULL, skc );
if( dek ) {
- skc->protect.algo = CIPHER_ALGO_BLOWFISH;
- skc->protect.s2k = 1;
- skc->protect.hash = DIGEST_ALGO_RMD160;
- memcpy(skc->protect.salt, salt, 8);
- randomize_buffer(skc->protect.iv, 8, 1);
+ skc->protect.algo = dek->algo;
+ skc->protect.s2k = *s2k;
rc = protect_secret_key( skc, dek );
if( rc ) {
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
@@ -148,7 +145,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
add_kbnode(pub_root, new_kbnode( pkt ));
/* don't know whether it makes sense to have the factors, so for now
- * we store them in the secret keyring (but they are secret) */
+ * we store them in the secret keyring (but they are not secret) */
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_SECRET_CERT;
pkt->pkt.secret_cert = skc;
@@ -165,7 +162,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
#ifdef ENABLE_RSA_KEYGEN
static int
gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
- byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
+ STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days )
{
int rc;
PACKET *pkt;
@@ -229,7 +226,7 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
static int
gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
- byte *salt, PKT_secret_cert **ret_skc, u16 valid_days )
+ STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days )
{
return G10ERR_GENERAL;
}
@@ -279,7 +276,7 @@ generate_keypair()
KBNODE sec_root = NULL;
PKT_secret_cert *skc = NULL;
DEK *dek = NULL;
- byte *salt;
+ STRING2KEY *s2k;
int rc;
int algo;
const char *algo_name;
@@ -530,14 +527,16 @@ generate_keypair()
tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
- dek = m_alloc_secure( sizeof *dek + 8 );
- salt = (byte*)dek + sizeof *dek;
+ dek = m_alloc_secure( sizeof *dek );
+ s2k = m_alloc_secure( sizeof *s2k );
for(;;) {
dek->algo = CIPHER_ALGO_BLOWFISH;
- randomize_buffer(salt, 8, 1);
- rc = make_dek_from_passphrase( dek , 2, salt );
+ s2k->mode = 1;
+ s2k->hash_algo = DIGESTA_ALGO_RMD160;
+ rc = make_dek_from_passphrase( dek , 2, s2k );
if( rc == -1 ) {
m_free(dek); dek = NULL;
+ m_free(s2k); s2k = NULL;
tty_printf(_(
"You don't want a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at any time,\n"
@@ -549,6 +548,7 @@ generate_keypair()
}
else if( rc ) {
m_free(dek); dek = NULL;
+ m_free(s2k); s2k = NULL;
m_free(uid);
log_error("Error getting the passphrase: %s\n", g10_errstr(rc) );
return;
@@ -581,13 +581,13 @@ generate_keypair()
"number generator a better chance to gain enough entropy.\n") );
if( algo == PUBKEY_ALGO_ELGAMAL )
- rc = gen_elg(nbits, pub_root, sec_root, dek, salt, &skc, valid_days );
+ rc = gen_elg(nbits, pub_root, sec_root, dek, s2k, &skc, valid_days );
#ifdef ENABLE_RSA_KEYGEN
else if( algo == PUBKEY_ALGO_RSA )
- rc = gen_rsa(nbits, pub_root, sec_root, dek, salt, &skc, valid_days );
+ rc = gen_rsa(nbits, pub_root, sec_root, dek, s2k, &skc, valid_days );
#endif
else if( algo == PUBKEY_ALGO_DSA )
- rc = gen_dsa(nbits, pub_root, sec_root, dek, salt, &skc, valid_days );
+ rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, &skc, valid_days );
else
BUG();
if( !rc ) {
@@ -667,6 +667,7 @@ generate_keypair()
free_secret_cert(skc);
m_free(uid);
m_free(dek);
+ m_free(s2k);
m_free(pub_fname);
m_free(sec_fname);
}
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 22af3561d..7e0ba18b7 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -50,7 +50,7 @@ typedef struct {
int encrypt_only; /* process only encrytion messages */
STRLIST signed_data;
DEK *dek;
- int last_was_pubkey_enc;
+ int last_was_session_key;
KBNODE list; /* the current list of packets */
int have_data;
IOBUF iobuf; /* used to get the filename etc. */
@@ -146,12 +146,47 @@ add_signature( CTX c, PACKET *pkt )
static void
+proc_symkey_enc( CTX c, PACKET *pkt )
+{
+ /* FIXME: NOT READY */
+ #if 0
+ PKT_symkey_enc *enc;
+ int result = 0;
+
+ c->last_was_session_key = 1;
+ enc = pkt->pkt.symkey_enc;
+ if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
+ || enc->pubkey_algo == PUBKEY_ALGO_DSA
+ || enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ m_free(c->dek ); /* paranoid: delete a pending DEK */
+ c->dek = m_alloc_secure( sizeof *c->dek );
+ if( (result = get_session_key( enc, c->dek )) ) {
+ /* error: delete the DEK */
+ m_free(c->dek); c->dek = NULL;
+ }
+ }
+ else
+ result = G10ERR_PUBKEY_ALGO;
+
+ if( result == -1 )
+ ;
+ else if( !result ) {
+ if( opt.verbose > 1 )
+ log_info( "pubkey_enc packet: Good DEK\n" );
+ }
+ else
+ log_error( "pubkey_enc packet: %s\n", g10_errstr(result));
+ free_packet(pkt);
+ #endif
+}
+
+static void
proc_pubkey_enc( CTX c, PACKET *pkt )
{
PKT_pubkey_enc *enc;
int result = 0;
- c->last_was_pubkey_enc = 1;
+ c->last_was_session_key = 1;
enc = pkt->pkt.pubkey_enc;
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
@@ -179,15 +214,14 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
}
-
static void
proc_encrypted( CTX c, PACKET *pkt )
{
int result = 0;
/*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
- if( !c->dek && !c->last_was_pubkey_enc ) {
- /* assume this is conventional encrypted data */
+ if( !c->dek && !c->last_was_session_key ) {
+ /* assume this is old conventional encrypted data */
c->dek = m_alloc_secure( sizeof *c->dek );
c->dek->algo = opt.def_cipher_algo;
result = make_dek_from_passphrase( c->dek, 0, NULL );
@@ -207,7 +241,7 @@ proc_encrypted( CTX c, PACKET *pkt )
log_error("encryption failed: %s\n", g10_errstr(result));
}
free_packet(pkt);
- c->last_was_pubkey_enc = 0;
+ c->last_was_session_key = 0;
}
@@ -232,7 +266,7 @@ proc_plaintext( CTX c, PACKET *pkt )
if( rc )
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
free_packet(pkt);
- c->last_was_pubkey_enc = 0;
+ c->last_was_session_key = 0;
}
@@ -264,7 +298,7 @@ proc_compressed( CTX c, PACKET *pkt )
if( rc )
log_error("uncompressing failed: %s\n", g10_errstr(rc));
free_packet(pkt);
- c->last_was_pubkey_enc = 0;
+ c->last_was_session_key = 0;
}
@@ -606,6 +640,7 @@ do_proc_packets( CTX c, IOBUF a )
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
case PKT_USER_ID:
+ case PKT_SYMKEY_ENC:
case PKT_PUBKEY_ENC:
case PKT_ENCRYPTED:
rc = G10ERR_UNEXPECTED;
@@ -625,6 +660,7 @@ do_proc_packets( CTX c, IOBUF a )
rc = G10ERR_UNEXPECTED;
goto leave;
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
+ case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
@@ -648,6 +684,7 @@ do_proc_packets( CTX c, IOBUF a )
case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break;
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
+ case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
diff --git a/g10/packet.h b/g10/packet.h
index 2393964c2..fb8ac20d8 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -37,7 +37,7 @@ typedef enum {
PKT_NONE =0,
PKT_PUBKEY_ENC =1, /* public key encrypted packet */
PKT_SIGNATURE =2, /* secret key encrypted packet */
- PKT_SESSION_KEY =3, /* session key packet (OpenPGP)*/
+ PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/
PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/
PKT_SECRET_CERT =5, /* secret key certificate */
PKT_PUBLIC_CERT =6, /* public key certificate */
@@ -55,6 +55,21 @@ typedef enum {
typedef struct packet_struct PACKET;
typedef struct {
+ byte mode;
+ byte hash_algo;
+ byte salt[8];
+ u32 count;
+} STRING2KEY;
+
+typedef struct {
+ byte version;
+ byte cipher_algo; /* cipher algorithm used */
+ STRING2KEY s2k;
+ byte seskeylen; /* keylength in byte or 0 for no seskey */
+ byte seskey[1];
+} PKT_symkey_enc;
+
+typedef struct {
u32 keyid[2]; /* 64 bit keyid */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
@@ -130,10 +145,7 @@ typedef struct {
/* and should never be passed to a mpi_xxx() */
struct {
byte algo; /* cipher used to protect the secret information*/
- byte s2k;
- byte hash;
- byte salt[8];
- byte count;
+ STRING2KEY s2k;
byte iv[8]; /* initialization vector for CFB mode */
} protect;
union {
@@ -180,6 +192,7 @@ struct packet_struct {
pkttype_t pkttype;
union {
void *generic;
+ PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */
PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */
PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
PKT_signature *signature; /* PKT_SIGNATURE */
@@ -217,6 +230,7 @@ u32 calc_packet_length( PACKET *pkt );
void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
/*-- free-packet.c --*/
+void free_symkey_enc( PKT_symkey_enc *enc );
void free_pubkey_enc( PKT_pubkey_enc *enc );
void free_seckey_enc( PKT_signature *enc );
int digest_algo_from_sig( PKT_signature *sig );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index eb56b09ae..f7913d3f9 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -42,7 +42,9 @@ 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 int parse_publickey( IOBUF inp, int pkttype, unsigned long 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,
PACKET *packet );
static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_signature *sig );
@@ -284,8 +286,11 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
pkt->pkt.secret_cert = m_alloc_clear(sizeof *pkt->pkt.secret_cert );
rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
break;
+ case PKT_SYMKEY_ENC:
+ rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
+ break;
case PKT_PUBKEY_ENC:
- rc = parse_publickey(inp, pkttype, pktlen, pkt );
+ rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
break;
case PKT_SIGNATURE:
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
@@ -407,7 +412,83 @@ skip_rest( IOBUF inp, unsigned long pktlen )
static int
-parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
+{
+ PKT_symkey_enc *k;
+ int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
+
+ if( pktlen < 4 ) {
+ log_error("packet(%d) too short\n", pkttype);
+ goto leave;
+ }
+ version = iobuf_get_noeof(inp); pktlen--;
+ if( k->version != 4 ) {
+ log_error("packet(%d) with unknown version %d\n", pkttype, version);
+ goto leave;
+ }
+ if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
+ log_error("packet(%d) too large\n", pkttype);
+ goto leave;
+ }
+ cipher_algo = iobuf_get_noeof(inp); pktlen--;
+ s2kmode = iobuf_get_noeof(inp); pktlen--;
+ hash_algo = iobuf_get_noeof(inp); pktlen--;
+ switch( s2kmode ) {
+ case 0: /* simple s2k */
+ minlen = 0;
+ break;
+ case 1: /* salted s2k */
+ minlen = 8;
+ break;
+ case 4: /* iterated+salted s2k */
+ minlen = 12;
+ break;
+ default:
+ log_error("unknown S2K %d\n", s2kmode );
+ goto leave;
+ }
+ if( minlen > pktlen ) {
+ log_error("packet with S2K %d too short\n", s2kmode );
+ goto leave;
+ }
+ seskeylen = pktlen - minlen;
+ k = packet->pkt.symkey_enc = m_alloc_clear( sizeof *packet->pkt.symkey_enc
+ + seskeylen - 1 );
+ k->version = version;
+ k->cipher_algo = cipher_algo;
+ k->s2k.mode = s2kmode;
+ k->s2k.hash_algo = hash_algo;
+ if( s2kmode == 1 || s2kmode == 4 ) {
+ for(i=0; i < 8 && pktlen; i++, pktlen-- )
+ k->s2k.salt[i] = iobuf_get_noeof(inp);
+ }
+ if( s2kmode == 4 ) {
+ k->s2k.count = read_32(inp); pktlen -= 4;
+ }
+ k->seskeylen = seskeylen;
+ for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
+ k->seskey[i] = iobuf_get_noeof(inp);
+ assert( !pktlen );
+
+ if( list_mode ) {
+ printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
+ version, cipher_algo, s2kmode, hash_algo);
+ if( s2kmode == 1 || s2kmode == 4 ) {
+ printf("\tsalt ");
+ for(i=0; i < 8; i++ )
+ printf("%02x", k->s2k.salt[i]);
+ if( s2kmode == 4 )
+ printf(", count %lu\n", (ulong)k->s2k.count );
+ }
+ }
+
+ leave:
+ skip_rest(inp, pktlen);
+ return 0;
+}
+
+static int
+parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
unsigned n;
PKT_pubkey_enc *k;
@@ -426,7 +507,7 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
k->keyid[1] = read_32(inp); pktlen -= 4;
k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
if( list_mode )
- printf(":public key encoded packet: version %d, keyid %08lX%08lX\n",
+ printf(":pubkey enc packet: version %d, keyid %08lX%08lX\n",
k->version, (ulong)k->keyid[0], (ulong)k->keyid[1]);
if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
n = pktlen;
@@ -845,34 +926,34 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) {
cert->is_protected = 1;
- cert->protect.count = 0;
+ cert->protect.s2k.count = 0;
if( cert->protect.algo == 255 ) {
if( pktlen < 3 ) {
rc = G10ERR_INVALID_PACKET;
goto leave;
}
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
- cert->protect.s2k = iobuf_get_noeof(inp); pktlen--;
- cert->protect.hash = iobuf_get_noeof(inp); pktlen--;
- switch( cert->protect.s2k ) {
+ cert->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
+ cert->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
+ switch( cert->protect.s2k.mode ) {
case 1:
- case 3:
+ case 4:
for(i=0; i < 8 && pktlen; i++, pktlen-- )
temp[i] = iobuf_get_noeof(inp);
- memcpy(cert->protect.salt, temp, 8 );
+ memcpy(cert->protect.s2k.salt, temp, 8 );
break;
}
- switch( cert->protect.s2k ) {
+ switch( cert->protect.s2k.mode ) {
case 0: if( list_mode ) printf( "\tsimple S2K" );
break;
case 1: if( list_mode ) printf( "\tsalted S2K" );
break;
- case 3: if( list_mode ) printf( "\titer+salt S2K" );
+ case 4: if( list_mode ) printf( "\titer+salt S2K" );
break;
default:
if( list_mode )
printf( "\tunknown S2K %d\n",
- cert->protect.s2k );
+ cert->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET;
goto leave;
}
@@ -880,23 +961,23 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode ) {
printf(", algo: %d, hash: %d",
cert->protect.algo,
- cert->protect.hash );
- if( cert->protect.s2k == 1
- || cert->protect.s2k == 3 ) {
+ cert->protect.s2k.hash_algo );
+ if( cert->protect.s2k.mode == 1
+ || cert->protect.s2k.mode == 4 ) {
printf(", salt: ");
for(i=0; i < 8; i++ )
- printf("%02x", cert->protect.salt[i]);
+ printf("%02x", cert->protect.s2k.salt[i]);
}
putchar('\n');
}
- if( cert->protect.s2k == 3 ) {
- if( !pktlen ) {
+ if( cert->protect.s2k.mode == 4 ) {
+ if( pktlen < 4 ) {
rc = G10ERR_INVALID_PACKET;
goto leave;
}
- cert->protect.count = iobuf_get_noeof(inp);
- pktlen--;
+ cert->protect.s2k.count = read_32(inp);
+ pktlen -= 4;
}
}
@@ -905,9 +986,9 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
printf( "\tprotect algo: %d\n",
cert->protect.algo);
/* old version, we don't have a S2K, so we fake one */
- cert->protect.s2k = 0;
+ cert->protect.s2k.mode = 0;
/* We need this kludge to cope with old GNUPG versions */
- cert->protect.hash =
+ cert->protect.s2k.hash_algo =
cert->protect.algo == CIPHER_ALGO_BLOWFISH160?
DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5;
}
@@ -981,33 +1062,34 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) {
cert->is_protected = 1;
- cert->protect.count = 0;
+ cert->protect.s2k.count = 0;
if( cert->protect.algo == 255 ) {
if( pktlen < 3 ) {
rc = G10ERR_INVALID_PACKET;
goto leave;
}
cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
- cert->protect.s2k = iobuf_get_noeof(inp); pktlen--;
- cert->protect.hash = iobuf_get_noeof(inp); pktlen--;
- switch( cert->protect.s2k ) {
+ cert->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
+ cert->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
+ switch( cert->protect.s2k.mode ) {
case 1:
- case 3:
+ case 4:
for(i=0; i < 8 && pktlen; i++, pktlen-- )
temp[i] = iobuf_get_noeof(inp);
- memcpy(cert->protect.salt, temp, 8 );
+ memcpy(cert->protect.s2k.salt, temp, 8 );
break;
}
- switch( cert->protect.s2k ) {
+ switch( cert->protect.s2k.mode ) {
case 0: if( list_mode ) printf( "\tsimple S2K" );
break;
case 1: if( list_mode ) printf( "\tsalted S2K" );
break;
- case 3: if( list_mode ) printf( "\titer+salt S2K" );
+ case 4: if( list_mode ) printf( "\titer+salt S2K" );
break;
default:
if( list_mode )
- printf( "\tunknown S2K %d\n", cert->protect.s2k );
+ printf( "\tunknown S2K %d\n",
+ cert->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET;
goto leave;
}
@@ -1015,22 +1097,23 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode ) {
printf(", algo: %d, hash: %d",
cert->protect.algo,
- cert->protect.hash );
- if( cert->protect.s2k == 1 || cert->protect.s2k == 3 ){
+ cert->protect.s2k.hash_algo );
+ if( cert->protect.s2k.mode == 1
+ || cert->protect.s2k.mode == 4 ){
printf(", salt: ");
for(i=0; i < 8; i++ )
- printf("%02x", cert->protect.salt[i]);
+ printf("%02x", cert->protect.s2k.salt[i]);
}
putchar('\n');
}
- if( cert->protect.s2k == 3 ) {
- if( !pktlen ) {
+ if( cert->protect.s2k.mode == 4 ) {
+ if( pktlen < 4 ) {
rc = G10ERR_INVALID_PACKET;
goto leave;
}
- cert->protect.count = iobuf_get_noeof(inp);
- pktlen--;
+ cert->protect.s2k.count = read_32(inp);
+ pktlen -= 4;
}
}
@@ -1038,8 +1121,8 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode )
printf( "\tprotect algo: %d\n", cert->protect.algo);
/* old version, we don't have a S2K, so we fake one */
- cert->protect.s2k = 0;
- cert->protect.hash = DIGEST_ALGO_MD5;
+ cert->protect.s2k.mode = 0;
+ cert->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
}
if( pktlen < 8 ) {
rc = G10ERR_INVALID_PACKET;
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 46ff83163..5ae3966ac 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -33,7 +33,7 @@
static int pwfd = -1;
-static int hash_passphrase( DEK *dek, char *pw, byte *salt );
+static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k );
void
set_passphrase_fd( int fd )
@@ -107,12 +107,11 @@ get_passphrase_hash( u32 *keyid, char *text, byte *salt )
/****************
* This function is used to construct a DEK from a user input.
- * It uses the default CIPHER. If salt is != NULL, include these
- * 8 bytes in the hash.
+ * It uses the default CIPHER.
* Returns: 0 = okay, -1 No passphrase entered, > 0 error
*/
int
-make_dek_from_passphrase( DEK *dek, int mode, byte *salt )
+make_dek_from_passphrase( DEK *dek, int mode, STRING2KEY *s2k )
{
char *pw, *pw2;
int rc=0;
@@ -132,45 +131,36 @@ make_dek_from_passphrase( DEK *dek, int mode, byte *salt )
if( !*pw )
rc = -1;
else
- rc = hash_passphrase( dek, pw, salt );
+ hash_passphrase( dek, pw, s2k, mode==2 );
m_free(pw);
return rc;
}
-static int
-hash_passphrase( DEK *dek, char *pw, byte *salt )
+/****************
+ * Hash a passphrase using the supplied s2k. If create is true, create
+ * a new salt or whatelse must be filled into the s2k for a new key.
+ * always needs: dek->algo, s2k->mode, s2k->hash_algo.
+ */
+static void
+hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
{
+ MD_HANDLE md;
int rc = 0;
+ assert( s2k->hash_algo );
dek->keylen = 0;
- if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
- MD_HANDLE md;
-
- md = md_open(DIGEST_ALGO_RMD160, 1);
- if( salt )
- md_write( md, salt, 8 );
- md_write( md, pw, strlen(pw) );
- md_final( md );
- dek->keylen = 20;
- memcpy( dek->key, md_read(md,0), dek->keylen );
- md_close(md);
- }
- else if( dek->algo == CIPHER_ALGO_CAST ) {
- MD_HANDLE md;
-
- md = md_open(DIGEST_ALGO_SHA1, 1);
- if( salt )
- md_write( md, salt, 8 );
- md_write( md, pw, strlen(pw) );
- md_final( md );
- /* use only the low 128 bits */
- dek->keylen = 16;
- memcpy( dek->key, md_read(md,0), dek->keylen );
- md_close(md);
+ md = md_open( s2k->hash_algo, 1);
+ if( s2k->mode == 1 || s2k->mode == 4 ) {
+ if( create )
+ randomize_buffer(&s2k->salt, 8, 1);
+ md_write( md, s2k->salt, 8 );
}
- else
- rc = G10ERR_UNSUPPORTED;
- return rc;
+ md_write( md, pw, strlen(pw) );
+ md_final( md );
+ dek->keylen = cipher_get_keylen( dek->algo );
+ assert(dek->keylen > 0 && dek->keylen < DIM(dek->key) );
+ memcpy( dek->key, md_read(md,0), dek->keylen );
+ md_close(md);
}
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index d95d12380..340551cb2 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -54,9 +54,9 @@ do_check( PKT_secret_cert *cert )
case CIPHER_ALGO_BLOWFISH:
case CIPHER_ALGO_CAST:
keyid_from_skc( cert, keyid );
- if( cert->protect.s2k == 1 || cert->protect.s2k == 3 )
+ if( cert->protect.s2k.mode == 1 || cert->protect.s2k.mode == 4 )
dek = get_passphrase_hash( keyid, NULL,
- cert->protect.salt );
+ cert->protect.s2k.salt );
else
dek = get_passphrase_hash( keyid, NULL, NULL );
diff --git a/zlib/Makefile b/zlib/Makefile
index 404a76d02..a060f7842 100644
--- a/zlib/Makefile
+++ b/zlib/Makefile
@@ -93,7 +93,7 @@ POSUB = po
RANLIB = ranlib
USE_INCLUDED_LIBINTL = yes
USE_NLS = yes
-VERSION = 0.2.16
+VERSION = 0.2.16a
ZLIBS =
l =