1use ring::signature::{self, EcdsaSigningAlgorithm, EdDSAParameters};
2use std::fmt;
3use std::hash::{Hash, Hasher};
4use yasna::models::ObjectIdentifier;
5use yasna::DERWriter;
6use yasna::Tag;
7
8use crate::oid::*;
9use crate::RcgenError;
10
11pub(crate) enum SignAlgo {
12 EcDsa(&'static EcdsaSigningAlgorithm),
13 EdDsa(&'static EdDSAParameters),
14 Rsa(),
15}
16
17#[derive(PartialEq, Eq)]
18pub(crate) enum SignatureAlgorithmParams {
19 None,
21 Null,
23 RsaPss {
25 hash_algorithm: &'static [u64],
26 salt_length: u64,
27 },
28}
29
30pub struct SignatureAlgorithm {
32 oids_sign_alg: &'static [&'static [u64]],
33 pub(crate) sign_alg: SignAlgo,
34 oid_components: &'static [u64],
35 params: SignatureAlgorithmParams,
36}
37
38impl fmt::Debug for SignatureAlgorithm {
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40 use algo::*;
41 if self == &PKCS_RSA_SHA256 {
42 write!(f, "PKCS_RSA_SHA256")
43 } else if self == &PKCS_RSA_SHA384 {
44 write!(f, "PKCS_RSA_SHA384")
45 } else if self == &PKCS_RSA_SHA512 {
46 write!(f, "PKCS_RSA_SHA512")
47 } else if self == &PKCS_RSA_PSS_SHA256 {
48 write!(f, "PKCS_RSA_PSS_SHA256")
49 } else if self == &PKCS_ECDSA_P256_SHA256 {
50 write!(f, "PKCS_ECDSA_P256_SHA256")
51 } else if self == &PKCS_ECDSA_P384_SHA384 {
52 write!(f, "PKCS_ECDSA_P384_SHA384")
53 } else if self == &PKCS_ED25519 {
54 write!(f, "PKCS_ED25519")
55 } else {
56 write!(f, "Unknown")
57 }
58 }
59}
60
61impl PartialEq for SignatureAlgorithm {
62 fn eq(&self, other: &Self) -> bool {
63 (self.oids_sign_alg, self.oid_components) == (other.oids_sign_alg, other.oid_components)
64 }
65}
66
67impl Eq for SignatureAlgorithm {}
68
69impl Hash for SignatureAlgorithm {
71 fn hash<H: Hasher>(&self, state: &mut H) {
72 self.oids_sign_alg.hash(state);
74 }
75}
76
77impl SignatureAlgorithm {
78 pub(crate) fn iter() -> std::slice::Iter<'static, &'static SignatureAlgorithm> {
79 use algo::*;
80 static ALGORITHMS: &[&SignatureAlgorithm] = &[
81 &PKCS_RSA_SHA256,
82 &PKCS_RSA_SHA384,
83 &PKCS_RSA_SHA512,
84 &PKCS_ECDSA_P256_SHA256,
86 &PKCS_ECDSA_P384_SHA384,
87 &PKCS_ED25519,
88 ];
89 ALGORITHMS.iter()
90 }
91
92 pub fn from_oid(oid: &[u64]) -> Result<&'static SignatureAlgorithm, RcgenError> {
94 for algo in Self::iter() {
95 if algo.oid_components == oid {
96 return Ok(algo);
97 }
98 }
99 Err(RcgenError::UnsupportedSignatureAlgorithm)
100 }
101}
102
103pub mod algo {
105 use super::*;
106
107 pub static PKCS_RSA_SHA256: SignatureAlgorithm = SignatureAlgorithm {
109 oids_sign_alg: &[&OID_RSA_ENCRYPTION],
110 sign_alg: SignAlgo::Rsa(),
111 oid_components: &[1, 2, 840, 113549, 1, 1, 11],
113 params: SignatureAlgorithmParams::Null,
114 };
115
116 pub static PKCS_RSA_SHA384: SignatureAlgorithm = SignatureAlgorithm {
118 oids_sign_alg: &[&OID_RSA_ENCRYPTION],
119 sign_alg: SignAlgo::Rsa(),
120 oid_components: &[1, 2, 840, 113549, 1, 1, 12],
122 params: SignatureAlgorithmParams::Null,
123 };
124
125 pub static PKCS_RSA_SHA512: SignatureAlgorithm = SignatureAlgorithm {
127 oids_sign_alg: &[&OID_RSA_ENCRYPTION],
128 sign_alg: SignAlgo::Rsa(),
129 oid_components: &[1, 2, 840, 113549, 1, 1, 13],
131 params: SignatureAlgorithmParams::Null,
132 };
133
134 pub(crate) static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm {
141 oids_sign_alg: &[&OID_RSASSA_PSS],
144 sign_alg: SignAlgo::Rsa(),
145 oid_components: &OID_RSASSA_PSS, params: SignatureAlgorithmParams::RsaPss {
148 hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 1],
150 salt_length: 20,
151 },
152 };
153
154 pub static PKCS_ECDSA_P256_SHA256: SignatureAlgorithm = SignatureAlgorithm {
156 oids_sign_alg: &[&OID_EC_PUBLIC_KEY, &OID_EC_SECP_256_R1],
157 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P256_SHA256_ASN1_SIGNING),
158 oid_components: &[1, 2, 840, 10045, 4, 3, 2],
160 params: SignatureAlgorithmParams::None,
161 };
162
163 pub static PKCS_ECDSA_P384_SHA384: SignatureAlgorithm = SignatureAlgorithm {
165 oids_sign_alg: &[&OID_EC_PUBLIC_KEY, &OID_EC_SECP_384_R1],
166 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P384_SHA384_ASN1_SIGNING),
167 oid_components: &[1, 2, 840, 10045, 4, 3, 3],
169 params: SignatureAlgorithmParams::None,
170 };
171
172 pub static PKCS_ED25519: SignatureAlgorithm = SignatureAlgorithm {
176 oids_sign_alg: &[&[1, 3, 101, 112]],
178 sign_alg: SignAlgo::EdDsa(&signature::ED25519),
179 oid_components: &[1, 3, 101, 112],
181 params: SignatureAlgorithmParams::None,
182 };
183}
184impl SignatureAlgorithm {
186 fn alg_ident_oid(&self) -> ObjectIdentifier {
187 ObjectIdentifier::from_slice(self.oid_components)
188 }
189 fn write_params(&self, writer: &mut yasna::DERWriterSeq) {
190 match self.params {
191 SignatureAlgorithmParams::None => (),
192 SignatureAlgorithmParams::Null => {
193 writer.next().write_null();
194 },
195 SignatureAlgorithmParams::RsaPss {
196 hash_algorithm,
197 salt_length,
198 } => {
199 writer.next().write_sequence(|writer| {
200 let oid = ObjectIdentifier::from_slice(hash_algorithm);
203 writer.next().write_tagged(Tag::context(0), |writer| {
205 writer.write_sequence(|writer| {
206 writer.next().write_oid(&oid);
207 });
208 });
209 writer.next().write_tagged(Tag::context(1), |writer| {
211 writer.write_sequence(|writer| {
212 const ID_MGF1: &[u64] = &[1, 2, 840, 113549, 1, 1, 8];
214 let oid = ObjectIdentifier::from_slice(ID_MGF1);
215 writer.next().write_oid(&oid);
216 writer.next().write_sequence(|writer| {
217 let oid = ObjectIdentifier::from_slice(hash_algorithm);
218 writer.next().write_oid(&oid);
219 writer.next().write_null();
220 });
221 });
222 });
223 writer.next().write_tagged(Tag::context(2), |writer| {
225 writer.write_u64(salt_length);
226 });
227 })
229 },
230 }
231 }
232 pub(crate) fn write_alg_ident(&self, writer: DERWriter) {
234 writer.write_sequence(|writer| {
235 writer.next().write_oid(&self.alg_ident_oid());
236 self.write_params(writer);
237 });
238 }
239 pub(crate) fn write_oids_sign_alg(&self, writer: DERWriter) {
241 writer.write_sequence(|writer| {
242 for oid in self.oids_sign_alg {
243 let oid = ObjectIdentifier::from_slice(oid);
244 writer.next().write_oid(&oid);
245 }
246 self.write_params(writer);
247 });
248 }
249}