aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/call-agent.c118
-rw-r--r--g10/call-agent.h10
-rw-r--r--g10/keygen.c54
3 files changed, 45 insertions, 137 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 0fb392c9c..632cabe8b 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -103,13 +103,6 @@ struct cache_nonce_parm_s
};
-struct scd_genkey_parm_s
-{
- struct agent_card_genkey_s *cgk;
- char *savedbytes; /* Malloced space to save key parameter chunks. */
-};
-
-
static gpg_error_t learn_status_cb (void *opaque, const char *line);
@@ -979,133 +972,50 @@ agent_scd_writekey (int keyno, const char *serialno,
-static gpg_error_t
-scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
- const char *line)
-{
- gpg_error_t err = 0;
- char *p;
-
- if (!parm->savedbytes)
- {
- parm->savedbytes = xtrystrdup (line);
- if (!parm->savedbytes)
- err = gpg_error_from_syserror ();
- }
- else
- {
- p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
- if (!p)
- err = gpg_error_from_syserror ();
- else
- {
- strcpy (stpcpy (p, parm->savedbytes), line);
- xfree (parm->savedbytes);
- parm->savedbytes = p;
- }
- }
-
- return err;
-}
-
/* Status callback for the SCD GENKEY command. */
static gpg_error_t
scd_genkey_cb (void *opaque, const char *line)
{
- struct scd_genkey_parm_s *parm = opaque;
+ u32 *createtime = opaque;
const char *keyword = line;
int keywordlen;
- gpg_error_t rc = 0;
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
;
while (spacep (line))
line++;
- if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
- {
- parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
- }
- else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
- {
- gcry_mpi_t a;
- const char *name = line;
-
- while (*line && !spacep (line))
- line++;
- while (spacep (line))
- line++;
-
- if (*name == '-' && spacep (name+1))
- rc = scd_genkey_cb_append_savedbytes (parm, line);
- else
- {
- if (parm->savedbytes)
- {
- rc = scd_genkey_cb_append_savedbytes (parm, line);
- if (!rc)
- rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
- parm->savedbytes, 0, NULL);
- }
- else
- rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
- if (rc)
- log_error ("error parsing received key data: %s\n",
- gpg_strerror (rc));
- else if (*name == 'n' && spacep (name+1))
- parm->cgk->n = a;
- else if (*name == 'e' && spacep (name+1))
- parm->cgk->e = a;
- else
- {
- log_info ("unknown parameter name in received key data\n");
- gcry_mpi_release (a);
- rc = gpg_error (GPG_ERR_INV_PARAMETER);
- }
-
- xfree (parm->savedbytes);
- parm->savedbytes = NULL;
- }
- }
- else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
+ if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
{
- parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
+ *createtime = (u32)strtoul (line, NULL, 10);
}
else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
{
write_status_text (STATUS_PROGRESS, line);
}
- return rc;
+ return 0;
}
-/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
- this implementation. If CREATEDATE is not 0, it will be passed to
- SCDAEMON so that the key is created with this timestamp. INFO will
- receive information about the generated key. */
+/* Send a GENKEY command to the SCdaemon. If CREATETIME is not 0, it
+ will be passed to SCDAEMON so that the key is created with this
+ timestamp. On success, creation time is stored back to CREATETIME. */
int
-agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
- const char *serialno, u32 createtime)
+agent_scd_genkey (int keyno, int force, u32 *createtime)
{
int rc;
char line[ASSUAN_LINELENGTH];
gnupg_isotime_t tbuf;
- struct scd_genkey_parm_s parms;
struct default_inq_parm_s dfltparm;
memset (&dfltparm, 0, sizeof dfltparm);
- (void)serialno;
-
- memset (&parms, 0, sizeof parms);
- parms.cgk = info;
-
rc = start_agent (NULL, 1);
if (rc)
return rc;
- if (createtime)
- epoch2isotime (tbuf, createtime);
+ if (*createtime)
+ epoch2isotime (tbuf, *createtime);
else
*tbuf = 0;
@@ -1116,12 +1026,9 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
line[DIM(line)-1] = 0;
dfltparm.ctx = agent_ctx;
- memset (info, 0, sizeof *info);
rc = assuan_transact (agent_ctx, line,
NULL, NULL, default_inq_cb, &dfltparm,
- scd_genkey_cb, &parms);
-
- xfree (parms.savedbytes);
+ scd_genkey_cb, createtime);
status_sc_op_failure (rc);
return rc;
@@ -1854,7 +1761,8 @@ agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
if (err)
return err;
- snprintf (line, DIM(line)-1, "%sREADKEY %s", fromcard? "SCD ":"", hexkeygrip);
+ snprintf (line, DIM(line)-1, "READKEY %s%s", fromcard? "--card ":"",
+ hexkeygrip);
init_membuf (&data, 1024);
err = assuan_transact (agent_ctx, line,
diff --git a/g10/call-agent.h b/g10/call-agent.h
index d85a6fd5d..032c345e5 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -68,13 +68,6 @@ struct agent_card_info_s
unsigned int status_indicator;
};
-struct agent_card_genkey_s {
- char fprvalid;
- char fpr[20];
- u32 created_at;
- gcry_mpi_t n;
- gcry_mpi_t e;
-};
/* Release the card info structure. */
@@ -107,8 +100,7 @@ int agent_scd_writekey (int keyno, const char *serialno,
const unsigned char *keydata, size_t keydatalen);
/* Send a GENKEY command to the SCdaemon. */
-int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
- const char *serialno, u32 createtime);
+int agent_scd_genkey (int keyno, int force, u32 *createtime);
/* Send a READKEY command to the SCdaemon. */
int agent_scd_readcert (const char *certidstr,
diff --git a/g10/keygen.c b/g10/keygen.c
index 9cf314d29..90f8544cb 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4870,9 +4870,14 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
{
#ifdef ENABLE_CARD_SUPPORT
gpg_error_t err;
- struct agent_card_genkey_s info;
PACKET *pkt;
PKT_public_key *pk;
+ char keyid[10];
+ unsigned char *public;
+ gcry_sexp_t s_key;
+
+ snprintf (keyid, DIM(keyid)-1, "OPENPGP.%d", keyno);
+ keyid[DIM(keyid)-1] = 0;
if (algo != PUBKEY_ALGO_RSA)
return gpg_error (GPG_ERR_PUBKEY_ALGO);
@@ -4888,7 +4893,7 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
}
/* Note: SCD knows the serialnumber, thus there is no point in passing it. */
- err = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
+ err = agent_scd_genkey (keyno, 1, timestamp);
/* The code below is not used because we force creation of
* the a card key (3rd arg).
* if (gpg_err_code (rc) == GPG_ERR_EEXIST)
@@ -4898,16 +4903,9 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
* tty_printf ("\n");
* if ( cpr_get_answer_is_yes( "keygen.card.replace_key",
* _("Replace existing key? ")))
- * rc = agent_scd_genkey (&info, keyno, 1);
+ * rc = agent_scd_genkey (keyno, 1, timestamp);
* }
*/
- if (!err && (!info.n || !info.e))
- {
- log_error ("communication error with SCD\n");
- gcry_mpi_release (info.n);
- gcry_mpi_release (info.e);
- err = gpg_error (GPG_ERR_GENERAL);
- }
if (err)
{
log_error ("key generation failed: %s\n", gpg_strerror (err));
@@ -4916,30 +4914,40 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
return err;
}
- /* Send the learn command so that the agent creates a shadow key for
+ /* Send the READKEY command so that the agent creates a shadow key for
card key. We need to do that now so that we are able to create
the self-signatures. */
- err = agent_scd_learn (NULL, 0);
+ err = agent_readkey (NULL, 1, keyid, &public);
+ if (err)
+ return err;
+ err = gcry_sexp_sscan (&s_key, NULL, public,
+ gcry_sexp_canon_len (public, 0, NULL, NULL));
+ xfree (public);
+ if (err)
+ return err;
+
+ if (algo == PUBKEY_ALGO_RSA)
+ err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
+ else if (algo == PUBKEY_ALGO_ECDSA
+ || algo == PUBKEY_ALGO_EDDSA
+ || algo == PUBKEY_ALGO_ECDH )
+ err = ecckey_from_sexp (pk->pkey, s_key, algo);
+ else
+ err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ gcry_sexp_release (s_key);
+
if (err)
{
- /* Oops: Card removed during generation. */
- log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
- xfree (pkt);
- xfree (pk);
+ log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
+ free_public_key (pk);
return err;
}
- if (*timestamp != info.created_at)
- log_info ("NOTE: the key does not use the suggested creation date\n");
- *timestamp = info.created_at;
-
- pk->timestamp = info.created_at;
+ pk->timestamp = *timestamp;
pk->version = 4;
if (expireval)
pk->expiredate = pk->timestamp + expireval;
pk->pubkey_algo = algo;
- pk->pkey[0] = info.n;
- pk->pkey[1] = info.e;
pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
pkt->pkt.public_key = pk;