1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

Made card key generate with backup key work for 2048 bit.

Improved card key generation prompts.
This commit is contained in:
Werner Koch 2009-05-15 19:26:46 +00:00
parent abc632a4a6
commit c4e92c3344
9 changed files with 130 additions and 75 deletions

View file

@ -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.

View file

@ -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",

View file

@ -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. */

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}