Skip to main content

json_web_key/
lib.rs

1//! Parse and convert JSON Web Keys
2//!
3//! It uses [serde](https://serde.rs), and provides a basic
4//! struct layout to work with JSON Web Keys.
5//! See: [RFC7517](https://datatracker.ietf.org/doc/html/rfc7517)
6//!
7//! ## Serializing
8//! `let jwk_str: String = json_web_key::to_string(&jwk)`
9//!
10//! ## Deserializing
11//! `let jwk : JsonWebKey = json_web_key::from_str(&jwk_str)`
12//!
13//! ## Serde support
14//! You can use [JsonWebKey] and [JsonWebKeySet] with any code that already
15//! uses serde (for example: axum form and query deserializers).
16
17pub mod cert;
18pub mod ec;
19pub mod error;
20pub mod jwk;
21pub mod key_operation;
22pub mod rsa;
23pub mod use_case;
24
25pub type Result<T> = std::result::Result<T, error::Error>;
26
27pub mod prelude {
28    pub use crate::cert::Certificate;
29    pub use crate::ec::EcWebKey;
30    pub use crate::jwk::JsonWebKey;
31    pub use crate::jwk::JsonWebKeySet;
32    pub use crate::key_operation::KeyOperation;
33    pub use crate::rsa::RsaWebKey;
34    pub use crate::use_case::UseCase;
35}
36
37mod encoded_bytes_field;
38
39/// Deserializes a string into a Json Web Key.
40pub fn from_str(s: &str) -> Result<jwk::JsonWebKey> {
41    let value: jwk::JsonWebKey = serde_json::from_str(s)?;
42
43    Ok(value)
44}
45
46/// Serializes a JSON Web Key into a JSON string.
47pub fn to_string(value: &jwk::JsonWebKey) -> Result<String> {
48    let value = serde_json::to_string(value)?;
49
50    Ok(value)
51}
52
53#[cfg(test)]
54mod tests {
55    use super::prelude::*;
56    use super::*;
57    use base64ct::{Base64UrlUnpadded, Encoding};
58    use serde_json::json;
59
60    #[test]
61    fn test_rsa_jwk() {
62        let webkey = json!({
63            "alg": "RS256",
64            "e": "MzYzNTM1MzMzNzBhCg",
65            "kid": "test",
66            "key_ops": [],
67            "kty": "RSA",
68            "n": "NDIzNzMzMzQzMTQyMzQ0NDMxMzUzMTM1Mzc0NDM2Mzg0NDM3NDMzOTQ2NDI0NDM4MzMzMTQyMzY0MzQ1CjQzMzc0MjM0NDMzOTQxMzAzMjMxMzkzNDMxNDQzMTM2NDQzODQ0NDI0NjQ2NDIzMjM1MzMzNjM3NDUzNQo0MjQyMzgzNDM4Mzg0MjM2NDUzNjM5NDQ0NDQ2NDI0NDMyMzgzOTMyNDU0NDQ1Mzk0MzQyMzAzNTQ0NDUKMzkzODMyMzczOTMzNDYzNzMzMzkzNjQxMzMzMzQ1NDI0NDMwMzczMjM2NDIzMzM2Mzk0NDQyNDM0NDM0CjM0MzI0NTQxMzIzMjQzNDE0MTM2NDUzNzMyNDI0MjQxMzIzNjMyNDYzMjQ2MzE0NTQxNDQ0NTMxMzMzMwozMjM0Mzg0NDMxMzY0NTQyMzUzMDQzNDUzOTM2NDY0NDQ1MzMzNjMyNDQzMzM5NDEzMzM2NDYzMjM0MzgKMzIzNzMyNDEzNTQxMzE0MzM2Mzg0NTMzNDU0NTM3MzYzMzQyNDE0MjM2MzA0MjM4MzgzMTM4MzMzMTQ1CjQyNDU0NTM1MzM0NDQ0Mzg0MTQ0NDE0NDMzNDIzNTQxMzEzMjM4NDQ0NTQ0MzYzNjMzMzMzNjQ0MzgzNAozODM5NDI0MzMyMzkzODQxNDUzNDQzNDY0MjM1MzYzNDMyMzk0MzM3NDEzNDMwMzIzOTM3MzMzOTMwNDQKNDMzMjMxMzEzOTMxNDE0MTQyNDQzOTM0NDYzODMwMzc0MzMxNDI0NjM3NDIzNjQxMzA0NjMwMzAzNjQ2CjM5MzE0MTMxNDIzOTQ1MzgzMDMyNDQ0MzQ0NDY0MjMzNDE0NTM5MzgzMDQ2MzI0MTQyNDMzOTM3MzUzNgo0MjQxNDIzNTQzMzgzMDMwNDMzNDQzMzIzNzQxMzE0MjM5NDQzNzQ0MzIzMTM0NDY0MzQ2MzEzMTQ0MzAKMzIzMDQyMzAzNDQ0MzQzMTM3MzQzMTMyMzU0NDM5NDIzNDMwMzAzODQxMzY0MjMwNDYzMDM0MzYzNTM5CjMwNDY0NDQ2NDMzMjM2NDMzMDM4NDQzNzQ2NDM0NDQxNDYzMzQ1MzAzNzQzMzYzOTQzMzAzNTM4MzQzMwo0NDQ2NDYzMzQyMzEzNzMxNDEzNzMxMzQzMTM5MzM0NjQ1MzY0MzMxMzM0MTQxMzk0NjMzMzYzMTMyMzIKMzEzODM4MzIzODQ1Mzc0MjMwNDQ0MjM1MzQzNTM4MzMzODMwMzMzMDMwMzA0MTM4NDI0MjQ1NDI0MTM4CjM1NDQzNTQxMzYzNzM3MzUzOTM2MzUzNTM3MzUzODMzMzM0NTMzNDQzMDMyMzUzNTQzMzE0MjMyNDMzNwozMzM5MGEK",
69        });
70
71        let empty_cert = Certificate {
72            chain: None,
73            sha256_thumbprint: None,
74            thumbprint: None,
75            url: None,
76        };
77
78        let wk_string = webkey.to_string();
79
80        let jwk: JsonWebKey = from_str(wk_string.as_str()).unwrap();
81
82        let JsonWebKey::RS256(key) = &jwk else {
83            panic!("Incorrect algorithm.")
84        };
85
86        let enc_mod = Base64UrlUnpadded::encode_string(&key.modulus);
87        let enc_exp = Base64UrlUnpadded::encode_string(&key.exponent);
88
89        assert_eq!(key.key_id, "test".into());
90        assert_eq!(enc_mod, webkey["n"]);
91        assert_eq!(enc_exp, webkey["e"]);
92        assert_eq!(key.cert, empty_cert);
93        assert_eq!(key.key_type, rsa::KeyType::RSA);
94        assert_eq!(key.key_ops.len(), 0);
95        assert_eq!(key.use_case, UseCase::None);
96    }
97}