aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog21
-rw-r--r--g10/call-agent.c22
-rw-r--r--g10/call-agent.h5
-rw-r--r--g10/card-util.c16
-rw-r--r--g10/keydb.h10
-rw-r--r--g10/keygen.c42
-rw-r--r--g10/passphrase.c75
7 files changed, 119 insertions, 72 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index bd54d1976..1f9751293 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,8 +1,29 @@
+2009-05-15 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a
verify option for a couple of years now).
+2009-05-14 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* keygen.c (parse_expire_string): Base ISO date string at noon.
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 444048a47..c8a2013ac 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -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",
diff --git a/g10/call-agent.h b/g10/call-agent.h
index ebe37b1cd..577926e44 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -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. */
diff --git a/g10/card-util.c b/g10/card-util.c
index 1d263669f..7d36ebf9c 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -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);
diff --git a/g10/keydb.h b/g10/keydb.h
index 4e8245876..ca3ca77ec 100644
--- a/g10/keydb.h
+++ b/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);
diff --git a/g10/keygen.c b/g10/keygen.c
index 8afa74e3e..96c68334e 100644
--- a/g10/keygen.c
+++ b/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;
}
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 8b952f72a..f5d301398 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -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);
+}