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

add DSA key generation

This commit is contained in:
Werner Koch 1998-05-05 20:34:20 +00:00
parent 42b03f6ebd
commit 69cf10ffab
17 changed files with 324 additions and 29 deletions

2
THANKS
View File

@ -24,6 +24,8 @@ Ulf M
Walter Koch walterk@ddorf.rhein-ruhr.de Walter Koch walterk@ddorf.rhein-ruhr.de
Werner Koch werner.koch@guug.de Werner Koch werner.koch@guug.de
Wim Vandeputte bunbun@reptile.rug.ac.be Wim Vandeputte bunbun@reptile.rug.ac.be
tzeruch@ceddec.com
Thanks to the German Unix User Group for providing FTP space and Thanks to the German Unix User Group for providing FTP space and
Martin Hamilton for hosting the mailing list. Martin Hamilton for hosting the mailing list.

2
TODO
View File

@ -47,3 +47,5 @@
* add readline support (but how can we allcoate it in secure memory?) * add readline support (but how can we allcoate it in secure memory?)
* add a testcase for --print-mds

View File

@ -1 +1 @@
0.2.17 0.2.17a

View File

@ -1,3 +1,13 @@
Tue May 5 21:28:55 1998 Werner Koch (wk@isil.d.shuttle.de)
* elgamal.c (elg_generate): choosing x was not correct, could
yield 6 bytes which are not from the random pool, tsss, tsss..
Tue May 5 14:09:06 1998 Werner Koch (wk@isil.d.shuttle.de)
* primegen.c (generate_elg_prime): Add arg mode, changed all
callers and implemented mode 1.
Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de) Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c (cipher_get_keylen): New. * cipher.c (cipher_get_keylen): New.

View File

