aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2025-02-05 10:03:30 +0000
committerWerner Koch <[email protected]>2025-02-05 10:03:30 +0000
commit9dba5ab4034fd3b60cc74a77befb8ac481d810f6 (patch)
treecaa53f1f9258071d47716133093d40b87fb357b4
parentpo: Update to po/pt.po (diff)
downloadgnupg-9dba5ab4034fd3b60cc74a77befb8ac481d810f6.tar.gz
gnupg-9dba5ab4034fd3b60cc74a77befb8ac481d810f6.zip
gpg: Fix --quick-add-key for Weierstrass ECC with usage given.
* g10/keygen.c (adjust_algo_for_ecdh_ecdsa): New. (parse_algo_usage_expire): Adjust key algo. -- GnuPG-bug-id: 7506
-rw-r--r--g10/keygen.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/g10/keygen.c b/g10/keygen.c
index 185585e3f..df6540273 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -219,6 +219,40 @@ get_default_pubkey_algo (void)
}
+/* Depending on the USE some public key algorithms need to be changed.
+ * In particular this is the case for standard EC curves which may
+ * have either ECDSA or ECDH as their algo. The function returns the
+ * new algo if demanded by USE. IF the function can't decide the algo
+ * is returned as is and it is expected that a letter error check will
+ * kick in. If no change is required ALGO is returned as is. */
+static int
+adjust_algo_for_ecdh_ecdsa (int algo, unsigned int use, const char *curve)
+{
+ int needalgo;
+
+ if (algo != PUBKEY_ALGO_ECDSA && algo != PUBKEY_ALGO_ECDH)
+ return algo; /* Not an algo we need to adjust. */
+
+ if (!curve || !*curve)
+ return algo; /* No curve given and thus we can't decide. */
+ if (!openpgp_is_curve_supported (curve, &needalgo, NULL))
+ return algo; /* Curve not supported - can't decide. */
+ if (needalgo)
+ return algo; /* No need to map the X{25519,488} curves because we
+ * would also need to change the curve. */
+
+ if (algo == PUBKEY_ALGO_ECDH
+ && (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH|PUBKEY_USAGE_CERT)))
+ return PUBKEY_ALGO_ECDSA; /* Switch to the signing variant. */
+
+ if (algo == PUBKEY_ALGO_ECDSA
+ && (use & (PUBKEY_USAGE_ENC)))
+ return PUBKEY_ALGO_ECDH; /* Switch to the encryption variant. */
+
+ return algo; /* Return as is. */
+}
+
+
static void
print_status_key_created (int letter, PKT_public_key *pk, const char *handle)
{
@@ -6741,6 +6775,9 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
return gpg_error (GPG_ERR_INV_VALUE);
}
+ /* Now do the tricky ECDSA/ECDH adjustment. */
+ algo = adjust_algo_for_ecdh_ecdsa (algo, use, curve);
+
/* Make sure a primary key has the CERT usage. */
if (!for_subkey)
use |= PUBKEY_USAGE_CERT;