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:
parent
45f1328259
commit
823d39fd55
2
TODO
2
TODO
@ -49,3 +49,5 @@
|
||||
|
||||
* add multi-user-id-sigs handling to import.c
|
||||
|
||||
* add tag 3 packet support to "-c"
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
@ -314,6 +319,37 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
|
||||
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
|
||||
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
|
||||
calc_plaintext( PKT_plaintext *pt )
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
35
g10/keygen.c
35
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);
|
||||
}
|
||||
|
@ -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. */
|
||||
@ -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
|
||||
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;
|
||||
|
24
g10/packet.h
24
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 */
|
||||
@ -54,6 +54,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;
|
||||
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
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 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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 =
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user