1use core::str::FromStr;
2
3use alloc::string::ToString;
4use serde::{Deserialize, Serialize};
5use strum::{Display, EnumIter, IntoStaticStr};
6
7use crate::{
8 error::InvalidAlgorithmError,
9 jose::{Algorithm as JwkAlgorithm, Curve, KeyType},
10 strings::to_upper_remove_seperators,
11};
12
13#[derive(
14 Debug,
15 Clone,
16 Copy,
17 PartialEq,
18 Eq,
19 Hash,
20 Serialize,
21 Deserialize,
22 IntoStaticStr,
23 Display,
24 EnumIter,
25)]
26#[serde(rename_all = "UPPERCASE")]
27#[strum(serialize_all = "UPPERCASE")]
28pub enum Algorithm {
29 Es256,
31 Es384,
33 #[strum(serialize = "Ed25519")]
35 #[serde(rename = "Ed25519")]
36 Ed25519,
37 }
50
51impl FromStr for Algorithm {
52 type Err = InvalidAlgorithmError;
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 match to_upper_remove_seperators(s).as_str() {
56 "ES256" => Ok(Algorithm::Es256),
57 "ES384" => Ok(Algorithm::Es384),
58 "ED25519" => Ok(Algorithm::Ed25519),
59 _ => Err(InvalidAlgorithmError(s.to_string())),
60 }
61 }
62}
63impl TryFrom<crate::jose::Algorithm> for Algorithm {
64 type Error = &'static str;
65
66 fn try_from(value: crate::jose::Algorithm) -> Result<Self, Self::Error> {
67 match value {
68 crate::jose::Algorithm::Es256 => Ok(Algorithm::Es256),
69 crate::jose::Algorithm::Es384 => Ok(Algorithm::Es384),
70 crate::jose::Algorithm::EdDsa => Ok(Algorithm::Ed25519),
71 _ => Err("unsupported algorithm"),
72 }
73 }
74}
75impl Algorithm {
76 pub fn jwt_algorithm(&self) -> JwkAlgorithm {
77 match self {
78 Algorithm::Es256 => JwkAlgorithm::Es256,
79 Algorithm::Es384 => JwkAlgorithm::Es384,
80 Algorithm::Ed25519 => JwkAlgorithm::EdDsa,
81 }
82 }
83
84 pub fn curve(&self) -> Option<Curve> {
85 match self {
86 Algorithm::Es256 => Some(Curve::P256),
87 Algorithm::Es384 => Some(Curve::P384),
88 Algorithm::Ed25519 => Some(Curve::Ed25519),
89 }
90 }
91 pub fn key_type(&self) -> KeyType {
92 match self {
93 Algorithm::Es256 => KeyType::Ec,
94 Algorithm::Es384 => KeyType::Ec,
95 Algorithm::Ed25519 => KeyType::Okp,
96 }
97 }
98
99 #[cfg(feature = "ring")]
100 pub(super) fn ring_ecdsa_signing_algorithm(
101 &self,
102 ) -> &'static ring::signature::EcdsaSigningAlgorithm {
103 match self {
104 Algorithm::Es256 => &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING,
105 Algorithm::Es384 => &ring::signature::ECDSA_P384_SHA384_FIXED_SIGNING,
106 _ => unreachable!("not an ecdsa algorithm: {}", self),
107 }
108 }
109 #[cfg(feature = "ring")]
110 pub(super) fn ring_ecdsa_verifying_algorithm(
111 &self,
112 ) -> &'static ring::signature::EcdsaVerificationAlgorithm {
113 match self {
114 Algorithm::Es256 => &ring::signature::ECDSA_P256_SHA256_FIXED,
115 Algorithm::Es384 => &ring::signature::ECDSA_P384_SHA384_FIXED,
116 _ => unreachable!("not an ecdsa algorithm: {}", self),
117 }
118 }
119 #[cfg(feature = "ring")]
132 pub(super) fn ring_ed_dsa_parameters(&self) -> &'static ring::signature::EdDSAParameters {
133 match self {
134 Algorithm::Ed25519 => &ring::signature::ED25519,
135 _ => unreachable!("not an eddsa algorithm: {}", self),
136 }
137 }
138}