diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 5 | ||||
-rw-r--r-- | g10/build-packet.c | 23 | ||||
-rw-r--r-- | g10/g10.c | 18 | ||||
-rw-r--r-- | g10/keyedit.c | 3 | ||||
-rw-r--r-- | g10/keygen.c | 95 | ||||
-rw-r--r-- | g10/main.h | 1 |
6 files changed, 138 insertions, 7 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index b61ea5cda..e69f10865 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +Tue May 5 22:11:59 1998 Werner Koch ([email protected]) + + * keygen.c (gen_dsa): New. + * build_packet.c (do_secret_cert): Support for DSA + Mon May 4 19:01:25 1998 Werner Koch ([email protected]) * compress.c: doubled buffer sizes diff --git a/g10/build-packet.c b/g10/build-packet.c index 07aaf0676..da6e413ac 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -292,6 +292,29 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc ) mpi_write(a, skc->d.elg.x ); 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) ) { mpi_write(a, skc->d.rsa.n ); mpi_write(a, skc->d.rsa.e ); @@ -72,6 +72,7 @@ static ARGPARSE_OPTS opts[] = { { 515, "fingerprint", 0, N_("list keys and fingerprints")}, #ifdef IS_G10 { 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")}, { 505, "delete-key",0, N_("remove key from the public keyring")}, { 524, "edit-key" ,0, N_("edit a key signature")}, @@ -171,7 +172,7 @@ enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey, aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys, - aListSigs, + aListSigs, aKeyadd, aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs, aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest, aNOP }; @@ -574,6 +575,7 @@ main( int argc, char **argv ) case 551: set_cmd( &cmd, aListKeys); break; case 552: set_cmd( &cmd, aListSigs); break; case 553: opt.skip_verify=1; break; + case 554: set_cmd( &cmd, aKeyadd); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -817,6 +819,11 @@ main( int argc, char **argv ) wrong_args("--gen-key"); generate_keypair(); break; + case aKeyadd: /* add a subkey (interactive) */ + if( argc != 1 ) + wrong_args("--add-key userid"); + generate_subkeypair(*argv); + break; #endif case aImport: @@ -873,19 +880,24 @@ main( int argc, char **argv ) putchar('\n'); } 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); putchar('\n'); } else if( argc == 3 ) { 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); printf("\nGenerator: "); mpi_print( stdout, g, 1 ); putchar('\n'); 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 usage(1); break; diff --git a/g10/keyedit.c b/g10/keyedit.c index 0a4afbf43..a475ed813 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -621,6 +621,8 @@ change_passphrase( const char *username ) break; } + /* fixme: unprotect all subkeys */ + if( rc ) tty_printf("Can't edit this key: %s\n", g10_errstr(rc)); else { @@ -648,6 +650,7 @@ change_passphrase( const char *username ) break; } else { /* okay */ + /* fixme: protect all subkeys too */ skc->protect.algo = dek->algo; skc->protect.s2k = *s2k; rc = protect_secret_key( skc, dek ); diff --git a/g10/keygen.c b/g10/keygen.c index e714c1605..771dcb36c 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -224,11 +224,84 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, #endif /*ENABLE_RSA_KEYGEN*/ +/**************** + * Generate a DSA key + */ static int 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 ) { algo = PUBKEY_ALGO_DSA; algo_name = "DSA"; - tty_printf(_("Sorry; DSA key generation is not yet supported.\n")); + break; } #ifdef ENABLE_RSA_KEYGEN else if( algo == 3 ) { @@ -380,6 +453,10 @@ generate_keypair() " <n>w = key expires in n weeks\n" " <n>m = key expires in n months\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; for(;;) { int mult; @@ -578,7 +655,7 @@ generate_keypair() 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, s2k, &skc, valid_days ); + rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, &skc, valid_days); else BUG(); if( !rc ) { @@ -663,3 +740,13 @@ generate_keypair() m_free(sec_fname); } + +/**************** + * add a new subkey to an existing key. + */ +void +generate_subkeypair( const char *userid ) +{ + log_fatal("To be implemented :-)\n"); +} + diff --git a/g10/main.h b/g10/main.h index 9a1ae4ddb..03436d058 100644 --- a/g10/main.h +++ b/g10/main.h @@ -70,6 +70,7 @@ int change_passphrase( const char *username ); /*-- keygen.c --*/ void generate_keypair(void); +void generate_subkeypair(const char *userid); /*-- openfile.c --*/ int overwrite_filep( const char *fname ); |