summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2020-01-01 00:00:00 +0100
committerVivien Kraus <vivien@planete-kraus.eu>2021-06-05 16:11:26 +0200
commitc37b145a323ec5353c1f57fa7d41d6c5cfea5c46 (patch)
treea5edcd0017a9201ca6a001d959b5c66ebeb4b603
parent1a5e600b5c0ec3730fd01ec97e81d609f981af45 (diff)
Add a function to hash a public key for DPoP.
-rw-r--r--ChangeLog1
-rw-r--r--NEWS5
-rw-r--r--po/fr.po2
-rw-r--r--po/webid-oidc.pot2
-rw-r--r--src/jwk/ChangeLog4
-rw-r--r--src/jwk/generate-key.c4
-rw-r--r--src/jwk/libwebidoidc-jwk.c14
-rw-r--r--src/scm/webid-oidc/stubs.scm3
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/jkt.scm23
10 files changed, 56 insertions, 5 deletions
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 <vivien@planete-kraus.eu>
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 <vivien@planete-kraus.eu>
+ * 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)))))