mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
Allow decryption with card keys > 3072 bits
* scd/command.c (MAXLEN_SETDATA): New. (cmd_setdata): Add option --append. * agent/call-scd.c (agent_card_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.
This commit is contained in:
parent
8f8c29d24c
commit
905b6a36d3
@ -926,17 +926,22 @@ agent_card_pkdecrypt (ctrl_t ctrl,
|
||||
return rc;
|
||||
|
||||
/* FIXME: use secure memory where appropriate */
|
||||
if (indatalen*2 + 50 > DIM(line))
|
||||
return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
|
||||
|
||||
sprintf (line, "SETDATA ");
|
||||
p = line + strlen (line);
|
||||
for (i=0; i < indatalen ; i++, p += 2 )
|
||||
sprintf (p, "%02X", indata[i]);
|
||||
for (len = 0; len < indatalen;)
|
||||
{
|
||||
p = stpcpy (line, "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 (ctrl->scd_local->ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return unlock_scd (ctrl, rc);
|
||||
}
|
||||
|
||||
init_membuf (&data, 1024);
|
||||
inqparm.ctx = ctrl->scd_local->ctx;
|
||||
|
@ -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
|
||||
{
|
||||
@ -3474,6 +3476,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;
|
||||
@ -3761,6 +3769,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;
|
||||
|
||||
|
@ -48,6 +48,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
|
||||
|
||||
@ -848,17 +851,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);
|
||||
|
||||
@ -872,15 +882,31 @@ 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);
|
||||
|
||||
xfree (ctrl->in_data.value);
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user