mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-02 16:43:03 +01:00
See ChangeLog: Wed Mar 8 18:44:59 CET 2000 Werner Koch
This commit is contained in:
parent
f818c5ea6b
commit
0154d59f4d
@ -1,3 +1,22 @@
|
||||
2000-03-08 10:38:38 Werner Koch (wk@habibti.openit.de)
|
||||
|
||||
* keygen.c (ask_algo): Removed is_v4 return value and the commented
|
||||
code to create Elg keys in a v3 packet. Removed the rounding
|
||||
of key sizes here.
|
||||
(do_create): Likewise removed arg v4_packet.
|
||||
(gen_elg): Likewise removed arg version. Now rounding keysizes here.
|
||||
(gen_dsa): Rounding keysize now here.
|
||||
(release_parameter_list): New
|
||||
(get_parameter*): New.
|
||||
(proc_parameter_file): New.
|
||||
(read_parameter_file): New.
|
||||
(generate_keypair): Splitted. Now uses read_parameter_file when in
|
||||
batch mode. Additional argument to specify a parameter file.
|
||||
(do_generate_keypair): Main bulk of above fucntion and uses the
|
||||
parameter list.
|
||||
(do_create): Don't print long notice in batch mode.
|
||||
* g10.c (main): Allow batched key generation.
|
||||
|
||||
Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* pubkey-enc.c (get_it): Print a note about unknown cipher algos.
|
||||
|
15
g10/g10.c
15
g10/g10.c
@ -1258,10 +1258,17 @@ main( int argc, char **argv )
|
||||
wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
|
||||
break;
|
||||
|
||||
case aKeygen: /* generate a key (interactive) */
|
||||
if( argc )
|
||||
wrong_args("--gen-key");
|
||||
generate_keypair();
|
||||
case aKeygen: /* generate a key */
|
||||
if( opt.batch ) {
|
||||
if( argc > 1 )
|
||||
wrong_args("--gen-key [parameterfile]");
|
||||
generate_keypair( argc? *argv : NULL );
|
||||
}
|
||||
else {
|
||||
if( argc )
|
||||
wrong_args("--gen-key");
|
||||
generate_keypair(NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case aFastImport:
|
||||
|
537
g10/keygen.c
537
g10/keygen.c
@ -35,6 +35,37 @@
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
enum para_name {
|
||||
pKEYTYPE,
|
||||
pKEYLENGTH,
|
||||
pSUBKEYTYPE,
|
||||
pSUBKEYLENGTH,
|
||||
pNAMEREAL,
|
||||
pNAMEEMAIL,
|
||||
pNAMECOMMENT,
|
||||
pUSERID,
|
||||
pEXPIREDATE,
|
||||
pKEYEXPIRE, /* in n seconds */
|
||||
pSUBKEYEXPIRE, /* in n seconds */
|
||||
pPASSPHRASE,
|
||||
pPASSPHRASE_DEK,
|
||||
pPASSPHRASE_S2K
|
||||
};
|
||||
|
||||
struct para_data_s {
|
||||
struct para_data_s *next;
|
||||
int lnr;
|
||||
enum para_name key;
|
||||
union {
|
||||
DEK *dek;
|
||||
STRING2KEY *s2k;
|
||||
char value[1];
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
static void do_generate_keypair( struct para_data_s *para );
|
||||
|
||||
|
||||
static void
|
||||
write_uid( KBNODE root, const char *s )
|
||||
@ -192,8 +223,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk )
|
||||
|
||||
static int
|
||||
gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval,
|
||||
int version )
|
||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
@ -204,6 +234,17 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
MPI *factors;
|
||||
|
||||
assert( is_ELGAMAL(algo) );
|
||||
|
||||
if( nbits < 512 ) {
|
||||
nbits = 1024;
|
||||
log_info(_("keysize invalid; using %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
if( (nbits % 32) ) {
|
||||
nbits = ((nbits + 31) / 32) * 32;
|
||||
log_info(_("keysize rounded up to %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
rc = pubkey_generate( algo, nbits, skey, &factors );
|
||||
if( rc ) {
|
||||
log_error("pubkey_generate failed: %s\n", g10_errstr(rc) );
|
||||
@ -213,7 +254,7 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
sk = m_alloc_clear( sizeof *sk );
|
||||
pk = m_alloc_clear( sizeof *pk );
|
||||
sk->timestamp = pk->timestamp = make_timestamp();
|
||||
sk->version = pk->version = version;
|
||||
sk->version = pk->version = 4;
|
||||
if( expireval ) {
|
||||
sk->expiredate = pk->expiredate = sk->timestamp + expireval;
|
||||
}
|
||||
@ -267,7 +308,7 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
* Generate a DSA key
|
||||
*/
|
||||
static int
|
||||
gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
|
||||
{
|
||||
int rc;
|
||||
@ -278,8 +319,15 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
MPI skey[5];
|
||||
MPI *factors;
|
||||
|
||||
if( nbits > 1024 )
|
||||
if( nbits > 1024 || nbits < 512 ) {
|
||||
nbits = 1024;
|
||||
log_info(_("keysize invalid; using %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
if( (nbits % 64) ) {
|
||||
nbits = ((nbits + 63) / 64) * 64;
|
||||
log_info(_("keysize rounded up to %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
rc = pubkey_generate( PUBKEY_ALGO_DSA, nbits, skey, &factors );
|
||||
if( rc ) {
|
||||
@ -379,7 +427,7 @@ check_valid_days( const char *s )
|
||||
* Returns: 0 to create both a DSA and a ElGamal key.
|
||||
*/
|
||||
static int
|
||||
ask_algo( int *ret_v4, int addmode )
|
||||
ask_algo( int addmode )
|
||||
{
|
||||
char *answer;
|
||||
int algo;
|
||||
@ -391,11 +439,7 @@ ask_algo( int *ret_v4, int addmode )
|
||||
if( addmode )
|
||||
tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 );
|
||||
tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 4 );
|
||||
#if 0
|
||||
tty_printf( _(" (%d) ElGamal in a v3 packet\n"), 5 );
|
||||
#endif
|
||||
|
||||
*ret_v4 = 1;
|
||||
for(;;) {
|
||||
answer = cpr_get("keygen.algo",_("Your selection? "));
|
||||
cpr_kill_prompt();
|
||||
@ -420,13 +464,6 @@ ask_algo( int *ret_v4, int addmode )
|
||||
algo = PUBKEY_ALGO_DSA;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
else if( algo == 5 ) {
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
*ret_v4 = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
tty_printf(_("Invalid selection.\n"));
|
||||
}
|
||||
@ -781,12 +818,12 @@ ask_passphrase( STRING2KEY **ret_s2k )
|
||||
|
||||
static int
|
||||
do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
|
||||
DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate,
|
||||
int v4_packet )
|
||||
DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate )
|
||||
{
|
||||
int rc=0;
|
||||
|
||||
tty_printf(_(
|
||||
if( !opt.batch )
|
||||
tty_printf(_(
|
||||
"We need to generate a lot of random bytes. It is a good idea to perform\n"
|
||||
"some other action (type on the keyboard, move the mouse, utilize the\n"
|
||||
"disks) during the prime generation; this gives the random number\n"
|
||||
@ -794,7 +831,7 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
|
||||
|
||||
if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E )
|
||||
rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k,
|
||||
sk, expiredate, v4_packet? 4:3 );
|
||||
sk, expiredate );
|
||||
else if( algo == PUBKEY_ALGO_DSA )
|
||||
rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
|
||||
else
|
||||
@ -835,54 +872,409 @@ generate_user_id()
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_parameter_list( struct para_data_s *r )
|
||||
{
|
||||
struct para_data_s *r2;
|
||||
|
||||
for( ; r ; r = r2 ) {
|
||||
r2 = r->next;
|
||||
if( r->key == pPASSPHRASE_DEK )
|
||||
m_free( r->u.dek );
|
||||
else if( r->key == pPASSPHRASE_S2K )
|
||||
m_free( r->u.s2k );
|
||||
|
||||
m_free(r);
|
||||
}
|
||||
}
|
||||
|
||||
static struct para_data_s *
|
||||
get_parameter( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r;
|
||||
|
||||
for( r = para; r && r->key != key; r = r->next )
|
||||
;
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_parameter_value( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r = get_parameter( para, key );
|
||||
return (r && *r->u.value)? r->u.value : NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
get_parameter_algo( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r = get_parameter( para, key );
|
||||
if( !r )
|
||||
return -1;
|
||||
if( isdigit( *r->u.value ) )
|
||||
return atoi( r->u.value );
|
||||
return string_to_pubkey_algo( r->u.value );
|
||||
}
|
||||
|
||||
|
||||
static u32
|
||||
get_parameter_u32( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r = get_parameter( para, key );
|
||||
|
||||
if( !r )
|
||||
return 0;
|
||||
return (unsigned int)strtoul( r->u.value, NULL, 10 );
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_parameter_uint( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
return get_parameter_u32( para, key );
|
||||
}
|
||||
|
||||
static DEK *
|
||||
get_parameter_dek( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r = get_parameter( para, key );
|
||||
return r? r->u.dek : NULL;
|
||||
}
|
||||
|
||||
static STRING2KEY *
|
||||
get_parameter_s2k( struct para_data_s *para, enum para_name key )
|
||||
{
|
||||
struct para_data_s *r = get_parameter( para, key );
|
||||
return r? r->u.s2k : NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
proc_parameter_file( struct para_data_s *para, const char *fname )
|
||||
{
|
||||
struct para_data_s *r;
|
||||
const char *s1, *s2, *s3;
|
||||
size_t n;
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
/* check that we have all required parameters */
|
||||
assert( get_parameter( para, pKEYTYPE ) );
|
||||
i = get_parameter_algo( para, pKEYTYPE );
|
||||
if( i < 1 || check_pubkey_algo2( i, PUBKEY_USAGE_SIG ) ) {
|
||||
r = get_parameter( para, pKEYTYPE );
|
||||
log_error("%s:%d: invalid algorithm\n", fname, r->lnr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = get_parameter_algo( para, pSUBKEYTYPE );
|
||||
if( i > 1 && check_pubkey_algo( i ) ) {
|
||||
r = get_parameter( para, pSUBKEYTYPE );
|
||||
log_error("%s:%d: invalid algorithm\n", fname, r->lnr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !get_parameter_value( para, pUSERID ) ) {
|
||||
/* create the formatted user ID */
|
||||
s1 = get_parameter_value( para, pNAMEREAL );
|
||||
s2 = get_parameter_value( para, pNAMECOMMENT );
|
||||
s3 = get_parameter_value( para, pNAMEEMAIL );
|
||||
if( s1 || s2 || s3 ) {
|
||||
n = (s1?strlen(s1):0) + (s2?strlen(s2):0) + (s3?strlen(s3):0);
|
||||
r = m_alloc_clear( sizeof *r + n + 20 );
|
||||
r->key = pUSERID;
|
||||
p = r->u.value;
|
||||
if( s1 )
|
||||
p = stpcpy(p, s1 );
|
||||
if( s2 )
|
||||
p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
|
||||
if( s3 )
|
||||
p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
}
|
||||
|
||||
r = get_parameter( para, pPASSPHRASE );
|
||||
if( r && *r->u.value ) {
|
||||
/* we have a plain text passphrase - create a DEK from it.
|
||||
* It is a little bit ridiculous to keep it ih secure memory
|
||||
* but becuase we do this alwasy, why not here */
|
||||
STRING2KEY *s2k;
|
||||
DEK *dek;
|
||||
|
||||
s2k = m_alloc_secure( sizeof *s2k );
|
||||
s2k->mode = opt.s2k_mode;
|
||||
s2k->hash_algo = opt.s2k_digest_algo;
|
||||
set_next_passphrase( r->u.value );
|
||||
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
|
||||
set_next_passphrase( NULL );
|
||||
assert( dek );
|
||||
memset( r->u.value, 0, strlen(r->u.value) );
|
||||
|
||||
r = m_alloc_clear( sizeof *r );
|
||||
r->key = pPASSPHRASE_S2K;
|
||||
r->u.s2k = s2k;
|
||||
r->next = para;
|
||||
para = r;
|
||||
r = m_alloc_clear( sizeof *r );
|
||||
r->key = pPASSPHRASE_DEK;
|
||||
r->u.dek = dek;
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
do_generate_keypair( para );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Kludge to allow non interactive key generation controlled
|
||||
* by a parameter file (which currently is only stdin)
|
||||
* Note, that string parameters are expected to be in UTF-8
|
||||
*/
|
||||
static void
|
||||
read_parameter_file( const char *fname )
|
||||
{
|
||||
static struct { const char *name;
|
||||
enum para_name key;
|
||||
} keywords[] = {
|
||||
{ "Key-Type", pKEYTYPE},
|
||||
{ "Key-Length", pKEYLENGTH },
|
||||
{ "Subkey-Type", pSUBKEYTYPE },
|
||||
{ "Subkey-Length", pSUBKEYLENGTH },
|
||||
{ "Name-Real", pNAMEREAL },
|
||||
{ "Name-Email", pNAMEEMAIL },
|
||||
{ "Name-Comment", pNAMECOMMENT },
|
||||
{ "Expire-Date", pEXPIREDATE },
|
||||
{ "Passphrase", pPASSPHRASE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
FILE *fp;
|
||||
char line[1024], *p;
|
||||
int lnr;
|
||||
const char *err = NULL;
|
||||
struct para_data_s *para, *r;
|
||||
int i;
|
||||
|
||||
if( !fname || !*fname || !strcmp(fname,"-") ) {
|
||||
fp = stdin;
|
||||
fname = "-";
|
||||
}
|
||||
else {
|
||||
fp = fopen( fname, "r" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lnr = 0;
|
||||
err = NULL;
|
||||
para = NULL;
|
||||
while( fgets( line, DIM(line)-1, fp ) ) {
|
||||
char *keyword, *value;
|
||||
|
||||
lnr++;
|
||||
if( *line && line[strlen(line)-1] != '\n' ) {
|
||||
err = "line too long";
|
||||
break;
|
||||
}
|
||||
for( p = line; isspace(*p); p++ )
|
||||
;
|
||||
if( !*p || *p == '#' )
|
||||
continue;
|
||||
keyword = p;
|
||||
if( *keyword == '%' ) {
|
||||
/* for now these are all comments but in future they may be used
|
||||
* to control certain aspects */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( !(p = strchr( p, ':' )) || p == keyword ) {
|
||||
err = "missing colon";
|
||||
break;
|
||||
}
|
||||
*p++ = 0;
|
||||
for( ; isspace(*p); p++ )
|
||||
;
|
||||
if( !*p ) {
|
||||
err = "missing argument";
|
||||
break;
|
||||
}
|
||||
value = p;
|
||||
trim_trailing_ws( value, strlen(value) );
|
||||
|
||||
for(i=0; keywords[i].name; i++ ) {
|
||||
if( !stricmp( keywords[i].name, keyword ) )
|
||||
break;
|
||||
}
|
||||
if( !keywords[i].name ) {
|
||||
err = "unknown keyword";
|
||||
break;
|
||||
}
|
||||
if( keywords[i].key != pKEYTYPE && !para ) {
|
||||
err = "parameter block does not start with \"Key-Type\"";
|
||||
break;
|
||||
}
|
||||
|
||||
if( keywords[i].key == pKEYTYPE && para ) {
|
||||
proc_parameter_file( para, fname );
|
||||
release_parameter_list( para );
|
||||
para = NULL;
|
||||
}
|
||||
else {
|
||||
for( r = para; r; r = r->next ) {
|
||||
if( r->key == keywords[i].key )
|
||||
break;
|
||||
}
|
||||
if( r ) {
|
||||
err = "duplicate keyword";
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = m_alloc_clear( sizeof *r + strlen( value ) );
|
||||
r->lnr = lnr;
|
||||
r->key = keywords[i].key;
|
||||
strcpy( r->u.value, value );
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
if( err )
|
||||
log_error("%s:%d: %s\n", fname, lnr, err );
|
||||
else if( ferror(fp) ) {
|
||||
log_error("%s:%d: read error: %s\n", fname, lnr, strerror(errno) );
|
||||
}
|
||||
else if( para ) {
|
||||
proc_parameter_file( para, fname );
|
||||
}
|
||||
release_parameter_list( para );
|
||||
if( strcmp( fname, "-" ) )
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a keypair
|
||||
* (fname is only used in batch mode)
|
||||
*/
|
||||
void
|
||||
generate_keypair()
|
||||
generate_keypair( const char *fname )
|
||||
{
|
||||
unsigned nbits;
|
||||
char *pub_fname = NULL;
|
||||
char *sec_fname = NULL;
|
||||
unsigned int nbits;
|
||||
char *uid = NULL;
|
||||
KBNODE pub_root = NULL;
|
||||
KBNODE sec_root = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
DEK *dek;
|
||||
STRING2KEY *s2k;
|
||||
int rc;
|
||||
int algo;
|
||||
u32 expire;
|
||||
int v4;
|
||||
int both = 0;
|
||||
u32 expire;
|
||||
struct para_data_s *para = NULL;
|
||||
struct para_data_s *r;
|
||||
|
||||
if( opt.batch || opt.answer_yes || opt.answer_no ) {
|
||||
log_error(_("Key generation can only be used in interactive mode\n"));
|
||||
if( opt.batch ) {
|
||||
read_parameter_file( fname );
|
||||
return;
|
||||
}
|
||||
|
||||
algo = ask_algo( &v4, 0 );
|
||||
if( !algo ) {
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
algo = ask_algo( 0 );
|
||||
if( !algo ) { /* default: DSA with ElG subkey of the specified size */
|
||||
both = 1;
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pKEYTYPE;
|
||||
sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA );
|
||||
r->next = para;
|
||||
para = r;
|
||||
tty_printf(_("DSA keypair will have 1024 bits.\n"));
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pKEYLENGTH;
|
||||
strcpy( r->u.value, "1024" );
|
||||
r->next = para;
|
||||
para = r;
|
||||
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pSUBKEYTYPE;
|
||||
sprintf( r->u.value, "%d", algo );
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
else {
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pKEYTYPE;
|
||||
sprintf( r->u.value, "%d", algo );
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
|
||||
nbits = ask_keysize( algo );
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
|
||||
sprintf( r->u.value, "%u", nbits);
|
||||
r->next = para;
|
||||
para = r;
|
||||
|
||||
expire = ask_expire_interval();
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pKEYEXPIRE;
|
||||
sprintf( r->u.value, "%lu", (ulong)expire );
|
||||
r->next = para;
|
||||
para = r;
|
||||
if( both ) {
|
||||
r = m_alloc_clear( sizeof *r + 20 );
|
||||
r->key = pSUBKEYEXPIRE;
|
||||
sprintf( r->u.value, "%lu", (ulong)expire );
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
|
||||
uid = ask_user_id(0);
|
||||
if( !uid ) {
|
||||
log_error(_("Key generation canceled.\n"));
|
||||
release_parameter_list( para );
|
||||
return;
|
||||
}
|
||||
r = m_alloc_clear( sizeof *r + strlen(uid) );
|
||||
r->key = pUSERID;
|
||||
strcpy( r->u.value, uid );
|
||||
r->next = para;
|
||||
para = r;
|
||||
|
||||
dek = ask_passphrase( &s2k );
|
||||
if( dek ) {
|
||||
r = m_alloc_clear( sizeof *r );
|
||||
r->key = pPASSPHRASE_DEK;
|
||||
r->u.dek = dek;
|
||||
r->next = para;
|
||||
para = r;
|
||||
r = m_alloc_clear( sizeof *r );
|
||||
r->key = pPASSPHRASE_S2K;
|
||||
r->u.s2k = s2k;
|
||||
r->next = para;
|
||||
para = r;
|
||||
}
|
||||
|
||||
proc_parameter_file( para, "[internal]" );
|
||||
release_parameter_list( para );
|
||||
}
|
||||
|
||||
|
||||
/* now check whether we are allowed to write to the keyrings */
|
||||
static void
|
||||
do_generate_keypair( struct para_data_s *para )
|
||||
{
|
||||
char *pub_fname = NULL;
|
||||
char *sec_fname = NULL;
|
||||
KBNODE pub_root = NULL;
|
||||
KBNODE sec_root = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
const char *s;
|
||||
int rc;
|
||||
|
||||
/* check whether we are allowed to write to the keyrings */
|
||||
pub_fname = make_filename(opt.homedir, "pubring.gpg", NULL );
|
||||
sec_fname = make_filename(opt.homedir, "secring.gpg", NULL );
|
||||
if( opt.verbose ) {
|
||||
tty_printf(_("writing public certificate to `%s'\n"), pub_fname );
|
||||
tty_printf(_("writing secret certificate to `%s'\n"), sec_fname );
|
||||
log_info(_("writing public certificate to `%s'\n"), pub_fname );
|
||||
log_info(_("writing secret certificate to `%s'\n"), sec_fname );
|
||||
}
|
||||
|
||||
/* we create the packets as a tree of kbnodes. Because the structure
|
||||
@ -893,24 +1285,31 @@ generate_keypair()
|
||||
pub_root = make_comment_node("#"); delete_kbnode(pub_root);
|
||||
sec_root = make_comment_node("#"); delete_kbnode(sec_root);
|
||||
|
||||
if( both )
|
||||
rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root,
|
||||
dek, s2k, &sk, expire, 1);
|
||||
else
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, &sk, expire, v4);
|
||||
if( !rc )
|
||||
write_uid(pub_root, uid );
|
||||
if( !rc )
|
||||
write_uid(sec_root, uid );
|
||||
if( !rc )
|
||||
rc = write_selfsig(pub_root, pub_root, sk);
|
||||
if( !rc )
|
||||
rc = write_selfsig(sec_root, pub_root, sk);
|
||||
rc = do_create( get_parameter_algo( para, pKEYTYPE ),
|
||||
get_parameter_uint( para, pKEYLENGTH ),
|
||||
pub_root, sec_root,
|
||||
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
||||
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
||||
&sk,
|
||||
get_parameter_u32( para, pKEYEXPIRE ) );
|
||||
if( !rc && (s=get_parameter_value(para, pUSERID)) ) {
|
||||
write_uid(pub_root, s );
|
||||
if( !rc )
|
||||
write_uid(sec_root, s );
|
||||
if( !rc )
|
||||
rc = write_selfsig(pub_root, pub_root, sk);
|
||||
if( !rc )
|
||||
rc = write_selfsig(sec_root, pub_root, sk);
|
||||
}
|
||||
|
||||
if( both ) {
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, NULL, expire, 1 );
|
||||
if( get_parameter( para, pSUBKEYTYPE ) ) {
|
||||
rc = do_create( get_parameter_algo( para, pSUBKEYTYPE ),
|
||||
get_parameter_uint( para, pSUBKEYLENGTH ),
|
||||
pub_root, sec_root,
|
||||
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
||||
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
||||
NULL,
|
||||
get_parameter_u32( para, pSUBKEYEXPIRE ) );
|
||||
if( !rc )
|
||||
rc = write_keybinding(pub_root, pub_root, sk);
|
||||
if( !rc )
|
||||
@ -959,12 +1358,17 @@ generate_keypair()
|
||||
else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
|
||||
log_error("can't write secret key: %s\n", g10_errstr(rc) );
|
||||
else {
|
||||
tty_printf(_("public and secret key created and signed.\n") );
|
||||
if( algo == PUBKEY_ALGO_DSA )
|
||||
if( !opt.batch )
|
||||
tty_printf(_("public and secret key created and signed.\n") );
|
||||
if( !opt.batch
|
||||
&& get_parameter_algo( para, pKEYTYPE ) == PUBKEY_ALGO_DSA
|
||||
&& !get_parameter( para, pSUBKEYTYPE ) )
|
||||
{
|
||||
tty_printf(_("Note that this key cannot be used for "
|
||||
"encryption. You may want to use\n"
|
||||
"the command \"--edit-key\" to generate a "
|
||||
"secondary key for this purpose.\n") );
|
||||
}
|
||||
}
|
||||
|
||||
if( !rc1 )
|
||||
@ -974,15 +1378,16 @@ generate_keypair()
|
||||
}
|
||||
|
||||
|
||||
if( rc )
|
||||
tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
|
||||
if( rc ) {
|
||||
if( opt.batch )
|
||||
log_error(_("Key generation failed: %s\n"), g10_errstr(rc) );
|
||||
else
|
||||
tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
|
||||
}
|
||||
release_kbnode( pub_root );
|
||||
release_kbnode( sec_root );
|
||||
if( sk ) /* the unprotected secret key */
|
||||
free_secret_key(sk);
|
||||
m_free(uid);
|
||||
m_free(dek);
|
||||
m_free(s2k);
|
||||
m_free(pub_fname);
|
||||
m_free(sec_fname);
|
||||
}
|
||||
@ -998,7 +1403,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
int okay=0, rc=0;
|
||||
KBNODE node;
|
||||
PKT_secret_key *sk = NULL; /* this is the primary sk */
|
||||
int v4, algo;
|
||||
int algo;
|
||||
u32 expire;
|
||||
unsigned nbits;
|
||||
char *passphrase = NULL;
|
||||
@ -1049,7 +1454,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
goto leave;
|
||||
|
||||
|
||||
algo = ask_algo( &v4, 1 );
|
||||
algo = ask_algo( 1 );
|
||||
assert(algo);
|
||||
nbits = ask_keysize( algo );
|
||||
expire = ask_expire_interval();
|
||||
@ -1066,7 +1471,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
}
|
||||
|
||||
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
|
||||
dek, s2k, NULL, expire, v4 );
|
||||
dek, s2k, NULL, expire );
|
||||
if( !rc )
|
||||
rc = write_keybinding(pub_keyblock, pub_keyblock, sk);
|
||||
if( !rc )
|
||||
|
@ -92,7 +92,7 @@ void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds,
|
||||
|
||||
/*-- keygen.c --*/
|
||||
u32 ask_expiredate(void);
|
||||
void generate_keypair(void);
|
||||
void generate_keypair( const char *fname );
|
||||
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
||||
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
|
||||
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||
|
Loading…
x
Reference in New Issue
Block a user