navajo/dsa/
algorithm.rs

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    /// ECDSA using P-256 and SHA-256
30    Es256,
31    /// ECDSA using P-384 and SHA-384
32    Es384,
33    /// Edwards Digital Signature Algorithm (EdDSA) over Curve25519
34    #[strum(serialize = "Ed25519")]
35    #[serde(rename = "Ed25519")]
36    Ed25519,
37    // /// RSA SSA PKCS#1 v1.5 2048 8192 bits SHA-256
38    // Rs256,
39    // /// RSA SSA PKCS#1 v1.5 2048 8192 bits SHA-384
40    // Rs384,
41    // /// RSA SSA PKCS#1 v1.5 2048 8192 bits SHA-512
42    // Rs512,
43    // /// RSA PSS 2048-8192 bits SHA-256
44    // Ps256,
45    // /// RSA PSS 2048-8192 bits SHA-384
46    // Ps384,
47    // /// RSA PSS 2048-8192 bits SHA-512
48    // Ps512,
49}
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")]
120    // pub(super) fn ring_rsa_signing_parameters(&self) -> &'static ring::signature::RsaParameters {
121    //     match self {
122    // Algorithm::Rs256 => &ring::signature::RSA_PKCS1_2048_8192_SHA256,
123    // Algorithm::Rs384 => &ring::signature::RSA_PKCS1_2048_8192_SHA384,
124    // Algorithm::Rs512 => &ring::signature::RSA_PKCS1_2048_8192_SHA512,
125    // Algorithm::Ps256 => &ring::signature::RSA_PSS_2048_8192_SHA256,
126    // Algorithm::Ps384 => &ring::signature::RSA_PSS_2048_8192_SHA384,
127    // Algorithm::Ps512 => &ring::signature::RSA_PSS_2048_8192_SHA512,
128    //     _ => unreachable!("not an rsa algorithm: {}", self),
129    // }
130    // }
131    #[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}