1#![allow(missing_docs)]
2use std::{fmt, str::FromStr};
8
9use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
10
11use crate::crypto::CryptoProvider;
12use crate::serialization::b64_encode;
13use crate::{
14 Algorithm, EncodingKey,
15 errors::{self, Error, ErrorKind},
16};
17
18#[derive(Clone, Debug, Eq, PartialEq, Hash)]
20pub enum PublicKeyUse {
21 Signature,
23 Encryption,
25 Other(String),
27}
28
29impl Serialize for PublicKeyUse {
30 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31 where
32 S: Serializer,
33 {
34 let string = match self {
35 PublicKeyUse::Signature => "sig",
36 PublicKeyUse::Encryption => "enc",
37 PublicKeyUse::Other(other) => other,
38 };
39
40 serializer.serialize_str(string)
41 }
42}
43
44impl<'de> Deserialize<'de> for PublicKeyUse {
45 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46 where
47 D: Deserializer<'de>,
48 {
49 struct PublicKeyUseVisitor;
50 impl de::Visitor<'_> for PublicKeyUseVisitor {
51 type Value = PublicKeyUse;
52
53 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(formatter, "a string")
55 }
56
57 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
58 where
59 E: de::Error,
60 {
61 Ok(match v {
62 "sig" => PublicKeyUse::Signature,
63 "enc" => PublicKeyUse::Encryption,
64 other => PublicKeyUse::Other(other.to_string()),
65 })
66 }
67 }
68
69 deserializer.deserialize_string(PublicKeyUseVisitor)
70 }
71}
72
73#[derive(Clone, Debug, Eq, PartialEq, Hash)]
75pub enum KeyOperations {
76 Sign,
78 Verify,
80 Encrypt,
82 Decrypt,
84 WrapKey,
86 UnwrapKey,
88 DeriveKey,
90 DeriveBits,
92 Other(String),
94}
95
96impl Serialize for KeyOperations {
97 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
98 where
99 S: Serializer,
100 {
101 let string = match self {
102 KeyOperations::Sign => "sign",
103 KeyOperations::Verify => "verify",
104 KeyOperations::Encrypt => "encrypt",
105 KeyOperations::Decrypt => "decrypt",
106 KeyOperations::WrapKey => "wrapKey",
107 KeyOperations::UnwrapKey => "unwrapKey",
108 KeyOperations::DeriveKey => "deriveKey",
109 KeyOperations::DeriveBits => "deriveBits",
110 KeyOperations::Other(other) => other,
111 };
112
113 serializer.serialize_str(string)
114 }
115}
116
117impl<'de> Deserialize<'de> for KeyOperations {
118 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
119 where
120 D: Deserializer<'de>,
121 {
122 struct KeyOperationsVisitor;
123 impl de::Visitor<'_> for KeyOperationsVisitor {
124 type Value = KeyOperations;
125
126 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(formatter, "a string")
128 }
129
130 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
131 where
132 E: de::Error,
133 {
134 Ok(match v {
135 "sign" => KeyOperations::Sign,
136 "verify" => KeyOperations::Verify,
137 "encrypt" => KeyOperations::Encrypt,
138 "decrypt" => KeyOperations::Decrypt,
139 "wrapKey" => KeyOperations::WrapKey,
140 "unwrapKey" => KeyOperations::UnwrapKey,
141 "deriveKey" => KeyOperations::DeriveKey,
142 "deriveBits" => KeyOperations::DeriveBits,
143 other => KeyOperations::Other(other.to_string()),
144 })
145 }
146 }
147
148 deserializer.deserialize_string(KeyOperationsVisitor)
149 }
150}
151
152#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
154#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
155pub enum KeyAlgorithm {
156 HS256,
158 HS384,
160 HS512,
162
163 ES256,
165 ES384,
167
168 RS256,
170 RS384,
172 RS512,
174
175 PS256,
177 PS384,
179 PS512,
181
182 EdDSA,
184
185 RSA1_5,
187
188 #[serde(rename = "RSA-OAEP")]
190 RSA_OAEP,
191
192 #[serde(rename = "RSA-OAEP-256")]
194 RSA_OAEP_256,
195
196 #[serde(other)]
198 UNKNOWN_ALGORITHM,
199}
200
201impl FromStr for KeyAlgorithm {
202 type Err = Error;
203 fn from_str(s: &str) -> errors::Result<Self> {
204 match s {
205 "HS256" => Ok(KeyAlgorithm::HS256),
206 "HS384" => Ok(KeyAlgorithm::HS384),
207 "HS512" => Ok(KeyAlgorithm::HS512),
208 "ES256" => Ok(KeyAlgorithm::ES256),
209 "ES384" => Ok(KeyAlgorithm::ES384),
210 "RS256" => Ok(KeyAlgorithm::RS256),
211 "RS384" => Ok(KeyAlgorithm::RS384),
212 "PS256" => Ok(KeyAlgorithm::PS256),
213 "PS384" => Ok(KeyAlgorithm::PS384),
214 "PS512" => Ok(KeyAlgorithm::PS512),
215 "RS512" => Ok(KeyAlgorithm::RS512),
216 "EdDSA" => Ok(KeyAlgorithm::EdDSA),
217 "RSA1_5" => Ok(KeyAlgorithm::RSA1_5),
218 "RSA-OAEP" => Ok(KeyAlgorithm::RSA_OAEP),
219 "RSA-OAEP-256" => Ok(KeyAlgorithm::RSA_OAEP_256),
220 _ => Err(ErrorKind::InvalidAlgorithmName.into()),
221 }
222 }
223}
224
225impl fmt::Display for KeyAlgorithm {
226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227 write!(f, "{:?}", self)
228 }
229}
230
231impl KeyAlgorithm {
232 fn to_algorithm(self) -> errors::Result<Algorithm> {
233 Algorithm::from_str(self.to_string().as_str())
234 }
235}
236
237#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
239pub struct CommonParameters {
240 #[serde(rename = "use", skip_serializing_if = "Option::is_none", default)]
243 pub public_key_use: Option<PublicKeyUse>,
244
245 #[serde(rename = "key_ops", skip_serializing_if = "Option::is_none", default)]
252 pub key_operations: Option<Vec<KeyOperations>>,
253
254 #[serde(rename = "alg", skip_serializing_if = "Option::is_none", default)]
256 pub key_algorithm: Option<KeyAlgorithm>,
257
258 #[serde(rename = "kid", skip_serializing_if = "Option::is_none", default)]
260 pub key_id: Option<String>,
261
262 #[serde(rename = "x5u", skip_serializing_if = "Option::is_none")]
266 pub x509_url: Option<String>,
267
268 #[serde(rename = "x5c", skip_serializing_if = "Option::is_none")]
272 pub x509_chain: Option<Vec<String>>,
273
274 #[serde(rename = "x5t", skip_serializing_if = "Option::is_none")]
278 pub x509_sha1_fingerprint: Option<String>,
279
280 #[serde(rename = "x5t#S256", skip_serializing_if = "Option::is_none")]
284 pub x509_sha256_fingerprint: Option<String>,
285}
286
287#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
290pub enum EllipticCurveKeyType {
291 #[default]
293 EC,
294}
295
296#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
299pub enum EllipticCurve {
300 #[serde(rename = "P-256")]
302 #[default]
303 P256,
304 #[serde(rename = "P-384")]
306 P384,
307 #[serde(rename = "P-521")]
309 P521,
310 #[serde(rename = "Ed25519")]
312 Ed25519,
313}
314
315#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
317pub struct EllipticCurveKeyParameters {
318 #[serde(rename = "kty")]
320 pub key_type: EllipticCurveKeyType,
321 #[serde(rename = "crv")]
324 pub curve: EllipticCurve,
325 pub x: String,
328 pub y: String,
331}
332
333#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
336pub enum RSAKeyType {
337 #[default]
339 RSA,
340}
341
342#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
344pub struct RSAKeyParameters {
345 #[serde(rename = "kty")]
347 pub key_type: RSAKeyType,
348
349 pub n: String,
352
353 pub e: String,
356}
357
358#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
361pub enum OctetKeyType {
362 #[serde(rename = "oct")]
364 #[default]
365 Octet,
366}
367
368#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
370pub struct OctetKeyParameters {
371 #[serde(rename = "kty")]
373 pub key_type: OctetKeyType,
374 #[serde(rename = "k")]
376 pub value: String,
377}
378
379#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
382pub enum OctetKeyPairType {
383 #[serde(rename = "OKP")]
385 #[default]
386 OctetKeyPair,
387}
388
389#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
391pub struct OctetKeyPairParameters {
392 #[serde(rename = "kty")]
394 pub key_type: OctetKeyPairType,
395 #[serde(rename = "crv")]
398 pub curve: EllipticCurve,
399 pub x: String,
401}
402
403#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
405#[serde(untagged)]
406pub enum AlgorithmParameters {
407 EllipticCurve(EllipticCurveKeyParameters),
408 RSA(RSAKeyParameters),
409 OctetKey(OctetKeyParameters),
410 OctetKeyPair(OctetKeyPairParameters),
411}
412
413#[derive(Debug, Clone, Eq, PartialEq)]
415pub enum ThumbprintHash {
416 SHA256,
417 SHA384,
418 SHA512,
419}
420
421#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
422pub struct Jwk {
423 #[serde(flatten)]
424 pub common: CommonParameters,
425 #[serde(flatten)]
427 pub algorithm: AlgorithmParameters,
428}
429
430impl Jwk {
431 pub fn is_supported(&self) -> bool {
433 match self.common.key_algorithm {
434 Some(alg) => alg.to_algorithm().is_ok(),
435 _ => false,
436 }
437 }
438 pub fn from_encoding_key(key: &EncodingKey, alg: Algorithm) -> crate::errors::Result<Self> {
439 Ok(Self {
440 common: CommonParameters {
441 key_algorithm: Some(match alg {
442 Algorithm::HS256 => KeyAlgorithm::HS256,
443 Algorithm::HS384 => KeyAlgorithm::HS384,
444 Algorithm::HS512 => KeyAlgorithm::HS512,
445 Algorithm::ES256 => KeyAlgorithm::ES256,
446 Algorithm::ES384 => KeyAlgorithm::ES384,
447 Algorithm::RS256 => KeyAlgorithm::RS256,
448 Algorithm::RS384 => KeyAlgorithm::RS384,
449 Algorithm::RS512 => KeyAlgorithm::RS512,
450 Algorithm::PS256 => KeyAlgorithm::PS256,
451 Algorithm::PS384 => KeyAlgorithm::PS384,
452 Algorithm::PS512 => KeyAlgorithm::PS512,
453 Algorithm::EdDSA => KeyAlgorithm::EdDSA,
454 }),
455 ..Default::default()
456 },
457 algorithm: match key.family() {
458 crate::algorithms::AlgorithmFamily::Hmac => {
459 AlgorithmParameters::OctetKey(OctetKeyParameters {
460 key_type: OctetKeyType::Octet,
461 value: b64_encode(key.inner()),
462 })
463 }
464 crate::algorithms::AlgorithmFamily::Rsa => {
465 let (n, e) = (CryptoProvider::get_default()
466 .jwk_utils
467 .extract_rsa_public_key_components)(
468 key.inner()
469 )?;
470 AlgorithmParameters::RSA(RSAKeyParameters {
471 key_type: RSAKeyType::RSA,
472 n: b64_encode(n),
473 e: b64_encode(e),
474 })
475 }
476 crate::algorithms::AlgorithmFamily::Ec => {
477 let (curve, x, y) = (CryptoProvider::get_default()
478 .jwk_utils
479 .extract_ec_public_key_coordinates)(
480 key.inner(), alg
481 )?;
482 AlgorithmParameters::EllipticCurve(EllipticCurveKeyParameters {
483 key_type: EllipticCurveKeyType::EC,
484 curve,
485 x: b64_encode(x),
486 y: b64_encode(y),
487 })
488 }
489 crate::algorithms::AlgorithmFamily::Ed => {
490 unimplemented!();
491 }
492 },
493 })
494 }
495
496 pub fn thumbprint(&self, hash_function: ThumbprintHash) -> String {
500 let pre = match &self.algorithm {
501 AlgorithmParameters::EllipticCurve(a) => match a.curve {
502 EllipticCurve::P256 | EllipticCurve::P384 | EllipticCurve::P521 => {
503 format!(
504 r#"{{"crv":{},"kty":{},"x":"{}","y":"{}"}}"#,
505 serde_json::to_string(&a.curve).unwrap(),
506 serde_json::to_string(&a.key_type).unwrap(),
507 a.x,
508 a.y,
509 )
510 }
511 EllipticCurve::Ed25519 => panic!("EllipticCurve can't contain this curve type"),
512 },
513 AlgorithmParameters::RSA(a) => {
514 format!(
515 r#"{{"e":"{}","kty":{},"n":"{}"}}"#,
516 a.e,
517 serde_json::to_string(&a.key_type).unwrap(),
518 a.n,
519 )
520 }
521 AlgorithmParameters::OctetKey(a) => {
522 format!(
523 r#"{{"k":"{}","kty":{}}}"#,
524 a.value,
525 serde_json::to_string(&a.key_type).unwrap()
526 )
527 }
528 AlgorithmParameters::OctetKeyPair(a) => match a.curve {
529 EllipticCurve::P256 | EllipticCurve::P384 | EllipticCurve::P521 => {
530 panic!("OctetKeyPair can't contain this curve type")
531 }
532 EllipticCurve::Ed25519 => {
533 format!(
534 r#"{{crv:{},"kty":{},"x":"{}"}}"#,
535 serde_json::to_string(&a.curve).unwrap(),
536 serde_json::to_string(&a.key_type).unwrap(),
537 a.x,
538 )
539 }
540 },
541 };
542
543 b64_encode((CryptoProvider::get_default().jwk_utils.compute_digest)(
544 pre.as_bytes(),
545 hash_function,
546 ))
547 }
548}
549
550#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
552pub struct JwkSet {
553 pub keys: Vec<Jwk>,
554}
555
556impl JwkSet {
557 pub fn find(&self, kid: &str) -> Option<&Jwk> {
559 self.keys
560 .iter()
561 .find(|jwk| jwk.common.key_id.is_some() && jwk.common.key_id.as_ref().unwrap() == kid)
562 }
563}
564
565#[cfg(test)]
566mod tests {
567 use serde_json::json;
568 use wasm_bindgen_test::wasm_bindgen_test;
569
570 use crate::Algorithm;
571 use crate::jwk::{
572 AlgorithmParameters, Jwk, JwkSet, KeyAlgorithm, OctetKeyType, RSAKeyParameters,
573 ThumbprintHash,
574 };
575 use crate::serialization::b64_encode;
576
577 #[test]
578 #[wasm_bindgen_test]
579 fn check_hs256() {
580 let key = b64_encode("abcdefghijklmnopqrstuvwxyz012345");
581 let jwks_json = json!({
582 "keys": [
583 {
584 "kty": "oct",
585 "alg": "HS256",
586 "kid": "abc123",
587 "k": key
588 }
589 ]
590 });
591
592 let set: JwkSet = serde_json::from_value(jwks_json).expect("Failed HS256 check");
593 assert_eq!(set.keys.len(), 1);
594 let key = &set.keys[0];
595 assert_eq!(key.common.key_id, Some("abc123".to_string()));
596 let algorithm = key.common.key_algorithm.unwrap().to_algorithm().unwrap();
597 assert_eq!(algorithm, Algorithm::HS256);
598
599 match &key.algorithm {
600 AlgorithmParameters::OctetKey(key) => {
601 assert_eq!(key.key_type, OctetKeyType::Octet);
602 assert_eq!(key.value, key.value)
603 }
604 _ => panic!("Unexpected key algorithm"),
605 }
606 }
607
608 #[test]
609 fn deserialize_unknown_key_algorithm() {
610 let key_alg_json = json!("");
611 let key_alg_result: KeyAlgorithm =
612 serde_json::from_value(key_alg_json).expect("Could not deserialize json");
613 assert_eq!(key_alg_result, KeyAlgorithm::UNKNOWN_ALGORITHM);
614 }
615
616 #[test]
617 #[wasm_bindgen_test]
618 fn check_thumbprint() {
619 let tp = Jwk {
620 common: crate::jwk::CommonParameters { key_id: Some("2011-04-29".to_string()), ..Default::default() },
621 algorithm: AlgorithmParameters::RSA(RSAKeyParameters {
622 key_type: crate::jwk::RSAKeyType::RSA,
623 n: "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw".to_string(),
624 e: "AQAB".to_string(),
625 }),
626 }
627 .thumbprint(ThumbprintHash::SHA256);
628 assert_eq!(tp.as_str(), "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs");
629 }
630}