mod aes_cbc_hs;
mod aes_gcm;
mod aes_kw;
mod ecdh_es;
mod ecdsa;
mod hmac;
mod pbes2;
mod rsa;
use alloc::string::String;
use serde::{Deserialize, Serialize};
#[doc(inline)]
pub use self::{
aes_cbc_hs::AesCbcHs,
aes_gcm::AesGcm,
aes_kw::AesKw,
ecdh_es::EcDhES,
ecdsa::EcDSA,
hmac::Hmac,
pbes2::Pbes2,
rsa::{RsaSigning, RsaesOaep, RsassaPkcs1V1_5, RsassaPss},
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
#[serde(untagged)]
pub enum JsonWebAlgorithm {
Signing(JsonWebSigningAlgorithm),
Encryption(JsonWebEncryptionAlgorithm),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum JsonWebSigningAlgorithm {
Hmac(Hmac),
Rsa(RsaSigning),
EcDSA(EcDSA),
EdDSA,
None,
Other(String),
}
impl From<JsonWebSigningAlgorithm> for JsonWebAlgorithm {
fn from(x: JsonWebSigningAlgorithm) -> Self {
Self::Signing(x)
}
}
impl_serde_jwa!(
JsonWebSigningAlgorithm,
[
"HS256" => Self::Hmac(Hmac::Hs256); Self::Hmac(Hmac::Hs256),
"HS384" => Self::Hmac(Hmac::Hs384); Self::Hmac(Hmac::Hs384),
"HS512" => Self::Hmac(Hmac::Hs512); Self::Hmac(Hmac::Hs512),
"RS256" => Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs256)); Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs256)),
"RS384" => Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs384)); Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs384)),
"RS512" => Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs512)); Self::Rsa(RsaSigning::RsPkcs1V1_5(RsassaPkcs1V1_5::Rs512)),
"ES256" => Self::EcDSA(EcDSA::Es256); Self::EcDSA(EcDSA::Es256),
"ES384" => Self::EcDSA(EcDSA::Es384); Self::EcDSA(EcDSA::Es384),
"ES512" => Self::EcDSA(EcDSA::Es512); Self::EcDSA(EcDSA::Es512),
"ES256K" => Self::EcDSA(EcDSA::Es256K); Self::EcDSA(EcDSA::Es256K),
"EdDSA" => Self::EdDSA; Self::EdDSA,
"PS256" => Self::Rsa(RsaSigning::Pss(RsassaPss::Ps256)); Self::Rsa(RsaSigning::Pss(RsassaPss::Ps256)),
"PS384" => Self::Rsa(RsaSigning::Pss(RsassaPss::Ps384)); Self::Rsa(RsaSigning::Pss(RsassaPss::Ps384)),
"PS512" => Self::Rsa(RsaSigning::Pss(RsassaPss::Ps512)); Self::Rsa(RsaSigning::Pss(RsassaPss::Ps512)),
"none" => Self::None; Self::None,
contrary: <JsonWebEncryptionAlgorithm>::Other,
expected: "a JSON Web Signing Algorithm",
got: "JSON Web Encryption Algorithm",
]
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum JsonWebEncryptionAlgorithm {
Rsa1_5,
RsaesOaep(RsaesOaep),
AesKw(AesKw),
Direct,
EcDhES(EcDhES),
AesGcmKw(AesGcm),
Pbes2(Pbes2),
Other(String),
}
impl From<JsonWebEncryptionAlgorithm> for JsonWebAlgorithm {
fn from(x: JsonWebEncryptionAlgorithm) -> Self {
Self::Encryption(x)
}
}
impl_serde_jwa!(
JsonWebEncryptionAlgorithm,
[
"RSA1_5" => Self::Rsa1_5; Self::Rsa1_5,
"RSA-OAEP" => Self::RsaesOaep(RsaesOaep::RsaesOaep); Self::RsaesOaep(RsaesOaep::RsaesOaep),
"RSA-OAEP-256" => Self::RsaesOaep(RsaesOaep::RsaesOaep256); Self::RsaesOaep(RsaesOaep::RsaesOaep256),
"A128KW" => Self::AesKw(AesKw::Aes128); Self::AesKw(AesKw::Aes128),
"A192KW" => Self::AesKw(AesKw::Aes192); Self::AesKw(AesKw::Aes192),
"A256KW" => Self::AesKw(AesKw::Aes256); Self::AesKw(AesKw::Aes256),
"dir" => Self::Direct; Self::Direct,
"ECDH-ES" => Self::EcDhES(EcDhES::Direct); Self::EcDhES(EcDhES::Direct),
"ECDH-ES+A128KW" => Self::EcDhES(EcDhES::AesKw(AesKw::Aes128)); Self::EcDhES(EcDhES::AesKw(AesKw::Aes128)),
"ECDH-ES+A192KW" => Self::EcDhES(EcDhES::AesKw(AesKw::Aes192)); Self::EcDhES(EcDhES::AesKw(AesKw::Aes192)),
"ECDH-ES+A256KW" => Self::EcDhES(EcDhES::AesKw(AesKw::Aes256)); Self::EcDhES(EcDhES::AesKw(AesKw::Aes256)),
"A128GCMKW" => Self::AesGcmKw(AesGcm::Aes128); Self::AesGcmKw(AesGcm::Aes128),
"A192GCMKW" => Self::AesGcmKw(AesGcm::Aes192); Self::AesGcmKw(AesGcm::Aes192),
"A256GCMKW" => Self::AesGcmKw(AesGcm::Aes256); Self::AesGcmKw(AesGcm::Aes256),
"PBES2-HS256+A128KW" => Self::Pbes2(Pbes2::Hs256Aes128); Self::Pbes2(Pbes2::Hs256Aes128),
"PBES2-HS384+A192KW" => Self::Pbes2(Pbes2::Hs384Aes192); Self::Pbes2(Pbes2::Hs384Aes192),
"PBES2-HS512+A256KW" => Self::Pbes2(Pbes2::Hs512Aes256); Self::Pbes2(Pbes2::Hs512Aes256),
contrary: <JsonWebSigningAlgorithm>::Other,
expected: "a JSON Web Encryption Algorithm",
got: "JSON Web Signing Algorithm",
]
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum JsonWebContentEncryptionAlgorithm {
AesCbcHs(AesCbcHs),
AesGcm(AesGcm),
Other(String),
}
impl_serde_jwa!(
JsonWebContentEncryptionAlgorithm,
[
"A128CBC-HS256" => Self::AesCbcHs(AesCbcHs::Aes128CbcHs256); Self::AesCbcHs(AesCbcHs::Aes128CbcHs256),
"A192CBC-HS384" => Self::AesCbcHs(AesCbcHs::Aes192CbcHs384); Self::AesCbcHs(AesCbcHs::Aes192CbcHs384),
"A256CBC-HS512" => Self::AesCbcHs(AesCbcHs::Aes256CbcHs512); Self::AesCbcHs(AesCbcHs::Aes256CbcHs512),
"A128GCM" => Self::AesGcm(AesGcm::Aes128); Self::AesGcm(AesGcm::Aes128),
"A192GCM" => Self::AesGcm(AesGcm::Aes192); Self::AesGcm(AesGcm::Aes192),
"A256GCM" => Self::AesGcm(AesGcm::Aes256); Self::AesGcm(AesGcm::Aes256),
expected: "JSON Web Content Encryption Algorithm",
got: "an invalid variant",
]
);
#[test]
fn test_others_not_stealing() {
use alloc::string::ToString;
let jwe = "dir";
let jwa: JsonWebAlgorithm =
serde_json::from_value(serde_json::Value::String(jwe.to_string())).unwrap();
assert!(matches!(
jwa,
JsonWebAlgorithm::Encryption(JsonWebEncryptionAlgorithm::Direct)
));
}