@ -22,6 +22,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include "util.h" #include "util.h"
#include "mpi.h" #include "mpi.h"
#include "cipher.h" #include "cipher.h"
@ -74,6 +75,123 @@ dsa_free_secret_key( DSA_secret_key *sk )
} }
static void
test_keys( DSA_public_key *pk, DSA_secret_key *sk, unsigned qbits )
{
MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
mpi_set_bytes( test, qbits, get_random_byte, 0 );
dsa_sign( out1_a, out1_b, test, sk );
if( !dsa_verify( out1_a, out1_b, test, pk ) )
log_fatal("DSA:: sign, verify failed\n");
mpi_free( test );
mpi_free( out1_a );
mpi_free( out1_b );
}
/****************
* Generate a DSA key pair with a key of size NBITS
* Returns: 2 structures filled with all needed values
* and an array with the n-1 factors of (p-1)
*/
void
dsa_generate( DSA_public_key *pk, DSA_secret_key *sk,
unsigned nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI q; /* the 160 bit prime factor */
MPI g; /* the generator */
MPI y; /* g^x mod p */
MPI x; /* the secret exponent */
MPI h, e; /* helper */
unsigned qbits;
byte *rndbuf;
assert( nbits >= 512 && nbits <= 1024 );
qbits = 160;
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
/* get q out of factors */
q = mpi_copy((*ret_factors)[0]);
if( mpi_get_nbits(q) != qbits )
BUG();
/* find a generator g (h and e are helpers)*/
/* e = (p-1)/q */
e = mpi_alloc( mpi_get_nlimbs(p) );
mpi_sub_ui( e, p, 1 );
mpi_fdiv_q( e, e, q );
g = mpi_alloc( mpi_get_nlimbs(p) );
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
do {
mpi_add_ui( h, h, 1 );
/* g = h^e mod p */
mpi_powm( g, h, e, p );
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
/* select a random number which has these properties:
* 0 < x < q-1
* This must be a very good random number because this
* is the secret part. */
if( DBG_CIPHER )
log_debug("choosing a random x ");
assert( qbits >= 16 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
do {
if( DBG_CIPHER )
fputc('.', stderr);
if( !rndbuf )
rndbuf = get_random_bits( qbits, 2, 1 );
else { /* change only some of the higher bits (= 2 bytes)*/
char *r = get_random_bits( 16, 2, 1 );
memcpy(rndbuf, r, 16/8 );
m_free(r);
}
mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
mpi_clear_highbit( x, qbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
m_free(rndbuf);
mpi_free( e );
mpi_free( h );
/* y = g^x mod p */
y = mpi_alloc( mpi_get_nlimbs(p) );
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
fputc('\n', stderr);
log_mpidump("dsa p= ", p );
log_mpidump("dsa q= ", q );
log_mpidump("dsa g= ", g );
log_mpidump("dsa y= ", y );
log_mpidump("dsa x= ", x );
}
/* copy the stuff to the key structures */
pk->p = mpi_copy(p);
pk->q = mpi_copy(q);
pk->g = mpi_copy(g);
pk->y = mpi_copy(y);
sk->p = p;
sk->q = q;
sk->g = g;
sk->y = y;
sk->x = x;
/* now we can test our keys (this should never fail!) */
test_keys( pk, sk, qbits );
}
/**************** /****************
* Test whether the secret key is valid. * Test whether the secret key is valid.
* Returns: if this is a valid key. * Returns: if this is a valid key.

View File

@ -41,8 +41,9 @@ typedef struct {
void dsa_free_public_key( DSA_public_key *pk ); void dsa_free_public_key( DSA_public_key *pk );
void dsa_free_secret_key( DSA_secret_key *sk ); void dsa_free_secret_key( DSA_secret_key *sk );
void dsa_generate( DSA_public_key *pk, DSA_secret_key *sk, unsigned nbits );
int dsa_check_secret_key( DSA_secret_key *sk ); int dsa_check_secret_key( DSA_secret_key *sk );
void dsa_generate( DSA_public_key *pk, DSA_secret_key *sk,
unsigned nbits, MPI **ret_factors );
void dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey); void dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
int dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey); int dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);

View File

@ -139,7 +139,7 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk,
else else
qbits = 240; qbits = 240;
g = mpi_alloc(1); g = mpi_alloc(1);
p = generate_elg_prime( nbits, qbits, g, ret_factors ); p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1); mpi_sub_ui(p_min1, p, 1);
@ -163,7 +163,7 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk,
} }
else { else {
char *r = get_random_bits( 16, 2, 1 ); char *r = get_random_bits( 16, 2, 1 );
memcpy(rndbuf, r, 16 ); memcpy(rndbuf, r, 16/8 );
m_free(r); m_free(r);
} }
} }

View File

@ -63,37 +63,49 @@ generate_public_prime( unsigned nbits )
* security from it - The prime number is public and we could also * security from it - The prime number is public and we could also
* offer the factors for those who are willing to check that it is * offer the factors for those who are willing to check that it is
* indeed a strong prime. * indeed a strong prime.
*
* mode 0: Standard
* 1: Make sure that at least one factor is of size qbits.
*/ */
MPI MPI
generate_elg_prime( unsigned pbits, unsigned qbits, MPI g, MPI **ret_factors ) generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **ret_factors )
{ {
int n; /* number of factors */ int n; /* number of factors */
int m; /* number of primes in pool */ int m; /* number of primes in pool */
unsigned fbits; /* length of prime factors */ unsigned fbits; /* length of prime factors */
MPI *factors; /* current factors */ MPI *factors; /* current factors */
MPI *pool; /* pool of primes */ MPI *pool; /* pool of primes */
MPI q; /* first prime factor */ MPI q; /* first prime factor (variable)*/
MPI prime; /* prime test value */ MPI prime; /* prime test value */
MPI q_factor; /* used for mode 1 */
byte *perms = NULL; byte *perms = NULL;
int i, j; int i, j;
int count1, count2; int count1, count2;
unsigned nprime; unsigned nprime;
unsigned req_qbits = qbits; /* the requested q bits size */
/* find number of needed prime factors */ /* find number of needed prime factors */
for(n=1; (pbits - qbits - 1) / n >= qbits; n++ ) for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
; ;
n--; n--;
if( !n ) if( !n || (mode==1 && n < 2) )
log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits ); log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
fbits = (pbits - qbits -1) / n; if( mode == 1 ) {
while( qbits + n*fbits < pbits ) n--;
qbits++; fbits = (pbits - 2*req_qbits -1) / n;
qbits = pbits - req_qbits - n*fbits;
}
else {
fbits = (pbits - req_qbits -1) / n;
qbits = pbits - n*fbits;
}
if( DBG_CIPHER ) if( DBG_CIPHER )
log_debug("gen prime: pbits=%u qbits=%u fbits=%u n=%d\n", log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, qbits, fbits, n ); pbits, req_qbits, qbits, fbits, n );
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB ); prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
q = gen_prime( qbits, 0, 1 ); q = gen_prime( qbits, 0, 1 );
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
/* allocate an array to hold the factors + 2 for later usage */ /* allocate an array to hold the factors + 2 for later usage */
factors = m_alloc_clear( (n+2) * sizeof *factors ); factors = m_alloc_clear( (n+2) * sizeof *factors );
@ -139,6 +151,8 @@ generate_elg_prime( unsigned pbits, unsigned qbits, MPI g, MPI **ret_factors )
mpi_set( prime, q ); mpi_set( prime, q );
mpi_mul_ui( prime, prime, 2 ); mpi_mul_ui( prime, prime, 2 );
if( mode == 1 )
mpi_mul( prime, prime, q_factor );
for(i=0; i < n; i++ ) for(i=0; i < n; i++ )
mpi_mul( prime, prime, factors[i] ); mpi_mul( prime, prime, factors[i] );
mpi_add_ui( prime, prime, 1 ); mpi_add_ui( prime, prime, 1 );
@ -171,25 +185,39 @@ generate_elg_prime( unsigned pbits, unsigned qbits, MPI g, MPI **ret_factors )
putc('\n', stderr); putc('\n', stderr);
log_mpidump( "prime : ", prime ); log_mpidump( "prime : ", prime );
log_mpidump( "factor q: ", q ); log_mpidump( "factor q: ", q );
if( mode == 1 )
log_mpidump( "factor q0: ", q_factor );
for(i=0; i < n; i++ ) for(i=0; i < n; i++ )
log_mpidump( "factor pi: ", factors[i] ); log_mpidump( "factor pi: ", factors[i] );
log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) ); log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
if( mode == 1 )
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
for(i=0; i < n; i++ ) for(i=0; i < n; i++ )
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) ); fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
putc('\n', stderr); putc('\n', stderr);
} }
if( ret_factors ) { /* caller wants the factors */ if( ret_factors ) { /* caller wants the factors */
*ret_factors = m_alloc_clear( (n+1) * sizeof **ret_factors ); *ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
for(i=0; i < n; i++ ) if( mode == 1 ) {
i = 0;
(*ret_factors)[i++] = mpi_copy( q_factor );
for(; i <= n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] ); (*ret_factors)[i] = mpi_copy( factors[i] );
} }
else {
for(; i < n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
}
if( g ) { /* create a generator (start with 3)*/ if( g ) { /* create a generator (start with 3)*/
MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) ); MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
MPI b = mpi_alloc( mpi_get_nlimbs(prime) ); MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) ); MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
if( mode == 1 )
BUG(); /* not yet implemented */
factors[n] = q; factors[n] = q;
factors[n+1] = mpi_alloc_set_ui(2); factors[n+1] = mpi_alloc_set_ui(2);
mpi_sub_ui( pmin1, prime, 1 ); mpi_sub_ui( pmin1, prime, 1 );
@ -230,6 +258,7 @@ generate_elg_prime( unsigned pbits, unsigned qbits, MPI g, MPI **ret_factors )
} }
static MPI static MPI
gen_prime( unsigned nbits, int secret, int randomlevel ) gen_prime( unsigned nbits, int secret, int randomlevel )
{ {

View File

@ -702,10 +702,11 @@ transform( TIGER_CONTEXT *hd, byte *data )
u64 a,b,c,aa,bb,cc; u64 a,b,c,aa,bb,cc;
u64 x[8]; u64 x[8];
#ifdef BIG_ENDIAN_HOST #ifdef BIG_ENDIAN_HOST
#define MKWORD(d,n) ( (d)[8*(n)+0] << 56 | (d)[8*(n)+1] << 48 \ #define MKWORD(d,n) \
| (d)[8*(n)+2] << 40 | (d)[8*(n)+3] << 32 \ ( ((u64)(d)[8*(n)+0]) << 56 | ((u64)(d)[8*(n)+1]) << 48 \
| (d)[8*(n)+4] << 24 | (d)[8*(n)+5] << 16 \ | ((u64)(d)[8*(n)+2]) << 40 | ((u64)(d)[8*(n)+3]) << 32 \
| (d)[8*(n)+6] << 8 | (d)[8*(n)+7] ) | ((u64)(d)[8*(n)+4]) << 24 | ((u64)(d)[8*(n)+5]) << 16 \
| ((u64)(d)[8*(n)+6]) << 8 | ((u64)(d)[8*(n)+7]) )
x[0] = MKWORD(data, 0); x[0] = MKWORD(data, 0);
x[1] = MKWORD(data, 1); x[1] = MKWORD(data, 1);
x[2] = MKWORD(data, 2); x[2] = MKWORD(data, 2);

View File

@ -1,3 +1,8 @@
Tue May 5 22:11:59 1998 Werner Koch (wk@isil.d.shuttle.de)
* keygen.c (gen_dsa): New.
* build_packet.c (do_secret_cert): Support for DSA
Mon May 4 19:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) Mon May 4 19:01:25 1998 Werner Koch (wk@isil.d.shuttle.de)
* compress.c: doubled buffer sizes * compress.c: doubled buffer sizes

