use std::collections::BTreeMap;
use std::{fmt, str::FromStr};
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
use crate::crypto::{CryptoProvider, ec_pub_components_from_public_key};
use crate::errors::{self, Error, ErrorKind, new_error};
use crate::serialization::b64_encode;
use crate::{Algorithm, AlgorithmFamily, DecodingKey, EncodingKey, decoding::DecodingKeyKind};
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum PublicKeyUse {
Signature,
Encryption,
Other(String),
}
impl Serialize for PublicKeyUse {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = match self {
PublicKeyUse::Signature => "sig",
PublicKeyUse::Encryption => "enc",
PublicKeyUse::Other(other) => other,
};
serializer.serialize_str(string)
}
}
impl<'de> Deserialize<'de> for PublicKeyUse {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct PublicKeyUseVisitor;
impl de::Visitor<'_> for PublicKeyUseVisitor {
type Value = PublicKeyUse;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a string")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(match v {
"sig" => PublicKeyUse::Signature,
"enc" => PublicKeyUse::Encryption,
other => PublicKeyUse::Other(other.to_string()),
})
}
}
deserializer.deserialize_string(PublicKeyUseVisitor)
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum KeyOperations {
Sign,
Verify,
Encrypt,
Decrypt,
WrapKey,
UnwrapKey,
DeriveKey,
DeriveBits,
Other(String),
}
impl Serialize for KeyOperations {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let string = match self {
KeyOperations::Sign => "sign",
KeyOperations::Verify => "verify",
KeyOperations::Encrypt => "encrypt",
KeyOperations::Decrypt => "decrypt",
KeyOperations::WrapKey => "wrapKey",
KeyOperations::UnwrapKey => "unwrapKey",
KeyOperations::DeriveKey => "deriveKey",
KeyOperations::DeriveBits => "deriveBits",
KeyOperations::Other(other) => other,
};
serializer.serialize_str(string)
}
}
impl<'de> Deserialize<'de> for KeyOperations {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct KeyOperationsVisitor;
impl de::Visitor<'_> for KeyOperationsVisitor {
type Value = KeyOperations;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a string")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(match v {
"sign" => KeyOperations::Sign,
"verify" => KeyOperations::Verify,
"encrypt" => KeyOperations::Encrypt,
"decrypt" => KeyOperations::Decrypt,
"wrapKey" => KeyOperations::WrapKey,
"unwrapKey" => KeyOperations::UnwrapKey,
"deriveKey" => KeyOperations::DeriveKey,
"deriveBits" => KeyOperations::DeriveBits,
other => KeyOperations::Other(other.to_string()),
})
}
}
deserializer.deserialize_string(KeyOperationsVisitor)
}
}
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum KeyAlgorithm {
HS256,
HS384,
HS512,
ES256,
ES384,
RS256,
RS384,
RS512,
PS256,
PS384,
PS512,
EdDSA,
RSA1_5,
#[serde(rename = "RSA-OAEP")]
RSA_OAEP,
#[serde(rename = "RSA-OAEP-256")]
RSA_OAEP_256,
#[serde(other)]
UNKNOWN_ALGORITHM,
}
impl FromStr for KeyAlgorithm {
type Err = Error;
fn from_str(s: &str) -> errors::Result<Self> {
match s {
"HS256" => Ok(KeyAlgorithm::HS256),
"HS384" => Ok(KeyAlgorithm::HS384),
"HS512" => Ok(KeyAlgorithm::HS512),
"ES256" => Ok(KeyAlgorithm::ES256),
"ES384" => Ok(KeyAlgorithm::ES384),
"RS256" => Ok(KeyAlgorithm::RS256),
"RS384" => Ok(KeyAlgorithm::RS384),
"PS256" => Ok(KeyAlgorithm::PS256),
"PS384" => Ok(KeyAlgorithm::PS384),
"PS512" => Ok(KeyAlgorithm::PS512),
"RS512" => Ok(KeyAlgorithm::RS512),
"EdDSA" => Ok(KeyAlgorithm::EdDSA),
"RSA1_5" => Ok(KeyAlgorithm::RSA1_5),
"RSA-OAEP" => Ok(KeyAlgorithm::RSA_OAEP),
"RSA-OAEP-256" => Ok(KeyAlgorithm::RSA_OAEP_256),
_ => Err(ErrorKind::InvalidAlgorithmName.into()),
}
}
}
impl From<Algorithm> for KeyAlgorithm {
fn from(alg: Algorithm) -> Self {
match alg {
Algorithm::HS256 => KeyAlgorithm::HS256,
Algorithm::HS384 => KeyAlgorithm::HS384,
Algorithm::HS512 => KeyAlgorithm::HS512,
Algorithm::ES256 => KeyAlgorithm::ES256,
Algorithm::ES384 => KeyAlgorithm::ES384,
Algorithm::RS256 => KeyAlgorithm::RS256,
Algorithm::RS384 => KeyAlgorithm::RS384,
Algorithm::RS512 => KeyAlgorithm::RS512,
Algorithm::PS256 => KeyAlgorithm::PS256,
Algorithm::PS384 => KeyAlgorithm::PS384,
Algorithm::PS512 => KeyAlgorithm::PS512,
Algorithm::EdDSA => KeyAlgorithm::EdDSA,
}
}
}
impl TryFrom<KeyAlgorithm> for Algorithm {
type Error = Error;
fn try_from(alg: KeyAlgorithm) -> Result<Self, Self::Error> {
match alg {
KeyAlgorithm::HS256 => Ok(Algorithm::HS256),
KeyAlgorithm::HS384 => Ok(Algorithm::HS384),
KeyAlgorithm::HS512 => Ok(Algorithm::HS512),
KeyAlgorithm::ES256 => Ok(Algorithm::ES256),
KeyAlgorithm::ES384 => Ok(Algorithm::ES384),
KeyAlgorithm::RS256 => Ok(Algorithm::RS256),
KeyAlgorithm::RS384 => Ok(Algorithm::RS384),
KeyAlgorithm::RS512 => Ok(Algorithm::RS512),
KeyAlgorithm::PS256 => Ok(Algorithm::PS256),
KeyAlgorithm::PS384 => Ok(Algorithm::PS384),
KeyAlgorithm::PS512 => Ok(Algorithm::PS512),
KeyAlgorithm::EdDSA => Ok(Algorithm::EdDSA),
_ => Err(new_error(ErrorKind::UnsupportedAlgorithm)),
}
}
}
impl fmt::Display for KeyAlgorithm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl KeyAlgorithm {
fn to_algorithm(self) -> errors::Result<Algorithm> {
Algorithm::from_str(self.to_string().as_str())
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct CommonParameters {
#[serde(rename = "use", skip_serializing_if = "Option::is_none", default)]
pub public_key_use: Option<PublicKeyUse>,
#[serde(rename = "key_ops", skip_serializing_if = "Option::is_none", default)]
pub key_operations: Option<Vec<KeyOperations>>,
#[serde(rename = "alg", skip_serializing_if = "Option::is_none", default)]
pub key_algorithm: Option<KeyAlgorithm>,
#[serde(rename = "kid", skip_serializing_if = "Option::is_none", default)]
pub key_id: Option<String>,
#[serde(rename = "x5u", skip_serializing_if = "Option::is_none")]
pub x509_url: Option<String>,
#[serde(rename = "x5c", skip_serializing_if = "Option::is_none")]
pub x509_chain: Option<Vec<String>>,
#[serde(rename = "x5t", skip_serializing_if = "Option::is_none")]
pub x509_sha1_fingerprint: Option<String>,
#[serde(rename = "x5t#S256", skip_serializing_if = "Option::is_none")]
pub x509_sha256_fingerprint: Option<String>,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub enum EllipticCurveKeyType {
#[default]
EC,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[non_exhaustive]
pub enum EllipticCurve {
#[serde(rename = "P-256")]
#[default]
P256,
#[serde(rename = "P-384")]
P384,
#[serde(rename = "P-521")]
P521,
#[serde(rename = "Ed25519")]
Ed25519,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct EllipticCurveKeyParameters {
#[serde(rename = "kty")]
pub key_type: EllipticCurveKeyType,
#[serde(rename = "crv")]
pub curve: EllipticCurve,
pub x: String,
pub y: String,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub enum RSAKeyType {
#[default]
RSA,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct RSAKeyParameters {
#[serde(rename = "kty")]
pub key_type: RSAKeyType,
pub n: String,
pub e: String,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub enum OctetKeyType {
#[serde(rename = "oct")]
#[default]
Octet,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct OctetKeyParameters {
#[serde(rename = "kty")]
pub key_type: OctetKeyType,
#[serde(rename = "k")]
pub value: String,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub enum OctetKeyPairType {
#[serde(rename = "OKP")]
#[default]
OctetKeyPair,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct OctetKeyPairParameters {
#[serde(rename = "kty")]
pub key_type: OctetKeyPairType,
#[serde(rename = "crv")]
pub curve: EllipticCurve,
pub x: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default, Hash)]
pub struct OtherKeyParameters {
#[serde(flatten)]
#[allow(missing_docs)]
pub fields: BTreeMap<String, serde_json::Value>,
}
#[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),
}
#[derive(Debug, Clone, Eq, PartialEq)]
#[allow(missing_docs)]
#[non_exhaustive]
pub enum ThumbprintHash {
SHA256,
SHA384,
SHA512,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[allow(missing_docs)]
pub struct Jwk {
#[serde(flatten)]
pub common: CommonParameters,
#[serde(flatten)]
pub algorithm: AlgorithmParameters,
}
impl Jwk {
pub fn is_supported(&self) -> bool {
match self.common.key_algorithm {
Some(alg) => alg.to_algorithm().is_ok(),
_ => false,
}
}
pub fn from_encoding_key(key: &EncodingKey, alg: Algorithm) -> errors::Result<Self> {
Ok(Self {
common: CommonParameters { key_algorithm: Some(alg.into()), ..Default::default() },
algorithm: match key.family() {
AlgorithmFamily::Hmac => AlgorithmParameters::OctetKey(OctetKeyParameters {
key_type: OctetKeyType::Octet,
value: b64_encode(key.as_bytes()),
}),
AlgorithmFamily::Rsa => {
let (n, e) = (CryptoProvider::get_default()
.key_utils
.rsa_pub_components_from_private_key)(
key.as_bytes()
)?;
AlgorithmParameters::RSA(RSAKeyParameters {
key_type: RSAKeyType::RSA,
n: b64_encode(n),
e: b64_encode(e),
})
}
AlgorithmFamily::Ec => {
let (curve, x, y) = (CryptoProvider::get_default()
.key_utils
.ec_pub_components_from_private_key)(
key.as_bytes(), alg
)?;
AlgorithmParameters::EllipticCurve(EllipticCurveKeyParameters {
key_type: EllipticCurveKeyType::EC,
curve,
x: b64_encode(x),
y: b64_encode(y),
})
}
AlgorithmFamily::Ed => {
let curve_type: EllipticCurve = match key.as_bytes().len() {
48 => Ok(EllipticCurve::Ed25519),
_ => Err(Error::from(ErrorKind::InvalidEddsaKey)),
}?;
let public_key_bytes = (CryptoProvider::get_default()
.key_utils
.ed_pub_components_from_private_key)(
key.as_bytes(), &curve_type
)?;
AlgorithmParameters::OctetKeyPair(OctetKeyPairParameters {
key_type: OctetKeyPairType::OctetKeyPair,
curve: curve_type,
x: b64_encode(public_key_bytes),
})
}
},
})
}
pub fn from_decoding_key(
key: &DecodingKey,
alg: Option<Algorithm>,
) -> crate::errors::Result<Self> {
Ok(Self {
common: CommonParameters { key_algorithm: alg.map(|a| a.into()), ..Default::default() },
algorithm: match key.family() {
crate::algorithms::AlgorithmFamily::Hmac => {
AlgorithmParameters::OctetKey(OctetKeyParameters {
key_type: OctetKeyType::Octet,
value: b64_encode(key.try_get_as_bytes()?),
})
}
crate::algorithms::AlgorithmFamily::Rsa => {
let (n, e) = match &key.kind() {
DecodingKeyKind::RsaModulusExponent { n, e } => {
(b64_encode(n), b64_encode(e))
}
DecodingKeyKind::SecretOrDer(der) => {
let (n, e) = (CryptoProvider::get_default()
.key_utils
.rsa_pub_components_from_public_key)(
der
)?;
(b64_encode(n), b64_encode(e))
}
};
AlgorithmParameters::RSA(RSAKeyParameters { key_type: RSAKeyType::RSA, n, e })
}
crate::algorithms::AlgorithmFamily::Ec => {
let (curve, x, y) = ec_pub_components_from_public_key(key.try_get_as_bytes()?)?;
AlgorithmParameters::EllipticCurve(EllipticCurveKeyParameters {
key_type: EllipticCurveKeyType::EC,
curve,
x: b64_encode(x),
y: b64_encode(y),
})
}
crate::algorithms::AlgorithmFamily::Ed => {
let pub_bytes = key.try_get_as_bytes()?;
let (curve_type, x) = match pub_bytes.len() {
32 => (EllipticCurve::Ed25519, pub_bytes),
_ => return Err(ErrorKind::InvalidEddsaKey.into()),
};
AlgorithmParameters::OctetKeyPair(OctetKeyPairParameters {
key_type: OctetKeyPairType::OctetKeyPair,
curve: curve_type,
x: b64_encode(x),
})
}
},
})
}
pub fn thumbprint(&self, hash_function: ThumbprintHash) -> errors::Result<String> {
let pre = match &self.algorithm {
AlgorithmParameters::EllipticCurve(a) => match a.curve {
EllipticCurve::P256 | EllipticCurve::P384 | EllipticCurve::P521 => {
format!(
r#"{{"crv":{},"kty":{},"x":"{}","y":"{}"}}"#,
serde_json::to_string(&a.curve).unwrap(),
serde_json::to_string(&a.key_type).unwrap(),
a.x,
a.y,
)
}
EllipticCurve::Ed25519 => {
return Err(ErrorKind::InvalidKeyFormat.into());
}
},
AlgorithmParameters::RSA(a) => {
format!(
r#"{{"e":"{}","kty":{},"n":"{}"}}"#,
a.e,
serde_json::to_string(&a.key_type).unwrap(),
a.n,
)
}
AlgorithmParameters::OctetKey(a) => {
format!(
r#"{{"k":"{}","kty":{}}}"#,
a.value,
serde_json::to_string(&a.key_type).unwrap()
)
}
AlgorithmParameters::OctetKeyPair(a) => match a.curve {
EllipticCurve::P256 | EllipticCurve::P384 | EllipticCurve::P521 => {
return Err(ErrorKind::InvalidKeyFormat.into());
}
EllipticCurve::Ed25519 => {
format!(
r#"{{"crv":{},"kty":{},"x":"{}"}}"#,
serde_json::to_string(&a.curve).unwrap(),
serde_json::to_string(&a.key_type).unwrap(),
a.x,
)
}
},
AlgorithmParameters::Other(_) => return Err(ErrorKind::UnsupportedAlgorithm.into()),
};
Ok(b64_encode((CryptoProvider::get_default().key_utils.compute_digest)(
pre.as_bytes(),
hash_function,
)?))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default, Hash)]
#[allow(missing_docs)]
pub struct JwkSet {
pub keys: Vec<Jwk>,
}
impl JwkSet {
pub fn find(&self, kid: &str) -> Option<&Jwk> {
self.keys
.iter()
.find(|jwk| jwk.common.key_id.is_some() && jwk.common.key_id.as_ref().unwrap() == kid)
}
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use serde_json::json;
use wasm_bindgen_test::wasm_bindgen_test;
use crate::Algorithm;
use crate::errors::ErrorKind;
use crate::jwk::{
AlgorithmParameters, CommonParameters, EllipticCurve, Jwk, JwkSet, KeyAlgorithm,
OctetKeyPairParameters, OctetKeyPairType, OctetKeyType, RSAKeyParameters, ThumbprintHash,
};
use crate::serialization::b64_encode;
use crate::{DecodingKey, EncodingKey};
#[test]
#[wasm_bindgen_test]
fn check_hs256() {
let key = b64_encode("abcdefghijklmnopqrstuvwxyz012345");
let jwks_json = json!({
"keys": [
{
"kty": "oct",
"alg": "HS256",
"kid": "abc123",
"k": key
}
]
});
let set: JwkSet = serde_json::from_value(jwks_json).expect("Failed HS256 check");
assert_eq!(set.keys.len(), 1);
let key = &set.keys[0];
assert_eq!(key.common.key_id, Some("abc123".to_string()));
let algorithm = key.common.key_algorithm.unwrap().to_algorithm().unwrap();
assert_eq!(algorithm, Algorithm::HS256);
match &key.algorithm {
AlgorithmParameters::OctetKey(key) => {
assert_eq!(key.key_type, OctetKeyType::Octet);
assert_eq!(key.value, key.value)
}
_ => panic!("Unexpected key algorithm"),
}
}
#[test]
fn deserialize_unknown_key_algorithm() {
let key_alg_json = json!("");
let key_alg_result: KeyAlgorithm =
serde_json::from_value(key_alg_json).expect("Could not deserialize json");
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");
}
}
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() {
let tp = Jwk {
common: crate::jwk::CommonParameters { key_id: Some("2011-04-29".to_string()), ..Default::default() },
algorithm: AlgorithmParameters::RSA(RSAKeyParameters {
key_type: crate::jwk::RSAKeyType::RSA,
n: "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw".to_string(),
e: "AQAB".to_string(),
}),
}
.thumbprint(ThumbprintHash::SHA256)
.unwrap();
assert_eq!(tp.as_str(), "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs");
}
#[test]
fn check_thumbprint_bad_key() {
let jwk = Jwk {
common: CommonParameters {
key_algorithm: Some(KeyAlgorithm::ES256),
..Default::default()
},
algorithm: AlgorithmParameters::OctetKeyPair(OctetKeyPairParameters {
key_type: OctetKeyPairType::OctetKeyPair,
curve: EllipticCurve::P256,
x: "".to_string(),
}),
};
assert_eq!(
jwk.thumbprint(ThumbprintHash::SHA256).unwrap_err().into_kind(),
ErrorKind::InvalidKeyFormat
);
}
#[test]
#[wasm_bindgen_test]
fn check_alg_key_alg_conversion() {
let pairs = [
(Algorithm::HS256, KeyAlgorithm::HS256),
(Algorithm::HS384, KeyAlgorithm::HS384),
(Algorithm::HS512, KeyAlgorithm::HS512),
(Algorithm::ES256, KeyAlgorithm::ES256),
(Algorithm::ES384, KeyAlgorithm::ES384),
(Algorithm::RS256, KeyAlgorithm::RS256),
(Algorithm::RS384, KeyAlgorithm::RS384),
(Algorithm::RS512, KeyAlgorithm::RS512),
(Algorithm::PS256, KeyAlgorithm::PS256),
(Algorithm::PS384, KeyAlgorithm::PS384),
(Algorithm::PS512, KeyAlgorithm::PS512),
(Algorithm::EdDSA, KeyAlgorithm::EdDSA),
];
for (alg, k_alg) in pairs {
assert_eq!(KeyAlgorithm::from(alg), k_alg);
assert_eq!(Algorithm::try_from(k_alg), Ok(alg));
}
assert!(
Algorithm::try_from(KeyAlgorithm::RSA1_5)
.is_err_and(|e| *e.kind() == ErrorKind::UnsupportedAlgorithm)
);
assert!(
Algorithm::try_from(KeyAlgorithm::RSA_OAEP)
.is_err_and(|e| *e.kind() == ErrorKind::UnsupportedAlgorithm)
);
assert!(
Algorithm::try_from(KeyAlgorithm::RSA_OAEP_256)
.is_err_and(|e| *e.kind() == ErrorKind::UnsupportedAlgorithm)
);
}
#[test]
#[cfg(feature = "use_pem")]
fn check_jwk_from_decoding_key_rsa() {
let enc_key =
EncodingKey::from_rsa_pem(include_bytes!("../tests/rsa/private_rsa_key_pkcs8.pem"))
.unwrap();
let dec_key =
DecodingKey::from_rsa_pem(include_bytes!("../tests/rsa/public_rsa_key_pkcs8.pem"))
.unwrap();
let expected_jwk = Jwk::from_encoding_key(&enc_key, Algorithm::RS256).unwrap();
let jwk = Jwk::from_decoding_key(&dec_key, Some(Algorithm::RS256)).unwrap();
assert_eq!(jwk, expected_jwk);
}
#[test]
#[cfg(feature = "use_pem")]
fn check_jwk_from_decoding_key_ec() {
let enc_key =
EncodingKey::from_ec_pem(include_bytes!("../tests/ecdsa/private_ecdsa_key.pem"))
.unwrap();
let dec_key =
DecodingKey::from_ec_pem(include_bytes!("../tests/ecdsa/public_ecdsa_key.pem"))
.unwrap();
let expected_jwk = Jwk::from_encoding_key(&enc_key, Algorithm::ES256).unwrap();
let jwk = Jwk::from_decoding_key(&dec_key, Some(Algorithm::ES256)).unwrap();
assert_eq!(jwk, expected_jwk);
}
#[test]
#[cfg(feature = "use_pem")]
fn check_jwk_from_decoding_key_ed() {
let enc_key =
EncodingKey::from_ed_pem(include_bytes!("../tests/eddsa/private_ed25519_key.pem"))
.unwrap();
let dec_key =
DecodingKey::from_ed_pem(include_bytes!("../tests/eddsa/public_ed25519_key.pem"))
.unwrap();
let expected_jwk = Jwk::from_encoding_key(&enc_key, Algorithm::EdDSA).unwrap();
let jwk = Jwk::from_decoding_key(&dec_key, Some(Algorithm::EdDSA)).unwrap();
assert_eq!(jwk, expected_jwk);
}
#[test]
fn check_jwkset_default() {
#[derive(Default)]
struct Derived(JwkSet);
assert!(Derived::default().0.keys.is_empty());
}
}