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