aboutsummaryrefslogtreecommitdiffstats
path: root/g10/call-agent.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2011-06-16 12:27:33 +0000
committerWerner Koch <[email protected]>2011-06-16 12:27:33 +0000
commit37228cfa05005d56f0683782004edddb964f9192 (patch)
tree587671a8757d77a9904d0a60cc38bd407084fa4f /g10/call-agent.c
parentFix for latest fix in Libgcrypt. (diff)
downloadgnupg-37228cfa05005d56f0683782004edddb964f9192.tar.gz
gnupg-37228cfa05005d56f0683782004edddb964f9192.zip
Allow generation of card keys up to 4096 bit.
This patch implementes a chunk mode to pass the key parameters from scdaemon to gpg. This allows to pass arbitrary long key paremeters; it is used for keys larger than 3072 bit. Note: the card key generation in gpg is currently broken. The keys are generated but it is not possible to create the self-signature because at that time the gpg-agent does not yet know about the new keys and thus can't divert the sign request to the card. We either need to run the learn command right after calling agent_scd_genkey or implement a way to sign using the currently inserted card. Another option would be to get rid of agent_scd_genkey and implement the feature directly in agent_genkey.
Diffstat (limited to '')
-rw-r--r--g10/call-agent.c90
1 files changed, 75 insertions, 15 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 03ea1685f..5a10dbdb9 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -93,6 +93,13 @@ 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);
@@ -717,14 +724,43 @@ 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 agent_card_genkey_s *parm = opaque;
+ struct scd_genkey_parm_s *parm = opaque;
const char *keyword = line;
int keywordlen;
- gpg_error_t rc;
+ gpg_error_t rc = 0;
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
;
@@ -733,7 +769,7 @@ scd_genkey_cb (void *opaque, const char *line)
if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
{
- parm->fprvalid = unhexify_fpr (line, parm->fpr);
+ parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
}
else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
{
@@ -745,29 +781,47 @@ scd_genkey_cb (void *opaque, const char *line)
while (spacep (line))
line++;
- 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->n = a;
- else if (*name == 'e' && spacep (name+1))
- parm->e = a;
+ if (*name == '-' && spacep (name+1))
+ rc = scd_genkey_cb_append_savedbytes (parm, line);
else
{
- log_info ("unknown parameter name in received key data\n");
- gcry_mpi_release (a);
+ 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))
{
- parm->created_at = (u32)strtoul (line, NULL, 10);
+ parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
}
else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
{
write_status_text (STATUS_PROGRESS, line);
}
- return 0;
+ return rc;
}
/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
@@ -781,9 +835,13 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
int rc;
char line[ASSUAN_LINELENGTH];
gnupg_isotime_t tbuf;
+ struct scd_genkey_parm_s parms;
(void)serialno;
+ memset (&parms, 0, sizeof parms);
+ parms.cgk = info;
+
rc = start_agent (NULL, 1);
if (rc)
return rc;
@@ -802,7 +860,9 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
memset (info, 0, sizeof *info);
rc = assuan_transact (agent_ctx, line,
NULL, NULL, default_inq_cb, NULL,
- scd_genkey_cb, info);
+ scd_genkey_cb, &parms);
+
+ xfree (parms.savedbytes);
status_sc_op_failure (rc);
return rc;