1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

common,gpg,scd,sm: Fix for Curve25519 OID supporting new and old.

* common/util.h (openpgp_curve_to_oid): Add new argument to select OID
by OpenPGP version.
* common/openpgp-oid.c (openpgp_curve_to_oid): Implement returning
selected OID for Curve25519.
* common/openpgp-fpr.c (compute_openpgp_fpr_ecc): Follow the change,
selecting by the version.
* g10/export.c (match_curve_skey_pk): Likewise.
(transfer_format_to_openpgp): Likewise.
* g10/gpg.c (list_config): Likewise, print new OID.
* g10/keygen.c (ecckey_from_sexp): Likewise, selecting by the version.
* sm/encrypt.c (ecdh_encrypt): Likewise, don't care.
* sm/minip12.c (build_ecc_key_sequence): Likewise, new OID.
* scd/app-openpgp.c (ecdh_params, gen_challenge): Likewise, don't
care.
(ecc_read_pubkey, change_keyattr_from_string, ecc_writekey): Likewise,
old OID.

--

GnuPG-bug-id: 7316
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2024-10-08 15:25:41 +09:00
parent f5703994d4
commit 57dce1ee62
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054
9 changed files with 28 additions and 19 deletions

View File

@ -231,7 +231,8 @@ compute_openpgp_fpr_ecc (int keyversion, unsigned long timestamp,
unsigned char nbits_q[2]; unsigned char nbits_q[2];
unsigned int n; unsigned int n;
curveoidstr = openpgp_curve_to_oid (curvename, &curvebits, &pgpalgo); curveoidstr = openpgp_curve_to_oid (curvename, &curvebits, &pgpalgo,
(keyversion > 4));
err = openpgp_oid_from_str (curveoidstr, &curveoid); err = openpgp_oid_from_str (curveoidstr, &curveoid);
if (err) if (err)
goto leave; goto leave;

View File

@ -443,9 +443,11 @@ openpgp_oid_is_cv448 (gcry_mpi_t a)
curve names. If R_ALGO is not NULL and a specific ECC algorithm is curve names. If R_ALGO is not NULL and a specific ECC algorithm is
required for this curve its OpenPGP algorithm number is stored required for this curve its OpenPGP algorithm number is stored
there; otherwise 0 is stored which indicates that ECDSA or ECDH can there; otherwise 0 is stored which indicates that ECDSA or ECDH can
be used. */ be used. SELECTOR specifies which OID should be returned: -1 for
don't care, 0 for old OID, 1 for new OID. */
const char * const char *
openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo) openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo,
int selector)
{ {
int i; int i;
unsigned int nbits = 0; unsigned int nbits = 0;
@ -479,6 +481,14 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo)
} }
} }
/* Special handling for Curve25519, where we have two valid OIDs. */
if (algo && i == 0)
{
/* Select new OID, if wanted. */
if (selector > 0)
oidstr = oidtable[2].oidstr;
}
if (r_nbits) if (r_nbits)
*r_nbits = nbits; *r_nbits = nbits;
if (r_algo) if (r_algo)

View File

@ -230,7 +230,8 @@ int openpgp_oid_is_cv448 (gcry_mpi_t a);
int openpgp_oid_is_ed448 (gcry_mpi_t a); int openpgp_oid_is_ed448 (gcry_mpi_t a);
enum gcry_kem_algos openpgp_oid_to_kem_algo (const char *oidname); enum gcry_kem_algos openpgp_oid_to_kem_algo (const char *oidname);
const char *openpgp_curve_to_oid (const char *name, const char *openpgp_curve_to_oid (const char *name,
unsigned int *r_nbits, int *r_algo); unsigned int *r_nbits, int *r_algo,
int selector);
const char *openpgp_oid_to_curve (const char *oid, int mode); const char *openpgp_oid_to_curve (const char *oid, int mode);
const char *openpgp_oid_or_name_to_curve (const char *oidname, int canon); const char *openpgp_oid_or_name_to_curve (const char *oidname, int canon);
const char *openpgp_enum_curves (int *idxp); const char *openpgp_enum_curves (int *idxp);

View File

@ -585,7 +585,7 @@ match_curve_skey_pk (gcry_sexp_t s_key, PKT_public_key *pk)
} }
if (!strcmp (curve_str, "Ed448")) if (!strcmp (curve_str, "Ed448"))
is_eddsa = 1; is_eddsa = 1;
oidstr = openpgp_curve_to_oid (curve_str, NULL, NULL); oidstr = openpgp_curve_to_oid (curve_str, NULL, NULL, (pk->version > 4));
if (!oidstr) if (!oidstr)
{ {
log_error ("no OID known for curve '%s'\n", curve_str); log_error ("no OID known for curve '%s'\n", curve_str);
@ -1280,7 +1280,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
goto leave; goto leave;
} }
oidstr = openpgp_curve_to_oid (curve, NULL, NULL); oidstr = openpgp_curve_to_oid (curve, NULL, NULL, (pk->version > 4));
if (!oidstr) if (!oidstr)
{ {
log_error ("no OID known for curve '%s'\n", curve); log_error ("no OID known for curve '%s'\n", curve);

View File

@ -1983,7 +1983,7 @@ list_config(char *items)
es_printf ("cfg:curveoid:"); es_printf ("cfg:curveoid:");
for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0) for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0)
{ {
s = openpgp_curve_to_oid (s, NULL, NULL); s = openpgp_curve_to_oid (s, NULL, NULL, 1);
es_printf ("%s%s", first?"":";", s? s:"[?]"); es_printf ("%s%s", first?"":";", s? s:"[?]");
} }
es_printf ("\n"); es_printf ("\n");

