From c37b145a323ec5353c1f57fa7d41d6c5cfea5c46 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Wed, 1 Jan 2020 00:00:00 +0100 Subject: Add a function to hash a public key for DPoP. --- ChangeLog | 1 + NEWS | 5 ++++- po/fr.po | 2 +- po/webid-oidc.pot | 2 +- src/jwk/ChangeLog | 4 ++++ src/jwk/generate-key.c | 4 ++++ src/jwk/libwebidoidc-jwk.c | 14 ++++++++++++++ src/scm/webid-oidc/stubs.scm | 3 ++- tests/Makefile.am | 3 ++- tests/jkt.scm | 23 +++++++++++++++++++++++ 10 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 tests/jkt.scm diff --git a/ChangeLog b/ChangeLog index 020a65a..10c78c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,7 @@ (Generating a key pair): Update NEWS (Strip a public key): Update NEWS (Hash some data): Update NEWS + (Hash a key): Update NEWS 2020-11-22 Vivien Kraus diff --git a/NEWS b/NEWS index 63f11c7..9c2eb24 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,10 @@ In order to avoid leaking the private components of a key, the =strip-key= function keeps only the required parts. ** Hash some data The function =hash= takes a string, and hashes its UTF-8 encoding. - +** Hash a key +In DPoP, the identity provider hashes the client's key in the access +token so that resource servers can verify that the client uses the +correct key. # Local Variables: # mode: org # End: diff --git a/po/fr.po b/po/fr.po index 869b9c1..677db22 100644 --- a/po/fr.po +++ b/po/fr.po @@ -121,7 +121,7 @@ msgstr "" msgid "Usage: generate-random [NUMBER OF BYTES]\n" msgstr "Utilisation : generate-random [NOMBRE D'OCTETS]\n" -#: src/jwk/generate-key.c:32 +#: src/jwk/generate-key.c:34 #, c-format msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "Utilisation : generate-key [NOMBRE DE BITS | COURBE]\n" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index f1fa6a0..83704c4 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -117,7 +117,7 @@ msgstr "" msgid "Usage: generate-random [NUMBER OF BYTES]\n" msgstr "" -#: src/jwk/generate-key.c:32 +#: src/jwk/generate-key.c:34 #, c-format msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "" diff --git a/src/jwk/ChangeLog b/src/jwk/ChangeLog index ebd0873..88b04e0 100644 --- a/src/jwk/ChangeLog +++ b/src/jwk/ChangeLog @@ -6,6 +6,10 @@ 2020-11-25 Vivien Kraus + * libwebidoidc-jwk.c (jkt): Implement the jkt function. + + * generate-key.c (run): display the hash of the key. + * libwebidoidc-jwk.c: new file. Add the strip function. diff --git a/src/jwk/generate-key.c b/src/jwk/generate-key.c index ec8ce76..e875b24 100644 --- a/src/jwk/generate-key.c +++ b/src/jwk/generate-key.c @@ -10,6 +10,8 @@ #define _(s) gettext (s) SCM webidoidc_generate_key_g (SCM args); +SCM webidoidc_strip_key_g (SCM key); +SCM webidoidc_jkt_g (SCM key); extern int init_webidoidc (void); @@ -48,6 +50,8 @@ run (void *params, int argc, char *argv[]) (scm_from_utf8_keyword ("n-size"), scm_from_size_t (n_size))); } + scm_display (webidoidc_jkt_g (data), scm_current_error_port ()); + fprintf (stderr, "\n"); scm_display (data, scm_current_output_port ()); } diff --git a/src/jwk/libwebidoidc-jwk.c b/src/jwk/libwebidoidc-jwk.c index 84da5da..71cb71c 100644 --- a/src/jwk/libwebidoidc-jwk.c +++ b/src/jwk/libwebidoidc-jwk.c @@ -3,6 +3,7 @@ #define _(s) dgettext (PACKAGE, s) void webid_oidc_random (size_t len, uint8_t * dst); +SCM webidoidc_hash_g (SCM alg, SCM payload); /* Register "generate-key", a guile function to generate a keypair. */ void init_webidoidc_jwk (void); @@ -173,9 +174,22 @@ SCM_DEFINE (webidoidc_strip_key_g, "strip-key", 1, 0, 0, (SCM key), scm_throw (unsupported_kty, scm_list_1 (key)); } +static SCM scm_to_json_string; + +SCM_SYMBOL (sha256, "SHA-256"); + +SCM_DEFINE (webidoidc_jkt_g, "jkt", 1, 0, 0, (SCM key), "Hash a public key.") +{ + SCM stripped = webidoidc_strip_key_g (key); + SCM as_json = scm_call_1 (scm_to_json_string, stripped); + SCM as_bytevector = scm_string_to_utf8 (as_json); + return webidoidc_hash_g (sha256, as_bytevector); +} + void init_webidoidc_jwk (void) { + scm_to_json_string = scm_c_public_ref ("json", "scm->json-string"); #ifndef SCM_MAGIC_SNARFER #include "libwebidoidc-jwk.x" #endif /* not SCM_MAGIC_SNARFER */ diff --git a/src/scm/webid-oidc/stubs.scm b/src/scm/webid-oidc/stubs.scm index 4f2036b..58fe356 100644 --- a/src/scm/webid-oidc/stubs.scm +++ b/src/scm/webid-oidc/stubs.scm @@ -46,7 +46,8 @@ (fix-generate-key . generate-key) (fix-kty . kty) strip-key - (fix-hash . hash)) + (fix-hash . hash) + jkt) ;; json reader from guile-json will not behave consistently with ;; SRFI-180 with objects: keys will be mapped to strings, not diff --git a/tests/Makefile.am b/tests/Makefile.am index cb41e05..e279463 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,7 +7,8 @@ TESTS = %reldir%/load-library.scm \ %reldir%/jwk-kty-rsa-correct.scm \ %reldir%/jwk-kty-rsa-incorrect.scm \ %reldir%/hash-ok.scm \ - %reldir%/hash-unsupported.scm + %reldir%/hash-unsupported.scm \ + %reldir%/jkt.scm EXTRA_DIST += $(TESTS) diff --git a/tests/jkt.scm b/tests/jkt.scm new file mode 100644 index 0000000..ca20f89 --- /dev/null +++ b/tests/jkt.scm @@ -0,0 +1,23 @@ +(use-modules (webid-oidc stubs) + (webid-oidc testing)) + +(with-test-environment + "jkt" + (lambda () + (let* ((key (json-string->scm "{ + \"kty\":\"EC\", + \"x\":\"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs\", + \"y\":\"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA\", + \"crv\":\"P-256\" + }")) + (jkt (jkt key)) + (expected "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I")) + (unless (string=? jkt expected) + (format (current-error-port) + "The JKT algorithm is not correct: +expected: ~a +obtained: ~a +" + expected + jkt) + (exit 1))))) -- cgit v1.2.3