summaryrefslogtreecommitdiffstats
path: root/g10/keyid.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2024-04-05 12:02:32 +0200
committerWerner Koch <wk@gnupg.org>2024-04-05 12:02:32 +0200
commit53c6b1e85854e242da254334ad84145b2b4d963e (patch)
treed95a1e70301bc0e25045693a132ae49bf63178fe /g10/keyid.c
parentagent: Make "PKDECRYPT --kem" with optional value work. (diff)
downloadgnupg2-53c6b1e85854e242da254334ad84145b2b4d963e.tar.xz
gnupg2-53c6b1e85854e242da254334ad84145b2b4d963e.zip
gpg: Support dual keygrips.
* g10/keyid.c (keygrip_from_pk): Add arg get_second to support dual algos. Implement for Kyber. (hexkeygrip_from_pk): Extend for dual algos. * g10/call-agent.c (agent_keytotpm): Bail out for dual algos. (agent_keytocard): Ditto. (agent_probe_secret_key): Handle dual algos. (agent_probe_any_secret_key): Ditto. (agent_get_keyinfo): Allow for dual algos but take only the first key. * g10/export.c (do_export_one_keyblock): Bail out for dual algos. -- This also adds some fixmes which we eventually need to address. GnuPG-bug-id: 6815
Diffstat (limited to 'g10/keyid.c')
-rw-r--r--g10/keyid.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/g10/keyid.c b/g10/keyid.c
index b42d918a4..09940cbfe 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -1293,16 +1293,22 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
- key parameters expressed as an canonical encoded S-Exp. ARRAY must
- be 20 bytes long. Returns 0 on success or an error code. */
+ * key parameters expressed as an canonical encoded S-Exp. ARRAY must
+ * be 20 bytes long. Returns 0 on success or an error code. If
+ * GET_SECOND Is one and PK has dual algorithm, the keygrip of the
+ * second algorithm is return; GPG_ERR_FALSE is returned if the algo
+ * is not a dual algorithm. */
gpg_error_t
-keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
+keygrip_from_pk (PKT_public_key *pk, unsigned char *array, int get_second)
{
gpg_error_t err;
gcry_sexp_t s_pkey;
if (DBG_PACKET)
- log_debug ("get_keygrip for public key\n");
+ log_debug ("get_keygrip for public key%s\n", get_second?" (second)":"");
+
+ if (get_second && pk->pubkey_algo != PUBKEY_ALGO_KYBER)
+ return gpg_error (GPG_ERR_FALSE);
switch (pk->pubkey_algo)
{
@@ -1351,14 +1357,30 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
break;
case PUBKEY_ALGO_KYBER:
- {
- char tmpname[15];
+ if (get_second)
+ {
+ char tmpname[15];
- snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk));
- err = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(%s(p%m)))",
- tmpname, pk->pkey[2]);
- }
+ snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk));
+ err = gcry_sexp_build (&s_pkey, NULL,
+ "(public-key(%s(p%m)))",
+ tmpname, pk->pkey[2]);
+ }
+ else
+ {
+ char *curve = openpgp_oid_to_str (pk->pkey[0]);
+ if (!curve)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ err = gcry_sexp_build (&s_pkey, NULL,
+ openpgp_oid_is_cv25519 (pk->pkey[0])
+ ? "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))"
+ : "(public-key(ecc(curve%s)(q%m)))",
+ curve, pk->pkey[1]);
+ xfree (curve);
+ }
+ }
break;
default:
@@ -1393,26 +1415,45 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
/* Store an allocated buffer with the keygrip of PK encoded as a
- hexstring at r_GRIP. Returns 0 on success. */
+ * hexstring at r_GRIP. Returns 0 on success. For dual algorithms
+ * the keygrips are delimited by a comma. */
gpg_error_t
hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
{
gpg_error_t err;
+ char *buf;
unsigned char grip[KEYGRIP_LEN];
+ unsigned char grip2[KEYGRIP_LEN];
*r_grip = NULL;
- err = keygrip_from_pk (pk, grip);
+ err = keygrip_from_pk (pk, grip, 0);
if (!err)
{
- char * buf = xtrymalloc (KEYGRIP_LEN * 2 + 1);
- if (!buf)
- err = gpg_error_from_syserror ();
+ if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
+ {
+ err = keygrip_from_pk (pk, grip2, 1);
+ if (err)
+ goto leave;
+ buf = xtrymalloc (2 * KEYGRIP_LEN * 2 + 1 + 1);
+ }
else
+ buf = xtrymalloc (KEYGRIP_LEN * 2 + 1);
+
+ if (!buf)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ bin2hex (grip, KEYGRIP_LEN, buf);
+ if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
{
- bin2hex (grip, KEYGRIP_LEN, buf);
- *r_grip = buf;
+ buf[2*KEYGRIP_LEN] = ',';
+ bin2hex (grip2, KEYGRIP_LEN, buf+2*KEYGRIP_LEN+1);
}
+ *r_grip = buf;
}
+ leave:
return err;
}