1use std::fmt;
4use std::cmp::Ordering;
5use std::hash::Hasher;
6use std::time;
7
8#[cfg(test)]
9use quickcheck::{Arbitrary, Gen};
10
11use crate::Error;
12use crate::crypto::{mpi, hash::Hash, mem::Protected, KeyPair};
13use crate::packet::key::{
14 KeyParts,
15 KeyRole,
16 KeyRoleRT,
17 PublicParts,
18 SecretParts,
19 UnspecifiedParts,
20};
21use crate::packet::prelude::*;
22use crate::PublicKeyAlgorithm;
23use crate::HashAlgorithm;
24use crate::types::Timestamp;
25use crate::Result;
26use crate::crypto::Password;
27use crate::KeyID;
28use crate::Fingerprint;
29use crate::KeyHandle;
30use crate::policy::HashAlgoSecurity;
31
32#[derive(PartialEq, Eq, Hash)]
58pub struct Key6<P: KeyParts, R: KeyRole> {
59 pub(crate) common: Key4<P, R>,
60}
61
62impl<P, R> Clone for Key6<P, R>
70 where P: KeyParts, R: KeyRole
71{
72 fn clone(&self) -> Self {
73 Key6 {
74 common: self.common.clone(),
75 }
76 }
77}
78
79impl<P, R> fmt::Debug for Key6<P, R>
80where P: KeyParts,
81 R: KeyRole,
82{
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 f.debug_struct("Key6")
85 .field("fingerprint", &self.fingerprint())
86 .field("creation_time", &self.creation_time())
87 .field("pk_algo", &self.pk_algo())
88 .field("mpis", &self.mpis())
89 .field("secret", &self.optional_secret())
90 .finish()
91 }
92}
93
94impl<P, R> fmt::Display for Key6<P, R>
95where P: KeyParts,
96 R: KeyRole,
97{
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 write!(f, "{}", self.fingerprint())
100 }
101}
102
103impl<P, R> Key6<P, R>
104where P: KeyParts,
105 R: KeyRole,
106{
107 pub fn hash_algo_security(&self) -> HashAlgoSecurity {
133 HashAlgoSecurity::SecondPreImageResistance
134 }
135
136 pub fn public_cmp<PB, RB>(&self, b: &Key6<PB, RB>) -> Ordering
143 where PB: KeyParts,
144 RB: KeyRole,
145 {
146 self.mpis().cmp(b.mpis())
147 .then_with(|| self.creation_time().cmp(&b.creation_time()))
148 .then_with(|| self.pk_algo().cmp(&b.pk_algo()))
149 }
150
151 pub fn public_eq<PB, RB>(&self, b: &Key6<PB, RB>) -> bool
159 where PB: KeyParts,
160 RB: KeyRole,
161 {
162 self.public_cmp(b) == Ordering::Equal
163 }
164
165 pub fn public_hash<H>(&self, state: &mut H)
172 where H: Hasher
173 {
174 self.common.public_hash(state);
175 }
176}
177
178impl<P, R> Key6<P, R>
179where
180 P: KeyParts,
181 R: KeyRole,
182{
183 pub fn creation_time(&self) -> time::SystemTime {
185 self.common.creation_time()
186 }
187
188 pub(crate) fn creation_time_raw(&self) -> Timestamp {
193 self.common.creation_time_raw()
194 }
195
196 pub fn set_creation_time<T>(&mut self, timestamp: T)
208 -> Result<time::SystemTime>
209 where T: Into<time::SystemTime>
210 {
211 self.common.set_creation_time(timestamp)
212 }
213
214 pub fn pk_algo(&self) -> PublicKeyAlgorithm {
216 self.common.pk_algo()
217 }
218
219 pub fn set_pk_algo(&mut self, pk_algo: PublicKeyAlgorithm)
223 -> PublicKeyAlgorithm
224 {
225 self.common.set_pk_algo(pk_algo)
226 }
227
228 pub fn mpis(&self) -> &mpi::PublicKey {
230 self.common.mpis()
231 }
232
233 pub fn mpis_mut(&mut self) -> &mut mpi::PublicKey {
235 self.common.mpis_mut()
236 }
237
238 pub fn set_mpis(&mut self, mpis: mpi::PublicKey) -> mpi::PublicKey {
242 self.common.set_mpis(mpis)
243 }
244
245 pub fn has_secret(&self) -> bool {
247 self.common.has_secret()
248 }
249
250 pub fn has_unencrypted_secret(&self) -> bool {
256 self.common.has_unencrypted_secret()
257 }
258
259 pub fn optional_secret(&self) -> Option<&SecretKeyMaterial> {
261 self.common.optional_secret()
262 }
263
264 pub fn key_handle(&self) -> KeyHandle {
271 self.fingerprint().into()
272 }
273
274 pub fn fingerprint(&self) -> Fingerprint {
280 let fp = self.common.fingerprint.get_or_init(|| {
281 let mut h = HashAlgorithm::SHA256.context()
282 .expect("SHA256 is MTI for RFC9580")
283 .for_signature(6);
286
287 self.hash(&mut h).expect("v6 key hashing is infallible");
288
289 let mut digest = [0u8; 32];
290 let _ = h.digest(&mut digest);
291 Fingerprint::V6(digest)
292 });
293
294 debug_assert!(matches!(fp, Fingerprint::V6(_)));
301
302 fp.clone()
303 }
304
305 pub fn keyid(&self) -> KeyID {
311 self.fingerprint().into()
312 }
313
314 pub(crate) fn from_common(common: Key4<P, R>) -> Self {
317 Key6 { common }
318 }
319
320 pub(crate) fn make(creation_time: Timestamp,
325 pk_algo: PublicKeyAlgorithm,
326 mpis: mpi::PublicKey,
327 secret: Option<SecretKeyMaterial>)
328 -> Result<Self>
329 where
330 {
331 Ok(Key6 {
332 common: Key4::make(creation_time, pk_algo, mpis, secret)?,
333 })
334 }
335
336 pub(crate) fn role(&self) -> KeyRoleRT {
337 self.common.role()
338 }
339
340 pub(crate) fn set_role(&mut self, role: KeyRoleRT) {
341 self.common.set_role(role);
342 }
343}
344
345impl<R> Key6<key::PublicParts, R>
346where R: KeyRole,
347{
348 pub fn new<T>(creation_time: T, pk_algo: PublicKeyAlgorithm,
350 mpis: mpi::PublicKey)
351 -> Result<Self>
352 where T: Into<time::SystemTime>
353 {
354 Ok(Key6 {
355 common: Key4::new(creation_time, pk_algo, mpis)?,
356 })
357 }
358
359 pub fn import_public_x25519<T>(public_key: &[u8], ctime: T)
365 -> Result<Self>
366 where
367 T: Into<Option<time::SystemTime>>,
368 {
369 Ok(Key6 {
370 common: Key4::new(ctime.into().unwrap_or_else(crate::now),
371 PublicKeyAlgorithm::X25519,
372 mpi::PublicKey::X25519 {
373 u: public_key.try_into()?,
374 })?,
375 })
376 }
377
378 pub fn import_public_x448<T>(public_key: &[u8], ctime: T)
384 -> Result<Self>
385 where
386 T: Into<Option<time::SystemTime>>,
387 {
388 Ok(Key6 {
389 common: Key4::new(ctime.into().unwrap_or_else(crate::now),
390 PublicKeyAlgorithm::X448,
391 mpi::PublicKey::X448 {
392 u: Box::new(public_key.try_into()?),
393 })?,
394 })
395 }
396
397 pub fn import_public_ed25519<T>(public_key: &[u8], ctime: T) -> Result<Self>
403 where
404 T: Into<Option<time::SystemTime>>,
405 {
406 Ok(Key6 {
407 common: Key4::new(ctime.into().unwrap_or_else(crate::now),
408 PublicKeyAlgorithm::Ed25519,
409 mpi::PublicKey::Ed25519 {
410 a: public_key.try_into()?,
411 })?,
412 })
413 }
414
415 pub fn import_public_ed448<T>(public_key: &[u8], ctime: T) -> Result<Self>
421 where
422 T: Into<Option<time::SystemTime>>,
423 {
424 Ok(Key6 {
425 common: Key4::new(ctime.into().unwrap_or_else(crate::now),
426 PublicKeyAlgorithm::Ed448,
427 mpi::PublicKey::Ed448 {
428 a: Box::new(public_key.try_into()?),
429 })?,
430 })
431 }
432
433 pub fn import_public_rsa<T>(e: &[u8], n: &[u8], ctime: T)
440 -> Result<Self> where T: Into<Option<time::SystemTime>>
441 {
442 Ok(Key6 {
443 common: Key4::import_public_rsa(e, n, ctime)?,
444 })
445 }
446}
447
448impl<R> Key6<SecretParts, R>
449where R: KeyRole,
450{
451 pub fn with_secret<T>(creation_time: T, pk_algo: PublicKeyAlgorithm,
454 mpis: mpi::PublicKey,
455 secret: SecretKeyMaterial)
456 -> Result<Self>
457 where T: Into<time::SystemTime>
458 {
459 Ok(Key6 {
460 common: Key4::with_secret(creation_time, pk_algo, mpis, secret)?,
461 })
462 }
463
464 pub fn import_secret_x25519<T>(private_key: &[u8],
473 ctime: T)
474 -> Result<Self>
475 where
476 T: Into<Option<std::time::SystemTime>>,
477 {
478 use crate::crypto::backend::{Backend, interface::Asymmetric};
479
480 let private_key = Protected::from(private_key);
481 let public_key = Backend::x25519_derive_public(&private_key)?;
482
483 Self::with_secret(
484 ctime.into().unwrap_or_else(crate::now),
485 PublicKeyAlgorithm::X25519,
486 mpi::PublicKey::X25519 {
487 u: public_key,
488 },
489 mpi::SecretKeyMaterial::X25519 {
490 x: private_key.into(),
491 }.into())
492 }
493
494 pub fn import_secret_x448<T>(private_key: &[u8],
503 ctime: T)
504 -> Result<Self>
505 where
506 T: Into<Option<std::time::SystemTime>>,
507 {
508 use crate::crypto::backend::{Backend, interface::Asymmetric};
509
510 let private_key = Protected::from(private_key);
511 let public_key = Backend::x448_derive_public(&private_key)?;
512
513 Self::with_secret(
514 ctime.into().unwrap_or_else(crate::now),
515 PublicKeyAlgorithm::X448,
516 mpi::PublicKey::X448 {
517 u: Box::new(public_key),
518 },
519 mpi::SecretKeyMaterial::X448 {
520 x: private_key.into(),
521 }.into())
522 }
523
524 pub fn import_secret_ed25519<T>(private_key: &[u8], ctime: T)
530 -> Result<Self>
531 where
532 T: Into<Option<time::SystemTime>>,
533 {
534 use crate::crypto::backend::{Backend, interface::Asymmetric};
535
536 let private_key = Protected::from(private_key);
537 let public_key = Backend::ed25519_derive_public(&private_key)?;
538
539 Self::with_secret(
540 ctime.into().unwrap_or_else(crate::now),
541 PublicKeyAlgorithm::Ed25519,
542 mpi::PublicKey::Ed25519 {
543 a: public_key,
544 },
545 mpi::SecretKeyMaterial::Ed25519 {
546 x: private_key.into(),
547 }.into())
548 }
549
550 pub fn import_secret_ed448<T>(private_key: &[u8], ctime: T)
556 -> Result<Self>
557 where
558 T: Into<Option<time::SystemTime>>,
559 {
560 use crate::crypto::backend::{Backend, interface::Asymmetric};
561
562 let private_key = Protected::from(private_key);
563 let public_key = Backend::ed448_derive_public(&private_key)?;
564
565 Self::with_secret(
566 ctime.into().unwrap_or_else(crate::now),
567 PublicKeyAlgorithm::Ed448,
568 mpi::PublicKey::Ed448 {
569 a: Box::new(public_key),
570 },
571 mpi::SecretKeyMaterial::Ed448 {
572 x: private_key.into(),
573 }.into())
574 }
575
576 pub fn into_keypair(self) -> Result<KeyPair> {
584 let (key, secret) = self.take_secret();
585 let secret = match secret {
586 SecretKeyMaterial::Unencrypted(secret) => secret,
587 SecretKeyMaterial::Encrypted(_) =>
588 return Err(Error::InvalidArgument(
589 "secret key material is encrypted".into()).into()),
590 };
591
592 KeyPair::new(key.role_into_unspecified().into(), secret)
593 }
594}
595
596macro_rules! impl_common_secret_functions_v6 {
597 ($t: ident) => {
598 impl<R> Key6<$t, R>
600 where R: KeyRole,
601 {
602 pub fn take_secret(mut self)
604 -> (Key6<PublicParts, R>, Option<SecretKeyMaterial>)
605 {
606 let old = std::mem::replace(&mut self.common.secret, None);
607 (self.parts_into_public(), old)
608 }
609
610 pub fn add_secret(mut self, secret: SecretKeyMaterial)
613 -> (Key6<SecretParts, R>, Option<SecretKeyMaterial>)
614 {
615 let old = std::mem::replace(&mut self.common.secret, Some(secret));
616 (self.parts_into_secret().expect("secret just set"), old)
617 }
618
619 pub fn steal_secret(&mut self) -> Option<SecretKeyMaterial>
621 {
622 std::mem::replace(&mut self.common.secret, None)
623 }
624 }
625 }
626}
627impl_common_secret_functions_v6!(PublicParts);
628impl_common_secret_functions_v6!(UnspecifiedParts);
629
630impl<R> Key6<SecretParts, R>
632where R: KeyRole,
633{
634 pub fn secret(&self) -> &SecretKeyMaterial {
636 self.common.secret()
637 }
638
639 pub fn secret_mut(&mut self) -> &mut SecretKeyMaterial {
641 self.common.secret_mut()
642 }
643
644 pub fn take_secret(mut self)
646 -> (Key6<PublicParts, R>, SecretKeyMaterial)
647 {
648 let old = std::mem::replace(&mut self.common.secret, None);
649 (self.parts_into_public(),
650 old.expect("Key<SecretParts, _> has a secret key material"))
651 }
652
653 pub fn add_secret(mut self, secret: SecretKeyMaterial)
657 -> (Key6<SecretParts, R>, SecretKeyMaterial)
658 {
659 let old = std::mem::replace(&mut self.common.secret, Some(secret));
660 (self.parts_into_secret().expect("secret just set"),
661 old.expect("Key<SecretParts, _> has a secret key material"))
662 }
663
664 pub fn decrypt_secret(self, password: &Password) -> Result<Self> {
679 let (key, mut secret) = self.take_secret();
680 let key = Key::V6(key);
682 secret.decrypt_in_place(&key, password)?;
683 let key = if let Key::V6(k) = key { k } else { unreachable!() };
684 Ok(key.add_secret(secret).0)
685 }
686
687 pub fn encrypt_secret(self, password: &Password)
702 -> Result<Key6<SecretParts, R>>
703 {
704 let (key, mut secret) = self.take_secret();
705 let key = Key::V6(key);
707 secret.encrypt_in_place(&key, password)?;
708 let key = if let Key::V6(k) = key { k } else { unreachable!() };
709 Ok(key.add_secret(secret).0)
710 }
711}
712
713impl<P, R> From<Key6<P, R>> for super::Key<P, R>
714where P: KeyParts,
715 R: KeyRole,
716{
717 fn from(p: Key6<P, R>) -> Self {
718 super::Key::V6(p)
719 }
720}
721
722#[cfg(test)]
723use crate::packet::key::{
724 PrimaryRole,
725 SubordinateRole,
726 UnspecifiedRole,
727};
728
729#[cfg(test)]
730impl Arbitrary for Key6<PublicParts, PrimaryRole> {
731 fn arbitrary(g: &mut Gen) -> Self {
732 Key6::from_common(Key4::arbitrary(g))
733 }
734}
735
736#[cfg(test)]
737impl Arbitrary for Key6<PublicParts, SubordinateRole> {
738 fn arbitrary(g: &mut Gen) -> Self {
739 Key6::from_common(Key4::arbitrary(g))
740 }
741}
742
743#[cfg(test)]
744impl Arbitrary for Key6<PublicParts, UnspecifiedRole> {
745 fn arbitrary(g: &mut Gen) -> Self {
746 Key6::from_common(Key4::arbitrary(g))
747 }
748}
749
750#[cfg(test)]
751impl Arbitrary for Key6<SecretParts, PrimaryRole> {
752 fn arbitrary(g: &mut Gen) -> Self {
753 Key6::from_common(Key4::arbitrary(g))
754 }
755}
756
757#[cfg(test)]
758impl Arbitrary for Key6<SecretParts, SubordinateRole> {
759 fn arbitrary(g: &mut Gen) -> Self {
760 Key6::from_common(Key4::arbitrary(g))
761 }
762}
763
764
765#[cfg(test)]
766mod tests {
767 use std::time::Duration;
768 use std::time::UNIX_EPOCH;
769
770 use crate::crypto::S2K;
771 use crate::packet::Key;
772 use crate::packet::key;
773 use crate::packet::Packet;
774 use super::*;
775 use crate::PacketPile;
776 use crate::serialize::Serialize;
777 use crate::types::*;
778 use crate::parse::Parse;
779
780 #[test]
781 fn primary_key_encrypt_decrypt() -> Result<()> {
782 key_encrypt_decrypt::<PrimaryRole>()
783 }
784
785 #[test]
786 fn subkey_encrypt_decrypt() -> Result<()> {
787 key_encrypt_decrypt::<SubordinateRole>()
788 }
789
790 fn key_encrypt_decrypt<R>() -> Result<()>
791 where
792 R: KeyRole + PartialEq,
793 {
794 let mut g = quickcheck::Gen::new(256);
795 let p: Password = Vec::<u8>::arbitrary(&mut g).into();
796
797 let check = |key: Key6<SecretParts, R>| -> Result<()> {
798 let key: Key<_, _> = key.into();
799 let encrypted = key.clone().encrypt_secret(&p)?;
800 let decrypted = encrypted.decrypt_secret(&p)?;
801 assert_eq!(key, decrypted);
802 Ok(())
803 };
804
805 use crate::types::Curve::*;
806 for curve in vec![NistP256, NistP384, NistP521, Ed25519] {
807 if ! curve.is_supported() {
808 eprintln!("Skipping unsupported {}", curve);
809 continue;
810 }
811
812 let key: Key6<_, R>
813 = Key6::generate_ecc(true, curve.clone())?;
814 check(key)?;
815 }
816
817 for bits in vec![2048, 3072] {
818 if ! PublicKeyAlgorithm::RSAEncryptSign.is_supported() {
819 eprintln!("Skipping unsupported RSA");
820 continue;
821 }
822
823 let key: Key6<_, R>
824 = Key6::generate_rsa(bits)?;
825 check(key)?;
826 }
827
828 Ok(())
829 }
830
831 #[test]
832 fn eq() {
833 use crate::types::Curve::*;
834
835 for curve in vec![NistP256, NistP384, NistP521] {
836 if ! curve.is_supported() {
837 eprintln!("Skipping unsupported {}", curve);
838 continue;
839 }
840
841 let sign_key : Key6<_, key::UnspecifiedRole>
842 = Key6::generate_ecc(true, curve.clone()).unwrap();
843 let enc_key : Key6<_, key::UnspecifiedRole>
844 = Key6::generate_ecc(false, curve).unwrap();
845 let sign_clone = sign_key.clone();
846 let enc_clone = enc_key.clone();
847
848 assert_eq!(sign_key, sign_clone);
849 assert_eq!(enc_key, enc_clone);
850 }
851
852 for bits in vec![1024, 2048, 3072, 4096] {
853 if ! PublicKeyAlgorithm::RSAEncryptSign.is_supported() {
854 eprintln!("Skipping unsupported RSA");
855 continue;
856 }
857
858 let key : Key6<_, key::UnspecifiedRole>
859 = Key6::generate_rsa(bits).unwrap();
860 let clone = key.clone();
861 assert_eq!(key, clone);
862 }
863 }
864
865 #[test]
866 fn generate_roundtrip() {
867 use crate::types::Curve::*;
868
869 let keys = vec![NistP256, NistP384, NistP521].into_iter().flat_map(|cv|
870 {
871 if ! cv.is_supported() {
872 eprintln!("Skipping unsupported {}", cv);
873 return Vec::new();
874 }
875
876 let sign_key : Key6<key::SecretParts, key::PrimaryRole>
877 = Key6::generate_ecc(true, cv.clone()).unwrap();
878 let enc_key = Key6::generate_ecc(false, cv).unwrap();
879
880 vec![sign_key, enc_key]
881 }).chain(vec![1024, 2048, 3072, 4096].into_iter().filter_map(|b| {
882 Key6::generate_rsa(b).ok()
883 }));
884
885 for key in keys {
886 let mut b = Vec::new();
887 Packet::SecretKey(key.clone().into()).serialize(&mut b).unwrap();
888
889 let pp = PacketPile::from_bytes(&b).unwrap();
890 if let Some(Packet::SecretKey(Key::V6(ref parsed_key))) =
891 pp.path_ref(&[0])
892 {
893 assert_eq!(key.creation_time(), parsed_key.creation_time());
894 assert_eq!(key.pk_algo(), parsed_key.pk_algo());
895 assert_eq!(key.mpis(), parsed_key.mpis());
896 assert_eq!(key.secret(), parsed_key.secret());
897
898 assert_eq!(&key, parsed_key);
899 } else {
900 panic!("bad packet: {:?}", pp.path_ref(&[0]));
901 }
902
903 let mut b = Vec::new();
904 let pk4 : Key6<PublicParts, PrimaryRole> = key.clone().into();
905 Packet::PublicKey(pk4.into()).serialize(&mut b).unwrap();
906
907 let pp = PacketPile::from_bytes(&b).unwrap();
908 if let Some(Packet::PublicKey(Key::V6(ref parsed_key))) =
909 pp.path_ref(&[0])
910 {
911 assert!(! parsed_key.has_secret());
912
913 let key = key.take_secret().0;
914 assert_eq!(&key, parsed_key);
915 } else {
916 panic!("bad packet: {:?}", pp.path_ref(&[0]));
917 }
918 }
919 }
920
921 #[test]
922 fn encryption_roundtrip() {
923 use crate::crypto::SessionKey;
924 use crate::types::Curve::*;
925
926 let keys = vec![NistP256, NistP384, NistP521].into_iter()
927 .filter_map(|cv| {
928 Key6::generate_ecc(false, cv).ok()
929 }).chain(vec![1024, 2048, 3072, 4096].into_iter().filter_map(|b| {
930 Key6::generate_rsa(b).ok()
931 }));
932
933 for key in keys.into_iter() {
934 let key: Key<key::SecretParts, key::UnspecifiedRole> = key.into();
935 let mut keypair = key.clone().into_keypair().unwrap();
936 let cipher = SymmetricAlgorithm::AES256;
937 let sk = SessionKey::new(cipher.key_size().unwrap()).unwrap();
938
939 let pkesk = PKESK6::for_recipient(&sk, &key).unwrap();
940 let sk_ = pkesk.decrypt(&mut keypair, None)
941 .expect("keypair should be able to decrypt PKESK");
942 assert_eq!(sk, sk_);
943
944 let sk_ =
945 pkesk.decrypt(&mut keypair, Some(cipher)).unwrap();
946 assert_eq!(sk, sk_);
947 }
948 }
949
950 #[test]
951 fn signature_roundtrip() {
952 use crate::types::{Curve::*, SignatureType};
953
954 let keys = vec![NistP256, NistP384, NistP521].into_iter()
955 .filter_map(|cv| {
956 Key6::generate_ecc(true, cv).ok()
957 }).chain(vec![1024, 2048, 3072, 4096].into_iter().filter_map(|b| {
958 Key6::generate_rsa(b).ok()
959 }));
960
961 for key in keys.into_iter() {
962 let key: Key<key::SecretParts, key::UnspecifiedRole> = key.into();
963 let mut keypair = key.clone().into_keypair().unwrap();
964 let hash = HashAlgorithm::default();
965
966 let ctx = hash.context().unwrap().for_signature(key.version());
968 let sig = SignatureBuilder::new(SignatureType::Binary)
969 .sign_hash(&mut keypair, ctx).unwrap();
970
971 let ctx = hash.context().unwrap().for_signature(key.version());
973 sig.verify_hash(&key, ctx).unwrap();
974 }
975 }
976
977 #[test]
978 fn secret_encryption_roundtrip() {
979 use crate::types::Curve::*;
980 use crate::types::SymmetricAlgorithm::*;
981 use crate::types::AEADAlgorithm::*;
982
983 let keys = vec![NistP256, NistP384, NistP521].into_iter()
984 .filter_map(|cv| -> Option<Key<key::SecretParts, key::PrimaryRole>> {
985 Key6::generate_ecc(false, cv).map(Into::into).ok()
986 }).chain(vec![1024, 2048, 3072, 4096].into_iter().filter_map(|b| {
987 Key6::generate_rsa(b).map(Into::into).ok()
988 }));
989
990 for key in keys {
991 for (symm, aead) in [(AES128, None),
992 (AES128, Some(OCB)),
993 (AES256, Some(EAX))] {
994 if ! aead.map(|a| a.is_supported()).unwrap_or(true) {
995 continue;
996 }
997 assert!(! key.secret().is_encrypted());
998
999 let password = Password::from("foobarbaz");
1000 let mut encrypted_key = key.clone();
1001
1002 encrypted_key.secret_mut()
1003 .encrypt_in_place_with(&key, S2K::default(), symm, aead,
1004 &password).unwrap();
1005 assert!(encrypted_key.secret().is_encrypted());
1006
1007 encrypted_key.secret_mut()
1008 .decrypt_in_place(&key, &password).unwrap();
1009 assert!(! key.secret().is_encrypted());
1010 assert_eq!(key, encrypted_key);
1011 assert_eq!(key.secret(), encrypted_key.secret());
1012 }
1013 }
1014 }
1015
1016 #[test]
1017 fn encrypt_huge_plaintext() -> Result<()> {
1018 let sk = crate::crypto::SessionKey::new(256).unwrap();
1019
1020 if PublicKeyAlgorithm::RSAEncryptSign.is_supported() {
1021 let rsa2k: Key<SecretParts, UnspecifiedRole> =
1022 Key6::generate_rsa(2048)?.into();
1023 assert!(matches!(
1024 rsa2k.encrypt(&sk).unwrap_err().downcast().unwrap(),
1025 crate::Error::InvalidArgument(_)
1026 ));
1027 }
1028
1029 Ok(())
1030 }
1031
1032 #[test]
1033 fn issue_1016() {
1034 let mut g = quickcheck::Gen::new(256);
1039
1040 let mut key = Key6::<PublicParts, UnspecifiedRole>::arbitrary(&mut g);
1041 let fpr1 = key.fingerprint();
1042 if key.creation_time() == UNIX_EPOCH {
1043 key.set_creation_time(UNIX_EPOCH + Duration::new(1, 0)).expect("ok");
1044 } else {
1045 key.set_creation_time(UNIX_EPOCH).expect("ok");
1046 }
1047 assert_ne!(fpr1, key.fingerprint());
1048
1049 let mut key = Key6::<PublicParts, UnspecifiedRole>::arbitrary(&mut g);
1050 let fpr1 = key.fingerprint();
1051 key.set_pk_algo(PublicKeyAlgorithm::from(u8::from(key.pk_algo()) + 1));
1052 assert_ne!(fpr1, key.fingerprint());
1053
1054 let mut key = Key6::<PublicParts, UnspecifiedRole>::arbitrary(&mut g);
1055 let fpr1 = key.fingerprint();
1056 loop {
1057 let mpis2 = mpi::PublicKey::arbitrary(&mut g);
1058 if key.mpis() != &mpis2 {
1059 *key.mpis_mut() = mpis2;
1060 break;
1061 }
1062 }
1063 assert_ne!(fpr1, key.fingerprint());
1064
1065 let mut key = Key6::<PublicParts, UnspecifiedRole>::arbitrary(&mut g);
1066 let fpr1 = key.fingerprint();
1067 loop {
1068 let mpis2 = mpi::PublicKey::arbitrary(&mut g);
1069 if key.mpis() != &mpis2 {
1070 key.set_mpis(mpis2);
1071 break;
1072 }
1073 }
1074 assert_ne!(fpr1, key.fingerprint());
1075 }
1076
1077 #[test]
1080 fn ecc_support() -> Result<()> {
1081 for for_signing in [true, false] {
1082 for curve in Curve::variants()
1083 .filter(Curve::is_supported)
1084 {
1085 match curve {
1086 Curve::Cv25519 if for_signing => continue,
1087 Curve::Ed25519 if ! for_signing => continue,
1088 _ => (),
1089 }
1090
1091 eprintln!("curve {}, for signing {:?}", curve, for_signing);
1092 let key: Key<SecretParts, UnspecifiedRole> =
1093 Key6::generate_ecc(for_signing, curve.clone())?.into();
1094 let mut pair = key.into_keypair()?;
1095
1096 if for_signing {
1097 use crate::crypto::Signer;
1098 let hash = HashAlgorithm::default();
1099 let digest = hash.context()?
1100 .for_signature(pair.public().version())
1101 .into_digest()?;
1102 let sig = pair.sign(hash, &digest)?;
1103 pair.public().verify(&sig, hash, &digest)?;
1104 } else {
1105 use crate::crypto::{SessionKey, Decryptor};
1106 let sk = SessionKey::new(32).unwrap();
1107 let ciphertext = pair.public().encrypt(&sk)?;
1108 assert_eq!(pair.decrypt(&ciphertext, Some(sk.len()))?, sk);
1109 }
1110 }
1111 }
1112 Ok(())
1113 }
1114
1115 #[test]
1116 fn ecc_encoding() -> Result<()> {
1117 for for_signing in [true, false] {
1118 for curve in Curve::variants()
1119 .filter(Curve::is_supported)
1120 {
1121 match curve {
1122 Curve::Cv25519 if for_signing => continue,
1123 Curve::Ed25519 if ! for_signing => continue,
1124 _ => (),
1125 }
1126
1127 use crate::crypto::mpi::{Ciphertext, MPI, PublicKey};
1128 eprintln!("curve {}, for signing {:?}", curve, for_signing);
1129
1130 let key: Key<SecretParts, UnspecifiedRole> =
1131 Key6::generate_ecc(for_signing, curve.clone())?.into();
1132
1133 let uncompressed = |mpi: &MPI| mpi.value()[0] == 0x04;
1134
1135 match key.mpis() {
1136 PublicKey::X25519 { .. } if ! for_signing => (),
1137 PublicKey::X448 { .. } if ! for_signing => (),
1138 PublicKey::Ed25519 { .. } if for_signing => (),
1139 PublicKey::Ed448 { .. } if for_signing => (),
1140 PublicKey::ECDSA { curve: c, q } if for_signing => {
1141 assert!(c == &curve);
1142 assert!(c != &Curve::Ed25519);
1143 assert!(uncompressed(q));
1144 },
1145 PublicKey::ECDH { curve: c, q, .. } if ! for_signing => {
1146 assert!(c == &curve);
1147 assert!(c != &Curve::Cv25519);
1148 assert!(uncompressed(q));
1149
1150 use crate::crypto::SessionKey;
1151 let sk = SessionKey::new(32).unwrap();
1152 let ciphertext = key.encrypt(&sk)?;
1153 if let Ciphertext::ECDH { e, .. } = &ciphertext {
1154 assert!(uncompressed(e));
1155 } else {
1156 panic!("unexpected ciphertext: {:?}", ciphertext);
1157 }
1158 },
1159 mpi => unreachable!(
1160 "curve {}, mpi {:?}, for signing {:?}",
1161 curve, mpi, for_signing),
1162 }
1163 }
1164 }
1165 Ok(())
1166 }
1167
1168
1169 #[test]
1170 fn v6_key_fingerprint() -> Result<()> {
1171 let p = Packet::from_bytes("-----BEGIN PGP ARMORED FILE-----
1172
1173xjcGY4d/4xYAAAAtCSsGAQQB2kcPAQEHQPlNp7tI1gph5WdwamWH0DMZmbudiRoI
1174JC6thFQ9+JWj
1175=SgmS
1176-----END PGP ARMORED FILE-----")?;
1177 let k: &Key<PublicParts, PrimaryRole> = p.downcast_ref().unwrap();
1178 assert_eq!(k.fingerprint().to_string(),
1179 "4EADF309C6BC874AE04702451548F93F\
1180 96FA7A01D0A33B5AF7D4E379E0F9F8EE".to_string());
1181 Ok(())
1182 }
1183}