1#[cfg(feature = "nethsm")]
4pub mod nethsm;
5
6#[cfg(feature = "yubihsm2")]
7pub mod yubihsm2;
8
9use std::{cmp::Ordering, collections::BTreeMap, fmt::Display};
10
11use pgp::{
12 composed::SignedPublicKey,
13 types::{KeyDetails as _, Timestamp},
14};
15use serde::{Deserialize, Serialize};
16use strum::{EnumIter, EnumString, IntoStaticStr};
17
18use crate::{
19 key::error::Error,
20 openpgp::{OpenPgpUserId, OpenPgpUserIdList, OpenPgpVersion},
21 signer::openpgp::{EmptyEd25519Signer, Notation, generate_certificate},
22};
23
24#[derive(
26 Clone,
27 Copy,
28 Debug,
29 Default,
30 Deserialize,
31 strum::Display,
32 strum::EnumString,
33 strum::EnumIter,
34 strum::IntoStaticStr,
35 Eq,
36 Hash,
37 Ord,
38 PartialEq,
39 PartialOrd,
40 Serialize,
41)]
42#[strum(ascii_case_insensitive)]
43pub enum DecryptMode {
44 AesCbc,
46
47 OaepMd5,
49
50 OaepSha1,
52
53 OaepSha224,
55
56 OaepSha256,
58
59 OaepSha384,
61
62 OaepSha512,
64
65 Pkcs1,
67
68 #[default]
70 Raw,
71}
72
73#[derive(
75 Clone,
76 Copy,
77 Debug,
78 Default,
79 Deserialize,
80 strum::Display,
81 strum::EnumString,
82 strum::EnumIter,
83 strum::IntoStaticStr,
84 Eq,
85 Hash,
86 Ord,
87 PartialEq,
88 PartialOrd,
89 Serialize,
90)]
91#[strum(ascii_case_insensitive)]
92pub enum EncryptMode {
93 #[default]
95 AesCbc,
96}
97
98#[derive(
100 Clone,
101 Copy,
102 Debug,
103 Default,
104 Deserialize,
105 strum::Display,
106 EnumString,
107 EnumIter,
108 IntoStaticStr,
109 Eq,
110 Hash,
111 Ord,
112 PartialEq,
113 PartialOrd,
114 Serialize,
115)]
116#[strum(ascii_case_insensitive)]
117pub enum KeyFormat {
118 Pem,
120
121 #[default]
123 Der,
124}
125
126pub const MIN_RSA_BIT_LENGTH: u32 = 2048;
130
131#[derive(
133 Clone,
134 Copy,
135 Debug,
136 Default,
137 Deserialize,
138 strum::Display,
139 EnumString,
140 EnumIter,
141 IntoStaticStr,
142 Eq,
143 Hash,
144 Ord,
145 PartialEq,
146 PartialOrd,
147 Serialize,
148)]
149#[strum(ascii_case_insensitive)]
150pub enum KeyType {
151 #[default]
153 Curve25519,
154
155 EcBp256,
157
158 EcBp384,
160
161 EcBp512,
163
164 EcK256,
166
167 EcP224,
169
170 EcP256,
172
173 EcP384,
175
176 EcP521,
178
179 Generic,
181
182 Rsa,
184}
185
186#[derive(
188 Clone,
189 Copy,
190 Debug,
191 Default,
192 Deserialize,
193 strum::Display,
194 EnumString,
195 EnumIter,
196 IntoStaticStr,
197 Hash,
198 Eq,
199 Ord,
200 PartialEq,
201 PartialOrd,
202 Serialize,
203)]
204#[strum(ascii_case_insensitive)]
205pub enum KeyMechanism {
206 AesDecryptionCbc,
208
209 AesEncryptionCbc,
211
212 EcdsaSignature,
214
215 #[default]
217 EdDsaSignature,
218
219 RsaDecryptionOaepMd5,
221
222 RsaDecryptionOaepSha1,
224
225 RsaDecryptionOaepSha224,
227
228 RsaDecryptionOaepSha256,
230
231 RsaDecryptionOaepSha384,
233
234 RsaDecryptionOaepSha512,
236
237 RsaDecryptionPkcs1,
239
240 RsaDecryptionRaw,
242
243 RsaSignaturePkcs1,
245
246 RsaSignaturePssSha1,
248
249 RsaSignaturePssSha224,
251
252 RsaSignaturePssSha256,
254
255 RsaSignaturePssSha384,
257
258 RsaSignaturePssSha512,
260}
261
262impl KeyMechanism {
263 pub fn curve25519_mechanisms() -> Vec<KeyMechanism> {
265 vec![KeyMechanism::EdDsaSignature]
266 }
267
268 pub fn elliptic_curve_mechanisms() -> Vec<KeyMechanism> {
270 vec![KeyMechanism::EcdsaSignature]
271 }
272
273 pub fn generic_mechanisms() -> Vec<KeyMechanism> {
275 vec![
276 KeyMechanism::AesDecryptionCbc,
277 KeyMechanism::AesEncryptionCbc,
278 ]
279 }
280
281 pub fn rsa_mechanisms() -> Vec<KeyMechanism> {
283 vec![
284 KeyMechanism::RsaDecryptionRaw,
285 KeyMechanism::RsaDecryptionPkcs1,
286 KeyMechanism::RsaDecryptionOaepMd5,
287 KeyMechanism::RsaDecryptionOaepSha1,
288 KeyMechanism::RsaDecryptionOaepSha224,
289 KeyMechanism::RsaDecryptionOaepSha256,
290 KeyMechanism::RsaDecryptionOaepSha384,
291 KeyMechanism::RsaDecryptionOaepSha512,
292 KeyMechanism::RsaSignaturePkcs1,
293 KeyMechanism::RsaSignaturePssSha1,
294 KeyMechanism::RsaSignaturePssSha224,
295 KeyMechanism::RsaSignaturePssSha256,
296 KeyMechanism::RsaSignaturePssSha384,
297 KeyMechanism::RsaSignaturePssSha512,
298 ]
299 }
300}
301
302#[derive(
304 Clone,
305 Copy,
306 Debug,
307 Deserialize,
308 strum::Display,
309 EnumString,
310 EnumIter,
311 IntoStaticStr,
312 Eq,
313 PartialEq,
314 Ord,
315 PartialOrd,
316 Hash,
317 Serialize,
318)]
319#[strum(ascii_case_insensitive)]
320pub enum SignatureType {
321 EcdsaK256,
324
325 EcdsaP224,
328
329 EcdsaP256,
332
333 EcdsaP384,
336
337 EcdsaP521,
340
341 EdDsa,
343
344 Pkcs1,
346
347 PssSha1,
349
350 PssSha224,
352
353 PssSha256,
355
356 PssSha384,
358
359 PssSha512,
361}
362
363#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
365pub enum CryptographicKeyContext {
366 #[serde(rename = "openpgp")]
368 OpenPgp {
369 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
371 notations: BTreeMap<String, String>,
372
373 user_ids: OpenPgpUserIdList,
375
376 version: OpenPgpVersion,
378 },
379
380 #[serde(rename = "raw")]
382 Raw,
383}
384
385impl CryptographicKeyContext {
386 pub fn validate_signing_key_setup(
420 &self,
421 key_type: KeyType,
422 key_mechanisms: &[KeyMechanism],
423 signature_type: SignatureType,
424 ) -> Result<(), crate::Error> {
425 match self {
426 Self::Raw => match (key_type, signature_type) {
427 (KeyType::Curve25519, SignatureType::EdDsa)
428 if key_mechanisms.contains(&KeyMechanism::EdDsaSignature) => {}
429 (KeyType::EcP256, SignatureType::EcdsaP256)
430 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
431 (KeyType::EcP384, SignatureType::EcdsaP384)
432 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
433 (KeyType::EcP521, SignatureType::EcdsaP521)
434 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
435 (KeyType::Rsa, SignatureType::Pkcs1)
436 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) => {}
437 (KeyType::Rsa, SignatureType::PssSha1)
438 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha1) => {}
439 (KeyType::Rsa, SignatureType::PssSha224)
440 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha224) => {}
441 (KeyType::Rsa, SignatureType::PssSha256)
442 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha256) => {}
443 (KeyType::Rsa, SignatureType::PssSha384)
444 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha384) => {}
445 (KeyType::Rsa, SignatureType::PssSha512)
446 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha512) => {}
447 _ => {
448 return Err(Error::InvalidRawSigningKeySetup {
449 key_type,
450 key_mechanisms: key_mechanisms.to_vec(),
451 signature_type,
452 }
453 .into());
454 }
455 },
456 Self::OpenPgp {
457 user_ids: _,
458 version: _,
459 notations: _,
460 } => match (key_type, signature_type) {
461 (KeyType::Curve25519, SignatureType::EdDsa)
462 if key_mechanisms.contains(&KeyMechanism::EdDsaSignature) => {}
463 (KeyType::EcP256, SignatureType::EcdsaP256)
464 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
465 (KeyType::EcP384, SignatureType::EcdsaP384)
466 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
467 (KeyType::EcP521, SignatureType::EcdsaP521)
468 if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
469 (KeyType::Rsa, SignatureType::Pkcs1)
470 if key_mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) => {}
471 _ => {
472 return Err(Error::InvalidOpenPgpSigningKeySetup {
473 key_type,
474 key_mechanisms: key_mechanisms.to_vec(),
475 signature_type,
476 }
477 .into());
478 }
479 },
480 }
481 Ok(())
482 }
483
484 pub fn openpgp_cert_size(&self) -> Result<Option<usize>, crate::Error> {
515 if let CryptographicKeyContext::OpenPgp {
516 user_ids,
517 notations,
518 ..
519 } = self
520 {
521 match generate_certificate(
522 &EmptyEd25519Signer,
523 Default::default(),
524 user_ids.as_ref(),
525 notations
526 .iter()
527 .map(|(name, value)| Notation { name, value })
528 .collect::<Vec<_>>()
529 .as_slice(),
530 Timestamp::now(),
531 Default::default(),
532 ) {
533 Err(error) => Err(error),
534 Ok(cert) => Ok(Some(cert.len())),
535 }
536 } else {
537 Ok(None)
538 }
539 }
540}
541
542impl Display for CryptographicKeyContext {
543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
544 match self {
545 Self::OpenPgp {
546 user_ids,
547 version,
548 notations,
549 } => {
550 write!(
551 f,
552 "OpenPGP (Version: {version}; User IDs: {}",
553 user_ids
554 .iter()
555 .map(|user_id| format!("\"{user_id}\""))
556 .collect::<Vec<String>>()
557 .join(", ")
558 )?;
559 if !notations.is_empty() {
560 write!(
561 f,
562 "; Notations: {}",
563 notations
564 .iter()
565 .map(|(key, value)| format!("\"{key}={value}\""))
566 .collect::<Vec<String>>()
567 .join(", ")
568 )?;
569 }
570 write!(f, ")")
571 }
572 Self::Raw => {
573 write!(f, "Raw")
574 }
575 }
576 }
577}
578
579impl Ord for CryptographicKeyContext {
580 fn cmp(&self, other: &Self) -> Ordering {
581 match (self, other) {
582 (
583 CryptographicKeyContext::OpenPgp {
584 notations: self_notations,
585 user_ids: self_user_ids,
586 version: self_version,
587 },
588 CryptographicKeyContext::OpenPgp {
589 notations: other_notations,
590 user_ids: other_user_ids,
591 version: other_version,
592 },
593 ) => (self_version, self_user_ids, self_notations).cmp(&(
594 other_version,
595 other_user_ids,
596 other_notations,
597 )),
598 (CryptographicKeyContext::OpenPgp { .. }, CryptographicKeyContext::Raw) => {
599 Ordering::Less
600 }
601 (CryptographicKeyContext::Raw, CryptographicKeyContext::OpenPgp { .. }) => {
602 Ordering::Greater
603 }
604 (CryptographicKeyContext::Raw, CryptographicKeyContext::Raw) => Ordering::Equal,
605 }
606 }
607}
608
609impl PartialOrd for CryptographicKeyContext {
610 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
611 Some(self.cmp(other))
612 }
613}
614
615impl TryFrom<SignedPublicKey> for CryptographicKeyContext {
616 type Error = crate::Error;
617
618 fn try_from(value: SignedPublicKey) -> Result<Self, Self::Error> {
629 let user_ids: Vec<OpenPgpUserId> = value
630 .details
631 .users
632 .iter()
633 .filter_map(|signed_user| signed_user.try_into().ok())
634 .collect();
635
636 let notations = value
637 .details
638 .users
639 .iter()
640 .flat_map(|user| &user.signatures)
641 .flat_map(|sig| sig.notations())
642 .fold(BTreeMap::new(), |mut acc, notation| {
643 acc.entry(String::from_utf8_lossy(¬ation.name).into())
644 .or_insert(String::from_utf8_lossy(¬ation.value).into());
645 acc
646 });
647
648 Ok(Self::OpenPgp {
649 user_ids: OpenPgpUserIdList::new(user_ids)?,
650 version: value.primary_key.version().try_into()?,
651 notations,
652 })
653 }
654}
655
656pub fn key_type_matches_mechanisms(
714 key_type: KeyType,
715 mechanisms: &[KeyMechanism],
716) -> Result<(), crate::Error> {
717 let valid_mechanisms: &[KeyMechanism] = match key_type {
718 KeyType::Curve25519 => &KeyMechanism::curve25519_mechanisms(),
719 KeyType::EcBp256
720 | KeyType::EcBp384
721 | KeyType::EcBp512
722 | KeyType::EcK256
723 | KeyType::EcP224
724 | KeyType::EcP256
725 | KeyType::EcP384
726 | KeyType::EcP521 => &KeyMechanism::elliptic_curve_mechanisms(),
727 KeyType::Generic => &KeyMechanism::generic_mechanisms(),
728 KeyType::Rsa => &KeyMechanism::rsa_mechanisms(),
729 };
730
731 let invalid_mechanisms = mechanisms
732 .iter()
733 .filter(|mechanism| !valid_mechanisms.contains(mechanism))
734 .cloned()
735 .collect::<Vec<KeyMechanism>>();
736
737 if invalid_mechanisms.is_empty() {
738 Ok(())
739 } else {
740 Err(Error::InvalidKeyMechanism {
741 key_type,
742 invalid_mechanisms,
743 }
744 .into())
745 }
746}
747
748pub fn key_type_and_mechanisms_match_signature_type(
775 key_type: KeyType,
776 mechanisms: &[KeyMechanism],
777 signature_type: SignatureType,
778) -> Result<(), crate::Error> {
779 match signature_type {
780 SignatureType::EcdsaK256 => {
781 if key_type != KeyType::EcK256 {
782 return Err(Error::InvalidKeyTypeForSignatureType {
783 key_type,
784 signature_type,
785 }
786 .into());
787 } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
788 return Err(Error::InvalidKeyMechanismsForSignatureType {
789 required_key_mechanism: KeyMechanism::EcdsaSignature,
790 signature_type,
791 }
792 .into());
793 }
794 }
795 SignatureType::EcdsaP224 => {
796 if key_type != KeyType::EcP224 {
797 return Err(Error::InvalidKeyTypeForSignatureType {
798 key_type,
799 signature_type,
800 }
801 .into());
802 } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
803 return Err(Error::InvalidKeyMechanismsForSignatureType {
804 required_key_mechanism: KeyMechanism::EcdsaSignature,
805 signature_type,
806 }
807 .into());
808 }
809 }
810 SignatureType::EcdsaP256 => {
811 if key_type != KeyType::EcP256 {
812 return Err(Error::InvalidKeyTypeForSignatureType {
813 key_type,
814 signature_type,
815 }
816 .into());
817 } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
818 return Err(Error::InvalidKeyMechanismsForSignatureType {
819 required_key_mechanism: KeyMechanism::EcdsaSignature,
820 signature_type,
821 }
822 .into());
823 }
824 }
825 SignatureType::EcdsaP384 => {
826 if key_type != KeyType::EcP384 {
827 return Err(Error::InvalidKeyTypeForSignatureType {
828 key_type,
829 signature_type,
830 }
831 .into());
832 } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
833 return Err(Error::InvalidKeyMechanismsForSignatureType {
834 required_key_mechanism: KeyMechanism::EcdsaSignature,
835 signature_type,
836 }
837 .into());
838 }
839 }
840 SignatureType::EcdsaP521 => {
841 if key_type != KeyType::EcP521 {
842 return Err(Error::InvalidKeyTypeForSignatureType {
843 key_type,
844 signature_type,
845 }
846 .into());
847 } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
848 return Err(Error::InvalidKeyMechanismsForSignatureType {
849 required_key_mechanism: KeyMechanism::EcdsaSignature,
850 signature_type,
851 }
852 .into());
853 }
854 }
855 SignatureType::EdDsa => {
856 if key_type != KeyType::Curve25519 {
857 return Err(Error::InvalidKeyTypeForSignatureType {
858 key_type,
859 signature_type,
860 }
861 .into());
862 } else if !mechanisms.contains(&KeyMechanism::EdDsaSignature) {
863 return Err(Error::InvalidKeyMechanismsForSignatureType {
864 required_key_mechanism: KeyMechanism::EdDsaSignature,
865 signature_type,
866 }
867 .into());
868 }
869 }
870 SignatureType::Pkcs1 => {
871 if key_type != KeyType::Rsa {
872 return Err(Error::InvalidKeyTypeForSignatureType {
873 key_type,
874 signature_type,
875 }
876 .into());
877 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) {
878 return Err(Error::InvalidKeyMechanismsForSignatureType {
879 required_key_mechanism: KeyMechanism::RsaSignaturePkcs1,
880 signature_type,
881 }
882 .into());
883 }
884 }
885 SignatureType::PssSha1 => {
886 if key_type != KeyType::Rsa {
887 return Err(Error::InvalidKeyTypeForSignatureType {
888 key_type,
889 signature_type,
890 }
891 .into());
892 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha1) {
893 return Err(Error::InvalidKeyMechanismsForSignatureType {
894 required_key_mechanism: KeyMechanism::RsaSignaturePssSha1,
895 signature_type,
896 }
897 .into());
898 }
899 }
900 SignatureType::PssSha224 => {
901 if key_type != KeyType::Rsa {
902 return Err(Error::InvalidKeyTypeForSignatureType {
903 key_type,
904 signature_type,
905 }
906 .into());
907 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha224) {
908 return Err(Error::InvalidKeyMechanismsForSignatureType {
909 required_key_mechanism: KeyMechanism::RsaSignaturePssSha224,
910 signature_type,
911 }
912 .into());
913 }
914 }
915 SignatureType::PssSha256 => {
916 if key_type != KeyType::Rsa {
917 return Err(Error::InvalidKeyTypeForSignatureType {
918 key_type,
919 signature_type,
920 }
921 .into());
922 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha256) {
923 return Err(Error::InvalidKeyMechanismsForSignatureType {
924 required_key_mechanism: KeyMechanism::RsaSignaturePssSha256,
925 signature_type,
926 }
927 .into());
928 }
929 }
930 SignatureType::PssSha384 => {
931 if key_type != KeyType::Rsa {
932 return Err(Error::InvalidKeyTypeForSignatureType {
933 key_type,
934 signature_type,
935 }
936 .into());
937 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha384) {
938 return Err(Error::InvalidKeyMechanismsForSignatureType {
939 required_key_mechanism: KeyMechanism::RsaSignaturePssSha384,
940 signature_type,
941 }
942 .into());
943 }
944 }
945 SignatureType::PssSha512 => {
946 if key_type != KeyType::Rsa {
947 return Err(Error::InvalidKeyTypeForSignatureType {
948 key_type,
949 signature_type,
950 }
951 .into());
952 } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha512) {
953 return Err(Error::InvalidKeyMechanismsForSignatureType {
954 required_key_mechanism: KeyMechanism::RsaSignaturePssSha512,
955 signature_type,
956 }
957 .into());
958 }
959 }
960 }
961 Ok(())
962}
963
964pub fn key_type_matches_length(key_type: KeyType, length: Option<u32>) -> Result<(), crate::Error> {
998 match key_type {
999 KeyType::Curve25519
1000 | KeyType::EcBp256
1001 | KeyType::EcBp384
1002 | KeyType::EcBp512
1003 | KeyType::EcK256
1004 | KeyType::EcP224
1005 | KeyType::EcP256
1006 | KeyType::EcP384
1007 | KeyType::EcP521 => {
1008 if length.is_some() {
1009 Err(Error::KeyLengthUnsupported { key_type }.into())
1010 } else {
1011 Ok(())
1012 }
1013 }
1014 KeyType::Generic => match length {
1015 None => Err(Error::KeyLengthRequired { key_type }.into()),
1016 Some(length) => {
1017 if ![128, 192, 256].contains(&length) {
1018 Err(Error::InvalidKeyLengthAes { key_length: length }.into())
1019 } else {
1020 Ok(())
1021 }
1022 }
1023 },
1024 KeyType::Rsa => match length {
1025 None => Err(Error::KeyLengthRequired { key_type }.into()),
1026 Some(length) => {
1027 if length < MIN_RSA_BIT_LENGTH {
1028 Err(Error::InvalidKeyLengthRsa { key_length: length }.into())
1029 } else {
1030 Ok(())
1031 }
1032 }
1033 },
1034 }
1035}
1036
1037#[cfg(test)]
1038mod tests {
1039 use std::str::FromStr;
1040
1041 use rstest::rstest;
1042 use testresult::TestResult;
1043
1044 use super::*;
1045
1046 #[rstest]
1047 #[case(KeyType::Curve25519, &[KeyMechanism::EdDsaSignature], SignatureType::EdDsa, None)]
1048 #[case(KeyType::EcP256, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP256, None)]
1049 #[case(KeyType::EcP384, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP384, None)]
1050 #[case(KeyType::EcP521, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP521, None)]
1051 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePkcs1], SignatureType::Pkcs1, None)]
1052 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha1], SignatureType::PssSha1, None)]
1053 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha224], SignatureType::PssSha224, None)]
1054 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha256], SignatureType::PssSha256, None)]
1055 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha384], SignatureType::PssSha384, None)]
1056 #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha512], SignatureType::PssSha512, None)]
1057 #[case(
1058 KeyType::Curve25519,
1059 &[KeyMechanism::EdDsaSignature],
1060 SignatureType::EcdsaP256,
1061 Some(Box::new(crate::Error::Key(Error::InvalidKeyTypeForSignatureType {
1062 key_type: KeyType::Curve25519,
1063 signature_type: SignatureType::EcdsaP256
1064 }))
1065 ))]
1066 #[case(
1067 KeyType::Curve25519,
1068 &[KeyMechanism::EcdsaSignature],
1069 SignatureType::EdDsa,
1070 Some(Box::new(crate::Error::Key(Error::InvalidKeyMechanismsForSignatureType {
1071 signature_type: SignatureType::EdDsa,
1072 required_key_mechanism: KeyMechanism::EdDsaSignature,
1073 }))
1074 ))]
1075 #[case(
1076 KeyType::EcP256,
1077 &[KeyMechanism::EcdsaSignature],
1078 SignatureType::EdDsa,
1079 Some(Box::new(crate::Error::Key(Error::InvalidKeyTypeForSignatureType {
1080 key_type: KeyType::EcP256,
1081 signature_type: SignatureType::EdDsa,
1082 }))
1083 ))]
1084 #[case(
1085 KeyType::EcP256,
1086 &[KeyMechanism::EdDsaSignature],
1087 SignatureType::EcdsaP256,
1088 Some(Box::new(crate::Error::Key(Error::InvalidKeyMechanismsForSignatureType {
1089 signature_type: SignatureType::EcdsaP256,
1090 required_key_mechanism: KeyMechanism::EcdsaSignature,
1091 }))
1092 ))]
1093 #[case(
1094 KeyType::EcP384,
1095 &[KeyMechanism::EcdsaSignature],
1096 SignatureType::EdDsa,
1097 Some(Box::new(crate::Error::Key(Error::InvalidKeyTypeForSignatureType {
1098 key_type: KeyType::EcP384,
1099 signature_type: SignatureType::EdDsa,
1100 }))
1101 ))]
1102 #[case(
1103 KeyType::EcP384,
1104 &[KeyMechanism::EdDsaSignature],
1105 SignatureType::EcdsaP384,
1106 Some(Box::new(crate::Error::Key(Error::InvalidKeyMechanismsForSignatureType {
1107 signature_type: SignatureType::EcdsaP384,
1108 required_key_mechanism: KeyMechanism::EcdsaSignature,
1109 }))
1110 ))]
1111 #[case(
1112 KeyType::EcP521,
1113 &[KeyMechanism::EcdsaSignature],
1114 SignatureType::EdDsa,
1115 Some(Box::new(crate::Error::Key(Error::InvalidKeyTypeForSignatureType {
1116 key_type: KeyType::EcP521,
1117 signature_type: SignatureType::EdDsa,
1118 }))
1119 ))]
1120 #[case(
1121 KeyType::EcP521,
1122 &[KeyMechanism::EdDsaSignature],
1123 SignatureType::EcdsaP521,
1124 Some(Box::new(crate::Error::Key(Error::InvalidKeyMechanismsForSignatureType {
1125 signature_type: SignatureType::EcdsaP521,
1126 required_key_mechanism: KeyMechanism::EcdsaSignature,
1127 }))
1128 ))]
1129 #[case(
1130 KeyType::Rsa,
1131 &[KeyMechanism::RsaSignaturePkcs1],
1132 SignatureType::EdDsa,
1133 Some(Box::new(crate::Error::Key(Error::InvalidKeyTypeForSignatureType {
1134 key_type: KeyType::Rsa,
1135 signature_type: SignatureType::EdDsa,
1136 }))
1137 ))]
1138 fn test_key_type_and_mechanisms_match_signature_type(
1139 #[case] key_type: KeyType,
1140 #[case] key_mechanisms: &[KeyMechanism],
1141 #[case] signature_type: SignatureType,
1142 #[case] result: Option<Box<crate::Error>>,
1143 ) -> TestResult {
1144 if let Some(error) = result {
1145 if let Err(fn_error) = key_type_and_mechanisms_match_signature_type(
1146 key_type,
1147 key_mechanisms,
1148 signature_type,
1149 ) {
1150 assert_eq!(fn_error.to_string(), error.to_string());
1151 } else {
1152 panic!("Did not return an Error!");
1153 }
1154 } else {
1155 key_type_and_mechanisms_match_signature_type(key_type, key_mechanisms, signature_type)?;
1156 }
1157
1158 Ok(())
1159 }
1160
1161 #[rstest]
1162 #[case("raw", Some(DecryptMode::Raw))]
1163 #[case("pkcs1", Some(DecryptMode::Pkcs1))]
1164 #[case("oaepmd5", Some(DecryptMode::OaepMd5))]
1165 #[case("oaepsha1", Some(DecryptMode::OaepSha1))]
1166 #[case("oaepsha224", Some(DecryptMode::OaepSha224))]
1167 #[case("oaepsha256", Some(DecryptMode::OaepSha256))]
1168 #[case("oaepsha384", Some(DecryptMode::OaepSha384))]
1169 #[case("oaepsha512", Some(DecryptMode::OaepSha512))]
1170 #[case("aescbc", Some(DecryptMode::AesCbc))]
1171 #[case("foo", None)]
1172 fn decryptmode_fromstr(
1173 #[case] input: &str,
1174 #[case] expected: Option<DecryptMode>,
1175 ) -> TestResult {
1176 if let Some(expected) = expected {
1177 assert_eq!(DecryptMode::from_str(input)?, expected);
1178 } else {
1179 assert!(DecryptMode::from_str(input).is_err());
1180 }
1181 Ok(())
1182 }
1183
1184 #[rstest]
1185 #[case("aescbc", Some(EncryptMode::AesCbc))]
1186 #[case("foo", None)]
1187 fn encryptmode_fromstr(
1188 #[case] input: &str,
1189 #[case] expected: Option<EncryptMode>,
1190 ) -> TestResult {
1191 if let Some(expected) = expected {
1192 assert_eq!(EncryptMode::from_str(input)?, expected);
1193 } else {
1194 assert!(EncryptMode::from_str(input).is_err());
1195 }
1196 Ok(())
1197 }
1198
1199 #[rstest]
1200 #[case("rsadecryptionraw", Some(KeyMechanism::RsaDecryptionRaw))]
1201 #[case("rsadecryptionpkcs1", Some(KeyMechanism::RsaDecryptionPkcs1))]
1202 #[case("rsadecryptionoaepmd5", Some(KeyMechanism::RsaDecryptionOaepMd5))]
1203 #[case("rsadecryptionoaepsha1", Some(KeyMechanism::RsaDecryptionOaepSha1))]
1204 #[case("rsadecryptionoaepsha224", Some(KeyMechanism::RsaDecryptionOaepSha224))]
1205 #[case("rsadecryptionoaepsha256", Some(KeyMechanism::RsaDecryptionOaepSha256))]
1206 #[case("rsadecryptionoaepsha384", Some(KeyMechanism::RsaDecryptionOaepSha384))]
1207 #[case("rsadecryptionoaepsha512", Some(KeyMechanism::RsaDecryptionOaepSha512))]
1208 #[case("rsadecryptionoaepsha512", Some(KeyMechanism::RsaDecryptionOaepSha512))]
1209 #[case("rsasignaturepkcs1", Some(KeyMechanism::RsaSignaturePkcs1))]
1210 #[case("rsasignaturepsssha1", Some(KeyMechanism::RsaSignaturePssSha1))]
1211 #[case("rsasignaturepsssha224", Some(KeyMechanism::RsaSignaturePssSha224))]
1212 #[case("rsasignaturepsssha256", Some(KeyMechanism::RsaSignaturePssSha256))]
1213 #[case("rsasignaturepsssha384", Some(KeyMechanism::RsaSignaturePssSha384))]
1214 #[case("rsasignaturepsssha512", Some(KeyMechanism::RsaSignaturePssSha512))]
1215 #[case("eddsasignature", Some(KeyMechanism::EdDsaSignature))]
1216 #[case("ecdsasignature", Some(KeyMechanism::EcdsaSignature))]
1217 #[case("aesencryptioncbc", Some(KeyMechanism::AesEncryptionCbc))]
1218 #[case("aesdecryptioncbc", Some(KeyMechanism::AesDecryptionCbc))]
1219 #[case("foo", None)]
1220 fn keymechanism_fromstr(
1221 #[case] input: &str,
1222 #[case] expected: Option<KeyMechanism>,
1223 ) -> TestResult {
1224 if let Some(expected) = expected {
1225 assert_eq!(KeyMechanism::from_str(input)?, expected);
1226 } else {
1227 assert!(KeyMechanism::from_str(input).is_err());
1228 }
1229 Ok(())
1230 }
1231
1232 #[rstest]
1233 #[case("rsa", Some(KeyType::Rsa))]
1234 #[case("curve25519", Some(KeyType::Curve25519))]
1235 #[case("ecp256", Some(KeyType::EcP256))]
1236 #[case("ecp384", Some(KeyType::EcP384))]
1237 #[case("ecp521", Some(KeyType::EcP521))]
1238 #[case("generic", Some(KeyType::Generic))]
1239 #[case("foo", None)]
1240 fn keytype_fromstr(#[case] input: &str, #[case] expected: Option<KeyType>) -> TestResult {
1241 if let Some(expected) = expected {
1242 assert_eq!(KeyType::from_str(input)?, expected);
1243 } else {
1244 assert!(KeyType::from_str(input).is_err());
1245 }
1246 Ok(())
1247 }
1248
1249 #[rstest]
1250 #[case("ecdsap256", Some(SignatureType::EcdsaP256))]
1251 #[case("ecdsap384", Some(SignatureType::EcdsaP384))]
1252 #[case("ecdsap521", Some(SignatureType::EcdsaP521))]
1253 #[case("eddsa", Some(SignatureType::EdDsa))]
1254 #[case("pkcs1", Some(SignatureType::Pkcs1))]
1255 #[case("psssha1", Some(SignatureType::PssSha1))]
1256 #[case("psssha224", Some(SignatureType::PssSha224))]
1257 #[case("psssha256", Some(SignatureType::PssSha256))]
1258 #[case("psssha384", Some(SignatureType::PssSha384))]
1259 #[case("psssha512", Some(SignatureType::PssSha512))]
1260 #[case("foo", None)]
1261 fn signaturetype_fromstr(
1262 #[case] input: &str,
1263 #[case] expected: Option<SignatureType>,
1264 ) -> TestResult {
1265 if let Some(expected) = expected {
1266 assert_eq!(SignatureType::from_str(input)?, expected);
1267 } else {
1268 assert!(SignatureType::from_str(input).is_err());
1269 }
1270 Ok(())
1271 }
1272}