From e6a7ae7612b1d8f6b46bc70a21493265dbfcc20b Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Thu, 1 Feb 2024 10:20:27 -0500 Subject: [PATCH] Add ES256K support (#90) --- README.md | 1 + lib/openssl/ec.c | 3 ++- lib/openssl/ecdsa.c | 29 +++++++++++++++++++++++++---- lib/openssl/jwk.c | 4 +++- tests/jose-jwk-gen | 1 + 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a3805585..b8f45c92 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ José is extensively tested against the RFC test vectors. | ES256 | YES | Signature | EC | | ES384 | YES | Signature | EC | | ES512 | YES | Signature | EC | +| ES256K | YES | Signature | EC | | PS256 | YES | Signature | RSA | | PS384 | YES | Signature | RSA | | PS512 | YES | Signature | RSA | diff --git a/lib/openssl/ec.c b/lib/openssl/ec.c index 46433a30..0301f063 100644 --- a/lib/openssl/ec.c +++ b/lib/openssl/ec.c @@ -48,10 +48,11 @@ jwk_make_execute(jose_cfg_t *cfg, json_t *jwk) if (json_unpack(jwk, "{s?s}", "crv", &crv) < 0) return false; - switch (str2enum(crv, "P-256", "P-384", "P-521", NULL)) { + switch (str2enum(crv, "P-256", "P-384", "P-521", "secp256k1", NULL)) { case 0: nid = NID_X9_62_prime256v1; break; case 1: nid = NID_secp384r1; break; case 2: nid = NID_secp521r1; break; + case 3: nid = NID_secp256k1; break; default: return false; } diff --git a/lib/openssl/ecdsa.c b/lib/openssl/ecdsa.c index 263e931f..df887d6b 100644 --- a/lib/openssl/ecdsa.c +++ b/lib/openssl/ecdsa.c @@ -22,7 +22,7 @@ #include -#define NAMES "ES256", "ES384", "ES512" +#define NAMES "ES256", "ES384", "ES512", "ES256K" typedef struct { jose_io_t io; @@ -137,6 +137,19 @@ alg2crv(const char *alg) case 0: return "P-256"; case 1: return "P-384"; case 2: return "P-521"; + case 3: return "secp256k1"; + default: return NULL; + } +} + +static const char * +alg2hash(const char *alg) +{ + switch (str2enum(alg, NAMES, NULL)) { + case 0: return "S256"; + case 1: return "S384"; + case 2: return "S512"; + case 3: return "S256"; default: return NULL; } } @@ -200,10 +213,11 @@ alg_sign_sug(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwk) if (!type || strcmp(type, "EC") != 0) return NULL; - switch (str2enum(curv, "P-256", "P-384", "P-521", NULL)) { + switch (str2enum(curv, "P-256", "P-384", "P-521", "secp256k1", NULL)) { case 0: return "ES256"; case 1: return "ES384"; case 2: return "ES512"; + case 3: return "ES256K"; default: return NULL; } } @@ -216,7 +230,7 @@ alg_sign_sig(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jws, jose_io_auto_t *io = NULL; io_t *i = NULL; - halg = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_HASH, &alg->name[1]); + halg = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_HASH, alg2hash(alg->name)); if (!halg) return NULL; @@ -248,7 +262,7 @@ alg_sign_ver(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jws, jose_io_auto_t *io = NULL; io_t *i = NULL; - halg = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_HASH, &alg->name[1]); + halg = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_HASH, alg2hash(alg->name)); if (!halg) return NULL; @@ -302,6 +316,13 @@ constructor(void) .sign.sug = alg_sign_sug, .sign.sig = alg_sign_sig, .sign.ver = alg_sign_ver }, + { .kind = JOSE_HOOK_ALG_KIND_SIGN, + .name = "ES256K", + .sign.sprm = "sign", + .sign.vprm = "verify", + .sign.sug = alg_sign_sug, + .sign.sig = alg_sign_sig, + .sign.ver = alg_sign_ver }, {} }; diff --git a/lib/openssl/jwk.c b/lib/openssl/jwk.c index 8fc1dd73..1e8f3118 100644 --- a/lib/openssl/jwk.c +++ b/lib/openssl/jwk.c @@ -169,6 +169,7 @@ jose_openssl_jwk_from_EC_POINT(jose_cfg_t *cfg, const EC_GROUP *grp, case NID_X9_62_prime256v1: crv = "P-256"; break; case NID_secp384r1: crv = "P-384"; break; case NID_secp521r1: crv = "P-521"; break; + case NID_secp256k1: crv = "secp256k1"; break; default: return NULL; } @@ -366,10 +367,11 @@ jose_openssl_jwk_to_EC_KEY(jose_cfg_t *cfg, const json_t *jwk) if (strcmp(kty, "EC") != 0) return NULL; - switch (str2enum(crv, "P-256", "P-384", "P-521", NULL)) { + switch (str2enum(crv, "P-256", "P-384", "P-521", "secp256k1", NULL)) { case 0: nid = NID_X9_62_prime256v1; break; case 1: nid = NID_secp384r1; break; case 2: nid = NID_secp521r1; break; + case 3: nid = NID_secp256k1; break; default: return NULL; } diff --git a/tests/jose-jwk-gen b/tests/jose-jwk-gen index 364ba22c..063fd4e1 100755 --- a/tests/jose-jwk-gen +++ b/tests/jose-jwk-gen @@ -17,6 +17,7 @@ done jose jwk gen -i '{ "kty": "EC", "crv": "P-256" }' jose jwk gen -i '{ "kty": "EC", "crv": "P-384" }' jose jwk gen -i '{ "kty": "EC", "crv": "P-521" }' +jose jwk gen -i '{ "kty": "EC", "crv": "secp256k1" }' jose jwk gen -i '{ "kty": "RSA", "bits": 3072 }' ! jose jwk gen -i '{ "kty": "RSA", "bits": 3072, "e": 257 }'