From 3e0b65a4c37238306ac262ad1c1266f84c83013a Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Mon, 6 Nov 2023 15:29:07 -0500 Subject: [PATCH] Migrate to jsonwebtoken --- Cargo.lock | 465 ++++----------------------- server/src/access/http.rs | 2 +- server/src/adm/command/make_token.rs | 2 +- server/src/config.rs | 10 +- server/src/oobe.rs | 2 +- token/Cargo.toml | 2 +- token/src/lib.rs | 92 +++++- 7 files changed, 149 insertions(+), 426 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bc8bd7..a122544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ dependencies = [ "base64 0.21.2", "chrono", "displaydoc", - "jwt-simple", + "jsonwebtoken", "lazy_static", "regex", "serde", @@ -361,7 +361,7 @@ dependencies = [ "hex", "http", "hyper", - "ring", + "ring 0.16.20", "time 0.3.21", "tokio", "tower", @@ -774,12 +774,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - [[package]] name = "base64" version = "0.13.1" @@ -802,12 +796,6 @@ dependencies = [ "vsimd", ] -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - [[package]] name = "bigdecimal" version = "0.3.1" @@ -819,12 +807,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "binstring" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0d60973d9320722cb1206f412740e162a33b8547ea8d6be75d7cff237c7a85" - [[package]] name = "bitflags" version = "1.3.2" @@ -970,11 +952,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -1086,18 +1069,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" -[[package]] -name = "coarsetime" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90d114103adbc625300f346d4d09dfb4ab1c4a8df6868435dd903392ecf4354" -dependencies = [ - "libc", - "once_cell", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -1172,12 +1143,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - [[package]] name = "const_format" version = "0.2.30" @@ -1270,18 +1235,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -1377,28 +1330,6 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "pem-rfc7468 0.6.0", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" -dependencies = [ - "const-oid", - "pem-rfc7468 0.7.0", - "zeroize", -] - [[package]] name = "derivative" version = "2.2.0" @@ -1429,7 +1360,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", "crypto-common", "subtle", ] @@ -1471,20 +1401,6 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" -[[package]] -name = "ecdsa" -version = "0.16.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" -dependencies = [ - "der 0.7.6", - "digest", - "elliptic-curve", - "rfc6979", - "signature 2.1.0", - "spki 0.7.2", -] - [[package]] name = "ed25519-compact" version = "2.0.4" @@ -1501,27 +1417,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -[[package]] -name = "elliptic-curve" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "hkdf", - "pem-rfc7468 0.7.0", - "pkcs8 0.10.2", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - [[package]] name = "encode_unicode" version = "0.3.6" @@ -1591,16 +1486,6 @@ dependencies = [ "instant", ] -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core", - "subtle", -] - [[package]] name = "filetime" version = "0.2.21" @@ -1764,31 +1649,19 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - [[package]] name = "h2" version = "0.3.19" @@ -1905,30 +1778,6 @@ dependencies = [ "digest", ] -[[package]] -name = "hmac-sha1-compact" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e2440a0078e20c3b68ca01234cea4219f23e64b0c0bdb1200c5550d54239bb" - -[[package]] -name = "hmac-sha256" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc736091aacb31ddaa4cd5f6988b3c21e99913ac846b41f32538c5fae5d71bfe" -dependencies = [ - "digest", -] - -[[package]] -name = "hmac-sha512" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520c9c3f6040661669bc5c91e551b605a520c8e0a63a766a91a65adef734d151" -dependencies = [ - "digest", -] - [[package]] name = "home" version = "0.5.5" @@ -2212,43 +2061,17 @@ dependencies = [ ] [[package]] -name = "jwt-simple" -version = "0.11.5" +name = "jsonwebtoken" +version = "9.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0537086995d782ba2fb6c120a88f0d66c5ee5f1208a3559826d4cf2264b170da" +checksum = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09" dependencies = [ - "anyhow", - "binstring", - "coarsetime", - "ct-codecs", - "ed25519-compact", - "hmac-sha1-compact", - "hmac-sha256", - "hmac-sha512", - "k256", - "p256", - "p384", - "rand", - "rsa", + "base64 0.21.2", + "pem", + "ring 0.17.5", "serde", "serde_json", - "spki 0.6.0", - "thiserror", - "zeroize", -] - -[[package]] -name = "k256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2", - "signature 2.1.0", + "simple_asn1", ] [[package]] @@ -2276,21 +2099,12 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", -] [[package]] name = "libc" -version = "0.2.144" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" - -[[package]] -name = "libm" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libsqlite3-sys" @@ -2466,23 +2280,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint-dig" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand", - "smallvec", - "zeroize", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -2493,17 +2290,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -2511,7 +2297,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2583,30 +2368,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - -[[package]] -name = "p384" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -2639,21 +2400,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] -name = "pem-rfc7468" -version = "0.6.0" +name = "pem" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" dependencies = [ - "base64ct", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", + "base64 0.21.2", + "serde", ] [[package]] @@ -2694,38 +2447,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" -dependencies = [ - "der 0.6.1", - "pkcs8 0.9.0", - "spki 0.6.0", - "zeroize", -] - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.6", - "spki 0.7.2", -] - [[package]] name = "pkg-config" version = "0.3.27" @@ -2753,15 +2474,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "primeorder" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" -dependencies = [ - "elliptic-curve", -] - [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -3013,16 +2725,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - [[package]] name = "ring" version = "0.16.20" @@ -3033,11 +2735,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "rkyv" version = "0.7.42" @@ -3066,27 +2782,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rsa" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" -dependencies = [ - "byteorder", - "digest", - "num-bigint-dig", - "num-integer", - "num-iter", - "num-traits", - "pkcs1", - "pkcs8 0.9.0", - "rand_core", - "signature 1.6.4", - "smallvec", - "subtle", - "zeroize", -] - [[package]] name = "rust_decimal" version = "1.29.1" @@ -3135,7 +2830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] @@ -3147,7 +2842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" dependencies = [ "log", - "ring", + "ring 0.16.20", "rustls-webpki", "sct", ] @@ -3179,8 +2874,8 @@ version = "0.100.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3231,8 +2926,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3404,20 +3099,6 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "sec1" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" -dependencies = [ - "base16ct", - "der 0.7.6", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - [[package]] name = "security-framework" version = "2.9.1" @@ -3605,32 +3286,24 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest", - "rand_core", -] - -[[package]] -name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" -dependencies = [ - "digest", - "rand_core", -] - [[package]] name = "simdutf8" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time 0.3.21", +] + [[package]] name = "slab" version = "0.4.8" @@ -3671,26 +3344,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" -dependencies = [ - "base64ct", - "der 0.7.6", -] - [[package]] name = "sqlformat" version = "0.2.1" @@ -4346,6 +3999,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.3.1" @@ -4530,8 +4189,8 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] diff --git a/server/src/access/http.rs b/server/src/access/http.rs index 0138def..e2b144f 100644 --- a/server/src/access/http.rs +++ b/server/src/access/http.rs @@ -101,7 +101,7 @@ pub async fn apply_auth(req: Request, next: Next) -> Response { .and_then(parse_authorization_header) .and_then(|jwt| { let state = req.extensions().get::().unwrap(); - let res_token = Token::from_jwt(&jwt, &state.config.token_hs256_secret); + let res_token = Token::from_jwt(&jwt, &state.config.token_hs256_secret.1); if let Err(e) = &res_token { tracing::debug!("Ignoring bad JWT token: {}", e); } diff --git a/server/src/adm/command/make_token.rs b/server/src/adm/command/make_token.rs index 1cfef1c..5777564 100644 --- a/server/src/adm/command/make_token.rs +++ b/server/src/adm/command/make_token.rs @@ -115,7 +115,7 @@ pub async fn run(config: Config, opts: Opts) -> Result<()> { if sub.dump_claims { println!("{}", serde_json::to_string(token.opaque_claims())?); } else { - let encoded_token = token.encode(&config.token_hs256_secret)?; + let encoded_token = token.encode(&config.token_hs256_secret.0)?; println!("{}", encoded_token); } diff --git a/server/src/config.rs b/server/src/config.rs index 7f24ba8..0c8a860 100644 --- a/server/src/config.rs +++ b/server/src/config.rs @@ -12,7 +12,7 @@ use derivative::Derivative; use serde::{de, Deserialize}; use xdg::BaseDirectories; -use crate::access::{decode_token_hs256_secret_base64, HS256Key}; +use crate::access::{decode_token_hs256_secret_base64, DecodingKey, EncodingKey}; use crate::narinfo::Compression as NixCompression; use crate::storage::{LocalStorageConfig, S3StorageConfig}; @@ -115,7 +115,7 @@ pub struct Config { #[serde(deserialize_with = "deserialize_token_hs256_secret_base64")] #[serde(default = "load_token_hs256_secret_from_env")] #[derivative(Debug = "ignore")] - pub token_hs256_secret: HS256Key, + pub token_hs256_secret: (EncodingKey, DecodingKey), } /// Database connection configuration. @@ -240,7 +240,7 @@ pub struct GarbageCollectionConfig { pub default_retention_period: Duration, } -fn load_token_hs256_secret_from_env() -> HS256Key { +fn load_token_hs256_secret_from_env() -> (EncodingKey, DecodingKey) { let s = env::var(ENV_TOKEN_HS256_SECRET_BASE64) .expect("The HS256 secret must be specified in either token_hs256_secret or the ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 environment."); @@ -296,7 +296,9 @@ impl Default for GarbageCollectionConfig { } } -fn deserialize_token_hs256_secret_base64<'de, D>(deserializer: D) -> Result +fn deserialize_token_hs256_secret_base64<'de, D>( + deserializer: D, +) -> Result<(EncodingKey, DecodingKey), D::Error> where D: de::Deserializer<'de>, { diff --git a/server/src/oobe.rs b/server/src/oobe.rs index 987edde..488c1db 100644 --- a/server/src/oobe.rs +++ b/server/src/oobe.rs @@ -77,7 +77,7 @@ pub async fn run_oobe() -> Result<()> { perm.destroy_cache = true; let key = decode_token_hs256_secret_base64(&hs256_secret_base64).unwrap(); - token.encode(&key)? + token.encode(&key.0)? }; eprintln!(); diff --git a/token/Cargo.toml b/token/Cargo.toml index c00a373..2a5ad73 100644 --- a/token/Cargo.toml +++ b/token/Cargo.toml @@ -11,7 +11,7 @@ attic = { path = "../attic", default-features = false } base64 = "0.21.2" chrono = "0.4.24" displaydoc = "0.2.4" -jwt-simple = "0.11.5" +jsonwebtoken = "9.1.0" lazy_static = "1.4.0" regex = "1.8.3" serde = "1.0.163" diff --git a/token/src/lib.rs b/token/src/lib.rs index 1437e1f..80e35c5 100644 --- a/token/src/lib.rs +++ b/token/src/lib.rs @@ -89,11 +89,8 @@ use std::error::Error as StdError; use base64::{engine::general_purpose::STANDARD as BASE64_STANDARD, Engine}; use chrono::{DateTime, Utc}; use displaydoc::Display; -pub use jwt_simple::{ - algorithms::{HS256Key, MACLike}, - claims::{Claims, JWTClaims}, - prelude::UnixTimeStamp, -}; +use jsonwebtoken::{Algorithm, Validation}; +pub use jsonwebtoken::{DecodingKey, EncodingKey}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, BoolFromInt}; @@ -126,6 +123,60 @@ macro_rules! require_permission_function { }; } +/// A set of JWT claims. +/// +/// The `CustomClaims` parameter can be set to `NoCustomClaims` if only standard +/// claims are used, or to a user-defined type that must be `serde`-serializable +/// if custom claims are required. +/// +/// NOTE: This has been lifted from jwt_simple, but UnixTimeStamp has been +/// changed to i64, and Audiences is now a string. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct JWTClaims { + /// Time the claims were created at + #[serde(rename = "iat", default, skip_serializing_if = "Option::is_none")] + pub issued_at: Option, + + /// Time the claims expire at + #[serde(rename = "exp", default, skip_serializing_if = "Option::is_none")] + pub expires_at: Option, + + /// Time the claims will be invalid until + #[serde(rename = "nbf", default, skip_serializing_if = "Option::is_none")] + pub invalid_before: Option, + + /// Issuer - This can be set to anything application-specific + #[serde(rename = "iss", default, skip_serializing_if = "Option::is_none")] + pub issuer: Option, + + /// Subject - This can be set to anything application-specific + #[serde(rename = "sub", default, skip_serializing_if = "Option::is_none")] + pub subject: Option, + + /// Audience + #[serde(rename = "aud", default, skip_serializing_if = "Option::is_none")] + pub audiences: Option, + + /// JWT identifier + /// + /// That property was originally designed to avoid replay attacks, but + /// keeping all previously sent JWT token IDs is unrealistic. + /// + /// Replay attacks are better addressed by keeping only the timestamp of the + /// last valid token for a user, and rejecting anything older in future + /// tokens. + #[serde(rename = "jti", default, skip_serializing_if = "Option::is_none")] + pub jwt_id: Option, + + /// Nonce + #[serde(rename = "nonce", default, skip_serializing_if = "Option::is_none")] + pub nonce: Option, + + /// Custom (application-defined) claims + #[serde(flatten)] + pub custom: CustomClaims, +} + /// A validated JSON Web Token. #[derive(Debug)] pub struct Token(JWTClaims); @@ -219,7 +270,7 @@ pub enum Error { PermissionDenied, /// JWT error: {0} - TokenError(jwt_simple::Error), + TokenError(jsonwebtoken::errors::Error), /// Base64 decode error: {0} Base64Error(base64::DecodeError), @@ -227,9 +278,18 @@ pub enum Error { impl Token { /// Verifies and decodes a token. - pub fn from_jwt(token: &str, key: &HS256Key) -> Result { - key.verify_token(token, None) + pub fn from_jwt(token: &str, key: &jsonwebtoken::DecodingKey) -> Result { + // TODO: create a static validator for us so we don't have to construct a new one every time? + + let mut validation = Validation::new(Algorithm::HS256); + validation.validate_nbf = true; + // validation.set_issuer(&[ctx.config.flakehub_jwt_bound_issuer.clone()]); + // validation.set_audience(&[ctx.config.jwt_bound_audience.clone()]); + validation.set_required_spec_claims(&["exp", "nbf", "aud", "iss", "sub"]); + + jsonwebtoken::decode::>(token, &key, &validation) .map_err(Error::TokenError) + .map(|tokendata| tokendata.claims) .map(Token) } @@ -241,9 +301,7 @@ impl Token { Self(JWTClaims { issued_at: None, - expires_at: Some(UnixTimeStamp::from_secs( - exp.timestamp().try_into().unwrap(), - )), + expires_at: Some(exp.timestamp()), invalid_before: None, issuer: None, subject: Some(sub), @@ -255,8 +313,9 @@ impl Token { } /// Encodes the token. - pub fn encode(&self, key: &HS256Key) -> Result { - key.authenticate(self.0.clone()).map_err(Error::TokenError) + pub fn encode(&self, key: &jsonwebtoken::EncodingKey) -> Result { + let header = jsonwebtoken::Header::default(); + jsonwebtoken::encode(&header, &self.0, key).map_err(Error::TokenError) } /// Returns the subject of the token. @@ -361,9 +420,12 @@ impl CachePermission { impl StdError for Error {} -pub fn decode_token_hs256_secret_base64(s: &str) -> Result { +pub fn decode_token_hs256_secret_base64(s: &str) -> Result<(EncodingKey, DecodingKey)> { let secret = BASE64_STANDARD.decode(s).map_err(Error::Base64Error)?; - Ok(HS256Key::from_bytes(&secret)) + Ok(( + EncodingKey::from_secret(&secret), + DecodingKey::from_secret(&secret), + )) } // bruh