Hi,

I'm trying to add an existing ECDSA key as a *signing* subkey of an existing RSA key.

Unfortunately this doesn't work. Instead, gpg only wants to add the ECDSA key as an ECDH *encrypting* subkey instead.

I dug through the source code and figured out why this is:

- gpg send READKEY for the ECDSA keygrip to gpg-agent.
- gpg-agent returns something like this:

D (10:public-key(3:ecc(5:curve10:NIST P-256)(1:q ... )))

Notice in particular that there is no indication of whether this is an ECDSA key or an ECDH key, just that it is an ECC key.

- libgcrypt matches this key type using the
`ecc_names`string array in`cipher/ecc.c`, and eventually maps it to`GCRY_PK_ECC`.

- this enum is converted by gnupg to the OpenPGP equivalent in
`map_gcry_pk_to_openpgp()`in gnupg`common/openpgp-oid.c`:

switch (algo) { case GCRY_PK_EDDSA: return PUBKEY_ALGO_EDDSA; case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; default: return algo < 110 ? (pubkey_algo_t)algo : 0; }

`GCRY_PK_ECC` falls through to the default case and its value is cast directly to `pubkey_algo_t`. The value of `GCRY_PK_ECC` is 18, which happens to match `PUBKEY_ALGO_ECDH`.

I hacked around this like so to produce an ECDSA subkey:

switch (algo) { case GCRY_PK_EDDSA: return PUBKEY_ALGO_EDDSA; case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; + case GCRY_PK_ECC: return PUBKEY_ALGO_ECDSA; default: return algo < 110 ? (pubkey_algo_t)algo : 0; }

Of course this is just a dirty hack and not an actual proper fix.

Can we please get the option to use an `ECC` key as either an `ECDH` encrypting subkey, or an `ECDSA` signing subkey?

Cheers,

Scott.

Note: I tested this on my distro's versions (gnupg-2.2.27, libgcrypt-1.9.2), but the logic in question hasn't changed in gnupg-2.3.1.