1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-14 21:47:19 +02:00

partial DSA support

This commit is contained in:
Werner Koch 1998-03-09 21:44:06 +00:00
parent 1b1a6d7e77
commit a6a8f1e706
62 changed files with 2247 additions and 447 deletions

View file

@ -141,6 +141,7 @@ check_elg( PKT_secret_cert *cert )
return 0;
}
static int
protect_elg( PKT_secret_cert *cert, DEK *dek )
{
@ -174,6 +175,126 @@ protect_elg( PKT_secret_cert *cert, DEK *dek )
return 0;
}
static int
check_dsa( PKT_secret_cert *cert )
{
byte *buffer;
u16 csum=0;
int res;
unsigned nbytes;
u32 keyid[2];
DSA_secret_key skey;
char save_iv[8];
if( cert->d.dsa.is_protected ) { /* remove the protection */
DEK *dek = NULL;
MPI test_x;
BLOWFISH_context *blowfish_ctx=NULL;
switch( cert->d.dsa.protect.algo ) {
case CIPHER_ALGO_NONE: BUG(); break;
case CIPHER_ALGO_BLOWFISH:
keyid_from_skc( cert, keyid );
if( cert->d.dsa.protect.s2k == 1
|| cert->d.dsa.protect.s2k == 3 )
dek = get_passphrase_hash( keyid, NULL,
cert->d.dsa.protect.salt );
else
dek = get_passphrase_hash( keyid, NULL, NULL );
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
blowfish_setiv( blowfish_ctx, NULL );
memcpy(save_iv, cert->d.dsa.protect.iv, 8 );
blowfish_decode_cfb( blowfish_ctx,
cert->d.dsa.protect.iv,
cert->d.dsa.protect.iv, 8 );
mpi_set_secure(cert->d.dsa.x );
/*fixme: maybe it is better to set the buffer secure with a
* new get_buffer_secure() function */
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes );
csum += checksum( buffer, nbytes );
test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.dsa.x) );
mpi_set_buffer( test_x, buffer, nbytes, 0 );
m_free( buffer );
m_free( blowfish_ctx );
/* now let's see wether we have used the right passphrase */
if( csum != cert->d.dsa.csum ) {
mpi_free(test_x);
memcpy( cert->d.dsa.protect.iv, save_iv, 8 );
return G10ERR_BAD_PASS;
}
skey.p = cert->d.dsa.p;
skey.q = cert->d.dsa.q;
skey.g = cert->d.dsa.g;
skey.y = cert->d.dsa.y;
skey.x = test_x;
res = dsa_check_secret_key( &skey );
memset( &skey, 0, sizeof skey );
if( !res ) {
mpi_free(test_x);
memcpy( cert->d.dsa.protect.iv, save_iv, 8 );
return G10ERR_BAD_PASS;
}
mpi_set(cert->d.dsa.x, test_x);
mpi_free(test_x);
cert->d.dsa.is_protected = 0;
break;
default:
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
}
}
else { /* not protected */
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
if( csum != cert->d.dsa.csum )
return G10ERR_CHECKSUM;
}
return 0;
}
static int
protect_dsa( PKT_secret_cert *cert, DEK *dek )
{
byte *buffer;
unsigned nbytes;
if( !cert->d.dsa.is_protected ) { /* add the protection */
BLOWFISH_context *blowfish_ctx=NULL;
switch( cert->d.dsa.protect.algo ) {
case CIPHER_ALGO_NONE: BUG(); break;
case CIPHER_ALGO_BLOWFISH:
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
blowfish_setiv( blowfish_ctx, NULL );
blowfish_encode_cfb( blowfish_ctx,
cert->d.dsa.protect.iv,
cert->d.dsa.protect.iv, 8 );
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
blowfish_encode_cfb( blowfish_ctx, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
m_free( buffer );
m_free( blowfish_ctx );
cert->d.dsa.is_protected = 1;
break;
default:
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
}
}
return 0;
}
#ifdef HAVE_RSA_CIPHER
static int
@ -282,6 +403,8 @@ check_secret_key( PKT_secret_cert *cert )
log_error("Invalid passphrase; please try again ...\n");
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
rc = check_elg( cert );
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
rc = check_dsa( cert );
#ifdef HAVE_RSA_CIPHER
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
rc = check_rsa( cert );
@ -303,6 +426,8 @@ is_secret_key_protected( PKT_secret_cert *cert )
{
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
return cert->d.elg.is_protected? cert->d.elg.protect.algo : 0;
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
return cert->d.dsa.is_protected? cert->d.dsa.protect.algo : 0;
#ifdef HAVE_RSA_CIPHER
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
return cert->d.rsa.is_protected? cert->d.rsa.protect_algo : 0;
@ -323,6 +448,8 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek )
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
return protect_elg( cert, dek );
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
return protect_dsa( cert, dek );
else
return G10ERR_PUBKEY_ALGO;
}