You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/app-crypt/gnupg/files/gnupg-2.0.19-support-sc-key...

185 lines
5.6 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

From ab4ea45f54006eba55db11263431c4c0c4f557dc Mon Sep 17 00:00:00 2001
From: Werner Koch <wk@gnupg.org>
Date: Tue, 6 Nov 2012 14:39:22 +0100
Subject: [PATCH 1/1] Allow decryption with card keys > 3072 bit
* scd/command.c (MAXLEN_SETDATA): New.
(cmd_setdata): Add option --append.
* g10/call-agent.c (agent_scd_pkdecrypt): Use new option for long data
* scd/app-openpgp.c (struct app_local_s): Add field manufacturer.
(app_select_openpgp): Store manufacturer.
(do_decipher): Print a note for broken cards.
--
Please note that I was not able to run a full test because I only have
broken cards (S/N < 346) available.
---
g10/call-agent.c | 22 ++++++++++++++--------
scd/app-openpgp.c | 10 ++++++++++
scd/command.c | 38 ++++++++++++++++++++++++++++++++------
3 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/g10/call-agent.c b/g10/call-agent.c
index cded773..373d8c9 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1034,7 +1034,7 @@ agent_scd_pksign (const char *serialno, int hashalgo,
/* Decrypt INDATA of length INDATALEN using the card identified by
- SERIALNO. Return the plaintext in a nwly allocated buffer stored
+ SERIALNO. Return the plaintext in a newly allocated buffer stored
at the address of R_BUF.
Note, we currently support only RSA or more exactly algorithms
@@ -1058,20 +1058,26 @@ agent_scd_pkdecrypt (const char *serialno,
return rc;
/* FIXME: use secure memory where appropriate */
- if (indatalen*2 + 50 > DIM(line))
- return gpg_error (GPG_ERR_GENERAL);
rc = select_openpgp (serialno);
if (rc)
return rc;
- sprintf (line, "SCD SETDATA ");
- p = line + strlen (line);
- for (i=0; i < indatalen ; i++, p += 2 )
- sprintf (p, "%02X", indata[i]);
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ for (len = 0; len < indatalen;)
+ {
+ p = stpcpy (line, "SCD SETDATA ");
+ if (len)
+ p = stpcpy (p, "--append ");
+ for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++)
+ {
+ sprintf (p, "%02X", indata[len]);
+ p += 2;
+ }
+ rc = assuan_transact (agent_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return rc;
+ }
init_membuf (&data, 1024);
snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index ff26b36..141b2b7 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -158,6 +158,8 @@ struct app_local_s {
unsigned char status_indicator; /* The card status indicator. */
+ unsigned int manufacturer:16; /* Manufacturer ID from the s/n. */
+
/* Keep track of the ISO card capabilities. */
struct
{
@@ -3462,6 +3464,12 @@ do_decipher (app_t app, const char *keyidstr,
indata, indatalen, le_value, padind,
outdata, outdatalen);
xfree (fixbuf);
+
+ if (gpg_err_code (rc) == GPG_ERR_CARD /* actual SW is 0x640a */
+ && app->app_local->manufacturer == 5
+ && app->card_version == 0x0200)
+ log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)"
+ " do not work with encryption keys > 2048 bits\n");
}
return rc;
@@ -3749,6 +3757,8 @@ app_select_openpgp (app_t app)
goto leave;
}
+ app->app_local->manufacturer = manufacturer;
+
if (app->card_version >= 0x0200)
app->app_local->extcap.is_v2 = 1;
diff --git a/scd/command.c b/scd/command.c
index 6053fc6..3ce4a57 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -46,6 +46,9 @@
/* Maximum allowed size of key data as used in inquiries. */
#define MAXLEN_KEYDATA 4096
+/* Maximum allowed total data size for SETDATA. */
+#define MAXLEN_SETDATA 4096
+
/* Maximum allowed size of certificate data as used in inquiries. */
#define MAXLEN_CERTDATA 16384
@@ -820,17 +823,24 @@ cmd_readkey (assuan_context_t ctx, char *line)
static const char hlp_setdata[] =
- "SETDATA <hexstring> \n"
+ "SETDATA [--append] <hexstring>\n"
"\n"
- "The client should use this command to tell us the data he want to sign.";
+ "The client should use this command to tell us the data he want to sign.\n"
+ "With the option --append, the data is appended to the data set by a\n"
+ "previous SETDATA command.";
static gpg_error_t
cmd_setdata (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
- int n;
+ int append;
+ int n, i, off;
char *p;
unsigned char *buf;
+ append = (ctrl->in_data.value && has_option (line, "--append"));
+
+ line = skip_options (line);
+
if (locked_session && locked_session != ctrl->server_local)
return gpg_error (GPG_ERR_LOCKED);
@@ -844,14 +854,30 @@ cmd_setdata (assuan_context_t ctx, char *line)
if ((n&1))
return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
n /= 2;
+ if (append)
+ {
+ if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
+ return set_error (GPG_ERR_TOO_LARGE,
+ "limit on total size of data reached");
+ buf = xtrymalloc (ctrl->in_data.valuelen + n);
+ }
+ else
buf = xtrymalloc (n);
if (!buf)
return out_of_core ();
+ if (append)
+ {
+ memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
+ off = ctrl->in_data.valuelen;
+ }
+ else
+ off = 0;
+ for (p=line, i=0; i < n; p += 2, i++)
+ buf[off+i] = xtoi_2 (p);
+
ctrl->in_data.value = buf;
- ctrl->in_data.valuelen = n;
- for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
- buf[n] = xtoi_2 (p);
+ ctrl->in_data.valuelen = off + n;
return 0;
}
--
1.7.2.5