1#[cfg(feature = "simple_asn1")]
50pub mod der;
51
52#[cfg(feature = "jsonwebtoken")]
54pub mod jwt;
55
56use num_bigint::BigUint;
57use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
58use std::str::FromStr;
59use thiserror::Error;
60
61#[derive(Error, Debug)]
62pub enum Error {
63 #[error("Public Key Parse Error: {0}")]
64 PubKeyParse(&'static str),
65 #[cfg(feature = "simple_asn1")]
66 #[error(transparent)]
67 ANS1DecodeError(#[from] simple_asn1::ASN1DecodeErr),
68 #[cfg(feature = "simple_asn1")]
69 #[error(transparent)]
70 ANS1EncodeError(#[from] simple_asn1::ASN1EncodeErr),
71 #[error(transparent)]
72 #[cfg(feature = "pem")]
73 PEMParseError(#[from] pem::PemError),
74 #[error(transparent)]
75 Base64UrlError(#[from] base64::DecodeError),
76 #[error(transparent)]
77 JSONParseError(#[from] serde_json::Error),
78}
79
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82pub struct JsonWebKeySet {
83 pub keys: Vec<JsonWebKey>,
84}
85
86impl JsonWebKeySet {
87 pub fn from_bytes(data: &[u8]) -> Result<JsonWebKeySet, Error> {
88 Ok(serde_json::from_slice(data)?)
89 }
90}
91
92impl FromStr for JsonWebKeySet {
93 type Err = Error;
94 fn from_str(data: &str) -> Result<JsonWebKeySet, Error> {
95 Ok(serde_json::from_str(data)?)
96 }
97}
98
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
101#[serde(untagged)]
102pub enum JsonWebKey {
103 ECPrivateKey {
104 #[serde(flatten)]
105 value: ECPrivateKey,
106 },
107 ECPublicKey {
108 #[serde(flatten)]
109 value: ECPublicKey,
110 },
111 RSAPrivateKey {
112 #[serde(flatten)]
113 value: Box<RSAPrivateKey>,
114 },
115 RSAPublicKey {
116 #[serde(flatten)]
117 value: RSAPublicKey,
118 },
119 SymmetricKey {
120 #[serde(flatten)]
121 value: SymmetricKey,
122 },
123}
124impl FromStr for JsonWebKey {
125 type Err = Error;
126 fn from_str(data: &str) -> Result<JsonWebKey, Error> {
127 Ok(serde_json::from_str(data)?)
128 }
129}
130
131impl JsonWebKey {
132 pub fn from_bytes(data: &[u8]) -> Result<JsonWebKey, Error> {
133 Ok(serde_json::from_slice(data)?)
134 }
135
136 pub fn ec_private_key(&self) -> Option<&ECPrivateKey> {
137 match self {
138 JsonWebKey::ECPrivateKey { value } => Some(value),
139 _ => None,
140 }
141 }
142
143 pub fn ec_public_key(&self) -> Option<&ECPublicKey> {
144 match self {
145 JsonWebKey::ECPublicKey { value } => Some(value),
146 _ => None,
147 }
148 }
149
150 pub fn rsa_private_key(&self) -> Option<&RSAPrivateKey> {
151 match self {
152 JsonWebKey::RSAPrivateKey { value } => Some(value),
153 _ => None,
154 }
155 }
156
157 pub fn rsa_public_key(&self) -> Option<&RSAPublicKey> {
158 match self {
159 JsonWebKey::RSAPublicKey { value } => Some(value),
160 _ => None,
161 }
162 }
163
164 pub fn symmetric_key(&self) -> Option<&SymmetricKey> {
165 match self {
166 JsonWebKey::SymmetricKey { value } => Some(value),
167 _ => None,
168 }
169 }
170}
171
172#[derive(Debug, Clone, PartialEq, Copy, Serialize, Deserialize)]
173pub enum ECCurveParameter {
174 #[serde(rename = "P-256")]
175 P256,
176 #[serde(rename = "P-384")]
177 P384,
178 #[serde(rename = "P-521")]
179 P521,
180}
181
182#[derive(Debug, Clone, PartialEq)]
184pub struct Base64BigUint {
185 big_uint: BigUint,
186 base64: String,
187}
188
189impl Base64BigUint {
190 pub fn to_base64url(&self) -> String {
191 base64::encode_config(&self.big_uint.to_bytes_be(), base64::URL_SAFE_NO_PAD)
192 }
193
194 pub fn from_base64url(value: &str) -> Result<Self, Error> {
195 Ok(Base64BigUint {
196 big_uint: BigUint::from_bytes_be(&base64::decode_config(
197 value,
198 base64::URL_SAFE_NO_PAD,
199 )?),
200 base64: value.to_string(),
201 })
202 }
203}
204
205impl Into<BigUint> for Base64BigUint {
206 fn into(self) -> BigUint {
207 self.big_uint
208 }
209}
210
211impl Into<Base64BigUint> for BigUint {
212 fn into(self) -> Base64BigUint {
213 Base64BigUint {
214 base64: base64::encode_config(self.to_bytes_be(), base64::URL_SAFE_NO_PAD),
215 big_uint: self,
216 }
217 }
218}
219
220impl Serialize for Base64BigUint {
221 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
222 where
223 S: Serializer,
224 {
225 self.to_base64url().serialize(serializer)
226 }
227}
228
229impl<'de> Deserialize<'de> for Base64BigUint {
230 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
231 where
232 D: Deserializer<'de>,
233 {
234 let value = String::deserialize(deserializer)?;
235 Ok(Base64BigUint::from_base64url(&value).map_err(|e| {
236 D::Error::custom(format!("failed to decode BASE64 URL: {} : {}", value, e))
237 })?)
238 }
239}
240
241#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
243pub struct ECPublicKey {
245 #[serde(flatten)]
246 pub generic: Generic,
247 pub crv: ECCurveParameter,
248 pub x: Base64BigUint,
249 #[serde(skip_serializing_if = "Option::is_none")]
250 pub y: Option<Base64BigUint>,
251}
252
253impl FromStr for ECPublicKey {
254 type Err = Error;
255 fn from_str(data: &str) -> Result<Self, Error> {
256 Ok(serde_json::from_str(data)?)
257 }
258}
259
260#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
261pub struct ECPrivateKey {
263 #[serde(flatten)]
264 pub public_key: ECPublicKey,
265 pub d: Base64BigUint,
266}
267
268impl FromStr for ECPrivateKey {
269 type Err = Error;
270 fn from_str(data: &str) -> Result<Self, Error> {
271 Ok(serde_json::from_str(data)?)
272 }
273}
274
275#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
276pub struct RSAPublicKey {
278 #[serde(flatten)]
279 pub generic: Generic,
280 pub n: Base64BigUint,
281 pub e: Base64BigUint,
282}
283
284impl FromStr for RSAPublicKey {
285 type Err = Error;
286 fn from_str(data: &str) -> Result<Self, Error> {
287 Ok(serde_json::from_str(data)?)
288 }
289}
290
291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
292pub struct RSAPrivateKey {
294 #[serde(flatten)]
295 pub public_key: RSAPublicKey,
296 pub d: Base64BigUint,
297 #[serde(flatten)]
298 pub optimizations: Option<RSAPrivateKeyOptimizations>,
299 pub oth: Option<Vec<RSAPrivateKeyOtherPrimesInfo>>,
300}
301
302impl FromStr for RSAPrivateKey {
303 type Err = Error;
304 fn from_str(data: &str) -> Result<Self, Error> {
305 Ok(serde_json::from_str(data)?)
306 }
307}
308
309#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
310pub struct RSAPrivateKeyOptimizations {
312 pub p: Base64BigUint,
313 pub q: Base64BigUint,
314 pub dp: Base64BigUint,
315 pub dq: Base64BigUint,
316 pub qi: Base64BigUint,
317}
318
319#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
320pub struct RSAPrivateKeyOtherPrimesInfo {
322 pub r: Base64BigUint,
323 pub d: Base64BigUint,
324 pub t: Base64BigUint,
325}
326
327#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
328#[serde(deny_unknown_fields)]
329pub struct SymmetricKey {
330 #[serde(flatten)]
331 pub generic: Generic,
332 pub k: String,
333}
334
335impl FromStr for SymmetricKey {
336 type Err = Error;
337 fn from_str(data: &str) -> Result<Self, Error> {
338 Ok(serde_json::from_str(data)?)
339 }
340}
341
342#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
345pub enum KeyType {
346 #[serde(rename = "EC")]
347 EllipticCurve,
348 #[serde(rename = "RSA")]
349 Rsa,
350 #[serde(rename = "oct")]
351 OctetSequence,
352}
353
354#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
355pub enum KeyUse {
356 #[serde(rename = "sig")]
357 Signature,
358 #[serde(rename = "enc")]
359 Encryption,
360}
361
362#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
365pub struct Generic {
366 pub kty: KeyType,
368 #[serde(skip_serializing_if = "Option::is_none", rename = "use")]
369 pub use_: Option<KeyUse>,
370 #[serde(skip_serializing_if = "Option::is_none")]
371 pub key_ops: Option<Vec<String>>,
372 #[serde(skip_serializing_if = "Option::is_none")]
373 pub alg: Option<String>,
374 #[serde(skip_serializing_if = "Option::is_none")]
375 pub kid: Option<String>,
376 #[serde(skip_serializing_if = "Option::is_none")]
377 pub x5u: Option<String>,
378 #[serde(skip_serializing_if = "Option::is_none")]
379 pub x5c: Option<Vec<String>>,
380 #[serde(skip_serializing_if = "Option::is_none")]
381 pub x5t: Option<String>,
382 #[serde(skip_serializing_if = "Option::is_none", rename = "x5t#S256")]
383 pub x5t_s256: Option<String>,
384}
385
386#[cfg(test)]
387mod test {
388 use super::*;
389
390 #[test]
391 fn load_rsa_pubkey1() -> Result<(), serde_json::Error> {
392 let pubkey_json: JsonWebKey =
393 serde_json::from_str(include_str!("../testfiles/test1.json"))?;
394 let pubkey_data = pubkey_json.rsa_public_key().unwrap();
395 assert_eq!(pubkey_data.generic.kty, KeyType::Rsa);
396 assert_eq!(pubkey_data.e.big_uint, BigUint::from(65537u64));
397 Ok(())
398 }
399
400 #[test]
401 fn load_rsa_pubkey2() -> Result<(), serde_json::Error> {
402 let pubkey_json: JsonWebKey =
403 serde_json::from_str(include_str!("../testfiles/test2.json"))?;
404 let pubkey_data = pubkey_json.rsa_public_key().unwrap();
405 assert_eq!(pubkey_data.generic.kty, KeyType::Rsa);
406 assert_eq!(pubkey_data.generic.alg.as_ref().unwrap(), "RS256");
407 assert_eq!(pubkey_data.generic.use_.unwrap(), KeyUse::Signature);
408 assert_eq!(
409 pubkey_data.generic.kid.as_ref().unwrap(),
410 "ctFNPw6mrKynlD3atDovZGBlbWRXj7IK0IBODJ_hqeI"
411 );
412 assert_eq!(
413 pubkey_data.generic.x5t.as_ref().unwrap(),
414 "ZsHe1ebgPQqmqNF8rjKqWEjh4hk"
415 );
416 assert_eq!(
417 pubkey_data.generic.x5t_s256.as_ref().unwrap(),
418 "VaYCCwkyvl8K71fldYXJtNjHAPTGom2ylqdAbedtKUI"
419 );
420 assert_eq!(pubkey_data.e.big_uint, BigUint::from(65537u64));
421 Ok(())
422 }
423
424 #[test]
425 fn load_private_keys() -> Result<(), serde_json::Error> {
426 let privkey_json: JsonWebKeySet =
427 serde_json::from_str(include_str!("../testfiles/example-private-key.json"))?;
428 assert_eq!(privkey_json.keys.len(), 2);
429
430 let ec_private_key = privkey_json.keys[0].ec_private_key().unwrap();
431 assert_eq!(
432 ec_private_key.public_key.generic.kty,
433 KeyType::EllipticCurve
434 );
435 assert_eq!(ec_private_key.public_key.crv, ECCurveParameter::P256);
436 assert_eq!(
437 ec_private_key.public_key.generic.use_.unwrap(),
438 KeyUse::Encryption
439 );
440 assert_eq!(ec_private_key.public_key.generic.kid.as_ref().unwrap(), "1");
441
442 let rsa_private_key = privkey_json.keys[1].rsa_private_key().unwrap();
443 assert_eq!(rsa_private_key.public_key.generic.kty, KeyType::Rsa);
444 assert!(rsa_private_key.optimizations.is_some());
445
446 Ok(())
447 }
448
449 #[test]
450 fn load_public_keys() -> Result<(), serde_json::Error> {
451 let pubkey_json: JsonWebKeySet =
452 serde_json::from_str(include_str!("../testfiles/example-public-key.json"))?;
453
454 let ec_public_key = pubkey_json.keys[0].ec_public_key().unwrap();
455 assert_eq!(ec_public_key.generic.kty, KeyType::EllipticCurve);
456 assert_eq!(ec_public_key.crv, ECCurveParameter::P256);
457 assert_eq!(ec_public_key.generic.use_.unwrap(), KeyUse::Encryption);
458 assert_eq!(ec_public_key.generic.kid.as_ref().unwrap(), "1");
459 assert_eq!(
460 ec_public_key.x.to_base64url(),
461 "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"
462 );
463 assert_eq!(
464 ec_public_key.y.as_ref().unwrap().to_base64url(),
465 "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"
466 );
467
468 let rsa_public_key = pubkey_json.keys[1].rsa_public_key().unwrap();
469 assert_eq!(rsa_public_key.generic.kty, KeyType::Rsa);
470 assert_eq!(rsa_public_key.e.to_base64url(), "AQAB");
471 assert_eq!(rsa_public_key.n.to_base64url(), "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw");
472 assert_eq!(rsa_public_key.generic.alg.as_ref().unwrap(), "RS256");
473 Ok(())
474 }
475
476 #[test]
477 fn load_symmetric_keys() -> Result<(), serde_json::Error> {
478 let symmetric_json: JsonWebKeySet =
479 serde_json::from_str(include_str!("../testfiles/example-symmetric-keys.json"))?;
480
481 let symmetric_key = symmetric_json.keys[0].symmetric_key().unwrap();
482 assert_eq!(symmetric_key.generic.kty, KeyType::OctetSequence);
483 assert_eq!(symmetric_key.generic.alg.as_ref().unwrap(), "A128KW");
484 assert_eq!(symmetric_key.k, "GawgguFyGrWKav7AX4VKUg");
485
486 let symmetric_key = symmetric_json.keys[1].symmetric_key().unwrap();
487 assert_eq!(symmetric_key.generic.kty, KeyType::OctetSequence);
488 assert_eq!(symmetric_key.k, "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
489 assert_eq!(
490 symmetric_key.generic.kid.as_ref().unwrap(),
491 "HMAC key used in JWS spec Appendix A.1 example"
492 );
493 Ok(())
494 }
495}