1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Aenderungen in der Eifel

This commit is contained in:
Werner Koch 1998-05-03 15:42:08 +00:00
parent 45f1328259
commit 823d39fd55
13 changed files with 307 additions and 127 deletions

2
TODO
View File

@ -49,3 +49,5 @@
* add multi-user-id-sigs handling to import.c * add multi-user-id-sigs handling to import.c
* add tag 3 packet support to "-c"

View File

@ -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) Thu Apr 30 16:33:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* sign.c (clearsign_file): Fixed "Hash: " armor line. * sign.c (clearsign_file): Fixed "Hash: " armor line.

View File

@ -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_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_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_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 int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
static u32 calc_plaintext( PKT_plaintext *pt ); static u32 calc_plaintext( PKT_plaintext *pt );
static int do_plaintext( IOBUF out, int ctb, 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: case PKT_SECRET_CERT:
rc = do_secret_cert( out, ctb, pkt->pkt.secret_cert ); rc = do_secret_cert( out, ctb, pkt->pkt.secret_cert );
break; break;
case PKT_SYMKEY_ENC:
rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
break;
case PKT_PUBKEY_ENC: case PKT_PUBKEY_ENC:
rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc ); rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
break; break;
@ -129,6 +133,7 @@ calc_packet_length( PACKET *pkt )
case PKT_COMMENT: case PKT_COMMENT:
case PKT_PUBLIC_CERT: case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT: case PKT_SECRET_CERT:
case PKT_SYMKEY_ENC:
case PKT_PUBKEY_ENC: case PKT_PUBKEY_ENC:
case PKT_ENCRYPTED: case PKT_ENCRYPTED:
case PKT_SIGNATURE: case PKT_SIGNATURE:
@ -270,13 +275,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
if( skc->is_protected ) { if( skc->is_protected ) {
iobuf_put(a, 0xff ); iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo ); iobuf_put(a, skc->protect.algo );
iobuf_put(a, skc->protect.s2k ); iobuf_put(a, skc->protect.s2k.mode );
iobuf_put(a, skc->protect.hash ); iobuf_put(a, skc->protect.s2k.hash_algo );
if( skc->protect.s2k == 1 if( skc->protect.s2k.mode == 1
|| skc->protect.s2k == 3 ) || skc->protect.s2k.mode == 4 )
iobuf_write(a, skc->protect.salt, 8 ); iobuf_write(a, skc->protect.s2k.salt, 8 );
if( skc->protect.s2k == 3 ) if( skc->protect.s2k.mode == 4 )
iobuf_put(a, skc->protect.count ); write_32(a, skc->protect.s2k.count );
iobuf_write(a, skc->protect.iv, 8 ); iobuf_write(a, skc->protect.iv, 8 );
} }
else else
@ -314,6 +319,37 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
return rc; return rc;
} }
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 static int
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
{ {
@ -348,7 +384,6 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
static u32 static u32
calc_plaintext( PKT_plaintext *pt ) calc_plaintext( PKT_plaintext *pt )
{ {

View File

@ -31,6 +31,11 @@
#include "cipher.h" #include "cipher.h"
#include "memory.h" #include "memory.h"
void
free_symkey_enc( PKT_symkey_enc *enc )
{
m_free(enc);
}
void void
free_pubkey_enc( PKT_pubkey_enc *enc ) free_pubkey_enc( PKT_pubkey_enc *enc )
@ -277,6 +282,9 @@ free_packet( PACKET *pkt )
case PKT_PUBKEY_ENC: case PKT_PUBKEY_ENC:
free_pubkey_enc( pkt->pkt.pubkey_enc ); free_pubkey_enc( pkt->pkt.pubkey_enc );
break; break;
case PKT_SYMKEY_ENC:
free_symkey_enc( pkt->pkt.symkey_enc );
break;
case PKT_PUBLIC_CERT: case PKT_PUBLIC_CERT:
free_public_cert( pkt->pkt.public_cert ); free_public_cert( pkt->pkt.public_cert );
break; break;

View File

@ -97,8 +97,8 @@ int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list,
/*-- passphrase.h --*/ /*-- passphrase.h --*/
void set_passphrase_fd( int fd ); void set_passphrase_fd( int fd );
int get_passphrase_fd(void); int get_passphrase_fd(void);
DEK *get_passphrase_hash( u32 *keyid, char *text, byte *salt ); DEK *get_passphrase_hash( u32 *keyid, char *text, STRING2KEY *s2k );
int make_dek_from_passphrase( DEK *dek, int mode, byte *salt ); int make_dek_from_passphrase( DEK *dek, int mode, STRING2KEY *s2k );
/*-- getkey.c --*/ /*-- getkey.c --*/
void add_keyring( const char *name ); void add_keyring( const char *name );

View File

@ -624,15 +624,16 @@ change_passphrase( const char *username )
if( rc ) if( rc )
tty_printf("Can't edit this key: %s\n", g10_errstr(rc)); tty_printf("Can't edit this key: %s\n", g10_errstr(rc));
else { else {
DEK *dek = m_alloc_secure( sizeof *dek + 8 ); DEK *dek = m_alloc_secure( sizeof *dek );
byte *salt = (byte*)dek + sizeof( *dek ); STRING2KEY *s2k = m_alloc_secure( sizeof *s2k );
tty_printf( "Enter the new passphrase for this secret key.\n\n" ); tty_printf( "Enter the new passphrase for this secret key.\n\n" );
for(;;) { for(;;) {
dek->algo = CIPHER_ALGO_BLOWFISH; dek->algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer(salt, 8, 1); s2k->mode = 1;
rc = make_dek_from_passphrase( dek , 2, salt ); s2k->hash_algo = DIGEST_ALGO_RMD160;
rc = make_dek_from_passphrase( dek , 2, s2k );
if( rc == -1 ) { if( rc == -1 ) {
rc = 0; rc = 0;
tty_printf( "You don't want a passphrase -" tty_printf( "You don't want a passphrase -"
@ -653,11 +654,8 @@ change_passphrase( const char *username )
break; break;
} }
else { /* okay */ else { /* okay */
skc->protect.algo = CIPHER_ALGO_BLOWFISH; skc->protect.algo = dek->algo;
skc->protect.s2k = 1; skc->protect.s2k = *s2k;
skc->protect.hash = DIGEST_ALGO_RMD160;
memcpy(skc->protect.salt, salt, 8);
randomize_buffer(skc->protect.iv, 8, 1);
rc = protect_secret_key( skc, dek ); rc = protect_secret_key( skc, dek );
if( rc ) if( rc )
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) ); log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
@ -666,6 +664,7 @@ change_passphrase( const char *username )
break; break;
} }
} }
m_free(s2k);
m_free(dek); m_free(dek);
} }

View File

@ -95,7 +95,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
static int static int
gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, 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 rc;
int i; 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 ); *ret_skc = copy_secret_cert( NULL, skc );
if( dek ) { if( dek ) {
skc->protect.algo = CIPHER_ALGO_BLOWFISH; skc->protect.algo = dek->algo;
skc->protect.s2k = 1; skc->protect.s2k = *s2k;
skc->protect.hash = DIGEST_ALGO_RMD160;
memcpy(skc->protect.salt, salt, 8);
randomize_buffer(skc->protect.iv, 8, 1);
rc = protect_secret_key( skc, dek ); rc = protect_secret_key( skc, dek );
if( rc ) { if( rc ) {
log_error("protect_secret_key failed: %s\n", g10_errstr(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 )); add_kbnode(pub_root, new_kbnode( pkt ));
/* don't know whether it makes sense to have the factors, so for now /* 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 = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_SECRET_CERT; pkt->pkttype = PKT_SECRET_CERT;
pkt->pkt.secret_cert = skc; 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 #ifdef ENABLE_RSA_KEYGEN
static int static int
gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, 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; int rc;
PACKET *pkt; PACKET *pkt;
@ -229,7 +226,7 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
static int static int
gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, 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; return G10ERR_GENERAL;
} }
@ -279,7 +276,7 @@ generate_keypair()
KBNODE sec_root = NULL; KBNODE sec_root = NULL;
PKT_secret_cert *skc = NULL; PKT_secret_cert *skc = NULL;
DEK *dek = NULL; DEK *dek = NULL;
byte *salt; STRING2KEY *s2k;
int rc; int rc;
int algo; int algo;
const char *algo_name; const char *algo_name;
@ -530,14 +527,16 @@ generate_keypair()
tty_printf(_("You need a Passphrase to protect your secret key.\n\n") ); tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
dek = m_alloc_secure( sizeof *dek + 8 ); dek = m_alloc_secure( sizeof *dek );
salt = (byte*)dek + sizeof *dek; s2k = m_alloc_secure( sizeof *s2k );
for(;;) { for(;;) {
dek->algo = CIPHER_ALGO_BLOWFISH; dek->algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer(salt, 8, 1); s2k->mode = 1;
rc = make_dek_from_passphrase( dek , 2, salt ); s2k->hash_algo = DIGESTA_ALGO_RMD160;
rc = make_dek_from_passphrase( dek , 2, s2k );
if( rc == -1 ) { if( rc == -1 ) {
m_free(dek); dek = NULL; m_free(dek); dek = NULL;
m_free(s2k); s2k = NULL;
tty_printf(_( tty_printf(_(
"You don't want a passphrase - this is probably a *bad* idea!\n" "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" "I will do it anyway. You can change your passphrase at any time,\n"
@ -549,6 +548,7 @@ generate_keypair()
} }
else if( rc ) { else if( rc ) {
m_free(dek); dek = NULL; m_free(dek); dek = NULL;
m_free(s2k); s2k = NULL;
m_free(uid); m_free(uid);
log_error("Error getting the passphrase: %s\n", g10_errstr(rc) ); log_error("Error getting the passphrase: %s\n", g10_errstr(rc) );
return; return;
@ -581,13 +581,13 @@ generate_keypair()
"number generator a better chance to gain enough entropy.\n") ); "number generator a better chance to gain enough entropy.\n") );
if( algo == PUBKEY_ALGO_ELGAMAL ) 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 #ifdef ENABLE_RSA_KEYGEN
else if( algo == PUBKEY_ALGO_RSA ) 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 #endif
else if( algo == PUBKEY_ALGO_DSA ) 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 else
BUG(); BUG();
if( !rc ) { if( !rc ) {
@ -667,6 +667,7 @@ generate_keypair()
free_secret_cert(skc); free_secret_cert(skc);
m_free(uid); m_free(uid);
m_free(dek); m_free(dek);
m_free(s2k);
m_free(pub_fname); m_free(pub_fname);
m_free(sec_fname); m_free(sec_fname);
} }

View File

@ -50,7 +50,7 @@ typedef struct {
int encrypt_only; /* process only encrytion messages */ int encrypt_only; /* process only encrytion messages */
STRLIST signed_data; STRLIST signed_data;
DEK *dek; DEK *dek;
int last_was_pubkey_enc; int last_was_session_key;
KBNODE list; /* the current list of packets */ KBNODE list; /* the current list of packets */
int have_data; int have_data;
IOBUF iobuf; /* used to get the filename etc. */ IOBUF iobuf; /* used to get the filename etc. */
@ -145,13 +145,48 @@ 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 static void
proc_pubkey_enc( CTX c, PACKET *pkt ) proc_pubkey_enc( CTX c, PACKET *pkt )
{ {
PKT_pubkey_enc *enc; PKT_pubkey_enc *enc;
int result = 0; int result = 0;
c->last_was_pubkey_enc = 1; c->last_was_session_key = 1;
enc = pkt->pkt.pubkey_enc; enc = pkt->pkt.pubkey_enc;
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/ /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
@ -179,15 +214,14 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
} }
static void static void
proc_encrypted( CTX c, PACKET *pkt ) proc_encrypted( CTX c, PACKET *pkt )
{ {
int result = 0; int result = 0;
/*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/ /*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
if( !c->dek && !c->last_was_pubkey_enc ) { if( !c->dek && !c->last_was_session_key ) {
/* assume this is conventional encrypted data */ /* assume this is old conventional encrypted data */
c->dek = m_alloc_secure( sizeof *c->dek ); c->dek = m_alloc_secure( sizeof *c->dek );
c->dek->algo = opt.def_cipher_algo; c->dek->algo = opt.def_cipher_algo;
result = make_dek_from_passphrase( c->dek, 0, NULL ); 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)); log_error("encryption failed: %s\n", g10_errstr(result));
} }
free_packet(pkt); 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 ) if( rc )
log_error( "handle plaintext failed: %s\n", g10_errstr(rc)); log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
free_packet(pkt); 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 ) if( rc )
log_error("uncompressing failed: %s\n", g10_errstr(rc)); log_error("uncompressing failed: %s\n", g10_errstr(rc));
free_packet(pkt); 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_PUBLIC_CERT:
case PKT_SECRET_CERT: case PKT_SECRET_CERT:
case PKT_USER_ID: case PKT_USER_ID:
case PKT_SYMKEY_ENC:
case PKT_PUBKEY_ENC: case PKT_PUBKEY_ENC:
case PKT_ENCRYPTED: case PKT_ENCRYPTED:
rc = G10ERR_UNEXPECTED; rc = G10ERR_UNEXPECTED;
@ -625,6 +660,7 @@ do_proc_packets( CTX c, IOBUF a )
rc = G10ERR_UNEXPECTED; rc = G10ERR_UNEXPECTED;
goto leave; goto leave;
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; 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_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break; case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
case PKT_PLAINTEXT: proc_plaintext( 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_USER_ID: newpkt = add_user_id( c, pkt ); break;
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
case PKT_PUBKEY_ENC: proc_pubkey_enc( 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_ENCRYPTED: proc_encrypted( c, pkt ); break;
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
case PKT_COMPRESSED: proc_compressed( c, pkt ); break; case PKT_COMPRESSED: proc_compressed( c, pkt ); break;

View File

@ -37,7 +37,7 @@ typedef enum {
PKT_NONE =0, PKT_NONE =0,
PKT_PUBKEY_ENC =1, /* public key encrypted packet */ PKT_PUBKEY_ENC =1, /* public key encrypted packet */
PKT_SIGNATURE =2, /* secret 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_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/
PKT_SECRET_CERT =5, /* secret key certificate */ PKT_SECRET_CERT =5, /* secret key certificate */
PKT_PUBLIC_CERT =6, /* public key certificate */ PKT_PUBLIC_CERT =6, /* public key certificate */
@ -54,6 +54,21 @@ typedef enum {
typedef struct packet_struct PACKET; 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 { typedef struct {
u32 keyid[2]; /* 64 bit keyid */ u32 keyid[2]; /* 64 bit keyid */
byte version; byte version;
@ -130,10 +145,7 @@ typedef struct {
/* and should never be passed to a mpi_xxx() */ /* and should never be passed to a mpi_xxx() */
struct { struct {
byte algo; /* cipher used to protect the secret information*/ byte algo; /* cipher used to protect the secret information*/
byte s2k; STRING2KEY s2k;
byte hash;
byte salt[8];
byte count;
byte iv[8]; /* initialization vector for CFB mode */ byte iv[8]; /* initialization vector for CFB mode */
} protect; } protect;
union { union {
@ -180,6 +192,7 @@ struct packet_struct {
pkttype_t pkttype; pkttype_t pkttype;
union { union {
void *generic; void *generic;
PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */
PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */ PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */
PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */ PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
PKT_signature *signature; /* PKT_SIGNATURE */ 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 ); void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
/*-- free-packet.c --*/ /*-- free-packet.c --*/
void free_symkey_enc( PKT_symkey_enc *enc );
void free_pubkey_enc( PKT_pubkey_enc *enc ); void free_pubkey_enc( PKT_pubkey_enc *enc );
void free_seckey_enc( PKT_signature *enc ); void free_seckey_enc( PKT_signature *enc );
int digest_algo_from_sig( PKT_signature *sig ); int digest_algo_from_sig( PKT_signature *sig );

View File

@ -42,7 +42,9 @@ static int copy_packet( IOBUF inp, IOBUF out, int pkttype,
unsigned long pktlen ); unsigned long pktlen );
static void skip_packet( IOBUF inp, 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 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 ); PACKET *packet );
static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_signature *sig ); 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 ); pkt->pkt.secret_cert = m_alloc_clear(sizeof *pkt->pkt.secret_cert );
rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt ); rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
break; break;
case PKT_SYMKEY_ENC:
rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
break;
case PKT_PUBKEY_ENC: case PKT_PUBKEY_ENC:
rc = parse_publickey(inp, pkttype, pktlen, pkt ); rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
break; break;
case PKT_SIGNATURE: case PKT_SIGNATURE:
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->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 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; unsigned n;
PKT_pubkey_enc *k; 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->keyid[1] = read_32(inp); pktlen -= 4;
k->pubkey_algo = iobuf_get_noeof(inp); pktlen--; k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
if( list_mode ) 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]); k->version, (ulong)k->keyid[0], (ulong)k->keyid[1]);
if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
n = pktlen; n = pktlen;
@ -845,34 +926,34 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
cert->protect.algo = iobuf_get_noeof(inp); pktlen--; cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) { if( cert->protect.algo ) {
cert->is_protected = 1; cert->is_protected = 1;
cert->protect.count = 0; cert->protect.s2k.count = 0;
if( cert->protect.algo == 255 ) { if( cert->protect.algo == 255 ) {
if( pktlen < 3 ) { if( pktlen < 3 ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
cert->protect.algo = iobuf_get_noeof(inp); pktlen--; cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
cert->protect.s2k = iobuf_get_noeof(inp); pktlen--; cert->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
cert->protect.hash = iobuf_get_noeof(inp); pktlen--; cert->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
switch( cert->protect.s2k ) { switch( cert->protect.s2k.mode ) {
case 1: case 1:
case 3: case 4:
for(i=0; i < 8 && pktlen; i++, pktlen-- ) for(i=0; i < 8 && pktlen; i++, pktlen-- )
temp[i] = iobuf_get_noeof(inp); temp[i] = iobuf_get_noeof(inp);
memcpy(cert->protect.salt, temp, 8 ); memcpy(cert->protect.s2k.salt, temp, 8 );
break; break;
} }
switch( cert->protect.s2k ) { switch( cert->protect.s2k.mode ) {
case 0: if( list_mode ) printf( "\tsimple S2K" ); case 0: if( list_mode ) printf( "\tsimple S2K" );
break; break;
case 1: if( list_mode ) printf( "\tsalted S2K" ); case 1: if( list_mode ) printf( "\tsalted S2K" );
break; break;
case 3: if( list_mode ) printf( "\titer+salt S2K" ); case 4: if( list_mode ) printf( "\titer+salt S2K" );
break; break;
default: default:
if( list_mode ) if( list_mode )
printf( "\tunknown S2K %d\n", printf( "\tunknown S2K %d\n",
cert->protect.s2k ); cert->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
@ -880,23 +961,23 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode ) { if( list_mode ) {
printf(", algo: %d, hash: %d", printf(", algo: %d, hash: %d",
cert->protect.algo, cert->protect.algo,
cert->protect.hash ); cert->protect.s2k.hash_algo );
if( cert->protect.s2k == 1 if( cert->protect.s2k.mode == 1
|| cert->protect.s2k == 3 ) { || cert->protect.s2k.mode == 4 ) {
printf(", salt: "); printf(", salt: ");
for(i=0; i < 8; i++ ) for(i=0; i < 8; i++ )
printf("%02x", cert->protect.salt[i]); printf("%02x", cert->protect.s2k.salt[i]);
} }
putchar('\n'); putchar('\n');
} }
if( cert->protect.s2k == 3 ) { if( cert->protect.s2k.mode == 4 ) {
if( !pktlen ) { if( pktlen < 4 ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
cert->protect.count = iobuf_get_noeof(inp); cert->protect.s2k.count = read_32(inp);
pktlen--; pktlen -= 4;
} }
} }
@ -905,9 +986,9 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
printf( "\tprotect algo: %d\n", printf( "\tprotect algo: %d\n",
cert->protect.algo); cert->protect.algo);
/* old version, we don't have a S2K, so we fake one */ /* 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 */ /* We need this kludge to cope with old GNUPG versions */
cert->protect.hash = cert->protect.s2k.hash_algo =
cert->protect.algo == CIPHER_ALGO_BLOWFISH160? cert->protect.algo == CIPHER_ALGO_BLOWFISH160?
DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5; 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--; cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
if( cert->protect.algo ) { if( cert->protect.algo ) {
cert->is_protected = 1; cert->is_protected = 1;
cert->protect.count = 0; cert->protect.s2k.count = 0;
if( cert->protect.algo == 255 ) { if( cert->protect.algo == 255 ) {
if( pktlen < 3 ) { if( pktlen < 3 ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
cert->protect.algo = iobuf_get_noeof(inp); pktlen--; cert->protect.algo = iobuf_get_noeof(inp); pktlen--;
cert->protect.s2k = iobuf_get_noeof(inp); pktlen--; cert->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
cert->protect.hash = iobuf_get_noeof(inp); pktlen--; cert->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
switch( cert->protect.s2k ) { switch( cert->protect.s2k.mode ) {
case 1: case 1:
case 3: case 4:
for(i=0; i < 8 && pktlen; i++, pktlen-- ) for(i=0; i < 8 && pktlen; i++, pktlen-- )
temp[i] = iobuf_get_noeof(inp); temp[i] = iobuf_get_noeof(inp);
memcpy(cert->protect.salt, temp, 8 ); memcpy(cert->protect.s2k.salt, temp, 8 );
break; break;
} }
switch( cert->protect.s2k ) { switch( cert->protect.s2k.mode ) {
case 0: if( list_mode ) printf( "\tsimple S2K" ); case 0: if( list_mode ) printf( "\tsimple S2K" );
break; break;
case 1: if( list_mode ) printf( "\tsalted S2K" ); case 1: if( list_mode ) printf( "\tsalted S2K" );
break; break;
case 3: if( list_mode ) printf( "\titer+salt S2K" ); case 4: if( list_mode ) printf( "\titer+salt S2K" );
break; break;
default: default:
if( list_mode ) if( list_mode )
printf( "\tunknown S2K %d\n", cert->protect.s2k ); printf( "\tunknown S2K %d\n",
cert->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
@ -1015,22 +1097,23 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode ) { if( list_mode ) {
printf(", algo: %d, hash: %d", printf(", algo: %d, hash: %d",
cert->protect.algo, cert->protect.algo,
cert->protect.hash ); cert->protect.s2k.hash_algo );
if( cert->protect.s2k == 1 || cert->protect.s2k == 3 ){ if( cert->protect.s2k.mode == 1
|| cert->protect.s2k.mode == 4 ){
printf(", salt: "); printf(", salt: ");
for(i=0; i < 8; i++ ) for(i=0; i < 8; i++ )
printf("%02x", cert->protect.salt[i]); printf("%02x", cert->protect.s2k.salt[i]);
} }
putchar('\n'); putchar('\n');
} }
if( cert->protect.s2k == 3 ) { if( cert->protect.s2k.mode == 4 ) {
if( !pktlen ) { if( pktlen < 4 ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
} }
cert->protect.count = iobuf_get_noeof(inp); cert->protect.s2k.count = read_32(inp);
pktlen--; pktlen -= 4;
} }
} }
@ -1038,8 +1121,8 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode ) if( list_mode )
printf( "\tprotect algo: %d\n", cert->protect.algo); printf( "\tprotect algo: %d\n", cert->protect.algo);
/* old version, we don't have a S2K, so we fake one */ /* old version, we don't have a S2K, so we fake one */
cert->protect.s2k = 0; cert->protect.s2k.mode = 0;
cert->protect.hash = DIGEST_ALGO_MD5; cert->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
} }
if( pktlen < 8 ) { if( pktlen < 8 ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;

View File

@ -33,7 +33,7 @@
static int pwfd = -1; 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 void
set_passphrase_fd( int fd ) 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. * This function is used to construct a DEK from a user input.
* It uses the default CIPHER. If salt is != NULL, include these * It uses the default CIPHER.
* 8 bytes in the hash.
* Returns: 0 = okay, -1 No passphrase entered, > 0 error * Returns: 0 = okay, -1 No passphrase entered, > 0 error
*/ */
int int
make_dek_from_passphrase( DEK *dek, int mode, byte *salt ) make_dek_from_passphrase( DEK *dek, int mode, STRING2KEY *s2k )
{ {
char *pw, *pw2; char *pw, *pw2;
int rc=0; int rc=0;
@ -132,45 +131,36 @@ make_dek_from_passphrase( DEK *dek, int mode, byte *salt )
if( !*pw ) if( !*pw )
rc = -1; rc = -1;
else else
rc = hash_passphrase( dek, pw, salt ); hash_passphrase( dek, pw, s2k, mode==2 );
m_free(pw); m_free(pw);
return rc; 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; int rc = 0;
assert( s2k->hash_algo );
dek->keylen = 0; dek->keylen = 0;
if( dek->algo == CIPHER_ALGO_BLOWFISH ) { md = md_open( s2k->hash_algo, 1);
MD_HANDLE md; if( s2k->mode == 1 || s2k->mode == 4 ) {
if( create )
md = md_open(DIGEST_ALGO_RMD160, 1); randomize_buffer(&s2k->salt, 8, 1);
if( salt ) md_write( md, s2k->salt, 8 );
md_write( md, salt, 8 ); }
md_write( md, pw, strlen(pw) ); md_write( md, pw, strlen(pw) );
md_final( md ); md_final( md );
dek->keylen = 20; 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 ); memcpy( dek->key, md_read(md,0), dek->keylen );
md_close(md); 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);
}
else
rc = G10ERR_UNSUPPORTED;
return rc;
} }

View File

@ -54,9 +54,9 @@ do_check( PKT_secret_cert *cert )
case CIPHER_ALGO_BLOWFISH: case CIPHER_ALGO_BLOWFISH:
case CIPHER_ALGO_CAST: case CIPHER_ALGO_CAST:
keyid_from_skc( cert, keyid ); 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, dek = get_passphrase_hash( keyid, NULL,
cert->protect.salt ); cert->protect.s2k.salt );
else else
dek = get_passphrase_hash( keyid, NULL, NULL ); dek = get_passphrase_hash( keyid, NULL, NULL );

View File

@ -93,7 +93,7 @@ POSUB = po
RANLIB = ranlib RANLIB = ranlib
USE_INCLUDED_LIBINTL = yes USE_INCLUDED_LIBINTL = yes
USE_NLS = yes USE_NLS = yes
VERSION = 0.2.16 VERSION = 0.2.16a
ZLIBS = ZLIBS =
l = l =