From 24095101a5069f15a9aea7512498ac436a76814a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 11 Feb 2020 14:38:03 +0100 Subject: [PATCH] common: Extend the openpgp_curve_to_oid function. * common/openpgp-oid.c (openpgp_curve_to_oid): Add optional arg R_NBITS. Change all callers. -- In particular for ed25519 and cv25519 it is quite useful to have an ability to get the required algorithm. --- common/openpgp-oid.c | 12 ++++++++++-- common/sexputil.c | 2 +- common/util.h | 3 ++- g10/card-util.c | 5 +++-- g10/export.c | 4 ++-- g10/gpg.c | 2 +- g10/keygen.c | 2 +- scd/app-openpgp.c | 8 ++++---- scd/app-piv.c | 5 +++-- 9 files changed, 27 insertions(+), 16 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 925384f3e..8fda23028 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -351,13 +351,17 @@ openpgp_oid_is_cv25519 (gcry_mpi_t a) /* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL store the bit size of the curve there. Returns NULL for unknown - curve names. */ + curve names. If R_ALGO is not NULL and a specific ECC algorithm is + required for this curve its OpenPGP algorithm number is stored + there; otherwise 0 is stored which indicates that ECDSA or ECDH can + be used. */ const char * -openpgp_curve_to_oid (const char *name, unsigned int *r_nbits) +openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo) { int i; unsigned int nbits = 0; const char *oidstr = NULL; + int algo = 0; if (name) { @@ -367,6 +371,7 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits) { oidstr = oidtable[i].oidstr; nbits = oidtable[i].nbits; + algo = oidtable[i].pubkey_algo; break; } if (!oidtable[i].name) @@ -378,6 +383,7 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits) { oidstr = oidtable[i].oidstr; nbits = oidtable[i].nbits; + algo = oidtable[i].pubkey_algo; break; } } @@ -385,6 +391,8 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits) if (r_nbits) *r_nbits = nbits; + if (r_algo) + *r_algo = algo; return oidstr; } diff --git a/common/sexputil.c b/common/sexputil.c index f99bc3b18..3ed95e43b 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -623,7 +623,7 @@ pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid) { const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL); const char *name = openpgp_oid_to_curve - (openpgp_curve_to_oid (curve, NULL), 0); + (openpgp_curve_to_oid (curve, NULL, NULL), 0); if (name) result = xtrystrdup (name); diff --git a/common/util.h b/common/util.h index a6bab2415..64d6c1627 100644 --- a/common/util.h +++ b/common/util.h @@ -238,7 +238,8 @@ int openpgp_oidbuf_is_ed25519 (const void *buf, size_t len); int openpgp_oid_is_ed25519 (gcry_mpi_t a); int openpgp_oidbuf_is_cv25519 (const void *buf, size_t len); int openpgp_oid_is_cv25519 (gcry_mpi_t a); -const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits); +const char *openpgp_curve_to_oid (const char *name, + unsigned int *r_nbits, int *r_algo); const char *openpgp_oid_to_curve (const char *oid, int canon); const char *openpgp_oid_or_name_to_curve (const char *oidname, int canon); const char *openpgp_enum_curves (int *idxp); diff --git a/g10/card-util.c b/g10/card-util.c index cb4dbe5e1..843abd823 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -632,7 +632,8 @@ current_card_status (ctrl_t ctrl, estream_t fp, if (info.key_attr[i].curve) { const char *oid; - oid = openpgp_curve_to_oid (info.key_attr[i].curve, NULL); + oid = openpgp_curve_to_oid (info.key_attr[i].curve, + NULL, NULL); if (oid) curve_for_print = openpgp_oid_to_curve (oid, 0); } @@ -1545,7 +1546,7 @@ ask_card_keyattr (int keyno, const struct key_attr *current) if (curve) { key_attr->algo = algo; - oid_str = openpgp_curve_to_oid (curve, NULL); + oid_str = openpgp_curve_to_oid (curve, NULL, NULL); key_attr->curve = openpgp_oid_to_curve (oid_str, 0); } else diff --git a/g10/export.c b/g10/export.c index 3517be72c..9160680d7 100644 --- a/g10/export.c +++ b/g10/export.c @@ -517,7 +517,7 @@ match_curve_skey_pk (gcry_sexp_t s_key, PKT_public_key *pk) log_error ("no curve name\n"); return gpg_error (GPG_ERR_UNKNOWN_CURVE); } - oidstr = openpgp_curve_to_oid (curve_str, NULL); + oidstr = openpgp_curve_to_oid (curve_str, NULL, NULL); if (!oidstr) { log_error ("no OID known for curve '%s'\n", curve_str); @@ -1023,7 +1023,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) goto leave; } - oidstr = openpgp_curve_to_oid (curve, NULL); + oidstr = openpgp_curve_to_oid (curve, NULL, NULL); if (!oidstr) { log_error ("no OID known for curve '%s'\n", curve); diff --git a/g10/gpg.c b/g10/gpg.c index 83524b13c..2ac34c9c1 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1879,7 +1879,7 @@ list_config(char *items) es_printf ("cfg:curveoid:"); for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0) { - s = openpgp_curve_to_oid (s, NULL); + s = openpgp_curve_to_oid (s, NULL, NULL); es_printf ("%s%s", first?"":";", s? s:"[?]"); } es_printf ("\n"); diff --git a/g10/keygen.c b/g10/keygen.c index 447743fca..06b098822 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1312,7 +1312,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) goto leave; } gcry_sexp_release (l2); - oidstr = openpgp_curve_to_oid (curve, &nbits); + oidstr = openpgp_curve_to_oid (curve, &nbits, NULL); if (!oidstr) { /* That can't happen because we used one of the curves diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 07fbf7474..62ec710bb 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1494,7 +1494,7 @@ ecdh_params (const char *curve) { unsigned int nbits; - openpgp_curve_to_oid (curve, &nbits); + openpgp_curve_to_oid (curve, &nbits, NULL); /* See RFC-6637 for those constants. 0x03: Number of bytes @@ -1535,7 +1535,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno, } curve = app->app_local->keyattr[keyno].ecc.curve; - oidstr = openpgp_curve_to_oid (curve, NULL); + oidstr = openpgp_curve_to_oid (curve, NULL, NULL); err = openpgp_oid_from_str (oidstr, &oid); if (err) return err; @@ -3608,7 +3608,7 @@ change_keyattr_from_string (app_t app, ctrl_t ctrl, const unsigned char *oidbuf; size_t oid_len; - oidstr = openpgp_curve_to_oid (string+n, NULL); + oidstr = openpgp_curve_to_oid (string+n, NULL, NULL); if (!oidstr) { err = gpg_error (GPG_ERR_INV_DATA); @@ -4115,7 +4115,7 @@ ecc_writekey (app_t app, ctrl_t ctrl, else algo = PUBKEY_ALGO_ECDSA; - oidstr = openpgp_curve_to_oid (curve, NULL); + oidstr = openpgp_curve_to_oid (curve, NULL, NULL); err = openpgp_oid_from_str (oidstr, &oid); if (err) goto leave; diff --git a/scd/app-piv.c b/scd/app-piv.c index 1b3e2e75b..cefc9d997 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -2927,9 +2927,10 @@ writekey_ecc (app_t app, data_object_t dobj, int keyref, name[toklen] = 0; /* Canonicalize the curve name. We use the openpgp * functions here because Libgcrypt has no generic curve - * alias lookup feature and the PIV suppotred curves alre + * alias lookup feature and the PIV supported curves are * also supported by OpenPGP. */ - xname = openpgp_oid_to_curve (openpgp_curve_to_oid (name, NULL), 0); + xname = openpgp_oid_to_curve (openpgp_curve_to_oid (name, NULL, NULL), + 0); xfree (name); if (xname && !strcmp (xname, "nistp256"))