mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
Made card key generate with backup key work for 2048 bit.
Improved card key generation prompts.
This commit is contained in:
parent
abc632a4a6
commit
c4e92c3344
@ -579,8 +579,10 @@ manually. Comment lines, indicated by a leading hash mark, as well as
|
||||
empty lines are ignored. An entry starts with optional whitespace,
|
||||
followed by the keygrip of the key given as 40 hex digits, optionally
|
||||
followed by the caching TTL in seconds and another optional field for
|
||||
arbitrary flags. The keygrip may be prefixed with a @code{!} to
|
||||
disable this entry.
|
||||
arbitrary flags. A non-zero TTL overrides the global default as
|
||||
set by @option{--default-cache-ttl-ssh}.
|
||||
|
||||
The keygrip may be prefixed with a @code{!} to disable an entry entry.
|
||||
|
||||
The following example lists exactly one key. Note that keys available
|
||||
through a OpenPGP smartcard in the active smartcard reader are
|
||||
@ -1054,7 +1056,7 @@ special handling of passphrases. This command uses a syntax which helps
|
||||
clients to use the agent with minimum effort.
|
||||
|
||||
@example
|
||||
GET_PASSPHRASE [--data] [--check] [--no-ask] @var{cache_id} [@var{error_message} @var{prompt} @var{description}]
|
||||
GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] [--qualitybar] @var{cache_id} [@var{error_message} @var{prompt} @var{description}]
|
||||
@end example
|
||||
|
||||
@var{cache_id} is expected to be a string used to identify a cached
|
||||
@ -1089,6 +1091,9 @@ If the option @option{--no-ask} is used and the passphrase is not in the
|
||||
cache the user will not be asked to enter a passphrase but the error
|
||||
code @code{GPG_ERR_NO_DATA} is returned.
|
||||
|
||||
If the option @option{--qualitybar} is used and a minimum passphrase
|
||||
length has been configured, a visual indication of the entered
|
||||
passphrase quality is shown.
|
||||
|
||||
@example
|
||||
CLEAR_PASSPHRASE @var{cache_id}
|
||||
|
@ -1,8 +1,29 @@
|
||||
2009-05-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keygen.c (gen_card_key_with_backup): Get the size of the key
|
||||
from the card.
|
||||
* call-agent.h (struct agent_card_info_s): Add field KEY_ATTR.
|
||||
* call-agent.c (learn_status_cb): Support KEY-ATTR.
|
||||
* card-util.c (card_status): Print key attributes.
|
||||
|
||||
2009-05-15 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a
|
||||
verify option for a couple of years now).
|
||||
|
||||
2009-05-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* call-agent.c (agent_get_passphrase): Add arg CHECK.
|
||||
* passphrase.c (passphrase_get): Pass new arg.
|
||||
|
||||
* keygen.c (gen_card_key_with_backup): Print a status error.
|
||||
(do_generate_keypair): Ditto.
|
||||
(do_ask_passphrase): Add arg MODE.
|
||||
(generate_raw_key): Call with mode 1.
|
||||
* passphrase.c (ask_passphrase): Remove becuase it is not used.
|
||||
(passphrase_to_dek): Factor code out to ...
|
||||
(passphrase_to_dek_ext): .. New. Add args CUSTDESC and CUSTPROMPT.
|
||||
|
||||
2009-05-13 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keygen.c (parse_expire_string): Base ISO date string at noon.
|
||||
|
@ -325,7 +325,19 @@ learn_status_cb (void *opaque, const char *line)
|
||||
else if (no == 3)
|
||||
parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
|
||||
}
|
||||
|
||||
else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
|
||||
{
|
||||
int keyno, algo, nbits;
|
||||
|
||||
sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
|
||||
keyno--;
|
||||
if (keyno >= 0 && keyno < DIM (parm->key_attr))
|
||||
{
|
||||
parm->key_attr[keyno].algo = algo;
|
||||
parm->key_attr[keyno].nbits = nbits;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -343,6 +355,9 @@ agent_learn (struct agent_card_info_s *info)
|
||||
rc = assuan_transact (agent_ctx, "LEARN --send",
|
||||
dummy_data_cb, NULL, default_inq_cb, NULL,
|
||||
learn_status_cb, info);
|
||||
/* Also try to get the key attributes. */
|
||||
if (!rc)
|
||||
agent_scd_getattr ("KEY-ATTR", info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -535,7 +550,6 @@ scd_genkey_cb (void *opaque, const char *line)
|
||||
int keywordlen;
|
||||
gpg_error_t rc;
|
||||
|
||||
log_debug ("got status line `%s'\n", line);
|
||||
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
|
||||
;
|
||||
while (spacep (line))
|
||||
@ -827,6 +841,7 @@ agent_get_passphrase (const char *cache_id,
|
||||
const char *prompt,
|
||||
const char *desc_msg,
|
||||
int repeat,
|
||||
int check,
|
||||
char **r_passphrase)
|
||||
{
|
||||
int rc;
|
||||
@ -863,8 +878,9 @@ agent_get_passphrase (const char *cache_id,
|
||||
goto no_mem;
|
||||
|
||||
snprintf (line, DIM(line)-1,
|
||||
"GET_PASSPHRASE --data --repeat=%d -- %s %s %s %s",
|
||||
"GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
|
||||
repeat,
|
||||
check? " --check --qualitybar":"",
|
||||
arg1? arg1:"X",
|
||||
arg2? arg2:"X",
|
||||
arg3? arg3:"X",
|
||||
|
@ -53,6 +53,10 @@ struct agent_card_info_s
|
||||
int is_v2; /* True if this is a v2 card. */
|
||||
int chvmaxlen[3]; /* Maximum allowed length of a CHV. */
|
||||
int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */
|
||||
struct { /* Array with key attributes. */
|
||||
int algo; /* Algorithm identifier. */
|
||||
unsigned int nbits; /* Supported keysize. */
|
||||
} key_attr[3];
|
||||
};
|
||||
|
||||
struct agent_card_genkey_s {
|
||||
@ -116,6 +120,7 @@ gpg_error_t agent_get_passphrase (const char *cache_id,
|
||||
const char *prompt,
|
||||
const char *desc_msg,
|
||||
int repeat,
|
||||
int check,
|
||||
char **r_passphrase);
|
||||
|
||||
/* Send the CLEAR_PASSPHRASE command to the agent. */
|
||||
|
@ -443,6 +443,10 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
fputs (":\n", fp);
|
||||
|
||||
fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
|
||||
for (i=0; i < DIM (info.key_attr); i++)
|
||||
if (info.key_attr[0].algo)
|
||||
fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
|
||||
info.key_attr[i].algo, info.key_attr[i].nbits);
|
||||
fprintf (fp, "maxpinlen:%d:%d:%d:\n",
|
||||
info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
|
||||
fprintf (fp, "pinretry:%d:%d:%d:\n",
|
||||
@ -518,6 +522,16 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
}
|
||||
tty_fprintf (fp, "Signature PIN ....: %s\n",
|
||||
info.chv1_cached? _("not forced"): _("forced"));
|
||||
if (info.key_attr[0].algo)
|
||||
{
|
||||
tty_fprintf (fp, "Key attributes ...:");
|
||||
for (i=0; i < DIM (info.key_attr); i++)
|
||||
tty_fprintf (fp, " %u%c",
|
||||
info.key_attr[i].nbits,
|
||||
info.key_attr[i].algo == 1? 'R':
|
||||
info.key_attr[i].algo == 17? 'D': '?');
|
||||
tty_fprintf (fp, "\n");
|
||||
}
|
||||
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
|
||||
info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
|
||||
tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
|
||||
@ -1077,7 +1091,7 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
|
||||
|
||||
*forced_chv1 = !info->chv1_cached;
|
||||
if (*forced_chv1)
|
||||
{ /* Switch of the forced mode so that during key generation we
|
||||
{ /* Switch off the forced mode so that during key generation we
|
||||
don't get bothered with PIN queries for each
|
||||
self-signature. */
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
|
||||
|
10
g10/keydb.h
10
g10/keydb.h
@ -202,11 +202,11 @@ int have_static_passphrase(void);
|
||||
void set_passphrase_from_string(const char *pass);
|
||||
void read_passphrase_from_fd( int fd );
|
||||
void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
|
||||
char *ask_passphrase (const char *description,
|
||||
const char *tryagain_text,
|
||||
const char *promptid,
|
||||
const char *prompt,
|
||||
const char *cacheid, int *canceled);
|
||||
DEK *passphrase_to_dek_ext(u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text,
|
||||
const char *custdesc, const char *custprompt,
|
||||
int *canceled);
|
||||
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text, int *canceled);
|
||||
|
42
g10/keygen.c
42
g10/keygen.c
@ -2153,21 +2153,28 @@ ask_user_id( int mode )
|
||||
}
|
||||
|
||||
|
||||
/* MODE 0 - standard
|
||||
1 - Ask for passphrase of the card backup key. */
|
||||
static DEK *
|
||||
do_ask_passphrase ( STRING2KEY **ret_s2k, int *r_canceled )
|
||||
do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled)
|
||||
{
|
||||
DEK *dek = NULL;
|
||||
STRING2KEY *s2k;
|
||||
const char *errtext = NULL;
|
||||
const char *custdesc = NULL;
|
||||
|
||||
tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
|
||||
|
||||
if (mode == 1)
|
||||
custdesc = _("Please enter a passphrase to protect the off-card "
|
||||
"backup of the new encryption key.");
|
||||
|
||||
s2k = xmalloc_secure( sizeof *s2k );
|
||||
for(;;) {
|
||||
s2k->mode = opt.s2k_mode;
|
||||
s2k->hash_algo = S2K_DIGEST_ALGO;
|
||||
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2,
|
||||
errtext, r_canceled);
|
||||
dek = passphrase_to_dek_ext (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
|
||||
errtext, custdesc, NULL, r_canceled);
|
||||
if (!dek && *r_canceled) {
|
||||
xfree(dek); dek = NULL;
|
||||
xfree(s2k); s2k = NULL;
|
||||
@ -2587,7 +2594,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
|
||||
STRING2KEY *s2k;
|
||||
DEK *dek;
|
||||
|
||||
dek = do_ask_passphrase ( &s2k, &canceled );
|
||||
dek = do_ask_passphrase (&s2k, 0, &canceled);
|
||||
if (dek)
|
||||
{
|
||||
r = xmalloc_clear( sizeof *r );
|
||||
@ -3085,7 +3092,7 @@ generate_keypair (const char *fname, const char *card_serialno,
|
||||
para = r;
|
||||
|
||||
canceled = 0;
|
||||
dek = card_serialno? NULL : do_ask_passphrase ( &s2k, &canceled );
|
||||
dek = card_serialno? NULL : do_ask_passphrase (&s2k, 0, &canceled);
|
||||
if( dek )
|
||||
{
|
||||
r = xmalloc_clear( sizeof *r );
|
||||
@ -3143,7 +3150,7 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at,
|
||||
log_info(_("keysize rounded up to %u bits\n"), nbits );
|
||||
}
|
||||
|
||||
dek = do_ask_passphrase (&s2k, &canceled);
|
||||
dek = do_ask_passphrase (&s2k, 1, &canceled);
|
||||
if (canceled)
|
||||
{
|
||||
rc = gpg_error (GPG_ERR_CANCELED);
|
||||
@ -3547,6 +3554,7 @@ do_generate_keypair (struct para_data_s *para,
|
||||
log_error ("key generation failed: %s\n", g10_errstr(rc) );
|
||||
else
|
||||
tty_printf (_("Key generation failed: %s\n"), g10_errstr(rc) );
|
||||
write_status_error (card? "card_key_generate":"key_generate", rc);
|
||||
print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
|
||||
}
|
||||
else
|
||||
@ -3660,7 +3668,7 @@ generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
|
||||
canceled = 0;
|
||||
if (ask_pass)
|
||||
dek = do_ask_passphrase (&s2k, &canceled);
|
||||
dek = do_ask_passphrase (&s2k, 0, &canceled);
|
||||
else if (passphrase)
|
||||
{
|
||||
s2k = xmalloc_secure ( sizeof *s2k );
|
||||
@ -3951,19 +3959,35 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
|
||||
PKT_public_key *pk;
|
||||
size_t n;
|
||||
int i;
|
||||
unsigned int nbits;
|
||||
|
||||
/* Get the size of the key directly from the card. */
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
|
||||
memset (&info, 0, sizeof info);
|
||||
if (!agent_scd_getattr ("KEY-ATTR", &info)
|
||||
&& info.key_attr[1].algo)
|
||||
nbits = info.key_attr[1].nbits;
|
||||
else
|
||||
nbits = 1024; /* All pre-v2.0 cards. */
|
||||
agent_release_card_info (&info);
|
||||
}
|
||||
|
||||
rc = generate_raw_key (algo, 1024, timestamp,
|
||||
/* Create a key of this size in memory. */
|
||||
rc = generate_raw_key (algo, nbits, timestamp,
|
||||
&sk_unprotected, &sk_protected);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* First, store the key to the card. */
|
||||
/* Store the key to the card. */
|
||||
rc = save_unprotected_key_to_card (sk_unprotected, keyno);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("storing key onto card failed: %s\n"), g10_errstr (rc));
|
||||
free_secret_key (sk_unprotected);
|
||||
free_secret_key (sk_protected);
|
||||
write_status_error ("save_key_to_card", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,8 @@ read_passphrase_from_fd( int fd )
|
||||
/*
|
||||
* Ask the GPG Agent for the passphrase.
|
||||
* Mode 0: Allow cached passphrase
|
||||
* 1: No cached passphrase FIXME: Not really implemented
|
||||
* 1: No cached passphrase; that is we are asking for a new passphrase
|
||||
* FIXME: Only partially implemented
|
||||
*
|
||||
* Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not
|
||||
* NULL, the function does set it to 1 if the user canceled the
|
||||
@ -260,6 +261,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
||||
char *my_prompt;
|
||||
char hexfprbuf[20*2+1];
|
||||
const char *my_cacheid;
|
||||
int check = (mode == 1);
|
||||
|
||||
if (canceled)
|
||||
*canceled = 0;
|
||||
@ -347,7 +349,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
||||
my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL;
|
||||
|
||||
rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
|
||||
repeat, &pw);
|
||||
repeat, check, &pw);
|
||||
|
||||
xfree (my_prompt);
|
||||
xfree (atext); atext = NULL;
|
||||
@ -432,54 +434,6 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Ask for a passphrase and return that string.
|
||||
*/
|
||||
char *
|
||||
ask_passphrase (const char *description,
|
||||
const char *tryagain_text,
|
||||
const char *promptid,
|
||||
const char *prompt,
|
||||
const char *cacheid, int *canceled)
|
||||
{
|
||||
char *pw = NULL;
|
||||
|
||||
(void)promptid;
|
||||
|
||||
if (canceled)
|
||||
*canceled = 0;
|
||||
|
||||
if (!opt.batch && description)
|
||||
{
|
||||
if (strchr (description, '%'))
|
||||
{
|
||||
char *tmp = percent_plus_unescape (description, 0xff);
|
||||
if (!tmp)
|
||||
log_fatal(_("out of core\n"));
|
||||
tty_printf ("\n%s\n", tmp);
|
||||
xfree (tmp);
|
||||
}
|
||||
else
|
||||
tty_printf ("\n%s\n",description);
|
||||
}
|
||||
|
||||
if (have_static_passphrase ())
|
||||
{
|
||||
pw = xmalloc_secure (strlen(fd_passwd)+1);
|
||||
strcpy (pw, fd_passwd);
|
||||
}
|
||||
else
|
||||
pw = passphrase_get (NULL, 0, cacheid, 0,
|
||||
tryagain_text, description, prompt,
|
||||
canceled );
|
||||
|
||||
if (!pw || !*pw)
|
||||
write_status( STATUS_MISSING_PASSPHRASE );
|
||||
|
||||
return pw;
|
||||
}
|
||||
|
||||
|
||||
/* Return a new DEK object Using the string-to-key sepcifier S2K. Use
|
||||
KEYID and PUBKEY_ALGO to prompt the user. Returns NULL is the user
|
||||
selected to cancel the passphrase entry and if CANCELED is not
|
||||
@ -490,9 +444,11 @@ ask_passphrase (const char *description,
|
||||
2: Ditto, but change the text to "repeat entry"
|
||||
*/
|
||||
DEK *
|
||||
passphrase_to_dek (u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text, int *canceled)
|
||||
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text,
|
||||
const char *custdesc, const char *custprompt,
|
||||
int *canceled)
|
||||
{
|
||||
char *pw = NULL;
|
||||
DEK *dek;
|
||||
@ -612,7 +568,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
|
||||
/* Divert to the gpg-agent. */
|
||||
pw = passphrase_get ( keyid, mode == 2, NULL,
|
||||
mode == 2? opt.passwd_repeat: 0,
|
||||
tryagain_text, NULL, NULL, canceled );
|
||||
tryagain_text, custdesc, custprompt, canceled);
|
||||
if (*canceled)
|
||||
{
|
||||
xfree (pw);
|
||||
@ -637,3 +593,14 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
|
||||
last_pw = pw;
|
||||
return dek;
|
||||
}
|
||||
|
||||
|
||||
DEK *
|
||||
passphrase_to_dek (u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text, int *canceled)
|
||||
{
|
||||
return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo,
|
||||
s2k, mode, tryagain_text, NULL, NULL,
|
||||
canceled);
|
||||
}
|
||||
|
@ -2368,6 +2368,9 @@ do_writekey (app_t app, ctrl_t ctrl,
|
||||
|
||||
maxbits = app->app_local->keyattr[keyno].n_bits;
|
||||
nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0;
|
||||
if (opt.verbose)
|
||||
log_info ("RSA modulus size is %u bits (%u bytes)\n",
|
||||
nbits, (unsigned int)rsa_n_len);
|
||||
if (nbits != maxbits)
|
||||
{
|
||||
log_error (_("RSA modulus missing or not of size %d bits\n"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user