aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/keygen.c')
-rw-r--r--g10/keygen.c78
1 files changed, 66 insertions, 12 deletions
diff --git a/g10/keygen.c b/g10/keygen.c
index 06b098822..d4b5fc121 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -94,6 +94,7 @@ enum para_name {
pSUBKEYGRIP,
pVERSION, /* Desired version of the key packet. */
pSUBVERSION, /* Ditto for the subpacket. */
+ pCARDKEY /* The keygrips have been taken from active card (bool). */
};
struct para_data_s {
@@ -103,6 +104,7 @@ struct para_data_s {
union {
u32 expire;
u32 creation;
+ int abool;
unsigned int usage;
struct revocation_key revkey;
char value[1];
@@ -1419,7 +1421,8 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
/* Create a keyblock using the given KEYGRIP. ALGO is the OpenPGP
algorithm of that keygrip. */
static int
-do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
+do_create_from_keygrip (ctrl_t ctrl, int algo,
+ const char *hexkeygrip, int cardkey,
kbnode_t pub_root, u32 timestamp, u32 expireval,
int is_subkey, int keygen_flags)
{
@@ -1448,7 +1451,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
{
unsigned char *public;
- err = agent_readkey (ctrl, 0, hexkeygrip, &public);
+ err = agent_readkey (ctrl, cardkey? 1:0, hexkeygrip, &public);
if (err)
return err;
err = gcry_sexp_sscan (&s_key, NULL,
@@ -2060,14 +2063,18 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
* algorithm is stored at R_SUBKEY_ALGO. If R_KEYGRIP is given, the
* user has the choice to enter the keygrip of an existing key. That
* keygrip is then stored at this address. The caller needs to free
- * it. */
+ * it. If R_CARDKEY is not NULL and the keygrip has been taken from
+ * an active card, true is stored there; if R_KEYTIME is not NULL the
+ * cretion time of that key is then stored there. */
static int
ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
- char **r_keygrip)
+ char **r_keygrip, int *r_cardkey, u32 *r_keytime)
{
gpg_error_t err;
char *keygrip = NULL;
+ u32 keytime = 0;
char *answer = NULL;
+ int cardkey = 0;
int algo;
int dummy_algo;
char *p;
@@ -2288,7 +2295,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
if (keyref)
{
keyref++;
- if (!agent_scd_readkey (keyref, &s_pkey))
+ if (!agent_scd_readkey (keyref, &s_pkey, NULL))
{
algostr = pubkey_algo_string (s_pkey, &algoid);
gcry_sexp_release (s_pkey);
@@ -2296,7 +2303,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
}
/* We use the flags also encode the algo for use
* below. We need to tweak the algo in case
- * GCRY_PK_ECC is returned becuase pubkey_algo_string
+ * GCRY_PK_ECC is returned because pubkey_algo_string
* is not aware of the OpenPGP algo mapping.
* FIXME: This is an ugly hack. */
sl->flags &= 0xff;
@@ -2366,9 +2373,22 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
xfree (keygrip);
keygrip = xstrdup (sl->d);
+ cardkey = 1;
if ((p = strchr (keygrip, ' ')))
*p = 0;
algo = (sl->flags >>8);
+
+ err = agent_scd_readkey (keygrip, NULL, &keytime);
+ if (err)
+ {
+ tty_printf (_("error reading the card: %s\n"),
+ gpg_strerror (err));
+ free_strlist (keypairlist);
+ xfree (keygrip);
+ keygrip = NULL;
+ goto ask_again;
+ }
+
if (opt.expert)
*r_usage = ask_key_flags_with_mask (algo, addmode,
(sl->flags & 0xff),
@@ -2392,6 +2412,10 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
xfree(answer);
if (r_keygrip)
*r_keygrip = keygrip;
+ if (r_cardkey)
+ *r_cardkey = cardkey;
+ if (r_keytime)
+ *r_keytime = keytime;
return algo;
}
@@ -3431,7 +3455,7 @@ parse_key_parameter_part (ctrl_t ctrl,
else
continue; /* Not usable for us. */
- if (agent_scd_readkey (keyref, &s_pkey))
+ if (agent_scd_readkey (keyref, &s_pkey, NULL))
continue; /* Could not read the key. */
algostr = pubkey_algo_string (s_pkey, &algoid);
@@ -3962,6 +3986,14 @@ get_parameter_revkey( struct para_data_s *para, enum para_name key )
}
static int
+get_parameter_bool (struct para_data_s *para, enum para_name key)
+{
+ struct para_data_s *r = get_parameter (para, key);
+ return (r && r->u.abool);
+}
+
+
+static int
proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
struct output_control_s *outctrl, int card )
{
@@ -4757,8 +4789,11 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
{
int subkey_algo;
char *key_from_hexgrip = NULL;
+ int cardkey;
+ u32 keytime;
- algo = ask_algo (ctrl, 0, &subkey_algo, &use, &key_from_hexgrip);
+ algo = ask_algo (ctrl, 0, &subkey_algo, &use,
+ &key_from_hexgrip, &cardkey, &keytime);
if (key_from_hexgrip)
{
r = xmalloc_clear( sizeof *r + 20 );
@@ -4785,6 +4820,21 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
r->next = para;
para = r;
+ r = xmalloc_clear (sizeof *r);
+ r->key = pCARDKEY;
+ r->u.abool = cardkey;
+ r->next = para;
+ para = r;
+
+ if (cardkey)
+ {
+ r = xmalloc_clear (sizeof *r);
+ r->key = pKEYCREATIONDATE;
+ r->u.creation = keytime;
+ r->next = para;
+ para = r;
+ }
+
xfree (key_from_hexgrip);
}
else
@@ -5169,6 +5219,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
int algo;
u32 expire;
const char *key_from_hexgrip = NULL;
+ int cardkey;
unsigned int keygen_flags;
if (outctrl->dryrun)
@@ -5238,13 +5289,14 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
algo = get_parameter_algo (ctrl, para, pKEYTYPE, NULL );
expire = get_parameter_u32( para, pKEYEXPIRE );
key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
+ cardkey = get_parameter_bool (para, pCARDKEY);
keygen_flags = outctrl->keygen_flags;
if (get_parameter_uint (para, pVERSION) == 5)
keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
if (key_from_hexgrip)
- err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
+ err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip, cardkey,
pub_root, timestamp, expire, 0, keygen_flags);
else if (!card)
err = do_create (algo,
@@ -5318,7 +5370,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
if (key_from_hexgrip)
- err = do_create_from_keygrip (ctrl, subkey_algo, key_from_hexgrip,
+ err = do_create_from_keygrip (ctrl, subkey_algo,
+ key_from_hexgrip, cardkey,
pub_root, timestamp,
get_parameter_u32 (para, pSUBKEYEXPIRE),
1, keygen_flags);
@@ -5596,6 +5649,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
const char *curve = NULL;
u32 cur_time;
char *key_from_hexgrip = NULL;
+ int cardkey = 0;
char *hexgrip = NULL;
char *serialno = NULL;
char *cache_nonce = NULL;
@@ -5660,7 +5714,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
if (interactive)
{
- algo = ask_algo (ctrl, 1, NULL, &use, &key_from_hexgrip);
+ algo = ask_algo (ctrl, 1, NULL, &use, &key_from_hexgrip, &cardkey, NULL);
log_assert (algo);
if (key_from_hexgrip)
@@ -5713,7 +5767,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
/* Start creation. */
if (key_from_hexgrip)
{
- err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
+ err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip, cardkey,
keyblock, cur_time, expire, 1,
keygen_flags);
}