aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--g10/ChangeLog8
-rw-r--r--g10/call-agent.c90
-rw-r--r--g10/card-util.c2
-rw-r--r--scd/ChangeLog6
-rw-r--r--scd/app-openpgp.c25
-rw-r--r--scd/command.c8
7 files changed, 117 insertions, 26 deletions
diff --git a/NEWS b/NEWS
index f37deb29e..c2271afc4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,9 @@
Noteworthy changes in version 2.1.0beta3
-----------------------------------------------------
- * Fixed regression in GPG'S secret key export function.
+ * Fixed regression in GPG's secret key export function.
+
+ * Allow generation of card keys up to 4096 bit.
Noteworthy changes in version 2.1.0beta2 (2011-03-08)
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 67b981387..2f107eb5a 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,11 @@
+2011-06-16 Werner Koch <[email protected]>
+
+ * card-util.c (ask_card_keysize): Bump key size limit to 4096.
+ * call-agent.c (scd_genkey_parm_s): New.
+ (agent_scd_genkey): Use new struct.
+ (scd_genkey_cb): Implement chunked mode for KEY-DATA.
+ (scd_genkey_cb_append_savedbytes): New.
+
2011-06-13 Werner Koch <[email protected]>
* pkglue.c (mpi_from_sexp): Use GCRYMPI_FMT_USG to avoid problems
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;
diff --git a/g10/card-util.c b/g10/card-util.c
index 0ffb18dd7..9c124bbfc 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -1294,7 +1294,7 @@ static unsigned int
ask_card_keysize (int keyno, unsigned int nbits)
{
unsigned int min_nbits = 1024;
- unsigned int max_nbits = 3072; /* GnuPG limit due to Assuan. */
+ unsigned int max_nbits = 4096;
char *prompt, *answer;
unsigned int req_nbits;
diff --git a/scd/ChangeLog b/scd/ChangeLog
index 0a614c855..9c4d03592 100644
--- a/scd/ChangeLog
+++ b/scd/ChangeLog
@@ -1,3 +1,9 @@
+2011-06-16 Werner Koch <[email protected]>
+
+ * app-openpgp.c (send_key_data): Implemented chunked mode.
+ (change_keyattr): Increase limit to 4096.
+ (do_decipher): Adjust padding for 4096 bit keys.
+
2011-02-23 Werner Koch <[email protected]>
* apdu.c (apdu_open_reader): Lock in to CCID if used once.
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 660519059..fef17faa9 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -756,20 +756,29 @@ static void
send_key_data (ctrl_t ctrl, const char *name,
const unsigned char *a, size_t alen)
{
- char *buf;
+ char *buffer, *buf;
+ size_t buflen;
- buf = bin2hex (a, alen, NULL);
- if (!buf)
+ buffer = buf = bin2hex (a, alen, NULL);
+ if (!buffer)
{
log_error ("memory allocation error in send_key_data\n");
return;
}
+ buflen = strlen (buffer);
+ /* 768 is the hexified size for the modulus of an 3072 bit key. We
+ use extra chunks to transmit larger data (i.e for 4096 bit). */
+ for ( ;buflen > 768; buflen -= 768, buf += 768)
+ send_status_info (ctrl, "KEY-DATA",
+ "-", 1,
+ buf, 768,
+ NULL, 0);
send_status_info (ctrl, "KEY-DATA",
name, (size_t)strlen(name),
- buf, (size_t)strlen (buf),
+ buf, buflen,
NULL, 0);
- xfree (buf);
+ xfree (buffer);
}
@@ -2365,7 +2374,7 @@ change_keyattr (app_t app, int keyno, unsigned int nbits,
assert (keyno >=0 && keyno <= 2);
- if (nbits > 3072)
+ if (nbits > 4096)
return gpg_error (GPG_ERR_TOO_LARGE);
/* Read the current attributes into a buffer. */
@@ -2823,7 +2832,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
already lead to a 527 byte long status line and thus a 4096 bit
key would exceed the Assuan line length limit. */
keybits = app->app_local->keyattr[keyno].n_bits;
- if (keybits > 3072)
+ if (keybits > 4096)
return gpg_error (GPG_ERR_TOO_LARGE);
/* Prepare for key generation by verifying the Admin PIN. */
@@ -3377,6 +3386,8 @@ do_decipher (app_t app, const char *keyidstr,
fixuplen = 256 - indatalen;
else if (indatalen >= (384-16) && indatalen < 384) /* 3072 bit key. */
fixuplen = 384 - indatalen;
+ else if (indatalen >= (512-16) && indatalen < 512) /* 4096 bit key. */
+ fixuplen = 512 - indatalen;
else
fixuplen = 0;
diff --git a/scd/command.c b/scd/command.c
index be11ccb77..a579b24eb 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1288,11 +1288,15 @@ static const char hlp_genkey[] =
"\n"
"Generate a key on-card identified by NO, which is application\n"
"specific. Return values are application specific. For OpenPGP\n"
- "cards 2 status lines are returned:\n"
+ "cards 3 status lines are returned:\n"
"\n"
" S KEY-FPR <hexstring>\n"
" S KEY-CREATED-AT <seconds_since_epoch>\n"
- " S KEY-DATA [p|n] <hexdata>\n"
+ " S KEY-DATA [-|p|n] <hexdata>\n"
+ "\n"
+ " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
+ " indicate that HEXDATA is the first chunk of a parameter given\n"
+ " by the next KEY-DATA.\n"
"\n"
"--force is required to overwrite an already existing key. The\n"
"KEY-CREATED-AT is required for further processing because it is\n"