jsonwebtoken/
jwk.rs

1#![allow(missing_docs)]
2///! This crate contains types only for working JWK and JWK Sets
3///! This is only meant to be used to deal with public JWK, not generate ones.
4///! Most of the code in this file is taken from https://github.com/lawliet89/biscuit but
5/// tweaked to remove the private bits as it's not the goal for this crate currently.
6///!
7use crate::Algorithm;
8use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
9use std::fmt;
10
11/// The intended usage of the public `KeyType`. This enum is serialized `untagged`
12#[derive(Clone, Debug, Eq, PartialEq, Hash)]
13pub enum PublicKeyUse {
14    /// Indicates a public key is meant for signature verification
15    Signature,
16    /// Indicates a public key is meant for encryption
17    Encryption,
18    /// Other usage
19    Other(String),
20}
21
22impl Serialize for PublicKeyUse {
23    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24    where
25        S: Serializer,
26    {
27        let string = match self {
28            PublicKeyUse::Signature => "sig",
29            PublicKeyUse::Encryption => "enc",
30            PublicKeyUse::Other(other) => other,
31        };
32
33        serializer.serialize_str(string)
34    }
35}
36
37impl<'de> Deserialize<'de> for PublicKeyUse {
38    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39    where
40        D: Deserializer<'de>,
41    {
42        struct PublicKeyUseVisitor;
43        impl<'de> de::Visitor<'de> for PublicKeyUseVisitor {
44            type Value = PublicKeyUse;
45
46            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
47                write!(formatter, "a string")
48            }
49
50            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
51            where
52                E: de::Error,
53            {
54                Ok(match v {
55                    "sig" => PublicKeyUse::Signature,
56                    "enc" => PublicKeyUse::Encryption,
57                    other => PublicKeyUse::Other(other.to_string()),
58                })
59            }
60        }
61
62        deserializer.deserialize_string(PublicKeyUseVisitor)
63    }
64}
65
66/// Operations that the key is intended to be used for. This enum is serialized `untagged`
67#[derive(Clone, Debug, Eq, PartialEq, Hash)]
68pub enum KeyOperations {
69    /// Computer digital signature or MAC
70    Sign,
71    /// Verify digital signature or MAC
72    Verify,
73    /// Encrypt content
74    Encrypt,
75    /// Decrypt content and validate decryption, if applicable
76    Decrypt,
77    /// Encrypt key
78    WrapKey,
79    /// Decrypt key and validate decryption, if applicable
80    UnwrapKey,
81    /// Derive key
82    DeriveKey,
83    /// Derive bits not to be used as a key
84    DeriveBits,
85    /// Other operation
86    Other(String),
87}
88
89impl Serialize for KeyOperations {
90    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91    where
92        S: Serializer,
93    {
94        let string = match self {
95            KeyOperations::Sign => "sign",
96            KeyOperations::Verify => "verify",
97            KeyOperations::Encrypt => "encrypt",
98            KeyOperations::Decrypt => "decrypt",
99            KeyOperations::WrapKey => "wrapKey",
100            KeyOperations::UnwrapKey => "unwrapKey",
101            KeyOperations::DeriveKey => "deriveKey",
102            KeyOperations::DeriveBits => "deriveBits",
103            KeyOperations::Other(other) => other,
104        };
105
106        serializer.serialize_str(string)
107    }
108}
109
110impl<'de> Deserialize<'de> for KeyOperations {
111    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
112    where
113        D: Deserializer<'de>,
114    {
115        struct KeyOperationsVisitor;
116        impl<'de> de::Visitor<'de> for KeyOperationsVisitor {
117            type Value = KeyOperations;
118
119            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
120                write!(formatter, "a string")
121            }
122
123            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
124            where
125                E: de::Error,
126            {
127                Ok(match v {
128                    "sign" => KeyOperations::Sign,
129                    "verify" => KeyOperations::Verify,
130                    "encrypt" => KeyOperations::Encrypt,
131                    "decrypt" => KeyOperations::Decrypt,
132                    "wrapKey" => KeyOperations::WrapKey,
133                    "unwrapKey" => KeyOperations::UnwrapKey,
134                    "deriveKey" => KeyOperations::DeriveKey,
135                    "deriveBits" => KeyOperations::DeriveBits,
136                    other => KeyOperations::Other(other.to_string()),
137                })
138            }
139        }
140
141        deserializer.deserialize_string(KeyOperationsVisitor)
142    }
143}
144
145/// Common JWK parameters
146#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
147pub struct CommonParameters {
148    /// The intended use of the public key. Should not be specified with `key_operations`.
149    /// See sections 4.2 and 4.3 of [RFC7517](https://tools.ietf.org/html/rfc7517).
150    #[serde(rename = "use", skip_serializing_if = "Option::is_none", default)]
151    pub public_key_use: Option<PublicKeyUse>,
152
153    /// The "key_ops" (key operations) parameter identifies the operation(s)
154    /// for which the key is intended to be used.  The "key_ops" parameter is
155    /// intended for use cases in which public, private, or symmetric keys
156    /// may be present.
157    /// Should not be specified with `public_key_use`.
158    /// See sections 4.2 and 4.3 of [RFC7517](https://tools.ietf.org/html/rfc7517).
159    #[serde(rename = "key_ops", skip_serializing_if = "Option::is_none", default)]
160    pub key_operations: Option<Vec<KeyOperations>>,
161
162    /// The algorithm intended for use with the key
163    #[serde(rename = "alg", skip_serializing_if = "Option::is_none", default)]
164    pub algorithm: Option<Algorithm>,
165
166    /// The case sensitive Key ID for the key
167    #[serde(rename = "kid", skip_serializing_if = "Option::is_none", default)]
168    pub key_id: Option<String>,
169
170    /// X.509 Public key cerfificate URL. This is currently not implemented (correctly).
171    ///
172    /// Serialized to `x5u`.
173    #[serde(rename = "x5u", skip_serializing_if = "Option::is_none")]
174    pub x509_url: Option<String>,
175
176    /// X.509 public key certificate chain. This is currently not implemented (correctly).
177    ///
178    /// Serialized to `x5c`.
179    #[serde(rename = "x5c", skip_serializing_if = "Option::is_none")]
180    pub x509_chain: Option<Vec<String>>,
181
182    /// X.509 Certificate SHA1 thumbprint. This is currently not implemented (correctly).
183    ///
184    /// Serialized to `x5t`.
185    #[serde(rename = "x5t", skip_serializing_if = "Option::is_none")]
186    pub x509_sha1_fingerprint: Option<String>,
187
188    /// X.509 Certificate SHA256 thumbprint. This is currently not implemented (correctly).
189    ///
190    /// Serialized to `x5t#S256`.
191    #[serde(rename = "x5t#S256", skip_serializing_if = "Option::is_none")]
192    pub x509_sha256_fingerprint: Option<String>,
193}
194
195/// Key type value for an Elliptic Curve Key.
196/// This single value enum is a workaround for Rust not supporting associated constants.
197#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
198pub enum EllipticCurveKeyType {
199    /// Key type value for an Elliptic Curve Key.
200    EC,
201}
202
203impl Default for EllipticCurveKeyType {
204    fn default() -> Self {
205        EllipticCurveKeyType::EC
206    }
207}
208
209/// Type of cryptographic curve used by a key. This is defined in
210/// [RFC 7518 #7.6](https://tools.ietf.org/html/rfc7518#section-7.6)
211#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
212pub enum EllipticCurve {
213    /// P-256 curve
214    #[serde(rename = "P-256")]
215    P256,
216    /// P-384 curve
217    #[serde(rename = "P-384")]
218    P384,
219    /// P-521 curve -- unsupported by `ring`.
220    #[serde(rename = "P-521")]
221    P521,
222    /// Ed25519 curve
223    #[serde(rename = "Ed25519")]
224    Ed25519,
225}
226
227impl Default for EllipticCurve {
228    fn default() -> Self {
229        EllipticCurve::P256
230    }
231}
232
233/// Parameters for an Elliptic Curve Key
234#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
235pub struct EllipticCurveKeyParameters {
236    /// Key type value for an Elliptic Curve Key.
237    #[serde(rename = "kty")]
238    pub key_type: EllipticCurveKeyType,
239    /// The "crv" (curve) parameter identifies the cryptographic curve used
240    /// with the key.
241    #[serde(rename = "crv")]
242    pub curve: EllipticCurve,
243    /// The "x" (x coordinate) parameter contains the x coordinate for the
244    /// Elliptic Curve point.
245    pub x: String,
246    /// The "y" (y coordinate) parameter contains the y coordinate for the
247    /// Elliptic Curve point.
248    pub y: String,
249}
250
251/// Key type value for an RSA Key.
252/// This single value enum is a workaround for Rust not supporting associated constants.
253#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
254pub enum RSAKeyType {
255    /// Key type value for an RSA Key.
256    RSA,
257}
258
259impl Default for RSAKeyType {
260    fn default() -> Self {
261        RSAKeyType::RSA
262    }
263}
264
265/// Parameters for a RSA Key
266#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
267pub struct RSAKeyParameters {
268    /// Key type value for a RSA Key
269    #[serde(rename = "kty")]
270    pub key_type: RSAKeyType,
271
272    /// The "n" (modulus) parameter contains the modulus value for the RSA
273    /// public key.
274    pub n: String,
275
276    /// The "e" (exponent) parameter contains the exponent value for the RSA
277    /// public key.
278    pub e: String,
279}
280
281/// Key type value for an Octet symmetric key.
282/// This single value enum is a workaround for Rust not supporting associated constants.
283#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
284pub enum OctetKeyType {
285    /// Key type value for an Octet symmetric key.
286    #[serde(rename = "oct")]
287    Octet,
288}
289
290impl Default for OctetKeyType {
291    fn default() -> Self {
292        OctetKeyType::Octet
293    }
294}
295
296/// Parameters for an Octet Key
297#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
298pub struct OctetKeyParameters {
299    /// Key type value for an Octet Key
300    #[serde(rename = "kty")]
301    pub key_type: OctetKeyType,
302    /// The octet key value
303    #[serde(rename = "k")]
304    pub value: String,
305}
306
307/// Key type value for an Octet Key Pair.
308/// This single value enum is a workaround for Rust not supporting associated constants.
309#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
310pub enum OctetKeyPairType {
311    /// Key type value for an Octet Key Pair.
312    #[serde(rename = "OKP")]
313    OctetKeyPair,
314}
315
316impl Default for OctetKeyPairType {
317    fn default() -> Self {
318        OctetKeyPairType::OctetKeyPair
319    }
320}
321
322/// Parameters for an Octet Key Pair
323#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
324pub struct OctetKeyPairParameters {
325    /// Key type value for an Octet Key Pair
326    #[serde(rename = "kty")]
327    pub key_type: OctetKeyPairType,
328    /// The "crv" (curve) parameter identifies the cryptographic curve used
329    /// with the key.
330    #[serde(rename = "crv")]
331    pub curve: EllipticCurve,
332    /// The "x" parameter contains the base64 encoded public key
333    pub x: String,
334}
335
336/// Algorithm specific parameters
337#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
338#[serde(untagged)]
339pub enum AlgorithmParameters {
340    EllipticCurve(EllipticCurveKeyParameters),
341    RSA(RSAKeyParameters),
342    OctetKey(OctetKeyParameters),
343    OctetKeyPair(OctetKeyPairParameters),
344}
345
346#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
347pub struct Jwk {
348    #[serde(flatten)]
349    pub common: CommonParameters,
350    /// Key algorithm specific parameters
351    #[serde(flatten)]
352    pub algorithm: AlgorithmParameters,
353}
354
355/// A JWK set
356#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
357pub struct JwkSet {
358    pub keys: Vec<Jwk>,
359}
360
361impl JwkSet {
362    /// Find the key in the set that matches the given key id, if any.
363    pub fn find(&self, kid: &str) -> Option<&Jwk> {
364        self.keys
365            .iter()
366            .find(|jwk| jwk.common.key_id.is_some() && jwk.common.key_id.as_ref().unwrap() == kid)
367    }
368}
369
370#[cfg(test)]
371mod tests {
372    use crate::jwk::{AlgorithmParameters, JwkSet, OctetKeyType};
373    use crate::serialization::b64_encode;
374    use crate::Algorithm;
375    use serde_json::json;
376
377    #[test]
378    fn check_hs256() {
379        let key = b64_encode("abcdefghijklmnopqrstuvwxyz012345");
380        let jwks_json = json!({
381            "keys": [
382                {
383                    "kty": "oct",
384                    "alg": "HS256",
385                    "kid": "abc123",
386                    "k": key
387                }
388            ]
389        });
390
391        let set: JwkSet = serde_json::from_value(jwks_json).expect("Failed HS256 check");
392        assert_eq!(set.keys.len(), 1);
393        let key = &set.keys[0];
394        assert_eq!(key.common.key_id, Some("abc123".to_string()));
395        assert_eq!(key.common.algorithm, Some(Algorithm::HS256));
396        match &key.algorithm {
397            AlgorithmParameters::OctetKey(key) => {
398                assert_eq!(key.key_type, OctetKeyType::Octet);
399                assert_eq!(key.value, key.value)
400            }
401            _ => panic!("Unexpected key algorithm"),
402        }
403    }
404}