[PATCH 3/8] g10: add new match_curve_skey_pk() function
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Sat May 21 01:41:06 CEST 2016
* g10/export.c (match_curve_skey_pk): new function, testing whether an
OpenPGP public key and an S-expression use the same curve.
---
g10/export.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/g10/export.c b/g10/export.c
index 5120e33..d931507 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -390,6 +390,71 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
return result;
}
+/* return an error if the key represented by the S-expression s_key
+ and the OpenPGP key represented by pk do not use the same curve. */
+static gpg_error_t
+match_curve_skey_pk (gcry_sexp_t s_key, PKT_public_key *pk)
+{
+ gcry_sexp_t curve = NULL, flags = NULL;
+ char *curve_str = NULL, *flag;
+ const char *oidstr = NULL;
+ gcry_mpi_t curve_as_mpi = NULL;
+ gpg_error_t err;
+ int is_eddsa = 0, idx = 0;
+
+ if (!(pk->pubkey_algo==PUBKEY_ALGO_ECDH ||
+ pk->pubkey_algo==PUBKEY_ALGO_ECDSA ||
+ pk->pubkey_algo==PUBKEY_ALGO_EDDSA))
+ return gpg_error (GPG_ERR_PUBKEY_ALGO);
+
+ curve = gcry_sexp_find_token (s_key, "curve", 0);
+ if (!curve)
+ {
+ log_error ("no reported curve\n");
+ err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ curve_str = gcry_sexp_nth_string (curve, 1);
+ gcry_sexp_release (curve); curve = NULL;
+ if (!curve_str)
+ {
+ log_error ("no curve name\n");
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ oidstr = openpgp_curve_to_oid (curve_str, NULL);
+ if (!oidstr)
+ {
+ log_error ("no OID known for curve '%s'\n", curve_str);
+ gcry_free (curve_str);
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+ }
+ gcry_free (curve_str);
+ err = openpgp_oid_from_str (oidstr, &curve_as_mpi);
+ if (err)
+ return err;
+ if (gcry_mpi_cmp(pk->pkey[0], curve_as_mpi))
+ {
+ log_error ("curves do not match\n");
+ err = gpg_error (GPG_ERR_INV_CURVE);
+ }
+ gcry_mpi_release (curve_as_mpi);
+ flags = gcry_sexp_find_token (s_key, "flags", 0);
+ if (flags)
+ for (idx = 1; idx < gcry_sexp_length (flags); idx++)
+ {
+ flag = gcry_sexp_nth_string (flags, idx);
+ if (flag && (strcmp ("eddsa", flag) == 0))
+ is_eddsa = 1;
+ gcry_free (flag);
+ }
+ if (is_eddsa !=
+ (pk->pubkey_algo==PUBKEY_ALGO_EDDSA))
+ {
+ log_error ("disagreement about EdDSA\n");
+ err = gpg_error (GPG_ERR_INV_CURVE);
+ }
+
+ return err;
+}
/* Return a canonicalized public key algoithms. This is used to
compare different flavors of algorithms (e.g. ELG and ELG_E are
--
2.8.1
More information about the Gnupg-devel
mailing list