aboutsummaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
Diffstat (limited to 'scd')
-rw-r--r--scd/app-openpgp.c33
-rw-r--r--scd/ccid-driver.c2
2 files changed, 28 insertions, 7 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 7480f5041..87d77a15b 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -3254,6 +3254,7 @@ build_privkey_template (app_t app, int keyno,
static gpg_error_t
build_ecc_privkey_template (app_t app, int keyno,
const unsigned char *ecc_d, size_t ecc_d_len,
+ size_t ecc_d_fixed_len,
const unsigned char *ecc_q, size_t ecc_q_len,
unsigned char **result, size_t *resultlen)
{
@@ -3269,6 +3270,18 @@ build_ecc_privkey_template (app_t app, int keyno,
size_t template_size;
int pubkey_required;
+ /* This case doesn't occur in GnuPG 2.3 or later, because
+ agent/sexp-secret.c does the fixup. */
+ if (ecc_d_fixed_len < ecc_d_len)
+ {
+ if (ecc_d_fixed_len != ecc_d_len - 1 || *ecc_d)
+ return gpg_error (GPG_ERR_INV_OBJ);
+
+ /* Remove the additional zero. */
+ ecc_d_len--;
+ ecc_d++;
+ }
+
pubkey_required = !!(app->app_local->keyattr[keyno].ecc.flags
& ECC_FLAG_PUBKEY);
@@ -3279,8 +3292,8 @@ build_ecc_privkey_template (app_t app, int keyno,
datalen = 0;
tp = privkey;
- tp += add_tlv (tp, 0x92, ecc_d_len);
- datalen += ecc_d_len;
+ tp += add_tlv (tp, 0x92, ecc_d_fixed_len);
+ datalen += ecc_d_fixed_len;
if (pubkey_required)
{
@@ -3323,8 +3336,14 @@ build_ecc_privkey_template (app_t app, int keyno,
memcpy (tp, suffix, suffix_len);
tp += suffix_len;
- memcpy (tp, ecc_d, ecc_d_len);
- tp += ecc_d_len;
+ if (ecc_d_fixed_len > ecc_d_len)
+ {
+ memset (tp, 0, ecc_d_fixed_len - ecc_d_len);
+ memcpy (tp + ecc_d_fixed_len - ecc_d_len, ecc_d, ecc_d_len);
+ }
+ else
+ memcpy (tp, ecc_d, ecc_d_len);
+ tp += ecc_d_fixed_len;
if (pubkey_required)
{
@@ -3843,6 +3862,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
unsigned int n;
size_t oid_len;
unsigned char fprbuf[20];
+ size_t ecc_d_fixed_len;
/* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)):
curve = "NIST P-256" */
@@ -3985,7 +4005,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
else
algo = PUBKEY_ALGO_ECDSA;
- oidstr = openpgp_curve_to_oid (curve, NULL);
+ oidstr = openpgp_curve_to_oid (curve, &n);
+ ecc_d_fixed_len = (n+7)/8;
err = openpgp_oid_from_str (oidstr, &oid);
if (err)
goto leave;
@@ -4050,7 +4071,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
int exmode;
err = build_ecc_privkey_template (app, keyno,
- ecc_d, ecc_d_len,
+ ecc_d, ecc_d_len, ecc_d_fixed_len,
ecc_q, ecc_q_len,
&template, &template_len);
if (err)
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index e255ace07..ddc83200b 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -1307,6 +1307,7 @@ ccid_vendor_specific_setup (ccid_driver_t handle)
DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n");
send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3,
NULL, 0, NULL);
+ libusb_clear_halt (handle->idev, handle->ep_intr);
}
return 0;
}
@@ -1596,7 +1597,6 @@ ccid_setup_intr (ccid_driver_t handle)
struct libusb_transfer *transfer;
int err;
- libusb_clear_halt (handle->idev, handle->ep_intr);
transfer = libusb_alloc_transfer (0);
handle->transfer = transfer;
libusb_fill_interrupt_transfer (transfer, handle->idev, handle->ep_intr,