diff options
Diffstat (limited to 'common/openpgp-oid.c')
-rw-r--r-- | common/openpgp-oid.c | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 493054950..92f0dfbcd 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -43,23 +43,34 @@ static struct { const char *oidstr; /* IETF formatted OID. */ unsigned int nbits; /* Nominal bit length of the curve. */ const char *alias; /* NULL or alternative name of the curve. */ + const char *abbr; /* NULL or abbreviated name of the curve. */ int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */ + enum gcry_kem_algos kem_algo; /* 0 or the KEM algorithm for PQC. */ } oidtable[] = { - { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", PUBKEY_ALGO_ECDH }, - { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", PUBKEY_ALGO_EDDSA }, - { "Curve25519", "1.3.101.110", 255, "cv25519", PUBKEY_ALGO_ECDH }, - { "Ed25519", "1.3.101.112", 255, "ed25519", PUBKEY_ALGO_EDDSA }, - { "X448", "1.3.101.111", 448, "cv448", PUBKEY_ALGO_ECDH }, - { "Ed448", "1.3.101.113", 456, "ed448", PUBKEY_ALGO_EDDSA }, + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", NULL, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 /* only during development */}, + { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", NULL, + PUBKEY_ALGO_EDDSA }, + { "Curve25519", "1.3.101.110", 255, "cv25519", NULL, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 }, + { "Ed25519", "1.3.101.112", 255, "ed25519", NULL, + PUBKEY_ALGO_EDDSA }, + { "X448", "1.3.101.111", 448, "cv448", NULL, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X448 }, + { "Ed448", "1.3.101.113", 456, "ed448", NULL, + PUBKEY_ALGO_EDDSA }, { "NIST P-256", "1.2.840.10045.3.1.7", 256, "nistp256" }, { "NIST P-384", "1.3.132.0.34", 384, "nistp384" }, { "NIST P-521", "1.3.132.0.35", 521, "nistp521" }, - { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256 }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384 }, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512 }, + { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256, NULL, "bp256", + 0, GCRY_KEM_RAW_BP256 }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384, NULL, "bp384", + 0, GCRY_KEM_RAW_BP384 }, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512, NULL, "bp512", + 0, GCRY_KEM_RAW_BP512 }, { "secp256k1", "1.3.132.0.10", 256 }, @@ -477,10 +488,20 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo) /* Map an OpenPGP OID to the Libgcrypt curve name. Returns NULL for - * unknown curve names. Unless CANON is set we prefer an alias name - * here which is more suitable for printing. */ + * unknown curve names. MODE defines which version of the curve name + * is returned. For example: + * + * | OID | mode=0 | mode=1 | mode=2 | + * |----------------------+-----------------+-----------------+----------| + * | 1.2.840.10045.3.1.7 | nistp256 | NIST P-256 | nistp256 | + * | 1.3.36.3.3.2.8.1.1.7 | brainpoolP256r1 | brainpoolP256r1 | bp256 | + * + * Thus mode 0 returns the name as commonly used gpg, mode 1 returns + * the canonical name, and mode 2 prefers an abbreviated name over the + * commonly used name. + */ const char * -openpgp_oid_to_curve (const char *oidstr, int canon) +openpgp_oid_to_curve (const char *oidstr, int mode) { int i; @@ -489,7 +510,15 @@ openpgp_oid_to_curve (const char *oidstr, int canon) for (i=0; oidtable[i].name; i++) if (!strcmp (oidtable[i].oidstr, oidstr)) - return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name; + { + if (mode == 2) + { + if (oidtable[i].abbr) + return oidtable[i].abbr; + mode = 0; /* No abbreviation - fallback to mode 0. */ + } + return !mode && oidtable[i].alias? oidtable[i].alias : oidtable[i].name; + } return NULL; } @@ -517,6 +546,29 @@ openpgp_oid_or_name_to_curve (const char *oidname, int canon) } +/* Return the KEM algorithm id for the curve with OIDNAME. */ +enum gcry_kem_algos +openpgp_oid_to_kem_algo (const char *oidname) +{ + int i; + + if (!oidname) + return 0; + + for (i=0; oidtable[i].name; i++) + if (!strcmp (oidtable[i].oidstr, oidname)) + return oidtable[i].kem_algo; + + for (i=0; oidtable[i].name; i++) + if (!ascii_strcasecmp (oidtable[i].name, oidname) + || (oidtable[i].alias + && !ascii_strcasecmp (oidtable[i].alias, oidname))) + return oidtable[i].kem_algo; + + return 0; +} + + /* Return true if the curve with NAME is supported. */ static int curve_supported_p (const char *name) @@ -574,7 +626,9 @@ openpgp_is_curve_supported (const char *name, int *r_algo, { if ((!ascii_strcasecmp (name, oidtable[idx].name) || (oidtable[idx].alias - && !ascii_strcasecmp (name, (oidtable[idx].alias)))) + && !ascii_strcasecmp (name, (oidtable[idx].alias))) + || (oidtable[idx].abbr + && !ascii_strcasecmp (name, (oidtable[idx].abbr)))) && curve_supported_p (oidtable[idx].name)) { if (r_algo) @@ -598,6 +652,7 @@ map_gcry_pk_to_openpgp (enum gcry_pk_algos 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_KEM: return PUBKEY_ALGO_KYBER; default: return algo < 110 ? (pubkey_algo_t)algo : 0; } } |