]> gitweb.factorcode.org Git - factor.git/commitdiff
crypto.jwt: Add a library to encode/decode jwt web tokens.
authorDoug Coleman <doug.coleman@gmail.com>
Fri, 9 Apr 2021 14:57:16 +0000 (09:57 -0500)
committerDoug Coleman <doug.coleman@gmail.com>
Fri, 9 Apr 2021 14:59:04 +0000 (09:59 -0500)
https://tools.ietf.org/html/rfc7519

online tester at https://jwt.io/#debugger

- we don't have a way to minify json (remove spaces from the final payload)
- had to add a word in base64 that urlencodes and removes trailing = signs
- only sha-256 is supported

extra/crypto/jwt/authors.txt [new file with mode: 0644]
extra/crypto/jwt/jwt-tests.factor [new file with mode: 0644]
extra/crypto/jwt/jwt.factor [new file with mode: 0644]

diff --git a/extra/crypto/jwt/authors.txt b/extra/crypto/jwt/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/extra/crypto/jwt/jwt-tests.factor b/extra/crypto/jwt/jwt-tests.factor
new file mode 100644 (file)
index 0000000..dd8fd5a
--- /dev/null
@@ -0,0 +1,24 @@
+! Copyright (C) 2021 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: checksums.sha crypto.jwt tools.test ;
+IN: crypto.jwt.tests
+
+{ t } [
+    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.he0ErCNloe4J7Id0Ry2SEDg09lKkZkfsRiGsdX_vgEg"
+    "" check-signature
+] unit-test
+
+{ t } [
+    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.QjxgSJl1C760VSNK4e5EZaYo6qemRqYL_Ol8ZgeQreg"
+    "covid" check-signature
+] unit-test
+
+{ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.he0ErCNloe4J7Id0Ry2SEDg09lKkZkfsRiGsdX_vgEg" } [
+    H{ { "alg" "HS256" } { "typ" "JWT" } }
+    H{
+        { "sub" "1234567890" }
+        { "name" "John Doe" }
+        { "iat" 1516239022 }
+    }
+    "" sha-256 sign-jwt
+] unit-test
\ No newline at end of file
diff --git a/extra/crypto/jwt/jwt.factor b/extra/crypto/jwt/jwt.factor
new file mode 100644 (file)
index 0000000..0b51235
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2021 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs base64 checksums.hmac checksums.sha json.reader
+json.writer kernel sequences splitting strings ;
+IN: crypto.jwt
+
+: jwt> ( jwt -- header payload signature )
+    "." split first3
+    [ urlsafe-base64> >string json> ]
+    [ urlsafe-base64> >string json> ]
+    [ ] tri* ;
+
+: hmac-signature ( encoded secret/f method/f -- signature )
+    [ "" or ] [ sha-256 or ] bi*
+    hmac-bytes >urlsafe-base64-jwt >string ;
+
+: jwt-encode-header-payload ( header payload -- encoded )
+    [ >json >urlsafe-base64-jwt ] bi@ "." glue ;
+
+: sign-jwt ( header payload secret/f method/f -- jwt )
+    [ jwt-encode-header-payload dup ] 2dip
+    hmac-signature "." "" glue-as ;
+
+ERROR: unsupported-jwt header ;
+
+: ensure-sha256 ( header -- header )
+    dup "typ" of "JWT" = [ unsupported-jwt ] unless
+    dup "alg" of "HS256" = [ unsupported-jwt ] unless ;
+
+: check-signature ( jwt secret/f -- ? )
+    [
+        "." split first3 [
+            dup
+            urlsafe-base64> >string json> ensure-sha256 drop
+        ] [ "." glue ]
+        [ ] tri*
+    ] dip
+    '[ _ f hmac-signature ] dip = ;