From 0154d59f4d44955c311fbd822d66eec4445b2c6a Mon Sep 17 00:00:00 2001 From: Werner Koch <wk@gnupg.org> Date: Wed, 8 Mar 2000 17:42:19 +0000 Subject: [PATCH] See ChangeLog: Wed Mar 8 18:44:59 CET 2000 Werner Koch --- g10/ChangeLog | 19 ++ g10/g10.c | 15 +- g10/keygen.c | 537 +++++++++++++++++++++++++++++++++++++++++++------- g10/main.h | 2 +- 4 files changed, 502 insertions(+), 71 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index ac7e6c846..3b21ace0c 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -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. diff --git a/g10/g10.c b/g10/g10.c index ae04184b9..38cd4bbec 100644 --- a/g10/g10.c +++ b/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: diff --git a/g10/keygen.c b/g10/keygen.c index 11c840786..2ed5a70e4 100644 --- a/g10/keygen.c +++ b/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 ) diff --git a/g10/main.h b/g10/main.h index 9a4969415..5a63fe636 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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 );