Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

- Add conversions between `Algorithm` and `KeyAlgorithm`
- JWKs can now be created from `DecodingKey`s, creation from `EncodingKey` and `DecodingKey` now supports Ed25519 as well
- BREAKING: `Algorithm` and `EllipticCurve` are now `non_exhaustive`
- JWKs with unknown key types are now deserializable
- BREAKING: `Algorithm`, `KeyAlgorithm`, `EllipticCurve` and `ThumbprintHash` are now `non_exhaustive`
- BREAKING: `Jwk.thumbprint` now returns a `Result<_>`
- BREAKING: `Header.extras` is now a struct that allows for deserialization to any `T`
- BREAKING: Implicit features resulting from optional crates have been removed
Expand Down
4 changes: 2 additions & 2 deletions examples/custom_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
&EncodingKey::from_secret(SECRET.as_ref()),
)?;

println!("serialized token: {}", &token);
println!("serialized token: {}", token);

let token_data = jsonwebtoken::decode::<Claims>(
&token,
&DecodingKey::from_secret(SECRET.as_ref()),
&Validation::new(Algorithm::HS256),
)?;

println!("token data:\n{:#?}", &token_data);
println!("token data:\n{:#?}", token_data);
Ok(())
}
1 change: 1 addition & 0 deletions src/decoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ impl DecodingKey {
kind: DecodingKeyKind::SecretOrDer(out),
})
}
AlgorithmParameters::Other(_) => Err(ErrorKind::UnsupportedAlgorithm.into()),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would nice to have a value in ErrorKind::UnsupportedAlgorithm but probably not a blocker

}
}

Expand Down
52 changes: 52 additions & 0 deletions src/jwk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Most of the code in this file is taken from <https://github.com/lawliet89/biscuit> but
//! tweaked to remove the private bits as it's not the goal for this crate currently.

use std::collections::BTreeMap;
use std::{fmt, str::FromStr};

use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
Expand Down Expand Up @@ -149,6 +150,7 @@ impl<'de> Deserialize<'de> for KeyOperations {
/// The algorithms of the keys
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum KeyAlgorithm {
/// HMAC using SHA-256
HS256,
Expand Down Expand Up @@ -439,20 +441,31 @@ pub struct OctetKeyPairParameters {
pub x: String,
}

/// Parameters for unknown keys
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct OtherKeyParameters {
#[serde(flatten)]
#[allow(missing_docs)]
pub fields: BTreeMap<String, serde_json::Value>,
}

/// Algorithm specific parameters
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(untagged)]
#[allow(missing_docs)]
#[non_exhaustive]
pub enum AlgorithmParameters {
EllipticCurve(EllipticCurveKeyParameters),
RSA(RSAKeyParameters),
OctetKey(OctetKeyParameters),
OctetKeyPair(OctetKeyPairParameters),
Other(OtherKeyParameters),
}

/// The function to use to hash the intermediate thumbprint data.
#[derive(Debug, Clone, Eq, PartialEq)]
#[allow(missing_docs)]
#[non_exhaustive]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can there be other?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I'm aware of currently, but I for one would appreciate a future capability of using SHA-3

pub enum ThumbprintHash {
SHA256,
SHA384,
Expand Down Expand Up @@ -643,6 +656,7 @@ impl Jwk {
)
}
},
AlgorithmParameters::Other(_) => return Err(ErrorKind::UnsupportedAlgorithm.into()),
};

Ok(b64_encode((CryptoProvider::get_default().key_utils.compute_digest)(
Expand Down Expand Up @@ -670,6 +684,8 @@ impl JwkSet {

#[cfg(test)]
mod tests {
use std::collections::BTreeMap;

use serde_json::json;
use wasm_bindgen_test::wasm_bindgen_test;

Expand Down Expand Up @@ -721,6 +737,42 @@ mod tests {
assert_eq!(key_alg_result, KeyAlgorithm::UNKNOWN_ALGORITHM);
}

#[test]
fn deserialize_unknown_kty() {
let parameters_json = json!({
"kty": "AKP",
"foo": "bar",
"solution": 42
});
let parameters_result: AlgorithmParameters =
serde_json::from_value(parameters_json).expect("Could not deserialize json");
match parameters_result {
AlgorithmParameters::Other(other_key_parameters) => {
let mut expected = BTreeMap::new();
expected.insert("kty".to_owned(), serde_json::to_value("AKP").unwrap());
expected.insert("foo".to_owned(), serde_json::to_value("bar").unwrap());
expected.insert("solution".to_owned(), serde_json::to_value(42).unwrap());
assert_eq!(other_key_parameters.fields, expected);
}
_ => {
panic!("Unexpected deserialization result");
}
}

// RFC 9964 Appendix A.1 JWK
let jwk: Jwk = serde_json::from_value(json!({
"kid": "T4xl70S7MT6Zeq6r9V9fPJGVn76wfnXJ21-gyo0Gu6o",
"kty": "AKP",
"alg": "ML-DSA-44",
"pub": "...",
"priv": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
}))
.expect("Could not deserialize json");

assert!(!jwk.is_supported());
assert!(matches!(jwk.algorithm, AlgorithmParameters::Other(_)));
}

#[test]
#[wasm_bindgen_test]
fn check_thumbprint() {
Expand Down
Loading