navajo/jose/
algorithm.rs

1use core::str::FromStr;
2
3use alloc::string::String;
4use serde::{Deserialize, Serialize};
5use strum::{Display, EnumIter, IntoStaticStr};
6
7use crate::{error::InvalidAlgorithmError, strings::to_upper_remove_seperators};
8
9use super::{Curve, KeyType};
10
11#[derive(
12    Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, IntoStaticStr, Display, EnumIter,
13)]
14#[serde(try_from = "String", into = "&str")]
15pub enum Algorithm {
16    /// HMAC using SHA-256
17    #[strum(serialize = "HS256")]
18    Hs256,
19
20    /// HMAC using SHA-384
21    #[strum(serialize = "HS384")]
22    Hs384,
23
24    /// HMAC using SHA-512
25    #[strum(serialize = "HS512")]
26    Hs512,
27
28    /// ECDSA using P-256 curve and SHA-256
29    #[strum(serialize = "ES256")]
30    Es256,
31
32    ///  ECDSA using secp256k1 curve and SHA-256
33    #[strum(serialize = "ES256K")]
34    Es256K,
35
36    ///  ECDSA using P-384 curve and SHA-384
37    #[strum(serialize = "ES384")]
38    Es384,
39
40    /// ECDSA using P-521 curve and SHA-512
41    #[strum(serialize = "ES512")]
42    Es512,
43
44    /// RSASSA-PKCS#1 v1.5 + SHA-256
45    #[strum(serialize = "RS256")]
46    Rs256,
47
48    /// RSASSA-PKCS#1 v1.5 + SHA-384
49    #[strum(serialize = "RS384")]
50    Rs384,
51
52    /// RSASSA-PKCS#1 v1.5 + SHA-512
53    #[strum(serialize = "RS512")]
54    Rs512,
55
56    /// RSASSA-PSS + SHA-256
57    #[strum(serialize = "PS256")]
58    Ps256,
59
60    /// RSASSA-PSS + SHA-384
61    #[strum(serialize = "PS384")]
62    Ps384,
63
64    /// RSA-SSA-PSS + SHA-512
65    #[strum(serialize = "PS512")]
66    Ps512,
67
68    /// Edwards-curve Digital Signature Algorithm (EdDSA) using Ed25519 or Ed448
69    /// curves
70    #[strum(serialize = "EdDSA")]
71    EdDsa,
72
73    /// RSAES using Optimal Asymmetric Encryption Padding (OAEP)
74    #[strum(serialize = "RSA-OAEP")]
75    RsaOaep,
76
77    /// RSAES using OAEP with SHA-256 hash algorithm
78    #[strum(serialize = "RSA-OAEP-256")]
79    RsaOaep256,
80
81    /// AES Key Wrap with a 128-bit key
82    #[strum(serialize = "A128KW")]
83    A128Kw,
84
85    /// AES Key Wrap with a 192-bit key
86    #[strum(serialize = "A192KW")]
87    A192Kw,
88
89    /// AES Key Wrap with a 256-bit key
90    #[strum(serialize = "A256KW")]
91    A256Kw,
92
93    /// AES GCM using a 128-bit key
94    #[strum(serialize = "A128GCM")]
95    A128Gcm,
96
97    /// AES GCM using a 192-bit key
98    #[strum(serialize = "A192GCM")]
99    A192Gcm,
100
101    /// AES GCM using a 256-bit key
102    #[strum(serialize = "A256GCM")]
103    A256Gcm,
104
105    /// AES CBC using a 128-bit key and HMAC-SHA-256 for authentication
106    #[strum(serialize = "A128CBC-HS256")]
107    A128CbcHs256,
108
109    /// AES CBC using a 192-bit key and HMAC-SHA-384 for authentication
110    #[strum(serialize = "A192CBC-HS384")]
111    A192CbcHs384,
112
113    /// AES CBC using a 256-bit key and HMAC-SHA-512 for authentication
114    #[strum(serialize = "A256CBC-HS512")]
115    A256CbcHs512,
116
117    /// ChaCha20-Poly1305
118    #[strum(serialize = "C20PKW")]
119    C20Pkw,
120
121    /// XChaCha20-Poly1305
122    #[strum(serialize = "XC20PKW")]
123    Xc20Pkw,
124}
125
126impl TryFrom<(KeyType, Curve)> for Algorithm {
127    type Error = String;
128
129    fn try_from((key_type, curve): (KeyType, Curve)) -> Result<Self, Self::Error> {
130        match key_type {
131            KeyType::Rsa => {
132                Err("RSA algorithms can not be determined by the key type and curve".into())
133            }
134            KeyType::Oct => Err(
135                "octet sequence algorithms can not be determined by the key type and curve".into(),
136            ),
137            KeyType::Ec => match curve {
138                Curve::P256 => Ok(Algorithm::Es256),
139                Curve::P384 => Ok(Algorithm::Es384),
140                _ => Err("unsupported curve".into()),
141            },
142            KeyType::Okp => match curve {
143                Curve::Ed25519 => Ok(Algorithm::EdDsa),
144                _ => Err("unsupported curve".into()),
145            },
146        }
147    }
148}
149#[cfg(feature = "dsa")]
150impl From<crate::dsa::Algorithm> for Algorithm {
151    fn from(alg: crate::dsa::Algorithm) -> Self {
152        
153        match alg {
154           crate::dsa::Algorithm::Ed25519 => Algorithm::EdDsa,
155           crate::dsa::Algorithm::Es256 => Algorithm::Es256,
156           crate::dsa::Algorithm::Es384 => Algorithm::Es384,
157        }
158    }
159}
160
161impl FromStr for Algorithm {
162    type Err = InvalidAlgorithmError;
163    fn from_str(s: &str) -> Result<Self, Self::Err> {
164        match to_upper_remove_seperators(s).as_str() {
165            "HS256" => Ok(Algorithm::Hs256),
166            "HS384" => Ok(Algorithm::Hs384),
167            "HS512" => Ok(Algorithm::Hs512),
168            "ES256" => Ok(Algorithm::Es256),
169            "ES256K" => Ok(Algorithm::Es256K),
170            "ES384" => Ok(Algorithm::Es384),
171            "ES512" => Ok(Algorithm::Es512),
172            "RS256" => Ok(Algorithm::Rs256),
173            "RS384" => Ok(Algorithm::Rs384),
174            "RS512" => Ok(Algorithm::Rs512),
175            "PS256" => Ok(Algorithm::Ps256),
176            "PS384" => Ok(Algorithm::Ps384),
177            "PS512" => Ok(Algorithm::Ps512),
178            "EDDSA" => Ok(Algorithm::EdDsa),
179            "RSAOAEP" => Ok(Algorithm::RsaOaep),
180            "RSAOAEP256" => Ok(Algorithm::RsaOaep256),
181            "A128KW" => Ok(Algorithm::A128Kw),
182            "A192KW" => Ok(Algorithm::A192Kw),
183            "A256KW" => Ok(Algorithm::A256Kw),
184            "A128GCM" => Ok(Algorithm::A128Gcm),
185            "A192GCM" => Ok(Algorithm::A192Gcm),
186            "A256GCM" => Ok(Algorithm::A256Gcm),
187            "A128CBCHS256" => Ok(Algorithm::A128CbcHs256),
188            "A192CBCHS384" => Ok(Algorithm::A192CbcHs384),
189            "A256CBCHS512" => Ok(Algorithm::A256CbcHs512),
190            "C20PKW" => Ok(Algorithm::C20Pkw),
191            "XC20PKW" => Ok(Algorithm::Xc20Pkw),
192
193            _ => Err(s.into()),
194        }
195    }
196}
197impl TryFrom<String> for Algorithm {
198    type Error = InvalidAlgorithmError;
199
200    fn try_from(value: String) -> Result<Self, Self::Error> {
201        Algorithm::from_str(value.as_str())
202    }
203}