diff --git a/g10/ChangeLog b/g10/ChangeLog index 1f9751293..ef6817037 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,12 @@ +2009-05-17 Werner Koch + + * keygen.c (ask_algo): Add arg R_SUBKEY_ALGO. Change return value + semantics. Change presented order of algorithms. Make RSA+RSA + the default. + (generate_keypair): Adjust for change. + (ask_keysize): Add arg PRIMARY_KEYSIZE for subkey creation. + Change callers. + 2009-05-15 Werner Koch * keygen.c (gen_card_key_with_backup): Get the size of the key diff --git a/g10/keygen.c b/g10/keygen.c index 96c68334e..1be65c42e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1636,94 +1636,141 @@ ask_key_flags(int algo,int subkey) } -/**************** - * Returns: 0 to create both a DSA and a Elgamal key. - * and only if key flags are to be written the desired usage. - */ +/* Ask for an algorithm. The function returns the algorithm id to + * create. If ADDMODE is false the function won't show an option to + * create the primary and subkey combined and won't set R_USAGE + * either. If a combined algorithm has been selected, the subkey + * algorithm is stored at R_SUBKEY_ALGO. */ static int -ask_algo (int addmode, unsigned int *r_usage) +ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) { - char *answer; - int algo; + char *answer; + int algo; + int dummy_algo; - *r_usage = 0; - tty_printf(_("Please select what kind of key you want:\n")); - if( !addmode ) - tty_printf(_(" (%d) DSA and Elgamal (default)\n"), 1 ); - tty_printf( _(" (%d) DSA (sign only)\n"), 2 ); - if (opt.expert) - tty_printf( _(" (%d) DSA (set your own capabilities)\n"), 3 ); - if( addmode ) - tty_printf(_(" (%d) Elgamal (encrypt only)\n"), 4 ); - tty_printf( _(" (%d) RSA (sign only)\n"), 5 ); - if (addmode) - tty_printf(_(" (%d) RSA (encrypt only)\n"), 6 ); - if (opt.expert) - tty_printf( _(" (%d) RSA (set your own capabilities)\n"), 7 ); + if (!r_subkey_algo) + r_subkey_algo = &dummy_algo; + + tty_printf (_("Please select what kind of key you want:\n")); - for(;;) { - answer = cpr_get("keygen.algo",_("Your selection? ")); - cpr_kill_prompt(); - algo = *answer? atoi(answer): 1; - xfree(answer); - if( algo == 1 && !addmode ) { - algo = 0; /* create both keys */ - break; - } - else if( algo == 7 && opt.expert ) { - algo = PUBKEY_ALGO_RSA; - *r_usage=ask_key_flags(algo,addmode); - break; - } - else if( algo == 6 && addmode ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 5 ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else if( algo == 4 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 3 && opt.expert ) { - algo = PUBKEY_ALGO_DSA; - *r_usage=ask_key_flags(algo,addmode); - break; - } - else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else - tty_printf(_("Invalid selection.\n")); + if (!addmode) + tty_printf (_(" (%d) RSA and RSA (default)\n"), 1 ); + if (!addmode) + tty_printf (_(" (%d) DSA and Elgamal\n"), 2 ); + + tty_printf (_(" (%d) DSA (sign only)\n"), 3 ); + tty_printf (_(" (%d) RSA (sign only)\n"), 4 ); + + if (addmode) + { + tty_printf (_(" (%d) Elgamal (encrypt only)\n"), 5 ); + tty_printf (_(" (%d) RSA (encrypt only)\n"), 6 ); } - - return algo; + if (opt.expert) + { + tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); + tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); + } + + for(;;) + { + *r_usage = 0; + *r_subkey_algo = 0; + answer = cpr_get ("keygen.algo", _("Your selection? ")); + cpr_kill_prompt (); + algo = *answer? atoi (answer) : 1; + xfree(answer); + if (algo == 1 && !addmode) + { + algo = PUBKEY_ALGO_RSA; + *r_subkey_algo = PUBKEY_ALGO_RSA; + break; + } + else if (algo == 2 && !addmode) + { + algo = PUBKEY_ALGO_DSA; + *r_subkey_algo = PUBKEY_ALGO_ELGAMAL_E; + break; + } + else if (algo == 3) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = PUBKEY_USAGE_SIG; + break; + } + else if (algo == 4) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_SIG; + break; + } + else if (algo == 5 && addmode) + { + algo = PUBKEY_ALGO_ELGAMAL_E; + *r_usage = PUBKEY_USAGE_ENC; + break; + } + else if (algo == 6 && addmode) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_ENC; + break; + } + else if (algo == 7 && opt.expert) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = ask_key_flags (algo, addmode); + break; + } + else if (algo == 8 && opt.expert) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = ask_key_flags (algo, addmode); + break; + } + else + tty_printf (_("Invalid selection.\n")); + } + + return algo; } +/* Ask for the key size. ALGO is the algorithjm. If PRIMARY_KEYSIZE + is not 0, the function asks for the size of the encryption + subkey. */ static unsigned -ask_keysize( int algo ) +ask_keysize (int algo, unsigned int primary_keysize) { unsigned int nbits, min, def=2048, max=4096; + int for_subkey = !!primary_keysize; + int autocomp = 0; if(opt.expert) min=512; else min=1024; + if (primary_keysize && !opt.expert) + { + /* Deduce the subkey size from the primary key size. */ + if (algo == PUBKEY_ALGO_DSA && primary_keysize > 3072) + nbits = 3072; /* For performance reasons we don't support more + than 3072 bit DSA. However we won't see this + case anyway because DSA can't be used as an + encryption subkey ;-). */ + else + nbits = primary_keysize; + autocomp = 1; + goto leave; + } + switch(algo) { case PUBKEY_ALGO_DSA: if(opt.flags.dsa2) { - def=1024; + def=2048; max=3072; } else @@ -1743,18 +1790,16 @@ ask_keysize( int algo ) for(;;) { - char *prompt,*answer; + char *prompt, *answer; -#define PROMPTSTRING _("What keysize do you want? (%u) ") - - prompt=xmalloc(strlen(PROMPTSTRING)+20); - sprintf(prompt,PROMPTSTRING,def); - -#undef PROMPTSTRING - - answer = cpr_get("keygen.size",prompt); - cpr_kill_prompt(); - nbits = *answer? atoi(answer): def; + if (for_subkey) + prompt = xasprintf (_("What keysize do you want " + "for the subkey? (%u) "), def); + else + prompt = xasprintf (_("What keysize do you want? (%u) "), def); + answer = cpr_get ("keygen.size", prompt); + cpr_kill_prompt (); + nbits = *answer? atoi (answer): def; xfree(prompt); xfree(answer); @@ -1767,15 +1812,18 @@ ask_keysize( int algo ) tty_printf(_("Requested keysize is %u bits\n"), nbits ); + leave: if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { nbits = ((nbits + 63) / 64) * 64; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf(_("rounded up to %u bits\n"), nbits ); } else if( (nbits % 32) ) { nbits = ((nbits + 31) / 32) * 32; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf(_("rounded up to %u bits\n"), nbits ); } return nbits; @@ -3003,16 +3051,19 @@ generate_keypair (const char *fname, const char *card_serialno, } else { - algo = ask_algo( 0, &use ); - if( !algo ) - { /* default: DSA with ElG subkey of the specified size */ + int subkey_algo; + + algo = ask_algo (0, &subkey_algo, &use); + if (subkey_algo) + { + /* Create primary and subkey at once. */ both = 1; r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; - sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); + sprintf( r->u.value, "%d", algo ); r->next = para; para = r; - nbits = ask_keysize( PUBKEY_ALGO_DSA ); + nbits = ask_keysize (algo, 0); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3024,10 +3075,9 @@ generate_keypair (const char *fname, const char *card_serialno, r->next = para; para = r; - algo = PUBKEY_ALGO_ELGAMAL_E; r = xmalloc_clear( sizeof *r + 20 ); r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); + sprintf( r->u.value, "%d", subkey_algo); r->next = para; para = r; r = xmalloc_clear( sizeof *r + 20 ); @@ -3055,10 +3105,10 @@ generate_keypair (const char *fname, const char *card_serialno, r->next = para; para = r; } - + nbits = 0; } - nbits = ask_keysize( algo ); + nbits = ask_keysize (algo, nbits); r = xmalloc_clear( sizeof *r + 20 ); r->key = both? pSUBKEYLENGTH : pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3658,9 +3708,9 @@ generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock) if (rc) goto leave; - algo = ask_algo (1, &use); + algo = ask_algo (1, NULL, &use); assert (algo); - nbits = ask_keysize (algo); + nbits = ask_keysize (algo, 0); expire = ask_expire_interval (0, NULL); if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", _("Really create? (y/N) "))) @@ -4017,8 +4067,8 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, mode_t oldmask; keyid_from_sk (sk, NULL); - sprintf (name_buffer,"sk_%08lX%08lX.gpg", - (ulong)sk->keyid[0], (ulong)sk->keyid[1]); + snprintf (name_buffer, sizeof name_buffer, "sk_%08lX%08lX.gpg", + (ulong)sk->keyid[0], (ulong)sk->keyid[1]); fname = make_filename (backup_dir, name_buffer, NULL); oldmask = umask (077);