1use std::{
2 borrow::Cow,
3};
4
5use crate::Result;
6use crate::cert::prelude::*;
7use crate::packet::{
8 header::BodyLength,
9 key,
10 Key,
11 Signature,
12 Tag,
13};
14use crate::seal;
15use crate::serialize::{
16 PacketRef,
17 Marshal, MarshalInto,
18 NetLength,
19 generic_serialize_into, generic_export_into,
20};
21
22
23impl Cert {
24 pub fn exportable(&self) -> bool {
54 let pk = self.primary_key();
55
56 if pk.self_signatures().chain(pk.self_revocations())
57 .any(|sig| sig.exportable().is_ok())
58 {
59 true
61 } else if self.userids().any(|userid| {
62 userid.self_signatures()
63 .chain(userid.self_revocations())
64 .any(|sig| sig.exportable().is_ok())
65 }) {
66 true
68 } else if self.user_attributes().any(|ua| {
69 ua.self_signatures()
70 .chain(ua.self_revocations())
71 .any(|sig| sig.exportable().is_ok())
72 }) {
73 true
76 } else {
77 false
79 }
80 }
81
82 fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
101 -> Result<()>
102 {
103 if export && ! self.exportable() {
104 return Ok(())
105 }
106
107 let primary = self.primary_key();
108 PacketRef::PublicKey(primary.key())
109 .serialize(o)?;
110
111 let serialize_sig =
113 |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
114 {
115 if export {
116 if sig.exportable().is_ok() {
117 PacketRef::Signature(sig).export(o)?;
118 }
119 } else {
120 PacketRef::Signature(sig).serialize(o)?;
121 }
122 Ok(())
123 };
124
125 for s in primary.signatures() {
126 serialize_sig(o, s)?;
127 }
128
129 for u in self.userids() {
130 if export && ! u.self_signatures().chain(u.self_revocations()).any(
131 |s| s.exportable().is_ok())
132 {
133 continue;
135 }
136
137 PacketRef::UserID(u.userid()).serialize(o)?;
138 for s in u.signatures() {
139 serialize_sig(o, s)?;
140 }
141 }
142
143 for u in self.user_attributes() {
144 if export && ! u.self_signatures().chain(u.self_revocations()).any(
145 |s| s.exportable().is_ok())
146 {
147 continue;
149 }
150
151 PacketRef::UserAttribute(u.user_attribute()).serialize(o)?;
152 for s in u.signatures() {
153 serialize_sig(o, s)?;
154 }
155 }
156
157 for k in self.keys().subkeys() {
158 if export && ! k.self_signatures().chain(k.self_revocations()).any(
159 |s| s.exportable().is_ok())
160 {
161 continue;
163 }
164
165 PacketRef::PublicSubkey(k.key()).serialize(o)?;
166 for s in k.signatures() {
167 serialize_sig(o, s)?;
168 }
169 }
170
171 for u in self.unknowns() {
172 if export && ! u.certifications().any(
173 |s| s.exportable().is_ok())
174 {
175 continue;
177 }
178
179 PacketRef::Unknown(u.unknown()).serialize(o)?;
180
181 for s in u.signatures() {
182 serialize_sig(o, s)?;
183 }
184 }
185
186 for s in self.bad_signatures() {
187 serialize_sig(o, s)?;
188 }
189
190 Ok(())
191 }
192}
193
194impl crate::serialize::Serialize for Cert {}
195
196impl seal::Sealed for Cert {}
197impl Marshal for Cert {
198 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
199 self.serialize_common(o, false)
200 }
201
202 fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
203 self.serialize_common(o, true)
204 }
205}
206
207impl crate::serialize::SerializeInto for Cert {}
208
209impl MarshalInto for Cert {
210 fn serialized_len(&self) -> usize {
211 let mut l = 0;
212 let primary = self.primary_key();
213 l += PacketRef::PublicKey(primary.key()).serialized_len();
214
215 for s in primary.signatures() {
216 l += PacketRef::Signature(s).serialized_len();
217 }
218
219 for u in self.userids() {
220 l += PacketRef::UserID(u.userid()).serialized_len();
221
222 for s in u.signatures() {
223 l += PacketRef::Signature(s).serialized_len();
224 }
225 }
226
227 for u in self.user_attributes() {
228 l += PacketRef::UserAttribute(u.user_attribute()).serialized_len();
229
230 for s in u.signatures() {
231 l += PacketRef::Signature(s).serialized_len();
232 }
233 }
234
235 for k in self.keys().subkeys() {
236 l += PacketRef::PublicSubkey(k.key()).serialized_len();
237
238 for s in k.signatures() {
239 l += PacketRef::Signature(s).serialized_len();
240 }
241 }
242
243 for u in self.unknowns() {
244 l += PacketRef::Unknown(u.unknown()).serialized_len();
245
246 for s in u.signatures() {
247 l += PacketRef::Signature(s).serialized_len();
248 }
249 }
250
251 for s in self.bad_signatures() {
252 l += PacketRef::Signature(s).serialized_len();
253 }
254
255 l
256 }
257
258 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
259 generic_serialize_into(self, self.serialized_len(), buf)
260 }
261
262 fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
263 generic_export_into(self, self.serialized_len(), buf)
264 }
265}
266
267impl Cert {
268 pub fn as_tsk(&self) -> TSK {
274 TSK::new(self)
275 }
276
277 pub fn into_tsk(self) -> TSK<'static> {
283 TSK::from(self)
284 }
285}
286
287pub struct TSK<'a> {
314 pub(crate) cert: Cow<'a, Cert>,
315 filter: Box<dyn Fn(&key::UnspecifiedSecret) -> bool + Send + Sync + 'a>,
316 emit_stubs: bool,
317}
318
319impl PartialEq for TSK<'_> {
320 fn eq(&self, other: &Self) -> bool {
321 if self.cert != other.cert {
324 return false;
325 }
326
327 for (a, b) in self.cert.keys()
329 .zip(other.cert.keys())
330 {
331 match (a.has_secret()
332 && (self.filter)(a.key().parts_as_secret().expect("has secret")),
333 b.has_secret()
334 && (other.filter)(b.key().parts_as_secret().expect("has_secret")))
335 {
336 (true, true) => if a.key().optional_secret() != b.key().optional_secret() {
338 return false;
339 },
340 (false, false) => if self.emit_stubs != other.emit_stubs {
342 return false;
343 },
344 _ => return false,
346 }
347 }
348
349 true
351 }
352}
353
354impl From<Cert> for TSK<'_> {
355 fn from(c: Cert) -> Self {
356 Self {
357 cert: Cow::Owned(c),
358 filter: Box::new(|_| true),
359 emit_stubs: false,
360 }
361 }
362}
363
364impl<'a> TSK<'a> {
365 fn new(cert: &'a Cert) -> Self {
367 Self {
368 cert: Cow::Borrowed(cert),
369 filter: Box::new(|_| true),
370 emit_stubs: false,
371 }
372 }
373
374 pub(crate) fn decompose(self)
376 -> (Cow<'a, Cert>,
377 Box<dyn Fn(&key::UnspecifiedSecret) -> bool + Send + Sync + 'a>,
378 bool)
379 {
380 (self.cert, self.filter, self.emit_stubs)
381 }
382
383 pub(crate) fn emits_secret_key_packets(&self) -> bool {
390 self.emit_stubs
391 || self.cert.keys().secret().any(|skb| (self.filter)(skb.key()))
392 }
393
394 pub fn set_filter<P>(mut self, predicate: P) -> Self
425 where P: Fn(&key::UnspecifiedSecret)-> bool + Send + Sync + 'a
426 {
427 self.filter = Box::new(predicate);
428 self
429 }
430
431 pub fn emit_secret_key_stubs(mut self, emit_stubs: bool) -> Self {
504 self.emit_stubs = emit_stubs;
505 self
506 }
507
508 pub(crate) fn add_stub<P, R>(key: Key<P, R>) -> key::UnspecifiedSecret
510 where
511 P: key::KeyParts,
512 R: key::KeyRole,
513 {
514 Self::add_stub_internal(key.parts_into_unspecified()
515 .role_into_unspecified())
516 }
517
518
519 pub(crate) fn add_stub_internal(key: key::UnspecifiedKey) -> key::UnspecifiedSecret
521 {
522
523 let stub = crate::crypto::S2K::Private {
525 tag: 101,
526 parameters: Some(vec![
527 0, 0x47, 0x4e, 0x55, 1 ].into()),
533 };
534 key.add_secret(key::SecretKeyMaterial::Encrypted(
535 key::Encrypted::new(
536 stub, 0.into(),
537 Some(crate::crypto::mpi::SecretKeyChecksum::Sum16),
541 vec![].into())))
542 .0.into()
543 }
544
545 fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
551 -> Result<()>
552 {
553 let serialize_sig =
555 |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
556 {
557 if export {
558 if sig.exportable().is_ok() {
559 PacketRef::Signature(sig).export(o)?;
560 }
561 } else {
562 PacketRef::Signature(sig).serialize(o)?;
563 }
564 Ok(())
565 };
566
567 let serialize_key =
569 |o: &mut dyn std::io::Write, key: &'a key::UnspecifiedKey,
570 tag_public, tag_secret|
571 {
572 let tag = if key.has_secret()
574 && (self.filter)(key.try_into().expect("checked for secrets"))
575 {
576 tag_secret
577 } else {
578 tag_public
579 };
580
581 if self.emit_stubs && (tag == Tag::PublicKey
582 || tag == Tag::PublicSubkey) {
583 let key_with_stub = Self::add_stub(key.clone());
584 return match tag {
585 Tag::PublicKey =>
586 crate::Packet::SecretKey(key_with_stub.into())
587 .serialize(o),
588 Tag::PublicSubkey =>
589 crate::Packet::SecretSubkey(key_with_stub.into())
590 .serialize(o),
591 _ => unreachable!(),
592 };
593 }
594
595 match tag {
596 Tag::PublicKey =>
597 PacketRef::PublicKey(key.into()).serialize(o),
598 Tag::PublicSubkey =>
599 PacketRef::PublicSubkey(key.into()).serialize(o),
600 Tag::SecretKey => {
601 PacketRef::SecretKey(
602 key.try_into().expect("checked for secrets"))
603 .serialize(o)
604 }
605 Tag::SecretSubkey => {
606 PacketRef::SecretSubkey(
607 key.try_into().expect("checked for secrets"))
608 .serialize(o)
609 }
610 _ => unreachable!(),
611 }
612 };
613
614 if export && ! self.cert.exportable() {
615 return Ok(())
616 }
617
618 let primary = self.cert.primary_key();
619 serialize_key(o, primary.key().into(),
620 Tag::PublicKey, Tag::SecretKey)?;
621
622 for s in primary.signatures() {
623 serialize_sig(o, s)?;
624 }
625
626 for u in self.cert.userids() {
627 if export && ! u.self_signatures().chain(u.self_revocations()).any(
628 |s| s.exportable().is_ok())
629 {
630 continue;
632 }
633
634 PacketRef::UserID(u.userid()).serialize(o)?;
635 for s in u.signatures() {
636 serialize_sig(o, s)?;
637 }
638 }
639
640 for u in self.cert.user_attributes() {
641 if export && ! u.self_signatures().chain(u.self_revocations()).any(
642 |s| s.exportable().is_ok())
643 {
644 continue;
646 }
647
648 PacketRef::UserAttribute(u.user_attribute()).serialize(o)?;
649 for s in u.signatures() {
650 serialize_sig(o, s)?;
651 }
652 }
653
654 for k in self.cert.keys().subkeys() {
655 if export && ! k.self_signatures().chain(k.self_revocations()).any(
656 |s| s.exportable().is_ok())
657 {
658 continue;
660 }
661
662 serialize_key(o, k.key().into(),
663 Tag::PublicSubkey, Tag::SecretSubkey)?;
664 for s in k.signatures() {
665 serialize_sig(o, s)?;
666 }
667 }
668
669 for u in self.cert.unknowns() {
670 if export && ! u.certifications().any(
671 |s| s.exportable().is_ok())
672 {
673 continue;
675 }
676
677 PacketRef::Unknown(u.unknown()).serialize(o)?;
678
679 for s in u.signatures() {
680 serialize_sig(o, s)?;
681 }
682 }
683
684 for s in self.cert.bad_signatures() {
685 serialize_sig(o, s)?;
686 }
687
688 Ok(())
689 }
690}
691
692impl<'a> crate::serialize::Serialize for TSK<'a> {}
693
694impl<'a> seal::Sealed for TSK<'a> {}
695impl<'a> Marshal for TSK<'a> {
696 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
697 self.serialize_common(o, false)
698 }
699
700 fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
701 self.serialize_common(o, true)
702 }
703}
704
705impl<'a> crate::serialize::SerializeInto for TSK<'a> {}
706
707impl<'a> MarshalInto for TSK<'a> {
708 fn serialized_len(&self) -> usize {
709 let mut l = 0;
710
711 let serialized_len_key
713 = |key: &'a key::UnspecifiedKey, tag_public, tag_secret|
714 {
715 let tag = if key.has_secret() && (self.filter)(key.try_into().expect("have secrets")) {
717 tag_secret
718 } else {
719 tag_public
720 };
721
722 if self.emit_stubs && (tag == Tag::PublicKey
723 || tag == Tag::PublicSubkey) {
724 let l = key.parts_as_public().net_len()
728 + match key.version() {
729 4 => 8,
730 6 => 12,
731 _ => 0, };
733 return 1 + BodyLength::Full(l as u32).serialized_len()
735 + l;
736 }
737
738 let packet = match tag {
739 Tag::PublicKey => PacketRef::PublicKey(key.into()),
740 Tag::PublicSubkey => PacketRef::PublicSubkey(key.into()),
741 Tag::SecretKey => {
742 PacketRef::SecretKey(
743 key.try_into().expect("checked for secrets"))
744 }
745 Tag::SecretSubkey => {
746 PacketRef::SecretSubkey(
747 key.try_into().expect("checked for secrets"))
748 }
749 _ => unreachable!(),
750 };
751
752 packet.serialized_len()
753 };
754
755 let primary = self.cert.primary_key();
756 l += serialized_len_key(primary.key().into(),
757 Tag::PublicKey, Tag::SecretKey);
758
759 for s in primary.signatures() {
760 l += PacketRef::Signature(s).serialized_len();
761 }
762
763 for u in self.cert.userids() {
764 l += PacketRef::UserID(u.userid()).serialized_len();
765
766 for s in u.signatures() {
767 l += PacketRef::Signature(s).serialized_len();
768 }
769 }
770
771 for u in self.cert.user_attributes() {
772 l += PacketRef::UserAttribute(u.user_attribute()).serialized_len();
773
774 for s in u.signatures() {
775 l += PacketRef::Signature(s).serialized_len();
776 }
777 }
778
779 for k in self.cert.keys().subkeys() {
780 l += serialized_len_key(k.key().into(),
781 Tag::PublicSubkey, Tag::SecretSubkey);
782
783 for s in k.signatures() {
784 l += PacketRef::Signature(s).serialized_len();
785 }
786 }
787
788 for u in self.cert.unknowns() {
789 l += PacketRef::Unknown(u.unknown()).serialized_len();
790
791 for s in u.signatures() {
792 l += PacketRef::Signature(s).serialized_len();
793 }
794 }
795
796 for s in self.cert.bad_signatures() {
797 l += PacketRef::Signature(s).serialized_len();
798 }
799
800 l
801 }
802
803 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
804 generic_serialize_into(self, self.serialized_len(), buf)
805 }
806
807 fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
808 generic_export_into(self, self.serialized_len(), buf)
809 }
810}
811
812#[cfg(test)]
813mod test {
814 use super::*;
815 use crate::vec_truncate;
816 use crate::parse::Parse;
817 use crate::packet::key;
818 use crate::policy::StandardPolicy as P;
819
820 #[test]
823 fn roundtrip_cert() {
824 for test in crate::tests::CERTS {
825 let cert = match Cert::from_bytes(test.bytes) {
826 Ok(t) => t,
827 Err(_) => continue,
828 };
829 assert!(! cert.is_tsk());
830 let buf = cert.as_tsk().to_vec().unwrap();
831 let cert_ = Cert::from_bytes(&buf).unwrap();
832
833 assert_eq!(cert, cert_, "roundtripping {}.pgp failed", test);
834 }
835 }
836
837 #[test]
840 fn roundtrip_tsk() {
841 for test in crate::tests::TSKS {
842 let cert = Cert::from_bytes(test.bytes).unwrap();
843 assert!(cert.is_tsk());
844
845 let mut buf = Vec::new();
846 cert.as_tsk().serialize(&mut buf).unwrap();
847 let cert_ = Cert::from_bytes(&buf).unwrap();
848
849 assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test);
850
851 let mut buf = Vec::new();
853 cert.as_tsk().set_filter(|_| true).serialize(&mut buf).unwrap();
854 let cert_ = Cert::from_bytes(&buf).unwrap();
855
856 assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test);
857 }
858 }
859
860 #[test]
863 fn reduce_to_cert_serialize() {
864 for test in crate::tests::TSKS {
865 let cert = Cert::from_bytes(test.bytes).unwrap();
866 assert!(cert.is_tsk());
867
868 let mut buf_cert = Vec::new();
870 cert.serialize(&mut buf_cert).unwrap();
871
872 let mut buf_tsk = Vec::new();
875 cert.as_tsk().set_filter(|_| false).serialize(&mut buf_tsk).unwrap();
876
877 let cert_ = Cert::from_bytes(&buf_cert).unwrap();
879 let tsk_ = Cert::from_bytes(&buf_tsk).unwrap();
880 assert_eq!(cert_, tsk_,
881 "reducing failed on {}-private.pgp: not Cert::eq",
882 test);
883
884 assert_eq!(buf_cert, buf_tsk,
886 "reducing failed on {}-private.pgp: serialized identity",
887 test);
888 }
889 }
890
891 #[test]
892 fn export() {
893 use crate::Packet;
894 use crate::cert::prelude::*;
895 use crate::types::{Curve, KeyFlags, SignatureType};
896 use crate::packet::{
897 signature, UserID, user_attribute::{UserAttribute, Subpacket},
898 key::Key6,
899 };
900
901 let p = &P::new();
902
903 let (cert, _) = CertBuilder::new().generate().unwrap();
904 let mut keypair = cert.primary_key().key().clone().parts_into_secret()
905 .unwrap().into_keypair().unwrap();
906
907 let key: key::SecretSubkey =
908 Key6::generate_ecc(false, Curve::Cv25519).unwrap().into();
909 let key_binding = key.bind(
910 &mut keypair, &cert,
911 signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
912 .set_key_flags(
913 KeyFlags::empty().set_transport_encryption())
914 .unwrap()
915 .set_exportable_certification(false).unwrap()).unwrap();
916
917 let uid = UserID::from("foo");
918 let uid_binding = uid.bind(
919 &mut keypair, &cert,
920 signature::SignatureBuilder::from(
921 cert.primary_key().with_policy(p, None).unwrap()
922 .direct_key_signature().unwrap().clone())
923 .set_type(SignatureType::PositiveCertification)
924 .preserve_signature_creation_time().unwrap()
925 .set_exportable_certification(false).unwrap()).unwrap();
926
927 let ua = UserAttribute::new(&[
928 Subpacket::Unknown(2, b"foo".to_vec().into_boxed_slice()),
929 ]).unwrap();
930 let ua_binding = ua.bind(
931 &mut keypair, &cert,
932 signature::SignatureBuilder::from(
933 cert.primary_key().with_policy(p, None).unwrap()
934 .direct_key_signature().unwrap().clone())
935 .set_type(SignatureType::PositiveCertification)
936 .preserve_signature_creation_time().unwrap()
937 .set_exportable_certification(false).unwrap()).unwrap();
938
939 let cert = cert.insert_packets(vec![
940 Packet::SecretSubkey(key), key_binding.into(),
941 uid.into(), uid_binding.into(),
942 ua.into(), ua_binding.into(),
943 ]).unwrap().0;
944
945 assert_eq!(cert.subkeys().count(), 1);
946 cert.subkeys().next().unwrap().binding_signature(p, None).unwrap();
947 assert_eq!(cert.userids().count(), 1);
948 assert!(cert.userids().with_policy(p, None).next().is_some());
949 assert_eq!(cert.user_attributes().count(), 1);
950 assert!(cert.user_attributes().with_policy(p, None).next().is_some());
951
952 let mut buf = Vec::new();
955 cert.export(&mut buf).unwrap();
956 let cert_ = Cert::from_bytes(&buf).unwrap();
957 assert_eq!(cert_.subkeys().count(), 0);
958 assert_eq!(cert_.userids().count(), 0);
959 assert_eq!(cert_.user_attributes().count(), 0);
960
961 let mut buf = vec![0; cert.serialized_len()];
962 let l = cert.export_into(&mut buf).unwrap();
963 vec_truncate(&mut buf, l);
964 let cert_ = Cert::from_bytes(&buf).unwrap();
965 assert_eq!(cert_.subkeys().count(), 0);
966 assert_eq!(cert_.userids().count(), 0);
967 assert_eq!(cert_.user_attributes().count(), 0);
968
969 let cert_ = Cert::from_bytes(&cert.export_to_vec().unwrap()).unwrap();
970 assert_eq!(cert_.subkeys().count(), 0);
971 assert_eq!(cert_.userids().count(), 0);
972 assert_eq!(cert_.user_attributes().count(), 0);
973
974 let mut buf = Vec::new();
976 cert.armored().export(&mut buf).unwrap();
977 let cert_ = Cert::from_bytes(&buf).unwrap();
978 assert_eq!(cert_.subkeys().count(), 0);
979 assert_eq!(cert_.userids().count(), 0);
980 assert_eq!(cert_.user_attributes().count(), 0);
981
982 let mut buf = vec![0; cert.serialized_len()];
983 let l = cert.armored().export_into(&mut buf).unwrap();
984 vec_truncate(&mut buf, l);
985 let cert_ = Cert::from_bytes(&buf).unwrap();
986 assert_eq!(cert_.subkeys().count(), 0);
987 assert_eq!(cert_.userids().count(), 0);
988 assert_eq!(cert_.user_attributes().count(), 0);
989
990 let cert_ =
991 Cert::from_bytes(&cert.armored().export_to_vec().unwrap()).unwrap();
992 assert_eq!(cert_.subkeys().count(), 0);
993 assert_eq!(cert_.userids().count(), 0);
994 assert_eq!(cert_.user_attributes().count(), 0);
995
996 let mut buf = Vec::new();
998 cert.as_tsk().export(&mut buf).unwrap();
999 let cert_ = Cert::from_bytes(&buf).unwrap();
1000 assert_eq!(cert_.subkeys().count(), 0);
1001 assert_eq!(cert_.userids().count(), 0);
1002 assert_eq!(cert_.user_attributes().count(), 0);
1003
1004 let mut buf = vec![0; cert.serialized_len()];
1005 let l = cert.as_tsk().export_into(&mut buf).unwrap();
1006 vec_truncate(&mut buf, l);
1007 let cert_ = Cert::from_bytes(&buf).unwrap();
1008 assert_eq!(cert_.subkeys().count(), 0);
1009 assert_eq!(cert_.userids().count(), 0);
1010 assert_eq!(cert_.user_attributes().count(), 0);
1011
1012 let cert_ =
1013 Cert::from_bytes(&cert.as_tsk().export_to_vec().unwrap()).unwrap();
1014 assert_eq!(cert_.subkeys().count(), 0);
1015 assert_eq!(cert_.userids().count(), 0);
1016 assert_eq!(cert_.user_attributes().count(), 0);
1017 }
1018
1019 #[test]
1021 fn issue_613() -> Result<()> {
1022 use crate::packet::key::*;
1023 use crate::{types::*, crypto::S2K};
1024 use crate::{*, cert::*, parse::Parse};
1025 let p = &crate::policy::StandardPolicy::new();
1026
1027 let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
1028 assert_eq!(cert.keys().with_policy(p, None)
1029 .alive().revoked(false).unencrypted_secret().count(), 2);
1030
1031 let buf = cert.as_tsk()
1033 .set_filter(|k| k.fingerprint() != cert.fingerprint())
1034 .emit_secret_key_stubs(true)
1035 .to_vec()?;
1036
1037 let cert_ = Cert::from_bytes(&buf)?;
1039
1040 assert!(cert_.primary_key().has_secret());
1042 assert_eq!(cert_.keys().with_policy(p, None)
1043 .alive().revoked(false).unencrypted_secret().count(), 1);
1044 if let Some(SecretKeyMaterial::Encrypted(sec)) =
1045 cert_.primary_key().key().optional_secret()
1046 {
1047 assert_eq!(sec.algo(), SymmetricAlgorithm::Unencrypted);
1048 if let S2K::Private { tag, .. } = sec.s2k() {
1049 assert_eq!(*tag, 101);
1050 } else {
1051 panic!("expected proprietary S2K type");
1052 }
1053 } else {
1054 panic!("expected ''encrypted'' secret key stub");
1055 }
1056
1057 let buf_ = cert_.as_tsk().to_vec()?;
1059 assert_eq!(buf, buf_);
1060 Ok(())
1061 }
1062
1063 #[test]
1065 fn issue_701() -> Result<()> {
1066 let cert_0 = Cert::from_bytes(crate::tests::key("testy.pgp"))?;
1067 let cert_1 = Cert::from_bytes(crate::tests::key("testy.pgp"))?;
1068 let tsk_0 = Cert::from_bytes(crate::tests::key("testy-private.pgp"))?;
1069 let tsk_1 = Cert::from_bytes(crate::tests::key("testy-private.pgp"))?;
1070
1071 macro_rules! check {
1074 ($a: expr, $b: expr, $expectation: expr) => {{
1075 let a = $a;
1076 let b = $b;
1077 let eq = a == b;
1078 let serialized_eq = a.to_vec()? == b.to_vec()?;
1079 let armored_eq = a.armored().to_vec()? == b.armored().to_vec()?;
1080 assert_eq!(serialized_eq, eq);
1081 assert_eq!(armored_eq, eq);
1082 assert_eq!(eq, $expectation);
1083 }};
1084 }
1085
1086 check!(&cert_0, &cert_1, true);
1090 check!(&cert_0, &tsk_0, true);
1091
1092 let no_secrets = |_: &_| false;
1094
1095 check!(tsk_0.as_tsk(), tsk_1.as_tsk(), true);
1097
1098 check!(tsk_0.as_tsk().set_filter(no_secrets),
1100 tsk_1.as_tsk().set_filter(no_secrets),
1101 true);
1102
1103 check!(
1106 tsk_0.as_tsk().emit_secret_key_stubs(true),
1107 tsk_1.as_tsk(),
1108 true);
1109
1110 check!(
1112 tsk_0.as_tsk().emit_secret_key_stubs(true).set_filter(no_secrets),
1113 tsk_1.as_tsk(),
1114 false);
1115
1116 check!(cert_0.as_tsk(), tsk_0.as_tsk(), false);
1119
1120 check!(cert_0.as_tsk(),
1122 tsk_0.as_tsk().set_filter(no_secrets),
1123 true);
1124
1125 Ok(())
1126 }
1127
1128 #[test]
1129 fn issue_1075() -> Result<()> {
1130 let cert = Cert::from_bytes(crate::tests::key("testy.pgp"))?;
1131 let tsk = Cert::from_bytes(crate::tests::key("testy-private.pgp"))?;
1132
1133 let no_secrets = |_: &_| false;
1135
1136 assert!(! cert.as_tsk().emits_secret_key_packets());
1137 assert!(cert.as_tsk().emit_secret_key_stubs(true)
1138 .emits_secret_key_packets());
1139 assert!(tsk.as_tsk().emits_secret_key_packets());
1140 assert!(! tsk.as_tsk().set_filter(no_secrets)
1141 .emits_secret_key_packets());
1142
1143 assert!(cert.armored().to_vec()? != tsk.as_tsk().armored().to_vec()?);
1144 assert_eq!(cert.armored().to_vec()?,
1145 cert.as_tsk().armored().to_vec()?);
1146 assert_eq!(cert.armored().to_vec()?,
1147 tsk.as_tsk().set_filter(no_secrets).armored().to_vec()?);
1148
1149 Ok(())
1150 }
1151
1152 #[test]
1153 fn into_packets() -> Result<()> {
1154 let cert = Cert::from_bytes(crate::tests::key("testy-private.pgp"))?;
1155
1156 fn t(tsk: TSK) {
1157 let a = tsk.to_vec().unwrap();
1158 let b = {
1159 let mut b = Vec::new();
1160 tsk.into_packets().for_each(|p| p.serialize(&mut b).unwrap());
1161 b
1162 };
1163 assert_eq!(a, b);
1164 }
1165
1166 let tsk = cert.clone().into_tsk();
1167 t(tsk);
1168
1169 let tsk = cert.clone().into_tsk().set_filter(|_| false);
1170 t(tsk);
1171
1172 let tsk = cert.clone().into_tsk()
1173 .set_filter(|k| k.fingerprint() == cert.fingerprint());
1174 t(tsk);
1175
1176 let tsk = cert.clone().into_tsk()
1177 .set_filter(|k| k.fingerprint() == cert.fingerprint())
1178 .emit_secret_key_stubs(true);
1179 t(tsk);
1180
1181 Ok(())
1182 }
1183}