View File

@ -1503,7 +1503,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
goto leave; goto leave;
} }
gcry_sexp_release (l2); gcry_sexp_release (l2);
oidstr = openpgp_curve_to_oid (curve, &nbits, NULL); oidstr = openpgp_curve_to_oid (curve, &nbits, NULL, pkversion > 4);
if (!oidstr) if (!oidstr)
{ {
/* That can't happen because we used one of the curves /* That can't happen because we used one of the curves
@ -1511,9 +1511,6 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
err = gpg_error (GPG_ERR_INV_OBJ); err = gpg_error (GPG_ERR_INV_OBJ);
goto leave; goto leave;
} }
/* For v5 keys we prefer the modern OID for cv25519. */
if (pkversion > 4 && !strcmp (oidstr, "1.3.6.1.4.1.3029.1.5.1"))
oidstr = "1.3.101.110";
err = openpgp_oid_from_str (oidstr, &array[0]); err = openpgp_oid_from_str (oidstr, &array[0]);
if (err) if (err)

View File

@ -1759,7 +1759,7 @@ ecdh_params (const char *curve)
{ {
unsigned int nbits; unsigned int nbits;
openpgp_curve_to_oid (curve, &nbits, NULL); openpgp_curve_to_oid (curve, &nbits, NULL, -1);
/* See RFC-6637 for those constants. /* See RFC-6637 for those constants.
0x03: Number of bytes 0x03: Number of bytes
@ -1801,7 +1801,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, int meta_update,
} }
curve = app->app_local->keyattr[keyno].ecc.curve; curve = app->app_local->keyattr[keyno].ecc.curve;
oidstr = openpgp_curve_to_oid (curve, NULL, NULL); oidstr = openpgp_curve_to_oid (curve, NULL, NULL, 0);
err = openpgp_oid_from_str (oidstr, &oid); err = openpgp_oid_from_str (oidstr, &oid);
if (err) if (err)
return err; return err;
@ -4194,7 +4194,7 @@ change_keyattr_from_string (app_t app, ctrl_t ctrl,
else else
{ {
nbits = 0; nbits = 0;
oidstr = openpgp_curve_to_oid (keyalgo, NULL, &algo); oidstr = openpgp_curve_to_oid (keyalgo, NULL, &algo, 0);
if (!oidstr) if (!oidstr)
{ {
err = gpg_error (GPG_ERR_INV_DATA); err = gpg_error (GPG_ERR_INV_DATA);
@ -4244,7 +4244,7 @@ change_keyattr_from_string (app_t app, ctrl_t ctrl,
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)
{ {
oidstr = openpgp_curve_to_oid (string+n, NULL, NULL); oidstr = openpgp_curve_to_oid (string+n, NULL, NULL, 0);
if (!oidstr) if (!oidstr)
{ {
err = gpg_error (GPG_ERR_INV_DATA); err = gpg_error (GPG_ERR_INV_DATA);
@ -4821,7 +4821,7 @@ ecc_writekey (app_t app, ctrl_t ctrl,
ecdh_param_len = 4; ecdh_param_len = 4;
} }
oidstr = openpgp_curve_to_oid (curve, &n, NULL); oidstr = openpgp_curve_to_oid (curve, &n, NULL, 0);
ecc_d_fixed_len = (n+7)/8; ecc_d_fixed_len = (n+7)/8;
err = openpgp_oid_from_str (oidstr, &oid); err = openpgp_oid_from_str (oidstr, &oid);
if (err) if (err)
@ -5552,7 +5552,7 @@ gen_challenge (app_t app, const void **r_data, size_t *r_datalen)
{ {
unsigned int n; unsigned int n;
openpgp_curve_to_oid (app->app_local->keyattr[2].ecc.curve, &n, NULL); openpgp_curve_to_oid (app->app_local->keyattr[2].ecc.curve, &n, NULL, -1);
/* No hash algo header, and appropriate length of random octets, /* No hash algo header, and appropriate length of random octets,
determined by field size of the curve. */ determined by field size of the curve. */
datalen = (n+7)/8; datalen = (n+7)/8;

View File

@ -218,7 +218,7 @@ ecdh_encrypt (DEK dek, gcry_sexp_t s_pkey, gcry_sexp_t *r_encval)
* canonical numerical OID. We also use this to get the size of the * canonical numerical OID. We also use this to get the size of the
* curve which we need to figure out a suitable hash algo. We * curve which we need to figure out a suitable hash algo. We
* should have a Libgcrypt function to do this; see bug report #4926. */ * should have a Libgcrypt function to do this; see bug report #4926. */
curve = openpgp_curve_to_oid (curvebuf, &curvebits, NULL); curve = openpgp_curve_to_oid (curvebuf, &curvebits, NULL, -1);
if (!curve) if (!curve)
{ {
err = gpg_error (GPG_ERR_UNKNOWN_CURVE); err = gpg_error (GPG_ERR_UNKNOWN_CURVE);

View File

@ -2596,7 +2596,7 @@ build_ecc_key_sequence (gcry_mpi_t *kparms, int mode, size_t *r_length)
/* We need to use our OpenPGP mapping to turn a curve name into its /* We need to use our OpenPGP mapping to turn a curve name into its
* canonical numerical OID. We should have a Libgcrypt function to * canonical numerical OID. We should have a Libgcrypt function to
* do this; see bug report #4926. */ * do this; see bug report #4926. */
curve = openpgp_curve_to_oid (p, &curvebits, NULL); curve = openpgp_curve_to_oid (p, &curvebits, NULL, 1);
xfree (p); xfree (p);
if (!curve) if (!curve)
{ {