use core::str::FromStr;
use alloc::string::String;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter, IntoStaticStr};
use crate::{error::InvalidAlgorithmError, strings::to_upper_remove_seperators};
use super::{Curve, KeyType};
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, IntoStaticStr, Display, EnumIter,
)]
#[serde(try_from = "String", into = "&str")]
pub enum Algorithm {
#[strum(serialize = "HS256")]
Hs256,
#[strum(serialize = "HS384")]
Hs384,
#[strum(serialize = "HS512")]
Hs512,
#[strum(serialize = "ES256")]
Es256,
#[strum(serialize = "ES256K")]
Es256K,
#[strum(serialize = "ES384")]
Es384,
#[strum(serialize = "ES512")]
Es512,
#[strum(serialize = "RS256")]
Rs256,
#[strum(serialize = "RS384")]
Rs384,
#[strum(serialize = "RS512")]
Rs512,
#[strum(serialize = "PS256")]
Ps256,
#[strum(serialize = "PS384")]
Ps384,
#[strum(serialize = "PS512")]
Ps512,
#[strum(serialize = "EdDSA")]
EdDsa,
#[strum(serialize = "RSA-OAEP")]
RsaOaep,
#[strum(serialize = "RSA-OAEP-256")]
RsaOaep256,
#[strum(serialize = "A128KW")]
A128Kw,
#[strum(serialize = "A192KW")]
A192Kw,
#[strum(serialize = "A256KW")]
A256Kw,
#[strum(serialize = "A128GCM")]
A128Gcm,
#[strum(serialize = "A192GCM")]
A192Gcm,
#[strum(serialize = "A256GCM")]
A256Gcm,
#[strum(serialize = "A128CBC-HS256")]
A128CbcHs256,
#[strum(serialize = "A192CBC-HS384")]
A192CbcHs384,
#[strum(serialize = "A256CBC-HS512")]
A256CbcHs512,
#[strum(serialize = "C20PKW")]
C20Pkw,
#[strum(serialize = "XC20PKW")]
Xc20Pkw,
}
impl TryFrom<(KeyType, Curve)> for Algorithm {
type Error = String;
fn try_from((key_type, curve): (KeyType, Curve)) -> Result<Self, Self::Error> {
match key_type {
KeyType::Rsa => {
Err("RSA algorithms can not be determined by the key type and curve".into())
}
KeyType::Oct => Err(
"octet sequence algorithms can not be determined by the key type and curve".into(),
),
KeyType::Ec => match curve {
Curve::P256 => Ok(Algorithm::Es256),
Curve::P384 => Ok(Algorithm::Es384),
_ => Err("unsupported curve".into()),
},
KeyType::Okp => match curve {
Curve::Ed25519 => Ok(Algorithm::EdDsa),
_ => Err("unsupported curve".into()),
},
}
}
}
#[cfg(feature = "dsa")]
impl From<crate::dsa::Algorithm> for Algorithm {
fn from(alg: crate::dsa::Algorithm) -> Self {
match alg {
crate::dsa::Algorithm::Ed25519 => Algorithm::EdDsa,
crate::dsa::Algorithm::Es256 => Algorithm::Es256,
crate::dsa::Algorithm::Es384 => Algorithm::Es384,
}
}
}
impl FromStr for Algorithm {
type Err = InvalidAlgorithmError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match to_upper_remove_seperators(s).as_str() {
"HS256" => Ok(Algorithm::Hs256),
"HS384" => Ok(Algorithm::Hs384),
"HS512" => Ok(Algorithm::Hs512),
"ES256" => Ok(Algorithm::Es256),
"ES256K" => Ok(Algorithm::Es256K),
"ES384" => Ok(Algorithm::Es384),
"ES512" => Ok(Algorithm::Es512),
"RS256" => Ok(Algorithm::Rs256),
"RS384" => Ok(Algorithm::Rs384),
"RS512" => Ok(Algorithm::Rs512),
"PS256" => Ok(Algorithm::Ps256),
"PS384" => Ok(Algorithm::Ps384),
"PS512" => Ok(Algorithm::Ps512),
"EDDSA" => Ok(Algorithm::EdDsa),
"RSAOAEP" => Ok(Algorithm::RsaOaep),
"RSAOAEP256" => Ok(Algorithm::RsaOaep256),
"A128KW" => Ok(Algorithm::A128Kw),
"A192KW" => Ok(Algorithm::A192Kw),
"A256KW" => Ok(Algorithm::A256Kw),
"A128GCM" => Ok(Algorithm::A128Gcm),
"A192GCM" => Ok(Algorithm::A192Gcm),
"A256GCM" => Ok(Algorithm::A256Gcm),
"A128CBCHS256" => Ok(Algorithm::A128CbcHs256),
"A192CBCHS384" => Ok(Algorithm::A192CbcHs384),
"A256CBCHS512" => Ok(Algorithm::A256CbcHs512),
"C20PKW" => Ok(Algorithm::C20Pkw),
"XC20PKW" => Ok(Algorithm::Xc20Pkw),
_ => Err(s.into()),
}
}
}
impl TryFrom<String> for Algorithm {
type Error = InvalidAlgorithmError;
fn try_from(value: String) -> Result<Self, Self::Error> {
Algorithm::from_str(value.as_str())
}
}