summaryrefslogtreecommitdiff
path: root/src/jwk/libwebidoidc-jwk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jwk/libwebidoidc-jwk.c')
-rw-r--r--src/jwk/libwebidoidc-jwk.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/jwk/libwebidoidc-jwk.c b/src/jwk/libwebidoidc-jwk.c
index 85386fb..84da5da 100644
--- a/src/jwk/libwebidoidc-jwk.c
+++ b/src/jwk/libwebidoidc-jwk.c
@@ -109,6 +109,70 @@ SCM_DEFINE (webidoidc_generate_key_g, "generate-key", 0, 0, 1, (SCM rest),
return ret;
}
+SCM_DEFINE (webidoidc_kty_g, "kty", 1, 0, 0, (SCM key),
+ "Return the type of @var{key}, @code{'EC} or @code{'RSA}. Return @code{#f} if this is not a JWK.")
+{
+ SCM crv = scm_assq_ref (key, kcrv);
+ const struct ecc_curve *c_crv = NULL;
+ struct ecc_point c_point;
+ struct ecc_scalar c_scalar;
+ struct rsa_public_key c_pub;
+ struct rsa_private_key c_key;
+ SCM ret = SCM_BOOL_F;
+ if (scm_is_true (crv))
+ {
+ c_crv = do_ecc_curve_load (crv, 0);
+ }
+ scm_dynwind_begin (0);
+ if (c_crv)
+ {
+ ecc_point_init (&c_point, c_crv);
+ dynwind_ecc_point_clear (&c_point);
+ ecc_scalar_init (&c_scalar, c_crv);
+ dynwind_ecc_scalar_clear (&c_scalar);
+ }
+ rsa_public_key_init (&c_pub);
+ dynwind_rsa_public_key_clear (&c_pub);
+ rsa_private_key_init (&c_key);
+ dynwind_rsa_private_key_clear (&c_key);
+ if (c_crv
+ && (do_ecc_point_load (&c_point, key)
+ || do_ecc_scalar_load (&c_scalar, key)))
+ {
+ ret = kty_ec;
+ }
+ else if (do_rsa_public_key_load (&c_pub, key)
+ || do_rsa_private_key_load (&c_key, key))
+ {
+ ret = kty_rsa;
+ }
+ scm_dynwind_end ();
+ return ret;
+}
+
+SCM_DEFINE (webidoidc_strip_key_g, "strip-key", 1, 0, 0, (SCM key),
+ "Strip a JWK, keeping only the parts that are required for a public key. The fields are sorted aphabetically.")
+{
+ SCM kty = webidoidc_kty_g (key);
+ SCM crv = scm_assq_ref (key, kcrv);
+ SCM x = scm_assq_ref (key, kx);
+ SCM y = scm_assq_ref (key, ky);
+ SCM n = scm_assq_ref (key, kn);
+ SCM e = scm_assq_ref (key, ke);
+ if (scm_is_eq (kty, kty_ec))
+ {
+ return scm_list_4 (scm_cons (kcrv, crv),
+ scm_cons (kkty, kty_ec),
+ scm_cons (kx, x), scm_cons (ky, y));
+ }
+ if (scm_is_eq (kty, kty_rsa))
+ {
+ return scm_list_3 (scm_cons (ke, e),
+ scm_cons (kkty, kty_rsa), scm_cons (kn, n));
+ }
+ scm_throw (unsupported_kty, scm_list_1 (key));
+}
+
void
init_webidoidc_jwk (void)
{