identity_jose/jws/
algorithm.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use core::fmt::Display;
5use core::fmt::Formatter;
6use core::fmt::Result;
7use std::str::FromStr;
8
9/// Supported algorithms for the JSON Web Signatures `alg` claim.
10///
11/// [More Info](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms)
12#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize)]
13#[cfg_attr(not(feature = "custom_alg"), derive(Copy))]
14#[allow(non_camel_case_types)]
15pub enum JwsAlgorithm {
16  /// HMAC using SHA-256
17  HS256,
18  /// HMAC using SHA-384
19  HS384,
20  /// HMAC using SHA-512
21  HS512,
22  /// RSASSA-PKCS1-v1_5 using SHA-256
23  RS256,
24  /// RSASSA-PKCS1-v1_5 using SHA-384
25  RS384,
26  /// RSASSA-PKCS1-v1_5 using SHA-512
27  RS512,
28  /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
29  PS256,
30  /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
31  PS384,
32  /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
33  PS512,
34  /// ECDSA using P-256 and SHA-256
35  ES256,
36  /// ECDSA using P-384 and SHA-384
37  ES384,
38  /// ECDSA using P-521 and SHA-512
39  ES512,
40  /// ECDSA using secp256k1 curve and SHA-256
41  ES256K,
42  /// No digital signature or MAC performed
43  #[serde(rename = "none")]
44  NONE,
45  /// EdDSA signature algorithms
46  EdDSA,
47  /// Custom algorithm
48  #[cfg(feature = "custom_alg")]
49  #[serde(untagged)]
50  Custom(String),
51}
52
53impl JwsAlgorithm {
54  /// A slice of all supported [`JwsAlgorithm`]s.
55  ///
56  /// Not available when feature `custom_alg` is enabled
57  /// as it is not possible to enumerate all variants when
58  /// supporting arbitrary `alg` values.
59  #[cfg(not(feature = "custom_alg"))]
60  pub const ALL: &'static [Self] = &[
61    Self::HS256,
62    Self::HS384,
63    Self::HS512,
64    Self::RS256,
65    Self::RS384,
66    Self::RS512,
67    Self::PS256,
68    Self::PS384,
69    Self::PS512,
70    Self::ES256,
71    Self::ES384,
72    Self::ES512,
73    Self::ES256K,
74    Self::NONE,
75    Self::EdDSA,
76  ];
77
78  /// Returns the JWS algorithm as a `str` slice.
79  #[cfg(not(feature = "custom_alg"))]
80  pub const fn name(self) -> &'static str {
81    match self {
82      Self::HS256 => "HS256",
83      Self::HS384 => "HS384",
84      Self::HS512 => "HS512",
85      Self::RS256 => "RS256",
86      Self::RS384 => "RS384",
87      Self::RS512 => "RS512",
88      Self::PS256 => "PS256",
89      Self::PS384 => "PS384",
90      Self::PS512 => "PS512",
91      Self::ES256 => "ES256",
92      Self::ES384 => "ES384",
93      Self::ES512 => "ES512",
94      Self::ES256K => "ES256K",
95      Self::NONE => "none",
96      Self::EdDSA => "EdDSA",
97    }
98  }
99
100  /// Returns the JWS algorithm as a `str` slice.
101  #[cfg(feature = "custom_alg")]
102  pub fn name(&self) -> String {
103    match self {
104      Self::HS256 => "HS256".to_string(),
105      Self::HS384 => "HS384".to_string(),
106      Self::HS512 => "HS512".to_string(),
107      Self::RS256 => "RS256".to_string(),
108      Self::RS384 => "RS384".to_string(),
109      Self::RS512 => "RS512".to_string(),
110      Self::PS256 => "PS256".to_string(),
111      Self::PS384 => "PS384".to_string(),
112      Self::PS512 => "PS512".to_string(),
113      Self::ES256 => "ES256".to_string(),
114      Self::ES384 => "ES384".to_string(),
115      Self::ES512 => "ES512".to_string(),
116      Self::ES256K => "ES256K".to_string(),
117      Self::NONE => "none".to_string(),
118      Self::EdDSA => "EdDSA".to_string(),
119      Self::Custom(name) => name.clone(),
120    }
121  }
122}
123
124impl FromStr for JwsAlgorithm {
125  type Err = crate::error::Error;
126
127  fn from_str(string: &str) -> std::result::Result<Self, Self::Err> {
128    match string {
129      "HS256" => Ok(Self::HS256),
130      "HS384" => Ok(Self::HS384),
131      "HS512" => Ok(Self::HS512),
132      "RS256" => Ok(Self::RS256),
133      "RS384" => Ok(Self::RS384),
134      "RS512" => Ok(Self::RS512),
135      "PS256" => Ok(Self::PS256),
136      "PS384" => Ok(Self::PS384),
137      "PS512" => Ok(Self::PS512),
138      "ES256" => Ok(Self::ES256),
139      "ES384" => Ok(Self::ES384),
140      "ES512" => Ok(Self::ES512),
141      "ES256K" => Ok(Self::ES256K),
142      "none" => Ok(Self::NONE),
143      "EdDSA" => Ok(Self::EdDSA),
144      #[cfg(feature = "custom_alg")]
145      value => Ok(Self::Custom(value.to_string())),
146      #[cfg(not(feature = "custom_alg"))]
147      _ => Err(crate::error::Error::JwsAlgorithmParsingError),
148    }
149  }
150}
151
152#[cfg(not(feature = "custom_alg"))]
153impl Display for JwsAlgorithm {
154  fn fmt(&self, f: &mut Formatter<'_>) -> Result {
155    f.write_str(self.name())
156  }
157}
158
159#[cfg(feature = "custom_alg")]
160impl Display for JwsAlgorithm {
161  fn fmt(&self, f: &mut Formatter<'_>) -> Result {
162    f.write_str(&(*self).name())
163  }
164}