1 use crate::Result;
2 use crate::cert::prelude::*;
3 use crate::packet::{key, Signature, Tag};
4 use crate::serialize::{
5     PacketRef,
6     Marshal, MarshalInto,
7     generic_serialize_into, generic_export_into,
8 };
9 
10 
11 impl Cert {
12     /// Serializes or exports the Cert.
13     ///
14     /// If `export` is true, then non-exportable signatures are not
15     /// written, and components without any exportable binding
16     /// signature or revocation are not exported.
17     ///
18     /// The signatures are ordered from authenticated and most
19     /// important to not authenticated and most likely to be abused.
20     /// The order is:
21     ///
22     ///   - Self revocations first.  They are authenticated and the
23     ///     most important information.
24     ///   - Self signatures.  They are authenticated.
25     ///   - Other signatures.  They are not authenticated at this point.
26     ///   - Other revocations.  They are not authenticated, and likely
27     ///     not well supported in other implementations, hence the
28     ///     least reliable way of revoking keys and therefore least
29     ///     useful and most likely to be abused.
serialize_common(&self, o: &mut dyn std::io::Write, export: bool) -> Result<()>30     fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
31                         -> Result<()>
32     {
33         let primary = self.primary_key();
34         PacketRef::PublicKey(primary.key())
35             .serialize(o)?;
36 
37         // Writes a signature if it is exportable or `! export`.
38         let serialize_sig =
39             |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
40         {
41             if export {
42                 if sig.exportable().is_ok() {
43                     PacketRef::Signature(sig).export(o)?;
44                 }
45             } else {
46                 PacketRef::Signature(sig).serialize(o)?;
47             }
48             Ok(())
49         };
50 
51         for s in primary.self_revocations() {
52             serialize_sig(o, s)?;
53         }
54         for s in primary.self_signatures() {
55             serialize_sig(o, s)?;
56         }
57         for s in primary.certifications() {
58             serialize_sig(o, s)?;
59         }
60         for s in primary.other_revocations() {
61             serialize_sig(o, s)?;
62         }
63 
64         for u in self.userids() {
65             if export && ! u.self_signatures().iter().chain(u.self_revocations()).any(
66                 |s| s.exportable().is_ok())
67             {
68                 // No exportable selfsig on this component, skip it.
69                 continue;
70             }
71 
72             PacketRef::UserID(u.userid()).serialize(o)?;
73             for s in u.self_revocations() {
74                 serialize_sig(o, s)?;
75             }
76             for s in u.self_signatures() {
77                 serialize_sig(o, s)?;
78             }
79             for s in u.certifications() {
80                 serialize_sig(o, s)?;
81             }
82             for s in u.other_revocations() {
83                 serialize_sig(o, s)?;
84             }
85         }
86 
87         for u in self.user_attributes() {
88             if export && ! u.self_signatures().iter().chain(u.self_revocations()).any(
89                 |s| s.exportable().is_ok())
90             {
91                 // No exportable selfsig on this component, skip it.
92                 continue;
93             }
94 
95             PacketRef::UserAttribute(u.user_attribute()).serialize(o)?;
96             for s in u.self_revocations() {
97                 serialize_sig(o, s)?;
98             }
99             for s in u.self_signatures() {
100                 serialize_sig(o, s)?;
101             }
102             for s in u.certifications() {
103                 serialize_sig(o, s)?;
104             }
105             for s in u.other_revocations() {
106                 serialize_sig(o, s)?;
107             }
108         }
109 
110         for k in self.subkeys() {
111             if export && ! k.self_signatures().iter().chain(k.self_revocations()).any(
112                 |s| s.exportable().is_ok())
113             {
114                 // No exportable selfsig on this component, skip it.
115                 continue;
116             }
117 
118             PacketRef::PublicSubkey(k.key()).serialize(o)?;
119             for s in k.self_revocations() {
120                 serialize_sig(o, s)?;
121             }
122             for s in k.self_signatures() {
123                 serialize_sig(o, s)?;
124             }
125             for s in k.certifications() {
126                 serialize_sig(o, s)?;
127             }
128             for s in k.other_revocations() {
129                 serialize_sig(o, s)?;
130             }
131         }
132 
133         for u in self.unknowns() {
134             if export && ! u.certifications().iter().any(
135                 |s| s.exportable().is_ok())
136             {
137                 // No exportable selfsig on this component, skip it.
138                 continue;
139             }
140 
141             PacketRef::Unknown(u.unknown()).serialize(o)?;
142 
143             for s in u.self_revocations() {
144                 serialize_sig(o, s)?;
145             }
146             for s in u.self_signatures() {
147                 serialize_sig(o, s)?;
148             }
149             for s in u.certifications() {
150                 serialize_sig(o, s)?;
151             }
152             for s in u.other_revocations() {
153                 serialize_sig(o, s)?;
154             }
155         }
156 
157         for s in self.bad_signatures() {
158             serialize_sig(o, s)?;
159         }
160 
161         Ok(())
162     }
163 }
164 
165 impl crate::serialize::Serialize for Cert {}
166 
167 impl Marshal for Cert {
serialize(&self, o: &mut dyn std::io::Write) -> Result<()>168     fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
169         self.serialize_common(o, false)
170     }
171 
export(&self, o: &mut dyn std::io::Write) -> Result<()>172     fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
173         self.serialize_common(o, true)
174     }
175 }
176 
177 impl crate::serialize::SerializeInto for Cert {}
178 
179 impl MarshalInto for Cert {
serialized_len(&self) -> usize180     fn serialized_len(&self) -> usize {
181         let mut l = 0;
182         let primary = self.primary_key();
183         l += PacketRef::PublicKey(primary.key()).serialized_len();
184 
185         for s in primary.self_revocations() {
186             l += PacketRef::Signature(s).serialized_len();
187         }
188         for s in primary.self_signatures() {
189             l += PacketRef::Signature(s).serialized_len();
190         }
191         for s in primary.certifications() {
192             l += PacketRef::Signature(s).serialized_len();
193         }
194         for s in primary.other_revocations() {
195             l += PacketRef::Signature(s).serialized_len();
196         }
197 
198         for u in self.userids() {
199             l += PacketRef::UserID(u.userid()).serialized_len();
200 
201             for s in u.self_revocations() {
202                 l += PacketRef::Signature(s).serialized_len();
203             }
204             for s in u.self_signatures() {
205                 l += PacketRef::Signature(s).serialized_len();
206             }
207             for s in u.certifications() {
208                 l += PacketRef::Signature(s).serialized_len();
209             }
210             for s in u.other_revocations() {
211                 l += PacketRef::Signature(s).serialized_len();
212             }
213         }
214 
215         for u in self.user_attributes() {
216             l += PacketRef::UserAttribute(u.user_attribute()).serialized_len();
217 
218             for s in u.self_revocations() {
219                 l += PacketRef::Signature(s).serialized_len();
220             }
221             for s in u.self_signatures() {
222                 l += PacketRef::Signature(s).serialized_len();
223             }
224             for s in u.certifications() {
225                 l += PacketRef::Signature(s).serialized_len();
226             }
227             for s in u.other_revocations() {
228                 l += PacketRef::Signature(s).serialized_len();
229             }
230         }
231 
232         for k in self.subkeys() {
233             l += PacketRef::PublicSubkey(k.key()).serialized_len();
234 
235             for s in k.self_revocations() {
236                 l += PacketRef::Signature(s).serialized_len();
237             }
238             for s in k.self_signatures() {
239                 l += PacketRef::Signature(s).serialized_len();
240             }
241             for s in k.certifications() {
242                 l += PacketRef::Signature(s).serialized_len();
243             }
244             for s in k.other_revocations() {
245                 l += PacketRef::Signature(s).serialized_len();
246             }
247         }
248 
249         for u in self.unknowns() {
250             l += PacketRef::Unknown(u.unknown()).serialized_len();
251 
252             for s in u.self_revocations() {
253                 l += PacketRef::Signature(s).serialized_len();
254             }
255             for s in u.self_signatures() {
256                 l += PacketRef::Signature(s).serialized_len();
257             }
258             for s in u.certifications() {
259                 l += PacketRef::Signature(s).serialized_len();
260             }
261             for s in u.other_revocations() {
262                 l += PacketRef::Signature(s).serialized_len();
263             }
264         }
265 
266         for s in self.bad_signatures() {
267             l += PacketRef::Signature(s).serialized_len();
268         }
269 
270         l
271     }
272 
serialize_into(&self, buf: &mut [u8]) -> Result<usize>273     fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
274         generic_serialize_into(self, self.serialized_len(), buf)
275     }
276 
export_into(&self, buf: &mut [u8]) -> Result<usize>277     fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
278         generic_export_into(self, self.serialized_len(), buf)
279     }
280 }
281 
282 impl Cert {
283     /// Derive a [`TSK`] object from this key.
284     ///
285     /// This object writes out secret keys during serialization.
286     ///
287     /// [`TSK`]: ../serialize/struct.TSK.html
as_tsk<'a>(&'a self) -> TSK<'a>288     pub fn as_tsk<'a>(&'a self) -> TSK<'a> {
289         TSK::new(self)
290     }
291 }
292 
293 /// A reference to a Cert that allows serialization of secret keys.
294 ///
295 /// To avoid accidental leakage, secret keys are not serialized when a
296 /// serializing a [`Cert`].  To serialize [`Cert`]s with secret keys,
297 /// use [`Cert::as_tsk()`] to create a `TSK`, which is a shim on top
298 /// of the `Cert`, and serialize this.
299 ///
300 /// [`Cert`]: ../cert/struct.Cert.html
301 /// [`Cert::as_tsk()`]: ../cert/struct.Cert.html#method.as_tsk
302 ///
303 /// # Example
304 /// ```
305 /// # use sequoia_openpgp::{*, cert::*, parse::Parse, serialize::Serialize};
306 /// # f().unwrap();
307 /// # fn f() -> Result<()> {
308 /// let (cert, _) = CertBuilder::new().generate()?;
309 /// assert!(cert.is_tsk());
310 ///
311 /// let mut buf = Vec::new();
312 /// cert.as_tsk().serialize(&mut buf)?;
313 ///
314 /// let cert_ = Cert::from_bytes(&buf)?;
315 /// assert!(cert_.is_tsk());
316 /// assert_eq!(cert, cert_);
317 /// # Ok(()) }
318 pub struct TSK<'a> {
319     cert: &'a Cert,
320     filter: Option<Box<dyn Fn(&'a key::UnspecifiedSecret) -> bool + 'a>>,
321 }
322 
323 impl<'a> TSK<'a> {
324     /// Creates a new view for the given `Cert`.
new(cert: &'a Cert) -> Self325     fn new(cert: &'a Cert) -> Self {
326         Self {
327             cert,
328             filter: None,
329         }
330     }
331 
332     /// Filters which secret keys to export using the given predicate.
333     ///
334     /// Note that the given filter replaces any existing filter.
335     ///
336     /// # Example
337     /// ```
338     /// # use sequoia_openpgp::{*, cert::*, parse::Parse, serialize::Serialize};
339     /// use sequoia_openpgp::policy::StandardPolicy;
340     ///
341     /// # f().unwrap();
342     /// # fn f() -> Result<()> {
343     /// let p = &StandardPolicy::new();
344     ///
345     /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;
346     /// assert_eq!(cert.keys().with_policy(p, None).alive().revoked(false).secret().count(), 2);
347     ///
348     /// // Only write out the primary key's secret.
349     /// let mut buf = Vec::new();
350     /// cert.as_tsk()
351     ///     .set_filter(|k| k.fingerprint() == cert.fingerprint())
352     ///     .serialize(&mut buf)?;
353     ///
354     /// let cert_ = Cert::from_bytes(&buf)?;
355     /// assert_eq!(cert_.keys().with_policy(p, None).alive().revoked(false).secret().count(), 1);
356     /// assert!(cert_.primary_key().has_secret());
357     /// # Ok(()) }
set_filter<P>(mut self, predicate: P) -> Self where P: 'a + Fn(&'a key::UnspecifiedSecret) -> bool358     pub fn set_filter<P>(mut self, predicate: P) -> Self
359         where P: 'a + Fn(&'a key::UnspecifiedSecret) -> bool
360     {
361         self.filter = Some(Box::new(predicate));
362         self
363     }
364 
365     /// Serializes or exports the Cert.
366     ///
367     /// If `export` is true, then non-exportable signatures are not
368     /// written, and components without any exportable binding
369     /// signature or revocation are not exported.
serialize_common(&self, o: &mut dyn std::io::Write, export: bool) -> Result<()>370     fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
371                         -> Result<()>
372     {
373         // Writes a signature if it is exportable or `! export`.
374         let serialize_sig =
375             |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
376         {
377             if export {
378                 if sig.exportable().is_ok() {
379                     PacketRef::Signature(sig).export(o)?;
380                 }
381             } else {
382                 PacketRef::Signature(sig).serialize(o)?;
383             }
384             Ok(())
385         };
386 
387         // Serializes public or secret key depending on the filter.
388         let serialize_key =
389             |o: &mut dyn std::io::Write, key: &'a key::UnspecifiedSecret,
390              tag_public, tag_secret|
391         {
392             let tag = if key.has_secret()
393                 && self.filter.as_ref().map(|f| f(key)).unwrap_or(true) {
394                 tag_secret
395             } else {
396                 tag_public
397             };
398 
399             match tag {
400                 Tag::PublicKey =>
401                     PacketRef::PublicKey(key.into()).serialize(o),
402                 Tag::PublicSubkey =>
403                     PacketRef::PublicSubkey(key.into()).serialize(o),
404                 Tag::SecretKey =>
405                     PacketRef::SecretKey(key.into()).serialize(o),
406                 Tag::SecretSubkey =>
407                     PacketRef::SecretSubkey(key.into()).serialize(o),
408                 _ => unreachable!(),
409             }
410         };
411 
412         let primary = self.cert.primary_key();
413         serialize_key(o, primary.key().into(),
414                       Tag::PublicKey, Tag::SecretKey)?;
415 
416         for s in primary.self_signatures() {
417             serialize_sig(o, s)?;
418         }
419         for s in primary.self_revocations() {
420             serialize_sig(o, s)?;
421         }
422         for s in primary.certifications() {
423             serialize_sig(o, s)?;
424         }
425         for s in primary.other_revocations() {
426             serialize_sig(o, s)?;
427         }
428 
429         for u in self.cert.userids() {
430             if export && ! u.self_signatures().iter().chain(u.self_revocations()).any(
431                 |s| s.exportable().is_ok())
432             {
433                 // No exportable selfsig on this component, skip it.
434                 continue;
435             }
436 
437             PacketRef::UserID(u.userid()).serialize(o)?;
438             for s in u.self_revocations() {
439                 serialize_sig(o, s)?;
440             }
441             for s in u.self_signatures() {
442                 serialize_sig(o, s)?;
443             }
444             for s in u.other_revocations() {
445                 serialize_sig(o, s)?;
446             }
447             for s in u.certifications() {
448                 serialize_sig(o, s)?;
449             }
450         }
451 
452         for u in self.cert.user_attributes() {
453             if export && ! u.self_signatures().iter().chain(u.self_revocations()).any(
454                 |s| s.exportable().is_ok())
455             {
456                 // No exportable selfsig on this component, skip it.
457                 continue;
458             }
459 
460             PacketRef::UserAttribute(u.user_attribute()).serialize(o)?;
461             for s in u.self_revocations() {
462                 serialize_sig(o, s)?;
463             }
464             for s in u.self_signatures() {
465                 serialize_sig(o, s)?;
466             }
467             for s in u.other_revocations() {
468                 serialize_sig(o, s)?;
469             }
470             for s in u.certifications() {
471                 serialize_sig(o, s)?;
472             }
473         }
474 
475         for k in self.cert.subkeys() {
476             if export && ! k.self_signatures().iter().chain(k.self_revocations()).any(
477                 |s| s.exportable().is_ok())
478             {
479                 // No exportable selfsig on this component, skip it.
480                 continue;
481             }
482 
483             serialize_key(o, k.key().into(),
484                           Tag::PublicSubkey, Tag::SecretSubkey)?;
485             for s in k.self_revocations() {
486                 serialize_sig(o, s)?;
487             }
488             for s in k.self_signatures() {
489                 serialize_sig(o, s)?;
490             }
491             for s in k.other_revocations() {
492                 serialize_sig(o, s)?;
493             }
494             for s in k.certifications() {
495                 serialize_sig(o, s)?;
496             }
497         }
498 
499         for u in self.cert.unknowns() {
500             if export && ! u.certifications().iter().any(
501                 |s| s.exportable().is_ok())
502             {
503                 // No exportable selfsig on this component, skip it.
504                 continue;
505             }
506 
507             PacketRef::Unknown(&u.unknown()).serialize(o)?;
508 
509             for s in u.self_revocations() {
510                 serialize_sig(o, s)?;
511             }
512             for s in u.self_signatures() {
513                 serialize_sig(o, s)?;
514             }
515             for s in u.other_revocations() {
516                 serialize_sig(o, s)?;
517             }
518             for s in u.certifications() {
519                 serialize_sig(o, s)?;
520             }
521         }
522 
523         for s in self.cert.bad_signatures() {
524             serialize_sig(o, s)?;
525         }
526 
527         Ok(())
528     }
529 }
530 
531 impl<'a> crate::serialize::Serialize for TSK<'a> {}
532 
533 impl<'a> Marshal for TSK<'a> {
serialize(&self, o: &mut dyn std::io::Write) -> Result<()>534     fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
535         self.serialize_common(o, false)
536     }
537 
export(&self, o: &mut dyn std::io::Write) -> Result<()>538     fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
539         self.serialize_common(o, true)
540     }
541 }
542 
543 impl<'a> crate::serialize::SerializeInto for TSK<'a> {}
544 
545 impl<'a> MarshalInto for TSK<'a> {
serialized_len(&self) -> usize546     fn serialized_len(&self) -> usize {
547         let mut l = 0;
548 
549         // Serializes public or secret key depending on the filter.
550         let serialized_len_key
551             = |key: &'a key::UnspecifiedSecret, tag_public, tag_secret|
552         {
553             let tag = if key.has_secret()
554                 && self.filter.as_ref().map(|f| f(key)).unwrap_or(true) {
555                 tag_secret
556             } else {
557                 tag_public
558             };
559 
560             let packet = match tag {
561                 Tag::PublicKey => PacketRef::PublicKey(key.into()),
562                 Tag::PublicSubkey => PacketRef::PublicSubkey(key.into()),
563                 Tag::SecretKey => PacketRef::SecretKey(key.into()),
564                 Tag::SecretSubkey => PacketRef::SecretSubkey(key.into()),
565                 _ => unreachable!(),
566             };
567 
568             packet.serialized_len()
569         };
570 
571         let primary = self.cert.primary_key();
572         l += serialized_len_key(primary.key().into(),
573                                 Tag::PublicKey, Tag::SecretKey);
574 
575         for s in primary.self_signatures() {
576             l += PacketRef::Signature(s).serialized_len();
577         }
578         for s in primary.self_revocations() {
579             l += PacketRef::Signature(s).serialized_len();
580         }
581         for s in primary.other_revocations() {
582             l += PacketRef::Signature(s).serialized_len();
583         }
584         for s in primary.certifications() {
585             l += PacketRef::Signature(s).serialized_len();
586         }
587 
588         for u in self.cert.userids() {
589             l += PacketRef::UserID(u.userid()).serialized_len();
590 
591             for s in u.self_revocations() {
592                 l += PacketRef::Signature(s).serialized_len();
593             }
594             for s in u.self_signatures() {
595                 l += PacketRef::Signature(s).serialized_len();
596             }
597             for s in u.other_revocations() {
598                 l += PacketRef::Signature(s).serialized_len();
599             }
600             for s in u.certifications() {
601                 l += PacketRef::Signature(s).serialized_len();
602             }
603         }
604 
605         for u in self.cert.user_attributes() {
606             l += PacketRef::UserAttribute(u.user_attribute()).serialized_len();
607 
608             for s in u.self_revocations() {
609                 l += PacketRef::Signature(s).serialized_len();
610             }
611             for s in u.self_signatures() {
612                 l += PacketRef::Signature(s).serialized_len();
613             }
614             for s in u.other_revocations() {
615                 l += PacketRef::Signature(s).serialized_len();
616             }
617             for s in u.certifications() {
618                 l += PacketRef::Signature(s).serialized_len();
619             }
620         }
621 
622         for k in self.cert.subkeys() {
623             l += serialized_len_key(k.key().into(),
624                                     Tag::PublicSubkey, Tag::SecretSubkey);
625 
626             for s in k.self_revocations() {
627                 l += PacketRef::Signature(s).serialized_len();
628             }
629             for s in k.self_signatures() {
630                 l += PacketRef::Signature(s).serialized_len();
631             }
632             for s in k.other_revocations() {
633                 l += PacketRef::Signature(s).serialized_len();
634             }
635             for s in k.certifications() {
636                 l += PacketRef::Signature(s).serialized_len();
637             }
638         }
639 
640         for u in self.cert.unknowns() {
641             l += PacketRef::Unknown(u.unknown()).serialized_len();
642 
643             for s in u.self_revocations() {
644                 l += PacketRef::Signature(s).serialized_len();
645             }
646             for s in u.self_signatures() {
647                 l += PacketRef::Signature(s).serialized_len();
648             }
649             for s in u.other_revocations() {
650                 l += PacketRef::Signature(s).serialized_len();
651             }
652             for s in u.certifications() {
653                 l += PacketRef::Signature(s).serialized_len();
654             }
655         }
656 
657         for s in self.cert.bad_signatures() {
658             l += PacketRef::Signature(s).serialized_len();
659         }
660 
661         l
662     }
663 
serialize_into(&self, buf: &mut [u8]) -> Result<usize>664     fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
665         generic_serialize_into(self, self.serialized_len(), buf)
666     }
667 
export_into(&self, buf: &mut [u8]) -> Result<usize>668     fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
669         generic_export_into(self, self.serialized_len(), buf)
670     }
671 }
672 
673 #[cfg(test)]
674 mod test {
675     use super::*;
676     use crate::vec_truncate;
677     use crate::parse::Parse;
678     use crate::packet::key;
679     use crate::policy::StandardPolicy as P;
680 
681     /// Demonstrates that public keys and all components are
682     /// serialized.
683     #[test]
roundtrip_cert()684     fn roundtrip_cert() {
685         for test in crate::tests::CERTS {
686             let cert = match Cert::from_bytes(test.bytes) {
687                 Ok(t) => t,
688                 Err(_) => continue,
689             };
690             assert!(! cert.is_tsk());
691             let buf = cert.as_tsk().to_vec().unwrap();
692             let cert_ = Cert::from_bytes(&buf).unwrap();
693 
694             assert_eq!(cert, cert_, "roundtripping {}.pgp failed", test);
695         }
696     }
697 
698     /// Demonstrates that secret keys and all components are
699     /// serialized.
700     #[test]
roundtrip_tsk()701     fn roundtrip_tsk() {
702         for test in crate::tests::TSKS {
703             let cert = Cert::from_bytes(test.bytes).unwrap();
704             assert!(cert.is_tsk());
705 
706             let mut buf = Vec::new();
707             cert.as_tsk().serialize(&mut buf).unwrap();
708             let cert_ = Cert::from_bytes(&buf).unwrap();
709 
710             assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test);
711 
712             // This time, use a trivial filter.
713             let mut buf = Vec::new();
714             cert.as_tsk().set_filter(|_| true).serialize(&mut buf).unwrap();
715             let cert_ = Cert::from_bytes(&buf).unwrap();
716 
717             assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test);
718         }
719     }
720 
721     /// Demonstrates that TSK::serialize() with the right filter
722     /// reduces to Cert::serialize().
723     #[test]
reduce_to_cert_serialize()724     fn reduce_to_cert_serialize() {
725         for test in crate::tests::TSKS {
726             let cert = Cert::from_bytes(test.bytes).unwrap();
727             assert!(cert.is_tsk());
728 
729             // First, use Cert::serialize().
730             let mut buf_cert = Vec::new();
731             cert.serialize(&mut buf_cert).unwrap();
732 
733             // When serializing using TSK::serialize, filter out all
734             // secret keys.
735             let mut buf_tsk = Vec::new();
736             cert.as_tsk().set_filter(|_| false).serialize(&mut buf_tsk).unwrap();
737 
738             // Check for equality.
739             let cert_ = Cert::from_bytes(&buf_cert).unwrap();
740             let tsk_ = Cert::from_bytes(&buf_tsk).unwrap();
741             assert_eq!(cert_, tsk_,
742                        "reducing failed on {}-private.pgp: not Cert::eq",
743                        test);
744 
745             // Check for identinty.
746             assert_eq!(buf_cert, buf_tsk,
747                        "reducing failed on {}-private.pgp: serialized identity",
748                        test);
749         }
750     }
751 
752     #[test]
export()753     fn export() {
754         use crate::Packet;
755         use crate::cert::prelude::*;
756         use crate::types::{Curve, KeyFlags, SignatureType};
757         use crate::packet::{
758             signature, UserID, user_attribute::{UserAttribute, Subpacket},
759             key::Key4,
760         };
761 
762         let p = &P::new();
763 
764         let (cert, _) = CertBuilder::new().generate().unwrap();
765         let mut keypair = cert.primary_key().key().clone().parts_into_secret()
766             .unwrap().into_keypair().unwrap();
767 
768         let key: key::SecretSubkey =
769             Key4::generate_ecc(false, Curve::Cv25519).unwrap().into();
770         let key_binding = key.bind(
771             &mut keypair, &cert,
772             signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
773                 .set_key_flags(
774                     &KeyFlags::empty().set_transport_encryption())
775                 .unwrap()
776                 .set_exportable_certification(false).unwrap()).unwrap();
777 
778         let uid = UserID::from("foo");
779         let uid_binding = uid.bind(
780             &mut keypair, &cert,
781             signature::SignatureBuilder::from(
782                 cert.primary_key().with_policy(p, None).unwrap()
783                     .direct_key_signature().unwrap().clone())
784                     .set_type(SignatureType::PositiveCertification)
785                     .preserve_signature_creation_time().unwrap()
786                     .set_exportable_certification(false).unwrap()).unwrap();
787 
788         let ua = UserAttribute::new(&[
789             Subpacket::Unknown(2, b"foo".to_vec().into_boxed_slice()),
790         ]).unwrap();
791         let ua_binding = ua.bind(
792             &mut keypair, &cert,
793             signature::SignatureBuilder::from(
794                 cert.primary_key().with_policy(p, None).unwrap()
795                     .direct_key_signature().unwrap().clone())
796                 .set_type(SignatureType::PositiveCertification)
797                 .preserve_signature_creation_time().unwrap()
798                 .set_exportable_certification(false).unwrap()).unwrap();
799 
800         let cert = cert.merge_packets(vec![
801             Packet::SecretSubkey(key), key_binding.into(),
802             uid.into(), uid_binding.into(),
803             ua.into(), ua_binding.into(),
804         ]).unwrap();
805 
806         assert_eq!(cert.subkeys().count(), 1);
807         cert.subkeys().nth(0).unwrap().binding_signature(p, None).unwrap();
808         assert_eq!(cert.userids().count(), 1);
809         assert!(cert.userids().with_policy(p, None).nth(0).is_some());
810         assert_eq!(cert.user_attributes().count(), 1);
811         assert!(cert.user_attributes().with_policy(p, None).nth(0).is_some());
812 
813         // The binding signature is not exportable, so when we export
814         // and re-parse, we expect the userid to be gone.
815         let mut buf = Vec::new();
816         cert.export(&mut buf).unwrap();
817         let cert_ = Cert::from_bytes(&buf).unwrap();
818         assert_eq!(cert_.subkeys().count(), 0);
819         assert_eq!(cert_.userids().count(), 0);
820         assert_eq!(cert_.user_attributes().count(), 0);
821 
822         let mut buf = vec![0; cert.serialized_len()];
823         let l = cert.export_into(&mut buf).unwrap();
824         vec_truncate(&mut buf, l);
825         let cert_ = Cert::from_bytes(&buf).unwrap();
826         assert_eq!(cert_.subkeys().count(), 0);
827         assert_eq!(cert_.userids().count(), 0);
828         assert_eq!(cert_.user_attributes().count(), 0);
829 
830         let cert_ = Cert::from_bytes(&cert.export_to_vec().unwrap()).unwrap();
831         assert_eq!(cert_.subkeys().count(), 0);
832         assert_eq!(cert_.userids().count(), 0);
833         assert_eq!(cert_.user_attributes().count(), 0);
834 
835         // Same, this time using the armor encoder.
836         let mut buf = Vec::new();
837         cert.armored().export(&mut buf).unwrap();
838         let cert_ = Cert::from_bytes(&buf).unwrap();
839         assert_eq!(cert_.subkeys().count(), 0);
840         assert_eq!(cert_.userids().count(), 0);
841         assert_eq!(cert_.user_attributes().count(), 0);
842 
843         let mut buf = vec![0; cert.serialized_len()];
844         let l = cert.armored().export_into(&mut buf).unwrap();
845         vec_truncate(&mut buf, l);
846         let cert_ = Cert::from_bytes(&buf).unwrap();
847         assert_eq!(cert_.subkeys().count(), 0);
848         assert_eq!(cert_.userids().count(), 0);
849         assert_eq!(cert_.user_attributes().count(), 0);
850 
851         let cert_ =
852             Cert::from_bytes(&cert.armored().export_to_vec().unwrap()).unwrap();
853         assert_eq!(cert_.subkeys().count(), 0);
854         assert_eq!(cert_.userids().count(), 0);
855         assert_eq!(cert_.user_attributes().count(), 0);
856 
857         // Same, this time as TSKs.
858         let mut buf = Vec::new();
859         cert.as_tsk().export(&mut buf).unwrap();
860         let cert_ = Cert::from_bytes(&buf).unwrap();
861         assert_eq!(cert_.subkeys().count(), 0);
862         assert_eq!(cert_.userids().count(), 0);
863         assert_eq!(cert_.user_attributes().count(), 0);
864 
865         let mut buf = vec![0; cert.serialized_len()];
866         let l = cert.as_tsk().export_into(&mut buf).unwrap();
867         vec_truncate(&mut buf, l);
868         let cert_ = Cert::from_bytes(&buf).unwrap();
869         assert_eq!(cert_.subkeys().count(), 0);
870         assert_eq!(cert_.userids().count(), 0);
871         assert_eq!(cert_.user_attributes().count(), 0);
872 
873         let cert_ =
874             Cert::from_bytes(&cert.as_tsk().export_to_vec().unwrap()).unwrap();
875         assert_eq!(cert_.subkeys().count(), 0);
876         assert_eq!(cert_.userids().count(), 0);
877         assert_eq!(cert_.user_attributes().count(), 0);
878     }
879 }
880