identity_jose/jws/
algorithm.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright 2020-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use core::fmt::Display;
use core::fmt::Formatter;
use core::fmt::Result;
use std::str::FromStr;

/// Supported algorithms for the JSON Web Signatures `alg` claim.
///
/// [More Info](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms)
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize, serde::Serialize)]
#[cfg_attr(not(feature = "custom_alg"), derive(Copy))]
#[allow(non_camel_case_types)]
pub enum JwsAlgorithm {
  /// HMAC using SHA-256
  HS256,
  /// HMAC using SHA-384
  HS384,
  /// HMAC using SHA-512
  HS512,
  /// RSASSA-PKCS1-v1_5 using SHA-256
  RS256,
  /// RSASSA-PKCS1-v1_5 using SHA-384
  RS384,
  /// RSASSA-PKCS1-v1_5 using SHA-512
  RS512,
  /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
  PS256,
  /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
  PS384,
  /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
  PS512,
  /// ECDSA using P-256 and SHA-256
  ES256,
  /// ECDSA using P-384 and SHA-384
  ES384,
  /// ECDSA using P-521 and SHA-512
  ES512,
  /// ECDSA using secp256k1 curve and SHA-256
  ES256K,
  /// No digital signature or MAC performed
  #[serde(rename = "none")]
  NONE,
  /// EdDSA signature algorithms
  EdDSA,
  /// Custom algorithm
  #[cfg(feature = "custom_alg")]
  #[serde(untagged)]
  Custom(String),
}

impl JwsAlgorithm {
  /// A slice of all supported [`JwsAlgorithm`]s.
  ///
  /// Not available when feature `custom_alg` is enabled
  /// as it is not possible to enumerate all variants when
  /// supporting arbitrary `alg` values.
  #[cfg(not(feature = "custom_alg"))]
  pub const ALL: &'static [Self] = &[
    Self::HS256,
    Self::HS384,
    Self::HS512,
    Self::RS256,
    Self::RS384,
    Self::RS512,
    Self::PS256,
    Self::PS384,
    Self::PS512,
    Self::ES256,
    Self::ES384,
    Self::ES512,
    Self::ES256K,
    Self::NONE,
    Self::EdDSA,
  ];

  /// Returns the JWS algorithm as a `str` slice.
  #[cfg(not(feature = "custom_alg"))]
  pub const fn name(self) -> &'static str {
    match self {
      Self::HS256 => "HS256",
      Self::HS384 => "HS384",
      Self::HS512 => "HS512",
      Self::RS256 => "RS256",
      Self::RS384 => "RS384",
      Self::RS512 => "RS512",
      Self::PS256 => "PS256",
      Self::PS384 => "PS384",
      Self::PS512 => "PS512",
      Self::ES256 => "ES256",
      Self::ES384 => "ES384",
      Self::ES512 => "ES512",
      Self::ES256K => "ES256K",
      Self::NONE => "none",
      Self::EdDSA => "EdDSA",
    }
  }

  /// Returns the JWS algorithm as a `str` slice.
  #[cfg(feature = "custom_alg")]
  pub fn name(&self) -> String {
    match self {
      Self::HS256 => "HS256".to_string(),
      Self::HS384 => "HS384".to_string(),
      Self::HS512 => "HS512".to_string(),
      Self::RS256 => "RS256".to_string(),
      Self::RS384 => "RS384".to_string(),
      Self::RS512 => "RS512".to_string(),
      Self::PS256 => "PS256".to_string(),
      Self::PS384 => "PS384".to_string(),
      Self::PS512 => "PS512".to_string(),
      Self::ES256 => "ES256".to_string(),
      Self::ES384 => "ES384".to_string(),
      Self::ES512 => "ES512".to_string(),
      Self::ES256K => "ES256K".to_string(),
      Self::NONE => "none".to_string(),
      Self::EdDSA => "EdDSA".to_string(),
      Self::Custom(name) => name.clone(),
    }
  }
}

impl FromStr for JwsAlgorithm {
  type Err = crate::error::Error;

  fn from_str(string: &str) -> std::result::Result<Self, Self::Err> {
    match string {
      "HS256" => Ok(Self::HS256),
      "HS384" => Ok(Self::HS384),
      "HS512" => Ok(Self::HS512),
      "RS256" => Ok(Self::RS256),
      "RS384" => Ok(Self::RS384),
      "RS512" => Ok(Self::RS512),
      "PS256" => Ok(Self::PS256),
      "PS384" => Ok(Self::PS384),
      "PS512" => Ok(Self::PS512),
      "ES256" => Ok(Self::ES256),
      "ES384" => Ok(Self::ES384),
      "ES512" => Ok(Self::ES512),
      "ES256K" => Ok(Self::ES256K),
      "none" => Ok(Self::NONE),
      "EdDSA" => Ok(Self::EdDSA),
      #[cfg(feature = "custom_alg")]
      value => Ok(Self::Custom(value.to_string())),
      #[cfg(not(feature = "custom_alg"))]
      _ => Err(crate::error::Error::JwsAlgorithmParsingError),
    }
  }
}

#[cfg(not(feature = "custom_alg"))]
impl Display for JwsAlgorithm {
  fn fmt(&self, f: &mut Formatter<'_>) -> Result {
    f.write_str(self.name())
  }
}

#[cfg(feature = "custom_alg")]
impl Display for JwsAlgorithm {
  fn fmt(&self, f: &mut Formatter<'_>) -> Result {
    f.write_str(&(*self).name())
  }
}