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 panic!("Expected an Error::InvalidKeyMechanism, but got {error}");
186 }
187 Ok(setup) => {
188 panic!(
189 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
190 );
191 }
192 }
193
194 Ok(())
195 }
196
197 #[rstest]
198 #[case::curve25519_with_length(KeyType::Curve25519, vec![KeyMechanism::EdDsaSignature], Some(1024))]
199 #[case::ecp521_with_length(KeyType::EcP521, vec![KeyMechanism::EcdsaSignature], Some(1024))]
200 fn signing_key_setup_new_fails_on_key_length_unsupported(
201 #[case] key_type: KeyType,
202 #[case] key_mechanisms: Vec<KeyMechanism>,
203 #[case] key_length: Option<u32>,
204 ) -> TestResult {
205 let result = SigningKeySetup::new(
206 key_type,
207 key_mechanisms,
208 key_length,
209 SignatureType::EdDsa,
210 CryptographicKeyContext::Raw,
211 );
212
213 match result {
214 Err(Error::KeyLengthUnsupported { .. }) => {}
215 Err(error) => {
216 panic!("Expected an Error::KeyLengthUnsupported, but got {error}");
217 }
218 Ok(setup) => {
219 panic!(
220 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
221 );
222 }
223 }
224
225 Ok(())
226 }
227
228 #[rstest]
229 #[case::rsa_too_short(KeyType::Rsa, vec![KeyMechanism::RsaSignaturePkcs1], Some(1024))]
230 #[case::rsa_no_length(KeyType::Rsa, vec![KeyMechanism::RsaSignaturePkcs1], None)]
231 fn signing_key_setup_new_fails_on_key_length_required_or_too_short(
232 #[case] key_type: KeyType,
233 #[case] key_mechanisms: Vec<KeyMechanism>,
234 #[case] key_length: Option<u32>,
235 ) -> TestResult {
236 let result = SigningKeySetup::new(
237 key_type,
238 key_mechanisms,
239 key_length,
240 SignatureType::EdDsa,
241 CryptographicKeyContext::Raw,
242 );
243
244 match result {
245 Err(Error::KeyLengthRequired { .. }) | Err(Error::InvalidKeyLengthRsa { .. }) => {}
246 Err(error) => {
247 panic!(
248 "Expected an Error::KeyLengthRequired or Error::InvalidKeyLengthRsa, but got {error}"
249 );
250 }
251 Ok(setup) => {
252 panic!(
253 "Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}"
254 );
255 }
256 }
257
258 Ok(())
259 }
260
261 #[rstest]
262 #[case::curve25519_ecdsap521(KeyType::Curve25519, vec![KeyMechanism::EdDsaSignature], SignatureType::EcdsaP521)]
263 #[case::ecdsap521_eddsa(KeyType::EcP521, vec![KeyMechanism::EcdsaSignature], SignatureType::EdDsa)]
264 fn signing_key_setup_new_fails_signature_type_mismatch(
265 #[case] key_type: KeyType,
266 #[case] key_mechanisms: Vec<KeyMechanism>,
267 #[case] signature_type: SignatureType,
268 ) -> TestResult {
269 let result = SigningKeySetup::new(
270 key_type,
271 key_mechanisms,
272 None,
273 signature_type,
274 CryptographicKeyContext::Raw,
275 );
276
277 match result {
278 Err(Error::InvalidKeyTypeForSignatureType { .. })
279 | Err(Error::InvalidKeyMechanismsForSignatureType { .. }) => {}
280 Err(error) => {
281 panic!(
282 "Expected an Error::InvalidKeyTypeForSignatureType or Error::InvalidKeyMechanismsForSignatureType, but got {error}"
283 )
284 }
285 Ok(setup) => {
286 panic!("Should have failed, but succeeded in creating a SigningKeySetup: {setup:?}")
287 }
288 }
289
290 Ok(())
291 }
292}