1use serde::{Deserialize, Serialize};
4
5use crate::key::{
6 CryptographicKeyContext,
7 KeyMechanism,
8 KeyType,
9 SignatureType,
10 key_type_and_mechanisms_match_signature_type,
11 key_type_matches_length,
12 key_type_matches_mechanisms,
13};
14
15#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
20pub struct SigningKeySetup {
21 key_type: KeyType,
22 key_mechanisms: Vec<KeyMechanism>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 key_length: Option<u32>,
25 signature_type: SignatureType,
26 key_context: CryptographicKeyContext,
27}
28
29impl SigningKeySetup {
30 pub fn new(
93 key_type: KeyType,
94 key_mechanisms: Vec<KeyMechanism>,
95 key_length: Option<u32>,
96 signature_type: SignatureType,
97 cryptographic_key_context: CryptographicKeyContext,
98 ) -> Result<Self, crate::Error> {
99 key_type_matches_mechanisms(key_type, &key_mechanisms)?;
100 key_type_matches_length(key_type, key_length)?;
101 key_type_and_mechanisms_match_signature_type(key_type, &key_mechanisms, signature_type)?;
102 cryptographic_key_context.validate_signing_key_setup(
103 key_type,
104 &key_mechanisms,
105 signature_type,
106 )?;
107
108 Ok(Self {
109 key_type,
110 key_mechanisms,
111 key_length,
112 signature_type,
113 key_context: cryptographic_key_context,
114 })
115 }
116
117 pub fn key_type(&self) -> KeyType {
119 self.key_type
120 }
121
122 pub fn key_mechanisms(&self) -> &[KeyMechanism] {
124 &self.key_mechanisms
125 }
126
127 pub fn key_length(&self) -> Option<u32> {
129 self.key_length
130 }
131
132 pub fn signature_type(&self) -> SignatureType {
134 self.signature_type
135 }
136
137 pub fn key_context(&self) -> &CryptographicKeyContext {
139 &self.key_context
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use rstest::rstest;
146 use testresult::TestResult;
147
148 use super::*;
149 use crate::key::Error;
150
151 #[test]
152 fn signing_key_setup_new_succeeds() -> TestResult {
153 let setup = SigningKeySetup::new(
154 KeyType::Curve25519,
155 vec![KeyMechanism::EdDsaSignature],
156 None,
157 SignatureType::EdDsa,
158 CryptographicKeyContext::Raw,
159 )?;
160
161 assert_eq!(setup.key_type(), KeyType::Curve25519);
162 assert_eq!(setup.key_mechanisms(), [KeyMechanism::EdDsaSignature]);
163 assert_eq!(setup.key_length(), None);
164 assert_eq!(setup.signature_type(), SignatureType::EdDsa);
165 assert_eq!(setup.key_context(), &CryptographicKeyContext::Raw);
166
167 Ok(())
168 }
169
170 #[rstest]
171 #[case::curve25519_ecdsa(KeyType::Curve25519, vec![KeyMechanism::EcdsaSignature])]
172 #[case::rsa_ecdsa(KeyType::Rsa, vec![KeyMechanism::EcdsaSignature])]
173 fn signing_key_setup_new_fails_on_key_type_mechanism_mismatch(
174 #[case] key_type: KeyType,
175 #[case] key_mechanisms: Vec<KeyMechanism>,
176 ) -> TestResult {
177 let result = SigningKeySetup::new(
178 key_type,
179 key_mechanisms,
180 None,
181 SignatureType::EdDsa,
182 CryptographicKeyContext::Raw,
183 );
184
185 match result {
186 Err(crate::Error::Key(Error::InvalidKeyMechanism { .. })) => {}
187 Err(error) => {
188 panic!("Expected an Error::InvalidKeyMechanism, but got {error}");
189 }
190 Ok(setup) => {
191 panic!(
192 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
193 );
194 }
195 }
196
197 Ok(())
198 }
199
200 #[rstest]
201 #[case::curve25519_with_length(KeyType::Curve25519, vec![KeyMechanism::EdDsaSignature], Some(1024))]
202 #[case::ecp521_with_length(KeyType::EcP521, vec![KeyMechanism::EcdsaSignature], Some(1024))]
203 fn signing_key_setup_new_fails_on_key_length_unsupported(
204 #[case] key_type: KeyType,
205 #[case] key_mechanisms: Vec<KeyMechanism>,
206 #[case] key_length: Option<u32>,
207 ) -> TestResult {
208 let result = SigningKeySetup::new(
209 key_type,
210 key_mechanisms,
211 key_length,
212 SignatureType::EdDsa,
213 CryptographicKeyContext::Raw,
214 );
215
216 match result {
217 Err(crate::Error::Key(Error::KeyLengthUnsupported { .. })) => {}
218 Err(error) => {
219 panic!("Expected an Error::KeyLengthUnsupported, but got {error}");
220 }
221 Ok(setup) => {
222 panic!(
223 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
224 );
225 }
226 }
227
228 Ok(())
229 }
230
231 #[rstest]
232 #[case::rsa_too_short(KeyType::Rsa, vec![KeyMechanism::RsaSignaturePkcs1], Some(1024))]
233 #[case::rsa_no_length(KeyType::Rsa, vec![KeyMechanism::RsaSignaturePkcs1], None)]
234 fn signing_key_setup_new_fails_on_key_length_required_or_too_short(
235 #[case] key_type: KeyType,
236 #[case] key_mechanisms: Vec<KeyMechanism>,
237 #[case] key_length: Option<u32>,
238 ) -> TestResult {
239 let result = SigningKeySetup::new(
240 key_type,
241 key_mechanisms,
242 key_length,
243 SignatureType::EdDsa,
244 CryptographicKeyContext::Raw,
245 );
246
247 match result {
248 Err(crate::Error::Key(Error::KeyLengthRequired { .. }))
249 | Err(crate::Error::Key(Error::InvalidKeyLengthRsa { .. })) => {}
250 Err(error) => {
251 panic!(
252 "Expected an Error::KeyLengthRequired or Error::InvalidKeyLengthRsa, but got {error}"
253 );
254 }
255 Ok(setup) => {
256 panic!(
257 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
258 );
259 }
260 }
261
262 Ok(())
263 }
264
265 #[rstest]
266 #[case::curve25519_ecdsap521(KeyType::Curve25519, vec![KeyMechanism::EdDsaSignature], SignatureType::EcdsaP521)]
267 #[case::ecdsap521_eddsa(KeyType::EcP521, vec![KeyMechanism::EcdsaSignature], SignatureType::EdDsa)]
268 fn signing_key_setup_new_fails_signature_type_mismatch(
269 #[case] key_type: KeyType,
270 #[case] key_mechanisms: Vec<KeyMechanism>,
271 #[case] signature_type: SignatureType,
272 ) -> TestResult {
273 let result = SigningKeySetup::new(
274 key_type,
275 key_mechanisms,
276 None,
277 signature_type,
278 CryptographicKeyContext::Raw,
279 );
280
281 match result {
282 Err(crate::Error::Key(Error::InvalidKeyTypeForSignatureType { .. }))
283 | Err(crate::Error::Key(Error::InvalidKeyMechanismsForSignatureType { .. })) => {}
284 Err(error) => {
285 panic!(
286 "Expected an Error::InvalidKeyTypeForSignatureType or Error::InvalidKeyMechanismsForSignatureType, but got {error}"
287 )
288 }
289 Ok(setup) => {
290 panic!("Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}")
291 }
292 }
293
294 Ok(())
295 }
296}