View File

@ -292,6 +292,29 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
mpi_write(a, skc->d.elg.x ); mpi_write(a, skc->d.elg.x );
write_16(a, skc->csum ); write_16(a, skc->csum );
} }
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
mpi_write(a, skc->d.dsa.p );
mpi_write(a, skc->d.dsa.q );
mpi_write(a, skc->d.dsa.g );
mpi_write(a, skc->d.dsa.y );
if( skc->is_protected ) {
iobuf_put(a, 0xff );
iobuf_put(a, skc->protect.algo );
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
iobuf_put(a, 0 );
mpi_write(a, skc->d.dsa.x );
write_16(a, skc->csum );
}
else if( is_RSA(skc->pubkey_algo) ) { else if( is_RSA(skc->pubkey_algo) ) {
mpi_write(a, skc->d.rsa.n ); mpi_write(a, skc->d.rsa.n );
mpi_write(a, skc->d.rsa.e ); mpi_write(a, skc->d.rsa.e );

View File

@ -72,6 +72,7 @@ static ARGPARSE_OPTS opts[] = {
{ 515, "fingerprint", 0, N_("list keys and fingerprints")}, { 515, "fingerprint", 0, N_("list keys and fingerprints")},
#ifdef IS_G10 #ifdef IS_G10
{ 503, "gen-key", 0, N_("generate a new key pair")}, { 503, "gen-key", 0, N_("generate a new key pair")},
{ 554, "add-key", 0, N_("add a subkey to a key pair")},
{ 506, "sign-key" ,0, N_("make a signature on a key in the keyring")}, { 506, "sign-key" ,0, N_("make a signature on a key in the keyring")},
{ 505, "delete-key",0, N_("remove key from the public keyring")}, { 505, "delete-key",0, N_("remove key from the public keyring")},
{ 524, "edit-key" ,0, N_("edit a key signature")}, { 524, "edit-key" ,0, N_("edit a key signature")},
@ -171,7 +172,7 @@ enum cmd_values { aNull = 0,
aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr,
aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey, aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey,
aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys, aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys,
aListSigs, aListSigs, aKeyadd,
aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs, aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs,
aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest, aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest,
aNOP }; aNOP };
@ -574,6 +575,7 @@ main( int argc, char **argv )
case 551: set_cmd( &cmd, aListKeys); break; case 551: set_cmd( &cmd, aListKeys); break;
case 552: set_cmd( &cmd, aListSigs); break; case 552: set_cmd( &cmd, aListSigs); break;
case 553: opt.skip_verify=1; break; case 553: opt.skip_verify=1; break;
case 554: set_cmd( &cmd, aKeyadd); break;
default : errors++; pargs.err = configfp? 1:2; break; default : errors++; pargs.err = configfp? 1:2; break;
} }
} }
@ -817,6 +819,11 @@ main( int argc, char **argv )
wrong_args("--gen-key"); wrong_args("--gen-key");
generate_keypair(); generate_keypair();
break; break;
case aKeyadd: /* add a subkey (interactive) */
if( argc != 1 )
wrong_args("--add-key userid");
generate_subkeypair(*argv);
break;
#endif #endif
case aImport: case aImport:
@ -873,19 +880,24 @@ main( int argc, char **argv )
putchar('\n'); putchar('\n');
} }
else if( argc == 2 ) { else if( argc == 2 ) {
mpi_print( stdout, generate_elg_prime( atoi(argv[0]), mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
atoi(argv[1]), NULL,NULL ), 1); atoi(argv[1]), NULL,NULL ), 1);
putchar('\n'); putchar('\n');
} }
else if( argc == 3 ) { else if( argc == 3 ) {
MPI g = mpi_alloc(1); MPI g = mpi_alloc(1);
mpi_print( stdout, generate_elg_prime( atoi(argv[0]), mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
atoi(argv[1]), g, NULL ), 1); atoi(argv[1]), g, NULL ), 1);
printf("\nGenerator: "); printf("\nGenerator: ");
mpi_print( stdout, g, 1 ); mpi_print( stdout, g, 1 );
putchar('\n'); putchar('\n');
mpi_free(g); mpi_free(g);
} }
else if( argc == 4 ) {
mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
atoi(argv[1]), NULL,NULL ), 1);
putchar('\n');
}
else else
usage(1); usage(1);
break; break;

