mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-07 22:01:07 +01:00
scd: Use canonical curve name of libgcrypt.
* scd/app-openpgp.c (send_key_attr): Use curve instead of OID. (ecdh_params): New. (ecc_read_pubkey): Use ecdh_params. Use curve name. (ecc_writekey): Likewise. (ecc_curve): Rename from ecc_oid. (parse_algorithm_attribute): Use ecc_curve. * g10/call-agent.c (learn_status_cb): Use openpgp_is_curve_supported to intern the curve name string. * g10/card-util.c (card_status): Conver curve name to alias for print. -- Now, sdcaemon answer for KEY-ATTR is in the canonical curve name instead of the alias. Since it is used of key generation for card encryption key with backup, it should be canonical name. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
945e7ab0dd
commit
b1828c17fc
@ -624,15 +624,7 @@ learn_status_cb (void *opaque, const char *line)
|
|||||||
parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
|
parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
|
||||||
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
|
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
|
||||||
|| algo == PUBKEY_ALGO_EDDSA)
|
|| algo == PUBKEY_ALGO_EDDSA)
|
||||||
{
|
parm->key_attr[keyno].curve = openpgp_is_curve_supported (line+n, NULL);
|
||||||
const char *curve;
|
|
||||||
|
|
||||||
for (i = 0; (curve = openpgp_enum_curves (&i));)
|
|
||||||
if (!strcmp (curve, line+n))
|
|
||||||
break;
|
|
||||||
|
|
||||||
parm->key_attr[keyno].curve = curve;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
|
else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
|
||||||
&& strchr("1234", keyword[11]))
|
&& strchr("1234", keyword[11]))
|
||||||
|
@ -568,7 +568,18 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
|
|||||||
else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
|
else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
|
||||||
|| info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
|
|| info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
|
||||||
|| info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
|
|| info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
|
||||||
tty_fprintf (fp, " %s", info.key_attr[i].curve);
|
{
|
||||||
|
const char *curve_for_print = "?";
|
||||||
|
|
||||||
|
if (info.key_attr[i].curve)
|
||||||
|
{
|
||||||
|
const char *oid;
|
||||||
|
oid = openpgp_curve_to_oid (info.key_attr[i].curve, NULL);
|
||||||
|
if (oid)
|
||||||
|
curve_for_print = openpgp_oid_to_curve (oid, 0);
|
||||||
|
}
|
||||||
|
tty_fprintf (fp, " %s", curve_for_print);
|
||||||
|
}
|
||||||
tty_fprintf (fp, "\n");
|
tty_fprintf (fp, "\n");
|
||||||
}
|
}
|
||||||
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
|
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
|
||||||
|
@ -228,7 +228,7 @@ struct app_local_s {
|
|||||||
rsa_key_format_t format;
|
rsa_key_format_t format;
|
||||||
} rsa;
|
} rsa;
|
||||||
struct {
|
struct {
|
||||||
const char *oid;
|
const char *curve;
|
||||||
int flags;
|
int flags;
|
||||||
} ecc;
|
} ecc;
|
||||||
};
|
};
|
||||||
@ -913,7 +913,7 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int keyno)
|
|||||||
keyno==1? PUBKEY_ALGO_ECDH :
|
keyno==1? PUBKEY_ALGO_ECDH :
|
||||||
(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
|
(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
|
||||||
PUBKEY_ALGO_EDDSA : PUBKEY_ALGO_ECDSA,
|
PUBKEY_ALGO_EDDSA : PUBKEY_ALGO_ECDSA,
|
||||||
openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 0));
|
app->app_local->keyattr[keyno].ecc.curve);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snprintf (buffer, sizeof buffer, "%d 0 0 UNKNOWN", keyno+1);
|
snprintf (buffer, sizeof buffer, "%d 0 0 UNKNOWN", keyno+1);
|
||||||
@ -1307,6 +1307,29 @@ rsa_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Determine KDF hash algorithm and KEK encryption algorithm by CURVE. */
|
||||||
|
static const unsigned char*
|
||||||
|
ecdh_params (const char *curve)
|
||||||
|
{
|
||||||
|
unsigned int nbits;
|
||||||
|
|
||||||
|
openpgp_curve_to_oid (curve, &nbits);
|
||||||
|
|
||||||
|
/* See RFC-6637 for those constants.
|
||||||
|
0x03: Number of bytes
|
||||||
|
0x01: Version for this parameter format
|
||||||
|
KDF algo
|
||||||
|
KEK algo
|
||||||
|
*/
|
||||||
|
if (nbits <= 256)
|
||||||
|
return (const unsigned char*)"\x03\x01\x08\x07";
|
||||||
|
else if (nbits <= 384)
|
||||||
|
return (const unsigned char*)"\x03\x01\x09\x08";
|
||||||
|
else
|
||||||
|
return (const unsigned char*)"\x03\x01\x0a\x09";
|
||||||
|
}
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
||||||
const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp)
|
const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp)
|
||||||
@ -1317,11 +1340,12 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
size_t ecc_q_len;
|
size_t ecc_q_len;
|
||||||
gcry_mpi_t oid = NULL;
|
gcry_mpi_t oid = NULL;
|
||||||
int n;
|
int n;
|
||||||
|
const char *curve;
|
||||||
|
const char *oidstr;
|
||||||
const unsigned char *oidbuf;
|
const unsigned char *oidbuf;
|
||||||
size_t oid_len;
|
size_t oid_len;
|
||||||
int algo;
|
int algo;
|
||||||
const char *format;
|
const char *format;
|
||||||
const char *curve;
|
|
||||||
|
|
||||||
ecc_q = find_tlv (data, datalen, 0x0086, &ecc_q_len);
|
ecc_q = find_tlv (data, datalen, 0x0086, &ecc_q_len);
|
||||||
if (!ecc_q)
|
if (!ecc_q)
|
||||||
@ -1330,10 +1354,11 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
return gpg_error (GPG_ERR_CARD);
|
return gpg_error (GPG_ERR_CARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = openpgp_oid_from_str (app->app_local->keyattr[keyno].ecc.oid, &oid);
|
curve = app->app_local->keyattr[keyno].ecc.curve;
|
||||||
|
oidstr = openpgp_curve_to_oid (curve, NULL);
|
||||||
|
err = openpgp_oid_from_str (oidstr, &oid);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
oidbuf = gcry_mpi_get_opaque (oid, &n);
|
oidbuf = gcry_mpi_get_opaque (oid, &n);
|
||||||
if (!oidbuf)
|
if (!oidbuf)
|
||||||
{
|
{
|
||||||
@ -1367,7 +1392,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
if (keyno == 1)
|
if (keyno == 1)
|
||||||
{
|
{
|
||||||
if (ctrl)
|
if (ctrl)
|
||||||
send_key_data (ctrl, "kdf", "\x03\x01\x08\x07", (size_t)4);
|
send_key_data (ctrl, "kdf/kek", ecdh_params (curve), (size_t)4);
|
||||||
algo = PUBKEY_ALGO_ECDH;
|
algo = PUBKEY_ALGO_ECDH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1383,7 +1408,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
unsigned char fprbuf[20];
|
unsigned char fprbuf[20];
|
||||||
|
|
||||||
err = store_fpr (app, keyno, created_at, fprbuf, algo, oidbuf, oid_len,
|
err = store_fpr (app, keyno, created_at, fprbuf, algo, oidbuf, oid_len,
|
||||||
qbuf, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
|
qbuf, ecc_q_len, ecdh_params (curve), (size_t)4);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -1397,8 +1422,9 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
|
|||||||
else
|
else
|
||||||
format = "(public-key(ecc(curve%s)(flags eddsa)(q%b)))";
|
format = "(public-key(ecc(curve%s)(flags eddsa)(q%b)))";
|
||||||
|
|
||||||
curve = openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1);
|
err = gcry_sexp_build (r_sexp, NULL, format,
|
||||||
err = gcry_sexp_build (r_sexp, NULL, format, curve, (int)ecc_q_len, qbuf);
|
app->app_local->keyattr[keyno].ecc.curve,
|
||||||
|
(int)ecc_q_len, qbuf);
|
||||||
leave:
|
leave:
|
||||||
gcry_mpi_release (oid);
|
gcry_mpi_release (oid);
|
||||||
xfree (qbuf);
|
xfree (qbuf);
|
||||||
@ -3342,8 +3368,9 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
const unsigned char *ecc_q = NULL;
|
const unsigned char *ecc_q = NULL;
|
||||||
const unsigned char *ecc_d = NULL;
|
const unsigned char *ecc_d = NULL;
|
||||||
size_t ecc_q_len, ecc_d_len;
|
size_t ecc_q_len, ecc_d_len;
|
||||||
|
const char *curve = NULL;
|
||||||
u32 created_at = 0;
|
u32 created_at = 0;
|
||||||
const char *oidstr = NULL;
|
const char *oidstr;
|
||||||
int flag_djb_tweak = 0;
|
int flag_djb_tweak = 0;
|
||||||
int algo;
|
int algo;
|
||||||
gcry_mpi_t oid = NULL;
|
gcry_mpi_t oid = NULL;
|
||||||
@ -3372,22 +3399,22 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
|
|
||||||
if (tok && toklen == 5 && !memcmp (tok, "curve", 5))
|
if (tok && toklen == 5 && !memcmp (tok, "curve", 5))
|
||||||
{
|
{
|
||||||
unsigned char *curve;
|
char *curve_name;
|
||||||
|
|
||||||
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
curve = xtrymalloc (toklen+1);
|
curve_name = xtrymalloc (toklen+1);
|
||||||
if (!curve)
|
if (!curve_name)
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (curve, tok, toklen);
|
memcpy (curve_name, tok, toklen);
|
||||||
curve[toklen] = 0;
|
curve_name[toklen] = 0;
|
||||||
oidstr = openpgp_curve_to_oid (curve, NULL);
|
curve = openpgp_is_curve_supported (curve_name, NULL);
|
||||||
xfree (curve);
|
xfree (curve_name);
|
||||||
}
|
}
|
||||||
else if (tok && toklen == 5 && !memcmp (tok, "flags", 5))
|
else if (tok && toklen == 5 && !memcmp (tok, "flags", 5))
|
||||||
{
|
{
|
||||||
@ -3474,7 +3501,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
|
|
||||||
/* Check that we have all parameters and that they match the card
|
/* Check that we have all parameters and that they match the card
|
||||||
description. */
|
description. */
|
||||||
if (!oidstr)
|
if (!curve)
|
||||||
{
|
{
|
||||||
log_error (_("unsupported curve\n"));
|
log_error (_("unsupported curve\n"));
|
||||||
err = gpg_error (GPG_ERR_INV_VALUE);
|
err = gpg_error (GPG_ERR_INV_VALUE);
|
||||||
@ -3493,6 +3520,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
else
|
else
|
||||||
algo = PUBKEY_ALGO_ECDSA;
|
algo = PUBKEY_ALGO_ECDSA;
|
||||||
|
|
||||||
|
oidstr = openpgp_curve_to_oid (curve, NULL);
|
||||||
err = openpgp_oid_from_str (oidstr, &oid);
|
err = openpgp_oid_from_str (oidstr, &oid);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -3505,7 +3533,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
oid_len = (n+7)/8;
|
oid_len = (n+7)/8;
|
||||||
|
|
||||||
if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
|
if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
|
||||||
|| app->app_local->keyattr[keyno].ecc.oid != oidstr
|
|| app->app_local->keyattr[keyno].ecc.curve != curve
|
||||||
|| (flag_djb_tweak !=
|
|| (flag_djb_tweak !=
|
||||||
(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)))
|
(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)))
|
||||||
{
|
{
|
||||||
@ -3580,7 +3608,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = store_fpr (app, keyno, created_at, fprbuf, algo, oidbuf, oid_len,
|
err = store_fpr (app, keyno, created_at, fprbuf, algo, oidbuf, oid_len,
|
||||||
ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
|
ecc_q, ecc_q_len, ecdh_params (curve), (size_t)4);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
gcry_mpi_release (oid);
|
gcry_mpi_release (oid);
|
||||||
@ -4578,12 +4606,11 @@ parse_historical (struct app_local_s *apploc,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the OID in an DER encoding is available by GnuPG/libgcrypt,
|
* Check if the OID in an DER encoding is available by GnuPG/libgcrypt,
|
||||||
* and return the constant string in dotted decimal form.
|
* and return the curve name. Return NULL if not available.
|
||||||
* Return NULL if not available.
|
|
||||||
* The constant string is not allocated dynamically, never free it.
|
* The constant string is not allocated dynamically, never free it.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
ecc_oid (unsigned char *buf, size_t buflen)
|
ecc_curve (unsigned char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
gcry_mpi_t oid;
|
gcry_mpi_t oid;
|
||||||
char *oidstr;
|
char *oidstr;
|
||||||
@ -4608,7 +4635,7 @@ ecc_oid (unsigned char *buf, size_t buflen)
|
|||||||
if (!oidstr)
|
if (!oidstr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
result = openpgp_curve_to_oid (oidstr, NULL);
|
result = openpgp_oid_to_curve (oidstr, 1);
|
||||||
xfree (oidstr);
|
xfree (oidstr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -4671,7 +4698,7 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
|
else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
|
||||||
|| *buffer == PUBKEY_ALGO_EDDSA)
|
|| *buffer == PUBKEY_ALGO_EDDSA)
|
||||||
{
|
{
|
||||||
const char *oid;
|
const char *curve;
|
||||||
int oidlen = buflen - 1;
|
int oidlen = buflen - 1;
|
||||||
|
|
||||||
app->app_local->keyattr[keyno].ecc.flags = 0;
|
app->app_local->keyattr[keyno].ecc.flags = 0;
|
||||||
@ -4683,22 +4710,22 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_PUBKEY;
|
app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_PUBKEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
oid = ecc_oid (buffer + 1, oidlen);
|
curve = ecc_curve (buffer + 1, oidlen);
|
||||||
|
|
||||||
if (!oid)
|
if (!curve)
|
||||||
log_printhex ("Curve with OID not supported: ", buffer+1, buflen-1);
|
log_printhex ("Curve with OID not supported: ", buffer+1, buflen-1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC;
|
app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC;
|
||||||
app->app_local->keyattr[keyno].ecc.oid = oid;
|
app->app_local->keyattr[keyno].ecc.curve = curve;
|
||||||
if (*buffer == PUBKEY_ALGO_EDDSA
|
if (*buffer == PUBKEY_ALGO_EDDSA
|
||||||
|| (*buffer == PUBKEY_ALGO_ECDH
|
|| (*buffer == PUBKEY_ALGO_ECDH
|
||||||
&& !strcmp (app->app_local->keyattr[keyno].ecc.oid,
|
&& !strcmp (app->app_local->keyattr[keyno].ecc.curve,
|
||||||
"1.3.6.1.4.1.3029.1.5.1")))
|
"Curve25519")))
|
||||||
app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_DJB_TWEAK;
|
app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_DJB_TWEAK;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_printf
|
log_printf
|
||||||
("ECC, curve=%s%s\n", app->app_local->keyattr[keyno].ecc.oid,
|
("ECC, curve=%s%s\n", app->app_local->keyattr[keyno].ecc.curve,
|
||||||
!(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
|
!(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
|
||||||
"": keyno==1? " (djb-tweak)": " (eddsa)");
|
"": keyno==1? " (djb-tweak)": " (eddsa)");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user