View File

@ -621,6 +621,8 @@ change_passphrase( const char *username )
break; break;
} }
/* fixme: unprotect all subkeys */
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 {
@ -648,6 +650,7 @@ change_passphrase( const char *username )
break; break;
} }
else { /* okay */ else { /* okay */
/* fixme: protect all subkeys too */
skc->protect.algo = dek->algo; skc->protect.algo = dek->algo;
skc->protect.s2k = *s2k; skc->protect.s2k = *s2k;
rc = protect_secret_key( skc, dek ); rc = protect_secret_key( skc, dek );

View File

@ -224,11 +224,84 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
#endif /*ENABLE_RSA_KEYGEN*/ #endif /*ENABLE_RSA_KEYGEN*/
/****************
* Generate a DSA key
*/
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,
STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days ) STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days )
{ {
return G10ERR_GENERAL; int rc;
int i;
PACKET *pkt;
PKT_secret_cert *skc;
PKT_public_cert *pkc;
DSA_public_key pk;
DSA_secret_key sk;
MPI *factors;
if( nbits > 1024 )
nbits = 1024;
dsa_generate( &pk, &sk, nbits, &factors );
skc = m_alloc_clear( sizeof *skc );
pkc = m_alloc_clear( sizeof *pkc );
skc->timestamp = pkc->timestamp = make_timestamp();
skc->version = pkc->version = 4;
/* valid days are not stored in the packet, but it is
* used here to put it into the signature.
*/
skc->valid_days = pkc->valid_days = valid_days;
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_DSA;
pkc->d.dsa.p = pk.p;
pkc->d.dsa.q = pk.q;
pkc->d.dsa.g = pk.g;
pkc->d.dsa.y = pk.y;
skc->d.dsa.p = sk.p;
skc->d.dsa.q = sk.q;
skc->d.dsa.g = sk.g;
skc->d.dsa.y = sk.y;
skc->d.dsa.x = sk.x;
skc->is_protected = 0;
skc->protect.algo = 0;
skc->csum = checksum_mpi( skc->d.dsa.x );
/* return an unprotected version of the skc */
*ret_skc = copy_secret_cert( NULL, skc );
if( dek ) {
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) );
free_public_cert(pkc);
free_secret_cert(skc);
return rc;
}
}
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_PUBLIC_CERT;
pkt->pkt.public_cert = pkc;
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 not secret)
* p = 2 * q * f1 * f2 * ... * fn
* We store only f1 to f_n-1 - fn can be calculated because p and q
* are known.
*/
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_SECRET_CERT;
pkt->pkt.secret_cert = skc;
add_kbnode(sec_root, new_kbnode( pkt ));
for(i=1; factors[i]; i++ ) /* the first one is q */
add_kbnode( sec_root,
make_mpi_comment_node("#:DSA_factor:", factors[i] ));
return 0;
} }
@ -312,7 +385,7 @@ generate_keypair()
else if( algo == 2 ) { else if( algo == 2 ) {
algo = PUBKEY_ALGO_DSA; algo = PUBKEY_ALGO_DSA;
algo_name = "DSA"; algo_name = "DSA";
tty_printf(_("Sorry; DSA key generation is not yet supported.\n")); break;
} }
#ifdef ENABLE_RSA_KEYGEN #ifdef ENABLE_RSA_KEYGEN
else if( algo == 3 ) { else if( algo == 3 ) {
@ -380,6 +453,10 @@ generate_keypair()
" <n>w = key expires in n weeks\n" " <n>w = key expires in n weeks\n"
" <n>m = key expires in n months\n" " <n>m = key expires in n months\n"
" <n>y = key expires in n years\n")); " <n>y = key expires in n years\n"));
/* Note: The elgamal subkey for DSA has no exiration date because
* is must be signed with the DSA key and this one has the expiration
* date */
answer = NULL; answer = NULL;
for(;;) { for(;;) {
int mult; int mult;
@ -578,7 +655,7 @@ generate_keypair()
rc = gen_rsa(nbits, pub_root, sec_root, dek, s2k, &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, s2k, &skc, valid_days ); rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, &skc, valid_days);
else else
BUG(); BUG();
if( !rc ) { if( !rc ) {
@ -663,3 +740,13 @@ generate_keypair()
m_free(sec_fname); m_free(sec_fname);
} }
/****************
* add a new subkey to an existing key.
*/
void
generate_subkeypair( const char *userid )
{
log_fatal("To be implemented :-)\n");
}

View File

@ -70,6 +70,7 @@ int change_passphrase( const char *username );
/*-- keygen.c --*/ /*-- keygen.c --*/
void generate_keypair(void); void generate_keypair(void);
void generate_subkeypair(const char *userid);
/*-- openfile.c --*/ /*-- openfile.c --*/
int overwrite_filep( const char *fname ); int overwrite_filep( const char *fname );

View File

@ -114,7 +114,8 @@ extern ushort small_prime_numbers[];
/*-- primegen.c --*/ /*-- primegen.c --*/
MPI generate_secret_prime( unsigned nbits ); MPI generate_secret_prime( unsigned nbits );
MPI generate_public_prime( unsigned nbits ); MPI generate_public_prime( unsigned nbits );
MPI generate_elg_prime( unsigned pbits, unsigned qbits, MPI g, MPI **factors ); MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **factors );
#endif /*G10_CIPHER_H*/ #endif /*G10_CIPHER_H*/

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.17 VERSION = 0.2.17a
ZLIBS = ZLIBS =
l = l =