Skip to main content

sequoia_openpgp/
serialize.rs

1//! Packet serialization infrastructure.
2//!
3//! OpenPGP defines a binary representation suitable for storing and
4//! communicating OpenPGP data structures (see [Section 3 ff. of RFC
5//! 9580]).  Serialization is the process of creating the binary
6//! representation.
7//!
8//!   [Section 3 ff. of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3
9//!
10//! There are two interfaces to serialize OpenPGP data.  Which one is
11//! applicable depends on whether or not the packet structure is
12//! already assembled in memory, with all information already in place
13//! (e.g. because it was previously parsed).
14//!
15//! If it is, you can use the [`Serialize`] or [`SerializeInto`]
16//! trait.  Otherwise, please use our [streaming serialization
17//! interface].
18//!
19//!   [streaming serialization interface]: stream
20//!
21//! # Streaming serialization
22//!
23//! The [streaming serialization interface] is the preferred way to
24//! create OpenPGP messages (see [Section 10.3 of RFC 9580]).  It is
25//! ergonomic, yet flexible enough to accommodate most use cases.  It
26//! requires little buffering, minimizing the memory footprint of the
27//! operation.
28//!
29//! This example demonstrates how to create the simplest possible
30//! OpenPGP message (see [Section 10.3 of RFC 9580]) containing just a
31//! literal data packet (see [Section 5.9 of RFC 9580]):
32//!
33//!   [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
34//!   [Section 5.9 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.9
35//!
36//! ```
37//! # fn main() -> sequoia_openpgp::Result<()> {
38//! use std::io::Write;
39//! use sequoia_openpgp as openpgp;
40//! use openpgp::serialize::stream::{Message, LiteralWriter};
41//!
42//! let mut o = vec![];
43//! {
44//!     let message = Message::new(&mut o);
45//!     let mut w = LiteralWriter::new(message).build()?;
46//!     w.write_all(b"Hello world.")?;
47//!     w.finalize()?;
48//! }
49//! assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", o.as_slice());
50//! # Ok(()) }
51//! ```
52//!
53//! For a more complete example, see the [streaming examples].
54//!
55//!   [streaming examples]: stream#examples
56//!
57//! # Serializing objects
58//!
59//! The traits [`Serialize`] and [`SerializeInto`] provide a mechanism
60//! to serialize OpenPGP data structures.  [`Serialize`] writes to
61//! [`io::Write`]rs, while [`SerializeInto`] writes into pre-allocated
62//! buffers, computes the size of the serialized representation, and
63//! provides a convenient method to create byte vectors with the
64//! serialized form.
65//!
66//!   [`io::Write`]: std::io::Write
67//!
68//! To prevent accidentally serializing data structures that are not
69//! commonly exchanged between OpenPGP implementations, [`Serialize`]
70//! and [`SerializeInto`] is only implemented for types like
71//! [`Packet`], [`Cert`], and [`Message`], but not for packet bodies
72//! like [`Signature`].
73//!
74//!   [`Packet`]: super::Packet
75//!   [`Cert`]: super::Cert
76//!   [`Message`]: super::Message
77//!   [`Signature`]: crate::packet::Signature
78//!
79//! This example demonstrates how to serialize a literal data packet
80//! (see [Section 5.9 of RFC 9580]):
81//!
82//! ```
83//! # fn main() -> sequoia_openpgp::Result<()> {
84//! use sequoia_openpgp as openpgp;
85//! use openpgp::packet::{Literal, Packet};
86//! use openpgp::serialize::{Serialize, SerializeInto};
87//!
88//! let mut l = Literal::default();
89//! l.set_body(b"Hello world.".to_vec());
90//!
91//! // Add packet framing.
92//! let p = Packet::from(l);
93//!
94//! // Using Serialize.
95//! let mut b = vec![];
96//! p.serialize(&mut b)?;
97//! assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", b.as_slice());
98//!
99//! // Using SerializeInto.
100//! let b = p.to_vec()?;
101//! assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", b.as_slice());
102//! # Ok(()) }
103//! ```
104//!
105//! # Marshalling objects
106//!
107//! The traits [`Marshal`] and [`MarshalInto`] provide a mechanism to
108//! serialize all OpenPGP data structures in this crate, even those
109//! not commonly interchanged between OpenPGP implementations.  For
110//! example, it allows the serialization of unframed packet bodies:
111//!
112//!
113//! ```
114//! # fn main() -> sequoia_openpgp::Result<()> {
115//! use sequoia_openpgp as openpgp;
116//! use openpgp::packet::Literal;
117//! use openpgp::serialize::{Marshal, MarshalInto};
118//!
119//! let mut l = Literal::default();
120//! l.set_body(b"Hello world.".to_vec());
121//!
122//! // Using Marshal.
123//! let mut b = vec![];
124//! l.serialize(&mut b)?;
125//! assert_eq!(b"b\x00\x00\x00\x00\x00Hello world.", b.as_slice());
126//!
127//! // Using MarshalInto.
128//! let b = l.to_vec()?;
129//! assert_eq!(b"b\x00\x00\x00\x00\x00Hello world.", b.as_slice());
130//! # Ok(()) }
131//! ```
132
133use std::io::{self, Write};
134use std::cmp;
135use std::convert::{TryFrom, TryInto};
136
137use super::*;
138
139mod cert;
140pub use self::cert::TSK;
141mod cert_armored;
142pub mod stream;
143use crate::crypto::S2K;
144use crate::packet::header::{
145    BodyLength,
146    CTB,
147    CTBNew,
148    CTBOld,
149};
150use crate::packet::signature::subpacket::{
151    SubpacketArea, Subpacket, SubpacketValue, SubpacketLength
152};
153use crate::packet::prelude::*;
154use crate::packet::signature::Signature3;
155use crate::seal;
156use crate::types::{
157    RevocationKey,
158    Timestamp,
159};
160
161// Whether to trace the modules execution (on stderr).
162const TRACE : bool = false;
163
164/// Serializes OpenPGP data structures.
165///
166/// This trait provides the same interface as the [`Marshal`] trait (in
167/// fact, it is just a wrapper around that trait), but only data
168/// structures that it makes sense to export implement it.
169///
170///
171/// Having a separate trait for data structures that it makes sense to
172/// export avoids an easy-to-make and hard-to-debug bug: inadvertently
173/// exporting an OpenPGP data structure without any framing
174/// information.
175///
176/// This bug is easy to make, because Rust infers types, which means
177/// that it is often not clear from the immediate context exactly what
178/// is being serialized.  This bug is hard to debug, because errors
179/// parsing data that has been incorrectly exported, are removed from
180/// the serialization code.
181///
182/// The following example shows how to correctly export a revocation
183/// certificate.  It should make clear how easy it is to forget to
184/// convert a bare signature into an OpenPGP packet before serializing
185/// it:
186///
187/// ```
188/// # use sequoia_openpgp as openpgp;
189/// # use openpgp::Result;
190/// use openpgp::cert::prelude::*;
191/// use openpgp::Packet;
192/// use openpgp::serialize::Serialize;
193///
194/// # fn main() -> Result<()> {
195/// let (_cert, rev) =
196///     CertBuilder::general_purpose(Some("alice@example.org"))
197///     .generate()?;
198/// let rev : Packet = rev.into();
199/// # let output = &mut Vec::new();
200/// rev.serialize(output)?;
201/// # Ok(())
202/// # }
203/// ```
204///
205/// Note: if you `use` both `Serialize` and [`Marshal`], then, because
206/// they both have the same methods, and all data structures that
207/// implement `Serialize` also implement [`Marshal`], you will have to
208/// use the Universal Function Call Syntax (UFCS) to call the methods
209/// on those objects, for example:
210///
211/// ```
212/// # use sequoia_openpgp as openpgp;
213/// # use openpgp::Result;
214/// # use openpgp::cert::prelude::*;
215/// # use openpgp::Packet;
216/// # use openpgp::serialize::Serialize;
217/// #
218/// # fn main() -> Result<()> {
219/// # let (_cert, rev) =
220/// #     CertBuilder::general_purpose(Some("alice@example.org"))
221/// #     .generate()?;
222/// # let rev : Packet = rev.into();
223/// # let output = &mut Vec::new();
224/// Serialize::serialize(&rev, output)?;
225/// # Ok(())
226/// # }
227/// ```
228///
229/// If you really needed [`Marshal`], we strongly recommend importing it
230/// in as small a scope as possible to avoid this, and to avoid
231/// accidentally exporting data without the required framing.
232pub trait Serialize : Marshal {
233    /// Writes a serialized version of the object to `o`.
234    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
235        Marshal::serialize(self, o)
236    }
237
238    /// Exports a serialized version of the object to `o`.
239    ///
240    /// This is similar to [`serialize(..)`], with these exceptions:
241    ///
242    ///   - It is an error to export a [`Signature`] if it is marked
243    ///     as non-exportable.
244    ///   - When exporting a [`Cert`], non-exportable signatures are
245    ///     not exported, and any component bound merely by
246    ///     non-exportable signatures is not exported.
247    ///
248    ///   [`serialize(..)`]: Serialize::serialize
249    ///   [`Signature`]: crate::packet::Signature
250    ///   [`Cert`]: super::Cert
251    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
252        Marshal::export(self, o)
253    }
254}
255
256/// Serializes OpenPGP data structures.
257///
258/// This trait provides the same interface as [`Serialize`], but is
259/// implemented for all data structures that can be serialized.
260///
261///
262/// In general, you should prefer the [`Serialize`] trait, as it is only
263/// implemented for data structures that are normally exported.  See
264/// the documentation for [`Serialize`] for more details.
265///
266/// # Sealed trait
267///
268/// This trait is [sealed] and cannot be implemented for types outside this crate.
269/// Therefore it can be extended in a non-breaking way.
270/// If you want to implement the trait inside the crate
271/// you also need to implement the `seal::Sealed` marker trait.
272///
273/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
274pub trait Marshal: seal::Sealed {
275    /// Writes a serialized version of the object to `o`.
276    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()>;
277
278    /// Exports a serialized version of the object to `o`.
279    ///
280    /// This is similar to [`serialize(..)`], with these exceptions:
281    ///
282    ///   - It is an error to export a [`Signature`] if it is marked
283    ///     as non-exportable.
284    ///   - When exporting a [`Cert`], non-exportable signatures are
285    ///     not exported, and any component bound merely by
286    ///     non-exportable signatures is not exported.
287    ///
288    ///   [`serialize(..)`]: Marshal::serialize
289    ///   [`Signature`]: crate::packet::Signature
290    ///   [`Cert`]: super::Cert
291    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
292        self.serialize(o)
293    }
294}
295
296/// Serializes OpenPGP data structures into pre-allocated buffers.
297///
298/// This trait provides the same interface as [`MarshalInto`], but is
299/// only implemented for data structures that can be serialized.
300///
301///
302/// In general, you should prefer this trait to [`MarshalInto`], as it
303/// is only implemented for data structures that are normally
304/// exported.  See the documentation for [`Serialize`] for more details.
305///
306pub trait SerializeInto : MarshalInto {
307    /// Computes the maximal length of the serialized representation.
308    ///
309    /// # Errors
310    ///
311    /// If serialization would fail, this function underestimates the
312    /// length.
313    fn serialized_len(&self) -> usize {
314        MarshalInto::serialized_len(self)
315    }
316
317    /// Serializes into the given buffer.
318    ///
319    /// Returns the length of the serialized representation.
320    ///
321    /// # Errors
322    ///
323    /// If the length of the given slice is smaller than the maximal
324    /// length computed by `serialized_len()`, this function returns
325    /// [`Error::InvalidArgument`].
326    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
327        MarshalInto::serialize_into(self, buf)
328    }
329
330    /// Serializes the packet to a vector.
331    fn to_vec(&self) -> Result<Vec<u8>> {
332        MarshalInto::to_vec(self)
333    }
334
335    /// Exports into the given buffer.
336    ///
337    /// This is similar to [`serialize_into(..)`], with these
338    /// exceptions:
339    ///
340    ///   - It is an error to export a [`Signature`] if it is marked
341    ///     as non-exportable.
342    ///   - When exporting a [`Cert`], non-exportable signatures are
343    ///     not exported, and any component bound merely by
344    ///     non-exportable signatures is not exported.
345    ///
346    ///   [`serialize_into(..)`]: SerializeInto::serialize_into
347    ///   [`Signature`]: crate::packet::Signature
348    ///   [`Cert`]: super::Cert
349    ///
350    /// Returns the length of the serialized representation.
351    ///
352    /// # Errors
353    ///
354    /// If the length of the given slice is smaller than the maximal
355    /// length computed by `serialized_len()`, this function returns
356    /// [`Error::InvalidArgument`].
357    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
358        MarshalInto::export_into(self, buf)
359    }
360
361    /// Exports to a vector.
362    ///
363    /// This is similar to [`to_vec()`], with these exceptions:
364    ///
365    ///   - It is an error to export a [`Signature`] if it is marked
366    ///     as non-exportable.
367    ///   - When exporting a [`Cert`], non-exportable signatures are
368    ///     not exported, and any component bound merely by
369    ///     non-exportable signatures is not exported.
370    ///
371    ///   [`to_vec()`]: SerializeInto::to_vec()
372    ///   [`Signature`]: crate::packet::Signature
373    ///   [`Cert`]: super::Cert
374    fn export_to_vec(&self) -> Result<Vec<u8>> {
375        MarshalInto::export_to_vec(self)
376    }
377}
378
379/// Serializes OpenPGP data structures into pre-allocated buffers.
380///
381/// This trait provides the same interface as [`SerializeInto`], but is
382/// implemented for all data structures that can be serialized.
383///
384///
385/// In general, you should prefer the [`SerializeInto`] trait, as it is
386/// only implemented for data structures that are normally exported.
387/// See the documentation for [`Serialize`] for more details.
388///
389///
390/// # Sealed trait
391///
392/// This trait is [sealed] and cannot be implemented for types outside this crate.
393/// Therefore it can be extended in a non-breaking way.
394/// If you want to implement the trait inside the crate
395/// you also need to implement the `seal::Sealed` marker trait.
396///
397/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
398pub trait MarshalInto : seal::Sealed {
399    /// Computes the maximal length of the serialized representation.
400    ///
401    /// # Errors
402    ///
403    /// If serialization would fail, this function underestimates the
404    /// length.
405    fn serialized_len(&self) -> usize;
406
407    /// Serializes into the given buffer.
408    ///
409    /// Returns the length of the serialized representation.
410    ///
411    /// # Errors
412    ///
413    /// If the length of the given slice is smaller than the maximal
414    /// length computed by `serialized_len()`, this function returns
415    /// [`Error::InvalidArgument`].
416    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize>;
417
418    /// Serializes the packet to a vector.
419    fn to_vec(&self) -> Result<Vec<u8>> {
420        let mut o = vec![0; self.serialized_len()];
421        let len = self.serialize_into(&mut o[..])?;
422        vec_truncate(&mut o, len);
423        o.shrink_to_fit();
424        Ok(o)
425    }
426
427    /// Exports into the given buffer.
428    ///
429    /// This is similar to [`serialize_into(..)`], with these
430    /// exceptions:
431    ///
432    ///   - It is an error to export a [`Signature`] if it is marked
433    ///     as non-exportable.
434    ///   - When exporting a [`Cert`], non-exportable signatures are
435    ///     not exported, and any component bound merely by
436    ///     non-exportable signatures is not exported.
437    ///
438    ///   [`serialize_into(..)`]: MarshalInto::serialize_into
439    ///   [`Signature`]: crate::packet::Signature
440    ///   [`Cert`]: super::Cert
441    ///
442    /// Returns the length of the serialized representation.
443    ///
444    /// # Errors
445    ///
446    /// If the length of the given slice is smaller than the maximal
447    /// length computed by `serialized_len()`, this function returns
448    /// [`Error::InvalidArgument`].
449    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
450        self.serialize_into(buf)
451    }
452
453    /// Exports to a vector.
454    ///
455    /// This is similar to [`to_vec()`], with these exceptions:
456    ///
457    ///   - It is an error to export a [`Signature`] if it is marked
458    ///     as non-exportable.
459    ///   - When exporting a [`Cert`], non-exportable signatures are
460    ///     not exported, and any component bound merely by
461    ///     non-exportable signatures is not exported.
462    ///
463    ///   [`to_vec()`]: MarshalInto::to_vec()
464    ///   [`Signature`]: crate::packet::Signature
465    ///   [`Cert`]: super::Cert
466    fn export_to_vec(&self) -> Result<Vec<u8>> {
467        let mut o = vec![0; self.serialized_len()];
468        let len = self.export_into(&mut o[..])?;
469        vec_truncate(&mut o, len);
470        o.shrink_to_fit();
471        Ok(o)
472    }
473}
474
475trait NetLength {
476    /// Computes the maximal length of the serialized representation
477    /// without framing.
478    ///
479    /// # Errors
480    ///
481    /// If serialization would fail, this function underestimates the
482    /// length.
483    fn net_len(&self) -> usize;
484
485    /// Computes the maximal length of the serialized representation
486    /// with framing.
487    ///
488    /// # Errors
489    ///
490    /// If serialization would fail, this function underestimates the
491    /// length.
492    fn gross_len(&self) -> usize {
493        let net = self.net_len();
494
495        1 // CTB
496            + BodyLength::Full(net as u32).serialized_len()
497            + net
498    }
499}
500
501/// Provides a generic implementation for SerializeInto::serialize_into.
502///
503/// For now, we express SerializeInto using Serialize.  In the future,
504/// we may provide implementations not relying on Serialize for a
505/// no_std configuration of this crate.
506fn generic_serialize_into(o: &dyn Marshal, serialized_len: usize,
507                          buf: &mut [u8])
508                          -> Result<usize> {
509    let buf_len = buf.len();
510    let mut cursor = ::std::io::Cursor::new(buf);
511    match o.serialize(&mut cursor) {
512        Ok(_) => (),
513        Err(e) => {
514            let short_write =
515                if let Some(ioe) = e.downcast_ref::<io::Error>() {
516                    ioe.kind() == io::ErrorKind::WriteZero
517                } else {
518                    false
519                };
520            return if short_write {
521                if buf_len >= serialized_len {
522                    let mut b = Vec::new();
523                    let need_len = o.serialize(&mut b).map(|_| b.len());
524                    panic!("o.serialized_len() = {} underestimated required \
525                            space, need {:?}", serialized_len, need_len);
526                }
527                Err(Error::InvalidArgument(
528                    format!("Invalid buffer size, expected {}, got {}",
529                            serialized_len, buf_len)).into())
530            } else {
531                Err(e)
532            }
533        }
534    };
535    Ok(cursor.position() as usize)
536}
537
538
539/// Provides a generic implementation for SerializeInto::export_into.
540///
541/// For now, we express SerializeInto using Serialize.  In the future,
542/// we may provide implementations not relying on Serialize for a
543/// no_std configuration of this crate.
544fn generic_export_into(o: &dyn Marshal, serialized_len: usize,
545                       buf: &mut [u8])
546                       -> Result<usize> {
547    let buf_len = buf.len();
548    let mut cursor = ::std::io::Cursor::new(buf);
549    match o.export(&mut cursor) {
550        Ok(_) => (),
551        Err(e) => {
552            let short_write =
553                if let Some(ioe) = e.downcast_ref::<io::Error>() {
554                    ioe.kind() == io::ErrorKind::WriteZero
555                } else {
556                    false
557                };
558            return if short_write {
559                if buf_len >= serialized_len {
560                    let mut b = Vec::new();
561                    let need_len = o.serialize(&mut b).map(|_| b.len());
562                    panic!("o.serialized_len() = {} underestimated required \
563                            space, need {:?}", serialized_len, need_len);
564                }
565                Err(Error::InvalidArgument(
566                    format!("Invalid buffer size, expected {}, got {}",
567                            serialized_len, buf_len)).into())
568            } else {
569                Err(e)
570            }
571        }
572    };
573    Ok(cursor.position() as usize)
574}
575
576#[test]
577fn test_generic_serialize_into() {
578    let u = UserID::from("Mr. Pink");
579    let mut b = vec![0; u.serialized_len()];
580    u.serialize_into(&mut b[..]).unwrap();
581
582    // Short buffer.
583    let mut b = vec![0; u.serialized_len() - 1];
584    let e = u.serialize_into(&mut b[..]).unwrap_err();
585    assert_match!(Some(Error::InvalidArgument(_)) = e.downcast_ref());
586}
587
588#[test]
589fn test_generic_export_into() {
590    let u = UserID::from("Mr. Pink");
591    let mut b = vec![0; u.serialized_len()];
592    u.export_into(&mut b[..]).unwrap();
593
594    // Short buffer.
595    let mut b = vec![0; u.serialized_len() - 1];
596    let e = u.export_into(&mut b[..]).unwrap_err();
597    assert_match!(Some(Error::InvalidArgument(_)) = e.downcast_ref());
598}
599
600fn write_byte(o: &mut dyn std::io::Write, b: u8) -> io::Result<()> {
601    o.write_all(&[b])
602}
603
604fn write_be_u16(o: &mut dyn std::io::Write, n: u16) -> io::Result<()> {
605    o.write_all(&n.to_be_bytes())
606}
607
608fn write_be_u32(o: &mut dyn std::io::Write, n: u32) -> io::Result<()> {
609    o.write_all(&n.to_be_bytes())
610}
611
612// Compute the log2 of an integer.  (This is simply the most
613// significant bit.)  Note: log2(0) = -Inf, but this function returns
614// log2(0) as 0 (which is the closest number that we can represent).
615fn log2(x: u32) -> usize {
616    if x == 0 {
617        0
618    } else {
619        31 - x.leading_zeros() as usize
620    }
621}
622
623#[test]
624fn log2_test() {
625    for i in 0..32 {
626        // eprintln!("log2(1 << {} = {}) = {}", i, 1u32 << i, log2(1u32 << i));
627        assert_eq!(log2(1u32 << i), i);
628        if i > 0 {
629            assert_eq!(log2((1u32 << i) - 1), i - 1);
630            assert_eq!(log2((1u32 << i) + 1), i);
631        }
632    }
633}
634
635impl seal::Sealed for BodyLength {}
636impl Marshal for BodyLength {
637    /// Emits the length encoded for use with new-style CTBs.
638    ///
639    /// Note: the CTB itself is not emitted.
640    ///
641    /// # Errors
642    ///
643    /// Returns [`Error::InvalidArgument`] if invoked on
644    /// [`BodyLength::Indeterminate`].  If you want to serialize an
645    /// old-style length, use [`serialize_old(..)`].
646    ///
647    /// [`Error::InvalidArgument`]: Error::InvalidArgument
648    /// [`serialize_old(..)`]: BodyLength::serialize_old()
649    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
650        match self {
651            BodyLength::Full(l) => {
652                let l = *l;
653                if l <= 191 {
654                    write_byte(o, l as u8)?;
655                } else if l <= 8383 {
656                    let v = l - 192;
657                    let v = v + (192 << 8);
658                    write_be_u16(o, v as u16)?;
659                } else {
660                    write_byte(o, 0xff)?;
661                    write_be_u32(o, l)?;
662                }
663            },
664            BodyLength::Partial(l) => {
665                let l = *l;
666                if l > 1 << 30 {
667                    return Err(Error::InvalidArgument(
668                        format!("Partial length too large: {}", l)).into());
669                }
670
671                let chunk_size_log2 = log2(l);
672                let chunk_size = 1 << chunk_size_log2;
673
674                if l != chunk_size {
675                    return Err(Error::InvalidArgument(
676                        format!("Not a power of two: {}", l)).into());
677                }
678
679                let size_byte = 224 + chunk_size_log2;
680                assert!(size_byte < 255);
681                write_byte(o, size_byte as u8)?;
682            },
683            BodyLength::Indeterminate =>
684                return Err(Error::InvalidArgument(
685                    "Indeterminate lengths are not support for new format packets".
686                        into()).into()),
687        }
688
689        Ok(())
690    }
691}
692
693impl MarshalInto for BodyLength {
694    fn serialized_len(&self) -> usize {
695        match self {
696            BodyLength::Full(l) => {
697                let l = *l;
698                if l <= 191 {
699                    1
700                } else if l <= 8383 {
701                    2
702                } else {
703                    5
704                }
705            },
706            BodyLength::Partial(_) => 1,
707            BodyLength::Indeterminate => 0,
708        }
709    }
710
711    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
712        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
713    }
714}
715
716impl BodyLength {
717    /// Emits the length encoded for use with old-style CTBs.
718    ///
719    /// Note: the CTB itself is not emitted.
720    ///
721    /// # Errors
722    ///
723    /// Returns [`Error::InvalidArgument`] if invoked on
724    /// [`BodyLength::Partial`].  If you want to serialize a
725    /// new-style length, use [`serialize(..)`].
726    ///
727    /// [`Error::InvalidArgument`]: Error::InvalidArgument
728    /// [`serialize(..)`]: Serialize
729    pub fn serialize_old<W: io::Write + ?Sized>(&self, o: &mut W) -> Result<()> {
730        // Assume an optimal encoding is desired.
731        let mut buffer = Vec::with_capacity(4);
732        match self {
733            BodyLength::Full(l) => {
734                let l = *l;
735                match l {
736                    // One octet length.
737                    // write_byte can't fail for a Vec.
738                    0 ..= 0xFF =>
739                        write_byte(&mut buffer, l as u8).unwrap(),
740                    // Two octet length.
741                    0x1_00 ..= 0xFF_FF =>
742                        write_be_u16(&mut buffer, l as u16).unwrap(),
743                    // Four octet length,
744                    _ =>
745                        write_be_u32(&mut buffer, l as u32).unwrap(),
746                }
747            },
748            BodyLength::Indeterminate => {},
749            BodyLength::Partial(_) =>
750                return Err(Error::InvalidArgument(
751                    "Partial body lengths are not support for old format packets".
752                        into()).into()),
753        }
754
755        o.write_all(&buffer)?;
756        Ok(())
757    }
758
759    /// Computes the length of the length encoded for use with
760    /// old-style CTBs.
761    fn old_serialized_len(&self) -> usize {
762        // Assume an optimal encoding is desired.
763        match self {
764            BodyLength::Full(l) => {
765                match *l {
766                    0 ..= 0xFF => 1,
767                    0x1_00 ..= 0xFF_FF => 2,
768                    _ => 4,
769                }
770            },
771            BodyLength::Indeterminate => 0,
772            BodyLength::Partial(_) => 0,
773        }
774    }
775}
776
777impl seal::Sealed for CTBNew {}
778impl Marshal for CTBNew {
779    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
780        let tag: u8 = self.tag().into();
781        o.write_all(&[0b1100_0000u8 | tag])?;
782        Ok(())
783    }
784}
785
786impl MarshalInto for CTBNew {
787    fn serialized_len(&self) -> usize { 1 }
788
789    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
790        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
791    }
792}
793
794impl seal::Sealed for CTBOld {}
795impl Marshal for CTBOld {
796    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
797        let tag: u8 = self.tag().into();
798        let length_type: u8 = self.length_type().into();
799        o.write_all(&[0b1000_0000u8 | (tag << 2) | length_type])?;
800        Ok(())
801    }
802}
803
804impl MarshalInto for CTBOld {
805    fn serialized_len(&self) -> usize { 1 }
806
807    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
808        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
809    }
810}
811
812impl seal::Sealed for CTB {}
813impl Marshal for CTB {
814    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
815        match self {
816            CTB::New(ref c) => c.serialize(o),
817            CTB::Old(ref c) => c.serialize(o),
818        }?;
819        Ok(())
820    }
821}
822
823impl MarshalInto for CTB {
824    fn serialized_len(&self) -> usize { 1 }
825
826    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
827        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
828    }
829}
830
831impl seal::Sealed for Header {}
832impl Marshal for Header {
833    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
834        self.ctb().serialize(o)?;
835        match self.ctb() {
836            CTB::New(_) => self.length().serialize(o)?,
837            CTB::Old(_) => self.length().serialize_old(o)?,
838        }
839        Ok(())
840    }
841}
842
843impl MarshalInto for Header {
844    fn serialized_len(&self) -> usize {
845        self.ctb().serialized_len()
846            + match self.ctb() {
847                CTB::New(_) => self.length().serialized_len(),
848                CTB::Old(_) => self.length().old_serialized_len(),
849            }
850    }
851
852    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
853        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
854    }
855}
856
857#[test]
858fn legacy_header() -> Result<()> {
859    use crate::serialize::MarshalInto;
860    let len = BodyLength::Indeterminate;
861    let ctb = CTB::Old(CTBOld::new(Tag::Literal, len)?);
862    assert_eq!(&ctb.to_vec()?[..], &[0b1_0_1011_11]);
863    // Bit encoding: OpenPGP_Legacy_Literal_Indeterminate
864    Ok(())
865}
866
867impl Serialize for KeyID {}
868impl seal::Sealed for KeyID {}
869impl Marshal for KeyID {
870    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
871        let raw = match self {
872            KeyID::Long(ref fp) => &fp[..],
873            KeyID::Invalid(ref fp) => &fp[..],
874        };
875        o.write_all(raw)?;
876        Ok(())
877    }
878}
879
880impl SerializeInto for KeyID {}
881impl MarshalInto for KeyID {
882    fn serialized_len(&self) -> usize {
883        match self {
884            KeyID::Long(_) => 8,
885            KeyID::Invalid(ref fp) => fp.len(),
886        }
887    }
888
889    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
890        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
891    }
892}
893
894impl Serialize for Fingerprint {}
895impl seal::Sealed for Fingerprint {}
896impl Marshal for Fingerprint {
897    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
898        o.write_all(self.as_bytes())?;
899        Ok(())
900    }
901}
902
903impl SerializeInto for Fingerprint {}
904impl MarshalInto for Fingerprint {
905    fn serialized_len(&self) -> usize {
906        self.as_bytes().len()
907    }
908
909    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
910        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
911    }
912}
913
914impl seal::Sealed for crypto::mpi::MPI {}
915impl Marshal for crypto::mpi::MPI {
916    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
917        write_be_u16(w, self.bits() as u16)?;
918        w.write_all(self.value())?;
919        Ok(())
920    }
921}
922
923impl MarshalInto for crypto::mpi::MPI {
924    fn serialized_len(&self) -> usize {
925        2 + self.value().len()
926    }
927
928    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
929        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
930    }
931}
932
933impl seal::Sealed for crypto::mpi::ProtectedMPI {}
934impl Marshal for crypto::mpi::ProtectedMPI {
935    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
936        write_be_u16(w, self.bits() as u16)?;
937        w.write_all(self.value())?;
938        Ok(())
939    }
940}
941
942impl MarshalInto for crypto::mpi::ProtectedMPI {
943    fn serialized_len(&self) -> usize {
944        2 + self.value().len()
945    }
946
947    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
948        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
949    }
950}
951
952/// Writes `buf` into `w` prefixed by the length as u8, bailing out if
953/// the length exceeds 256 bytes.
954fn write_field_with_u8_size(w: &mut dyn Write, name: &str, buf: &[u8])
955                            -> Result<()> {
956    w.write_all(&[buf.len().try_into()
957                  .map_err(|_| anyhow::Error::from(
958                      Error::InvalidArgument(
959                          format!("{} exceeds 255 bytes: {:?}",
960                                  name, buf))))?])?;
961    w.write_all(buf)?;
962    Ok(())
963}
964
965impl seal::Sealed for crypto::mpi::PublicKey {}
966impl Marshal for crypto::mpi::PublicKey {
967    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
968        use crate::crypto::mpi::PublicKey::*;
969
970        match self {
971            RSA { ref e, ref n } => {
972                n.serialize(w)?;
973                e.serialize(w)?;
974            }
975
976            DSA { ref p, ref q, ref g, ref y } => {
977                p.serialize(w)?;
978                q.serialize(w)?;
979                g.serialize(w)?;
980                y.serialize(w)?;
981            }
982
983            ElGamal { ref p, ref g, ref y } => {
984                p.serialize(w)?;
985                g.serialize(w)?;
986                y.serialize(w)?;
987            }
988
989            EdDSA { ref curve, ref q } => {
990                write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
991                q.serialize(w)?;
992            }
993
994            ECDSA { ref curve, ref q } => {
995                write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
996                q.serialize(w)?;
997            }
998
999            ECDH { ref curve, ref q, hash, sym } => {
1000                write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
1001                q.serialize(w)?;
1002                w.write_all(&[3u8, 1u8, u8::from(*hash), u8::from(*sym)])?;
1003            }
1004
1005            X25519 { u } => w.write_all(&u[..])?,
1006            X448 { u } => w.write_all(&u[..])?,
1007            Ed25519 { a } => w.write_all(&a[..])?,
1008            Ed448 { a } => w.write_all(&a[..])?,
1009
1010            MLDSA65_Ed25519 { eddsa, mldsa } => {
1011                w.write_all(eddsa.as_ref())?;
1012                w.write_all(mldsa.as_ref())?;
1013            },
1014
1015            MLDSA87_Ed448 { eddsa, mldsa } => {
1016                w.write_all(eddsa.as_ref())?;
1017                w.write_all(mldsa.as_ref())?;
1018            },
1019
1020            SLHDSA128s { public } => {
1021                w.write_all(public)?;
1022            },
1023
1024            SLHDSA128f { public } => {
1025                w.write_all(public)?;
1026            },
1027
1028            SLHDSA256s { public } => {
1029                w.write_all(public.as_ref())?;
1030            },
1031
1032            MLKEM768_X25519 { ecdh, mlkem } => {
1033                w.write_all(ecdh.as_ref())?;
1034                w.write_all(mlkem.as_ref())?;
1035            },
1036
1037            MLKEM1024_X448 { ecdh, mlkem } => {
1038                w.write_all(ecdh.as_ref())?;
1039                w.write_all(mlkem.as_ref())?;
1040            },
1041
1042            Unknown { ref mpis, ref rest } => {
1043                for mpi in mpis.iter() {
1044                    mpi.serialize(w)?;
1045                }
1046                w.write_all(rest)?;
1047            }
1048        }
1049
1050        Ok(())
1051    }
1052}
1053
1054impl MarshalInto for crypto::mpi::PublicKey {
1055    fn serialized_len(&self) -> usize {
1056        use crate::crypto::mpi::PublicKey::*;
1057        match self {
1058            RSA { ref e, ref n } => {
1059                n.serialized_len() + e.serialized_len()
1060            }
1061
1062            DSA { ref p, ref q, ref g, ref y } => {
1063                p.serialized_len() + q.serialized_len() + g.serialized_len()
1064                    + y.serialized_len()
1065            }
1066
1067            ElGamal { ref p, ref g, ref y } => {
1068                p.serialized_len() + g.serialized_len() + y.serialized_len()
1069            }
1070
1071            EdDSA { ref curve, ref q } => {
1072                1 + curve.oid().len() + q.serialized_len()
1073            }
1074
1075            ECDSA { ref curve, ref q } => {
1076                1 + curve.oid().len() + q.serialized_len()
1077            }
1078
1079            ECDH { ref curve, ref q, hash: _, sym: _ } => {
1080                1 + curve.oid().len() + q.serialized_len() + 4
1081            }
1082
1083            X25519 { .. } => 32,
1084            X448 { .. } => 56,
1085            Ed25519 { .. } => 32,
1086            Ed448 { .. } => 57,
1087
1088            MLDSA65_Ed25519 { .. } => 32 + 1952,
1089            MLDSA87_Ed448 { .. } => 57 + 2592,
1090
1091            SLHDSA128s { .. } => 32,
1092            SLHDSA128f { .. } => 32,
1093            SLHDSA256s { .. } => 64,
1094
1095            MLKEM768_X25519 { .. } => 32 + 1184,
1096            MLKEM1024_X448 { .. } => 56 + 1568,
1097
1098            Unknown { ref mpis, ref rest } => {
1099                mpis.iter().map(|mpi| mpi.serialized_len()).sum::<usize>()
1100                    + rest.len()
1101            }
1102        }
1103    }
1104
1105    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1106        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1107    }
1108}
1109
1110impl seal::Sealed for crypto::mpi::SecretKeyMaterial {}
1111impl Marshal for crypto::mpi::SecretKeyMaterial {
1112    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
1113        use crate::crypto::mpi::SecretKeyMaterial::*;
1114
1115        match self {
1116            RSA{ ref d, ref p, ref q, ref u } => {
1117                d.serialize(w)?;
1118                p.serialize(w)?;
1119                q.serialize(w)?;
1120                u.serialize(w)?;
1121            }
1122
1123            DSA{ ref x } => {
1124                x.serialize(w)?;
1125            }
1126
1127            ElGamal{ ref x } => {
1128                x.serialize(w)?;
1129            }
1130
1131            EdDSA{ ref scalar } => {
1132                scalar.serialize(w)?;
1133            }
1134
1135            ECDSA{ ref scalar } => {
1136                scalar.serialize(w)?;
1137            }
1138
1139            ECDH{ ref scalar } => {
1140                scalar.serialize(w)?;
1141            }
1142
1143            X25519 { x } => w.write_all(x)?,
1144            X448 { x } => w.write_all(x)?,
1145            Ed25519 { x } => w.write_all(x)?,
1146            Ed448 { x } => w.write_all(x)?,
1147
1148            MLDSA65_Ed25519 { eddsa, mldsa } => {
1149                w.write_all(eddsa.as_ref())?;
1150                w.write_all(mldsa.as_ref())?;
1151            },
1152
1153            MLDSA87_Ed448 { eddsa, mldsa } => {
1154                w.write_all(eddsa.as_ref())?;
1155                w.write_all(mldsa.as_ref())?;
1156            },
1157
1158            SLHDSA128s { secret } => {
1159                w.write_all(secret.as_ref())?;
1160            },
1161
1162            SLHDSA128f { secret } => {
1163                w.write_all(secret.as_ref())?;
1164            },
1165
1166            SLHDSA256s { secret } => {
1167                w.write_all(secret.as_ref())?;
1168            },
1169
1170            MLKEM768_X25519 { ecdh, mlkem } => {
1171                w.write_all(ecdh.as_ref())?;
1172                w.write_all(mlkem.as_ref())?;
1173            },
1174
1175            MLKEM1024_X448 { ecdh, mlkem } => {
1176                w.write_all(ecdh.as_ref())?;
1177                w.write_all(mlkem.as_ref())?;
1178            },
1179
1180            Unknown { ref mpis, ref rest } => {
1181                for mpi in mpis.iter() {
1182                    mpi.serialize(w)?;
1183                }
1184                w.write_all(rest)?;
1185            }
1186        }
1187
1188        Ok(())
1189    }
1190}
1191
1192impl MarshalInto for crypto::mpi::SecretKeyMaterial {
1193    fn serialized_len(&self) -> usize {
1194        use crate::crypto::mpi::SecretKeyMaterial::*;
1195        match self {
1196            RSA{ ref d, ref p, ref q, ref u } => {
1197                d.serialized_len() + p.serialized_len() + q.serialized_len()
1198                    + u.serialized_len()
1199            }
1200
1201            DSA{ ref x } => {
1202                x.serialized_len()
1203            }
1204
1205            ElGamal{ ref x } => {
1206                x.serialized_len()
1207            }
1208
1209            EdDSA{ ref scalar } => {
1210                scalar.serialized_len()
1211            }
1212
1213            ECDSA{ ref scalar } => {
1214                scalar.serialized_len()
1215            }
1216
1217            ECDH{ ref scalar } => {
1218                scalar.serialized_len()
1219            }
1220
1221            X25519 { .. } => 32,
1222            X448 { .. } => 56,
1223            Ed25519 { .. } => 32,
1224            Ed448 { .. } => 57,
1225
1226            MLDSA65_Ed25519 { .. } => 32 + 32,
1227            MLDSA87_Ed448 { .. } => 57 + 32,
1228
1229            SLHDSA128s { .. } => 64,
1230            SLHDSA128f { .. } => 64,
1231            SLHDSA256s { .. } => 128,
1232
1233            MLKEM768_X25519 { .. } => 32 + 64,
1234            MLKEM1024_X448 { .. } => 56 + 64,
1235
1236            Unknown { ref mpis, ref rest } => {
1237                mpis.iter().map(|mpi| mpi.serialized_len()).sum::<usize>()
1238                    + rest.len()
1239            }
1240        }
1241    }
1242
1243    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1244        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1245    }
1246}
1247
1248impl crypto::mpi::SecretKeyMaterial {
1249    /// Writes this secret key with a checksum to `w`.
1250    pub fn serialize_with_checksum(
1251        &self, w: &mut dyn io::Write,
1252        checksum: crypto::mpi::SecretKeyChecksum)
1253        -> Result<()>
1254    {
1255        // First, the MPIs.
1256        self.serialize(w)?;
1257
1258        match checksum {
1259            crypto::mpi::SecretKeyChecksum::SHA1 => {
1260                // The checksum is SHA1 over the serialized MPIs.
1261                let mut hash =
1262                    HashAlgorithm::SHA1.context().unwrap().for_digest();
1263                self.serialize(&mut hash)?;
1264                let mut digest = [0u8; 20];
1265                let _ = hash.digest(&mut digest);
1266                w.write_all(&digest)?;
1267            },
1268            crypto::mpi::SecretKeyChecksum::Sum16 => {
1269                w.write_all(&self.to_vec()?.iter()
1270                            .fold(0u16, |acc, v| acc.wrapping_add(*v as u16))
1271                            .to_be_bytes())?;
1272            },
1273        }
1274
1275        Ok(())
1276    }
1277}
1278
1279impl seal::Sealed for crypto::mpi::Ciphertext {}
1280impl Marshal for crypto::mpi::Ciphertext {
1281    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
1282        use crate::crypto::mpi::Ciphertext::*;
1283
1284        match self {
1285            RSA{ ref c } => {
1286                c.serialize(w)?;
1287            }
1288
1289            ElGamal{ ref e, ref c } => {
1290                e.serialize(w)?;
1291                c.serialize(w)?;
1292            }
1293
1294            ECDH{ ref e, ref key } => {
1295                e.serialize(w)?;
1296                write_field_with_u8_size(w, "Key", key)?;
1297            }
1298
1299            X25519 {  e, key } => {
1300                w.write_all(&e[..])?;
1301                write_field_with_u8_size(w, "Key", key)?;
1302            }
1303
1304            X448 {  e, key } => {
1305                w.write_all(&e[..])?;
1306                write_field_with_u8_size(w, "Key", key)?;
1307            }
1308
1309            MLKEM768_X25519 { ecdh, mlkem, esk } => {
1310                w.write_all(ecdh.as_ref())?;
1311                w.write_all(mlkem.as_ref())?;
1312                write_field_with_u8_size(w, "ESK", esk)?;
1313            },
1314
1315            MLKEM1024_X448 { ecdh, mlkem, esk } => {
1316                w.write_all(ecdh.as_ref())?;
1317                w.write_all(mlkem.as_ref())?;
1318                write_field_with_u8_size(w, "ESK", esk)?;
1319            },
1320
1321            Unknown { ref mpis, ref rest } => {
1322                for mpi in mpis.iter() {
1323                    mpi.serialize(w)?;
1324                }
1325                w.write_all(rest)?;
1326            }
1327        }
1328
1329        Ok(())
1330    }
1331}
1332
1333impl MarshalInto for crypto::mpi::Ciphertext {
1334    fn serialized_len(&self) -> usize {
1335        use crate::crypto::mpi::Ciphertext::*;
1336        match self {
1337            RSA{ ref c } => {
1338                c.serialized_len()
1339            }
1340
1341            ElGamal{ ref e, ref c } => {
1342                e.serialized_len() + c.serialized_len()
1343            }
1344
1345            ECDH{ ref e, ref key } => {
1346                e.serialized_len() + 1 + key.len()
1347            }
1348
1349            X25519 { key, .. } => {
1350                32 + 1 + key.len()
1351            }
1352
1353            X448 { key, .. } => {
1354                56 + 1 + key.len()
1355            }
1356
1357            MLKEM768_X25519 { esk, .. } =>
1358                32 + 1088 + 1 + esk.len(),
1359
1360            MLKEM1024_X448 { esk, .. } =>
1361                56 + 1568 + 1 + esk.len(),
1362
1363            Unknown { ref mpis, ref rest } => {
1364                mpis.iter().map(|mpi| mpi.serialized_len()).sum::<usize>()
1365                    + rest.len()
1366            }
1367        }
1368    }
1369
1370    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1371        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1372    }
1373}
1374
1375impl seal::Sealed for crypto::mpi::Signature {}
1376impl Marshal for crypto::mpi::Signature {
1377    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
1378        use crate::crypto::mpi::Signature::*;
1379
1380        match self {
1381            RSA { ref s } => {
1382                s.serialize(w)?;
1383            }
1384            DSA { ref r, ref s } => {
1385                r.serialize(w)?;
1386                s.serialize(w)?;
1387            }
1388            ElGamal { ref r, ref s } => {
1389                r.serialize(w)?;
1390                s.serialize(w)?;
1391            }
1392            EdDSA { ref r, ref s } => {
1393                r.serialize(w)?;
1394                s.serialize(w)?;
1395            }
1396            ECDSA { ref r, ref s } => {
1397                r.serialize(w)?;
1398                s.serialize(w)?;
1399            }
1400
1401            Ed25519 { s } => w.write_all(&s[..])?,
1402            Ed448 { s } => w.write_all(&s[..])?,
1403
1404            SLHDSA128s { sig } => {
1405                w.write_all(sig.as_ref())?;
1406            },
1407
1408            SLHDSA128f { sig } => {
1409                w.write_all(sig.as_ref())?;
1410            },
1411
1412            SLHDSA256s { sig } => {
1413                w.write_all(sig.as_ref())?;
1414            },
1415
1416
1417            MLDSA65_Ed25519 { eddsa, mldsa } => {
1418                w.write_all(&eddsa[..])?;
1419                w.write_all(&mldsa[..])?;
1420            },
1421
1422            MLDSA87_Ed448 { eddsa, mldsa } => {
1423                w.write_all(&eddsa[..])?;
1424                w.write_all(&mldsa[..])?;
1425            },
1426
1427            Unknown { ref mpis, ref rest } => {
1428                for mpi in mpis.iter() {
1429                    mpi.serialize(w)?;
1430                }
1431                w.write_all(rest)?;
1432            }
1433        }
1434
1435        Ok(())
1436    }
1437}
1438
1439impl MarshalInto for crypto::mpi::Signature {
1440    fn serialized_len(&self) -> usize {
1441        use crate::crypto::mpi::Signature::*;
1442        match self {
1443            RSA { ref s } => {
1444                s.serialized_len()
1445            }
1446            DSA { ref r, ref s } => {
1447                r.serialized_len() + s.serialized_len()
1448            }
1449            ElGamal { ref r, ref s } => {
1450                r.serialized_len() + s.serialized_len()
1451            }
1452            EdDSA { ref r, ref s } => {
1453                r.serialized_len() + s.serialized_len()
1454            }
1455            ECDSA { ref r, ref s } => {
1456                r.serialized_len() + s.serialized_len()
1457            }
1458
1459            Ed25519 { .. } => 64,
1460            Ed448 { .. } => 114,
1461
1462            MLDSA65_Ed25519 { .. } => 64 + 3309,
1463            MLDSA87_Ed448 { .. } => 114 + 4627,
1464
1465            SLHDSA128s { .. } => 7856,
1466            SLHDSA128f { .. } => 17088,
1467            SLHDSA256s { .. } => 29792,
1468
1469            Unknown { ref mpis, ref rest } => {
1470                mpis.iter().map(|mpi| mpi.serialized_len()).sum::<usize>()
1471                    + rest.len()
1472            }
1473        }
1474    }
1475
1476    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1477        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1478    }
1479}
1480
1481impl seal::Sealed for S2K {}
1482impl Marshal for S2K {
1483    fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
1484        #[allow(deprecated)]
1485        match self {
1486            &S2K::Simple{ hash } => {
1487                w.write_all(&[0, hash.into()])?;
1488            }
1489            &S2K::Salted{ hash, salt } => {
1490                w.write_all(&[1, hash.into()])?;
1491                w.write_all(&salt[..])?;
1492            }
1493            &S2K::Iterated{ hash, salt, hash_bytes } => {
1494                w.write_all(&[3, hash.into()])?;
1495                w.write_all(&salt[..])?;
1496                w.write_all(&[S2K::encode_count(hash_bytes)?])?;
1497            }
1498            S2K::Implicit => (),
1499            S2K::Argon2 { salt, t, p, m, } => {
1500                w.write_all(&[4])?;
1501                w.write_all(salt)?;
1502                w.write_all(&[*t, *p, *m])?;
1503            },
1504            S2K::Private { tag, parameters }
1505            | S2K::Unknown { tag, parameters} => {
1506                w.write_all(&[*tag])?;
1507                if let Some(p) = parameters.as_ref() {
1508                    w.write_all(p)?;
1509                }
1510            }
1511        }
1512
1513        Ok(())
1514    }
1515}
1516
1517impl MarshalInto for S2K {
1518    fn serialized_len(&self) -> usize {
1519        #[allow(deprecated)]
1520        match self {
1521            &S2K::Simple{ .. } => 2,
1522            &S2K::Salted{ .. } => 2 + 8,
1523            &S2K::Iterated{ .. } => 2 + 8 + 1,
1524            S2K::Implicit => 0,
1525            S2K::Argon2 { .. } => 20,
1526            S2K::Private { parameters, .. }
1527            | S2K::Unknown { parameters, .. } =>
1528                1 + parameters.as_ref().map(|p| p.len()).unwrap_or(0),
1529        }
1530    }
1531
1532    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1533        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1534    }
1535}
1536
1537impl seal::Sealed for Unknown {}
1538impl Marshal for Unknown {
1539    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1540        o.write_all(self.body())?;
1541        Ok(())
1542    }
1543}
1544
1545impl NetLength for Unknown {
1546    fn net_len(&self) -> usize {
1547        self.body().len()
1548    }
1549}
1550
1551impl MarshalInto for Unknown {
1552    fn serialized_len(&self) -> usize {
1553        self.net_len()
1554    }
1555
1556    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1557        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1558    }
1559}
1560
1561impl seal::Sealed for SubpacketArea {}
1562impl Marshal for SubpacketArea {
1563    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1564        for sb in self.iter() {
1565            sb.serialize(o)?;
1566        }
1567        Ok(())
1568    }
1569}
1570
1571impl MarshalInto for SubpacketArea {
1572    fn serialized_len(&self) -> usize {
1573        self.iter().map(|sb| sb.serialized_len()).sum()
1574    }
1575
1576    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1577        let mut written = 0;
1578        for sb in self.iter() {
1579            let n = sb.serialize_into(&mut buf[written..])?;
1580            written += cmp::min(buf.len() - written, n);
1581        }
1582        Ok(written)
1583    }
1584}
1585
1586impl seal::Sealed for Subpacket {}
1587impl Marshal for Subpacket {
1588    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1589        let tag = u8::from(self.tag())
1590            | if self.critical() { 1 << 7 } else { 0 };
1591
1592        self.length.serialize(o)?;
1593        o.write_all(&[tag])?;
1594        self.value().serialize(o)
1595    }
1596}
1597
1598impl MarshalInto for Subpacket {
1599    fn serialized_len(&self) -> usize {
1600        self.length.serialized_len() + 1 + self.value().serialized_len()
1601    }
1602
1603    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1604        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1605    }
1606}
1607
1608impl seal::Sealed for SubpacketValue {}
1609impl Marshal for SubpacketValue {
1610    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1611        use self::SubpacketValue::*;
1612        #[allow(deprecated)]
1613        match self {
1614            SignatureCreationTime(t) =>
1615                write_be_u32(o, (*t).into())?,
1616            SignatureExpirationTime(t) =>
1617                write_be_u32(o, (*t).into())?,
1618            ExportableCertification(e) =>
1619                o.write_all(&[if *e { 1 } else { 0 }])?,
1620            TrustSignature { ref level, ref trust } =>
1621                o.write_all(&[*level, *trust])?,
1622            RegularExpression(ref re) => {
1623                o.write_all(re)?;
1624                o.write_all(&[0])?;
1625            },
1626            Revocable(r) =>
1627                o.write_all(&[if *r { 1 } else { 0 }])?,
1628            KeyExpirationTime(t) =>
1629                write_be_u32(o, (*t).into())?,
1630            PreferredSymmetricAlgorithms(ref p) =>
1631                for a in p {
1632                    o.write_all(&[(*a).into()])?;
1633                },
1634            RevocationKey(rk) => rk.serialize(o)?,
1635            Issuer(ref id) =>
1636                o.write_all(id.as_bytes())?,
1637            NotationData(nd) => {
1638                o.write_all(nd.flags().as_bitfield().as_bytes())?;
1639                write_be_u16(o, nd.name().len() as u16)?;
1640                write_be_u16(o, nd.value().len() as u16)?;
1641                o.write_all(nd.name().as_bytes())?;
1642                o.write_all(nd.value())?;
1643            },
1644            PreferredHashAlgorithms(ref p) =>
1645                for a in p {
1646                    o.write_all(&[(*a).into()])?;
1647                },
1648            PreferredCompressionAlgorithms(ref p) =>
1649                for a in p {
1650                    o.write_all(&[(*a).into()])?;
1651                },
1652            KeyServerPreferences(ref p) =>
1653                o.write_all(p.as_bitfield().as_bytes())?,
1654            PreferredKeyServer(ref p) =>
1655                o.write_all(p)?,
1656            PrimaryUserID(p) =>
1657                o.write_all(&[if *p { 1 } else { 0 }])?,
1658            PolicyURI(ref p) =>
1659                o.write_all(p)?,
1660            KeyFlags(ref f) =>
1661                o.write_all(f.as_bitfield().as_bytes())?,
1662            SignersUserID(ref uid) =>
1663                o.write_all(uid)?,
1664            ReasonForRevocation { ref code, ref reason } => {
1665                o.write_all(&[(*code).into()])?;
1666                o.write_all(reason)?;
1667            },
1668            Features(ref f) =>
1669                o.write_all(f.as_bitfield().as_bytes())?,
1670            SignatureTarget { pk_algo, hash_algo, ref digest } => {
1671                o.write_all(&[(*pk_algo).into(), (*hash_algo).into()])?;
1672                o.write_all(digest)?;
1673            },
1674            EmbeddedSignature(sig) => sig.serialize(o)?,
1675            IssuerFingerprint(ref fp) => match fp {
1676                Fingerprint::V4(_) => {
1677                    o.write_all(&[4])?;
1678                    o.write_all(fp.as_bytes())?;
1679                },
1680                Fingerprint::V6(_) => {
1681                    o.write_all(&[6])?;
1682                    o.write_all(fp.as_bytes())?;
1683                },
1684                _ => return Err(Error::InvalidArgument(
1685                    "Unknown kind of fingerprint".into()).into()),
1686            }
1687            IntendedRecipient(ref fp) => match fp {
1688                Fingerprint::V4(_) => {
1689                    o.write_all(&[4])?;
1690                    o.write_all(fp.as_bytes())?;
1691                },
1692                Fingerprint::V6(_) => {
1693                    o.write_all(&[6])?;
1694                    o.write_all(fp.as_bytes())?;
1695                },
1696                _ => return Err(Error::InvalidArgument(
1697                    "Unknown kind of fingerprint".into()).into()),
1698            }
1699            ApprovedCertifications(digests) => {
1700                for digest in digests {
1701                    o.write_all(digest)?;
1702                }
1703            },
1704
1705            PreferredAEADCiphersuites(p) =>
1706                for (symm, aead) in p {
1707                    o.write_all(&[(*symm).into(), (*aead).into()])?;
1708                },
1709
1710            Unknown { body, .. } =>
1711                o.write_all(body)?,
1712        }
1713        Ok(())
1714    }
1715}
1716
1717impl MarshalInto for SubpacketValue {
1718    fn serialized_len(&self) -> usize {
1719        use self::SubpacketValue::*;
1720        #[allow(deprecated)]
1721        match self {
1722            SignatureCreationTime(_) => 4,
1723            SignatureExpirationTime(_) => 4,
1724            ExportableCertification(_) => 1,
1725            TrustSignature { .. } => 2,
1726            RegularExpression(ref re) => re.len() + 1,
1727            Revocable(_) => 1,
1728            KeyExpirationTime(_) => 4,
1729            PreferredSymmetricAlgorithms(ref p) => p.len(),
1730            RevocationKey(rk) => rk.serialized_len(),
1731            Issuer(ref id) => (id as &dyn MarshalInto).serialized_len(),
1732            NotationData(nd) => 4 + 2 + 2 + nd.name().len() + nd.value().len(),
1733            PreferredHashAlgorithms(ref p) => p.len(),
1734            PreferredCompressionAlgorithms(ref p) => p.len(),
1735            KeyServerPreferences(p) => p.as_bitfield().as_bytes().len(),
1736            PreferredKeyServer(ref p) => p.len(),
1737            PrimaryUserID(_) => 1,
1738            PolicyURI(ref p) => p.len(),
1739            KeyFlags(f) => f.as_bitfield().as_bytes().len(),
1740            SignersUserID(ref uid) => uid.len(),
1741            ReasonForRevocation { ref reason, .. } => 1 + reason.len(),
1742            Features(f) => f.as_bitfield().as_bytes().len(),
1743            SignatureTarget { ref digest, .. } => 2 + digest.len(),
1744            EmbeddedSignature(sig) => sig.serialized_len(),
1745            IssuerFingerprint(ref fp) =>
1746                1 + (fp as &dyn MarshalInto).serialized_len(),
1747            IntendedRecipient(ref fp) =>
1748                1 + (fp as &dyn MarshalInto).serialized_len(),
1749            ApprovedCertifications(digests) =>
1750                digests.iter().map(|d| d.len()).sum(),
1751            PreferredAEADCiphersuites(c) => c.len() * 2,
1752            Unknown { body, .. } => body.len(),
1753        }
1754    }
1755
1756    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1757        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1758    }
1759}
1760
1761impl seal::Sealed for SubpacketLength {}
1762impl Marshal for SubpacketLength {
1763    /// Writes the subpacket length to `sink`.
1764    fn serialize(&self, sink: &mut dyn std::io::Write)
1765                            -> Result<()> {
1766        match self.raw {
1767            Some(ref raw) => sink.write_all(raw)?,
1768            None => {
1769                BodyLength::serialize(&BodyLength::Full(self.len() as u32), sink)?
1770            }
1771        };
1772
1773        Ok(())
1774    }
1775}
1776
1777impl MarshalInto for SubpacketLength {
1778    /// Returns the length of the serialized subpacket length.
1779    fn serialized_len(&self) -> usize {
1780        if let Some(ref raw) = self.raw {
1781            raw.len()
1782        } else {
1783            Self::len_optimal_encoding(self.len() as u32)
1784        }
1785    }
1786
1787    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1788        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1789    }
1790}
1791
1792
1793impl seal::Sealed for RevocationKey {}
1794impl Marshal for RevocationKey {
1795    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1796        let (pk_algo, fp) = self.revoker();
1797        o.write_all(&[self.class(), pk_algo.into()])?;
1798        o.write_all(fp.as_bytes())?;
1799        Ok(())
1800    }
1801}
1802
1803impl MarshalInto for RevocationKey {
1804    fn serialized_len(&self) -> usize {
1805        1 + 1 + self.revoker().1.as_bytes().len()
1806    }
1807
1808    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1809        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1810    }
1811}
1812
1813impl seal::Sealed for Signature {}
1814impl Marshal for Signature {
1815    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1816        match self {
1817            Signature::V3(ref s) => s.serialize(o),
1818            Signature::V4(ref s) => s.serialize(o),
1819            Signature::V6(ref s) => s.serialize(o),
1820        }
1821    }
1822
1823    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
1824        match self {
1825            Signature::V3(ref s) => s.export(o),
1826            Signature::V4(ref s) => s.export(o),
1827            Signature::V6(ref s) => s.export(o),
1828        }
1829    }
1830}
1831
1832impl MarshalInto for Signature {
1833    fn serialized_len(&self) -> usize {
1834        match self {
1835            Signature::V3(ref s) => s.serialized_len(),
1836            Signature::V4(ref s) => s.serialized_len(),
1837            Signature::V6(ref s) => s.serialized_len(),
1838        }
1839    }
1840
1841    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1842        match self {
1843            Signature::V3(ref s) => s.serialize_into(buf),
1844            Signature::V4(ref s) => s.serialize_into(buf),
1845            Signature::V6(ref s) => s.serialize_into(buf),
1846        }
1847    }
1848
1849    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
1850        match self {
1851            Signature::V3(ref s) => s.export_into(buf),
1852            Signature::V4(ref s) => s.export_into(buf),
1853            Signature::V6(ref s) => s.export_into(buf),
1854        }
1855    }
1856
1857    fn export_to_vec(&self) -> Result<Vec<u8>> {
1858        match self {
1859            Signature::V3(ref s) => s.export_to_vec(),
1860            Signature::V4(ref s) => s.export_to_vec(),
1861            Signature::V6(ref s) => s.export_to_vec(),
1862        }
1863    }
1864}
1865
1866impl NetLength for Signature {
1867    fn net_len(&self) -> usize {
1868        match self {
1869            Signature::V3(sig) => sig.net_len(),
1870            Signature::V4(sig) => sig.net_len(),
1871            Signature::V6(sig) => sig.net_len(),
1872        }
1873    }
1874}
1875
1876impl seal::Sealed for Signature3 {}
1877impl Marshal for Signature3 {
1878    /// Writes a serialized version of the specified `Signature`
1879    /// packet to `o`.
1880    ///
1881    /// # Errors
1882    ///
1883    /// Returns [`Error::InvalidArgument`] if `self` does not contain
1884    /// a valid v3 signature.  Because v3 signature support was added
1885    /// late in the 1.x release cycle, `Signature3` is just a thin
1886    /// wrapper around a `Signature4`.  As such, it is possible to add
1887    /// v4 specific data to a `Signature3`.  In general, this isn't a
1888    /// significnat problem as generating v3 is deprecated.
1889    ///
1890    /// [`Error::InvalidArgument`]: Error::InvalidArgument
1891    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
1892        use crate::packet::signature::subpacket::SubpacketTag;
1893
1894        assert_eq!(self.version(), 3);
1895        write_byte(o, self.version())?;
1896        // hashed length.
1897        write_byte(o, 5)?;
1898        write_byte(o, self.typ().into())?;
1899        if let Some(SubpacketValue::SignatureCreationTime(ct))
1900            = self.hashed_area().subpacket(
1901                SubpacketTag::SignatureCreationTime)
1902            .map(|sp| sp.value())
1903        {
1904            write_be_u32(o, u32::from(*ct))?;
1905        } else {
1906            return Err(Error::InvalidArgument(
1907                "Invalid v3 signature, missing creation time.".into()).into());
1908        }
1909
1910        // Only one signature creation time subpacket is allowed in
1911        // the hashed area.
1912        let mut iter = self.hashed_area().iter();
1913        let _ = iter.next();
1914        if iter.next().is_some() {
1915            return Err(Error::InvalidArgument(
1916                format!("Invalid v3 signature: \
1917                         subpackets are not allowed: {}",
1918                        self.hashed_area().iter().map(|sp| {
1919                            format!("{}: {:?}", sp.tag(), sp.value())
1920                        }).collect::<Vec<String>>().join(", "))).into());
1921        }
1922
1923        if let Some(SubpacketValue::Issuer(keyid))
1924            = self.unhashed_area().subpacket(SubpacketTag::Issuer)
1925            .map(|sp| sp.value())
1926        {
1927            match keyid {
1928                KeyID::Long(bytes) => {
1929                    assert_eq!(bytes.len(), 8);
1930                    o.write_all(&bytes[..])?;
1931                }
1932                KeyID::Invalid(_) => {
1933                    return Err(Error::InvalidArgument(
1934                        "Invalid v3 signature, invalid issuer.".into()).into());
1935                }
1936            }
1937        } else {
1938            return Err(Error::InvalidArgument(
1939                "Invalid v3 signature, missing issuer.".into()).into());
1940        }
1941
1942        // Only one issuer subpacket is allowed in the unhashed area.
1943        let mut iter = self.unhashed_area().iter();
1944        let _ = iter.next();
1945        if iter.next().is_some() {
1946            return Err(Error::InvalidArgument(
1947                format!("Invalid v3 signature: \
1948                         subpackets are not allowed: {}",
1949                        self.unhashed_area().iter().map(|sp| {
1950                            format!("{}: {:?}", sp.tag(), sp.value())
1951                        }).collect::<Vec<String>>().join(", "))).into());
1952        }
1953
1954        write_byte(o, self.pk_algo().into())?;
1955        write_byte(o, self.hash_algo().into())?;
1956
1957        write_byte(o, self.digest_prefix()[0])?;
1958        write_byte(o, self.digest_prefix()[1])?;
1959
1960        self.mpis().serialize(o)?;
1961
1962        Ok(())
1963    }
1964
1965    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
1966        self.exportable()?;
1967        self.serialize(o)
1968    }
1969}
1970
1971impl NetLength for Signature3 {
1972    fn net_len(&self) -> usize {
1973        assert_eq!(self.version(), 3);
1974
1975        1 // Version.
1976            + 1 // Hashed length.
1977            + 1 // Signature type.
1978            + 4 // Creation time.
1979            + 8 // Issuer.
1980            + 1 // PK algorithm.
1981            + 1 // Hash algorithm.
1982            + 2 // Hash prefix.
1983            + self.mpis().serialized_len()
1984    }
1985}
1986
1987impl MarshalInto for Signature3 {
1988    fn serialized_len(&self) -> usize {
1989        self.net_len()
1990    }
1991
1992    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
1993        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
1994    }
1995
1996    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
1997        self.exportable()?;
1998        self.serialize_into(buf)
1999    }
2000
2001    fn export_to_vec(&self) -> Result<Vec<u8>> {
2002        self.exportable()?;
2003        self.to_vec()
2004    }
2005}
2006
2007impl seal::Sealed for Signature4 {}
2008impl Marshal for Signature4 {
2009    /// Writes a serialized version of the specified `Signature`
2010    /// packet to `o`.
2011    ///
2012    /// # Errors
2013    ///
2014    /// Returns [`Error::InvalidArgument`] if either the hashed-area
2015    /// or the unhashed-area exceeds the size limit of 2^16.
2016    ///
2017    /// [`Error::InvalidArgument`]: Error::InvalidArgument
2018    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2019        assert_eq!(self.version(), 4);
2020        write_byte(o, self.version())?;
2021        write_byte(o, self.typ().into())?;
2022        write_byte(o, self.pk_algo().into())?;
2023        write_byte(o, self.hash_algo().into())?;
2024
2025        let l = self.hashed_area().serialized_len();
2026        if l > std::u16::MAX as usize {
2027            return Err(Error::InvalidArgument(
2028                "Hashed area too large".into()).into());
2029        }
2030        write_be_u16(o, l as u16)?;
2031        self.hashed_area().serialize(o)?;
2032
2033        let l = self.unhashed_area().serialized_len();
2034        if l > std::u16::MAX as usize {
2035            return Err(Error::InvalidArgument(
2036                "Unhashed area too large".into()).into());
2037        }
2038        write_be_u16(o, l as u16)?;
2039        self.unhashed_area().serialize(o)?;
2040
2041        write_byte(o, self.digest_prefix()[0])?;
2042        write_byte(o, self.digest_prefix()[1])?;
2043
2044        self.mpis().serialize(o)?;
2045
2046        Ok(())
2047    }
2048
2049    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
2050        self.exportable()?;
2051        self.serialize(o)
2052    }
2053}
2054
2055impl NetLength for Signature4 {
2056    fn net_len(&self) -> usize {
2057        assert_eq!(self.version(), 4);
2058
2059        1 // Version.
2060            + 1 // Signature type.
2061            + 1 // PK algorithm.
2062            + 1 // Hash algorithm.
2063            + 2 // Hashed area size.
2064            + self.hashed_area().serialized_len()
2065            + 2 // Unhashed area size.
2066            + self.unhashed_area().serialized_len()
2067            + 2 // Hash prefix.
2068            + self.mpis().serialized_len()
2069    }
2070}
2071
2072impl MarshalInto for Signature4 {
2073    fn serialized_len(&self) -> usize {
2074        self.net_len()
2075    }
2076
2077    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2078        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2079    }
2080
2081    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
2082        self.exportable()?;
2083        self.serialize_into(buf)
2084    }
2085
2086    fn export_to_vec(&self) -> Result<Vec<u8>> {
2087        self.exportable()?;
2088        self.to_vec()
2089    }
2090}
2091
2092impl seal::Sealed for Signature6 {}
2093impl Marshal for Signature6 {
2094    /// Writes a serialized version of the specified `Signature`
2095    /// packet to `o`.
2096    ///
2097    /// # Errors
2098    ///
2099    /// Returns [`Error::InvalidArgument`] if either the hashed-area
2100    /// or the unhashed-area exceeds the size limit of 2^16.
2101    ///
2102    /// [`Error::InvalidArgument`]: Error::InvalidArgument
2103    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2104        assert_eq!(self.version(), 6);
2105        write_byte(o, self.version())?;
2106        write_byte(o, self.typ().into())?;
2107        write_byte(o, self.pk_algo().into())?;
2108        write_byte(o, self.hash_algo().into())?;
2109
2110        let l = self.hashed_area().serialized_len();
2111        if l > u32::MAX as usize {
2112            return Err(Error::InvalidArgument(
2113                "Hashed area too large".into()).into());
2114        }
2115        write_be_u32(o, l as u32)?;
2116        self.hashed_area().serialize(o)?;
2117
2118        let l = self.unhashed_area().serialized_len();
2119        if l > u32::MAX as usize {
2120            return Err(Error::InvalidArgument(
2121                "Unhashed area too large".into()).into());
2122        }
2123        write_be_u32(o, l as u32)?;
2124        self.unhashed_area().serialize(o)?;
2125
2126        write_byte(o, self.digest_prefix()[0])?;
2127        write_byte(o, self.digest_prefix()[1])?;
2128        write_byte(o, self.salt().len() as u8)?;
2129        o.write_all(self.salt())?;
2130
2131        self.mpis().serialize(o)?;
2132
2133        Ok(())
2134    }
2135
2136    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
2137        self.exportable()?;
2138        self.serialize(o)
2139    }
2140}
2141
2142impl NetLength for Signature6 {
2143    fn net_len(&self) -> usize {
2144        assert_eq!(self.version(), 6);
2145
2146        1 // Version.
2147            + 1 // Signature type.
2148            + 1 // PK algorithm.
2149            + 1 // Hash algorithm.
2150            + 4 // Hashed area size.
2151            + self.hashed_area().serialized_len()
2152            + 4 // Unhashed area size.
2153            + self.unhashed_area().serialized_len()
2154            + 2 // Hash prefix.
2155            + 1 // Salt length.
2156            + self.salt().len()
2157            + self.mpis().serialized_len()
2158    }
2159}
2160
2161impl MarshalInto for Signature6 {
2162    fn serialized_len(&self) -> usize {
2163        self.net_len()
2164    }
2165
2166    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2167        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2168    }
2169
2170    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
2171        self.exportable()?;
2172        self.serialize_into(buf)
2173    }
2174
2175    fn export_to_vec(&self) -> Result<Vec<u8>> {
2176        self.exportable()?;
2177        self.to_vec()
2178    }
2179}
2180
2181impl seal::Sealed for OnePassSig {}
2182impl Marshal for OnePassSig {
2183    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2184        match self {
2185            OnePassSig::V3(ref s) => s.serialize(o),
2186            OnePassSig::V6(ref s) => s.serialize(o),
2187        }
2188    }
2189}
2190
2191impl MarshalInto for OnePassSig {
2192    fn serialized_len(&self) -> usize {
2193        match self {
2194            OnePassSig::V3(ref s) => s.serialized_len(),
2195            OnePassSig::V6(ref s) => s.serialized_len(),
2196        }
2197    }
2198
2199    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2200        match self {
2201            OnePassSig::V3(ref s) => s.serialize_into(buf),
2202            OnePassSig::V6(ref s) => s.serialize_into(buf),
2203        }
2204    }
2205}
2206
2207impl NetLength for OnePassSig {
2208    fn net_len(&self) -> usize {
2209        match self {
2210            OnePassSig::V3(ref s) => s.net_len(),
2211            OnePassSig::V6(ref s) => s.net_len(),
2212        }
2213    }
2214}
2215
2216impl seal::Sealed for OnePassSig3 {}
2217impl Marshal for OnePassSig3 {
2218    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2219        write_byte(o, 3)?; // Version.
2220        write_byte(o, self.typ().into())?;
2221        write_byte(o, self.hash_algo().into())?;
2222        write_byte(o, self.pk_algo().into())?;
2223        o.write_all(self.issuer().as_bytes())?;
2224        write_byte(o, self.last_raw())?;
2225
2226        Ok(())
2227    }
2228}
2229
2230impl NetLength for OnePassSig3 {
2231    fn net_len(&self) -> usize {
2232        1 // Version.
2233            + 1 // Signature type.
2234            + 1 // Hash algorithm
2235            + 1 // PK algorithm.
2236            + 8 // Issuer.
2237            + 1 // Last.
2238    }
2239}
2240
2241impl MarshalInto for OnePassSig3 {
2242    fn serialized_len(&self) -> usize {
2243        self.net_len()
2244    }
2245
2246    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2247        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2248    }
2249}
2250
2251impl seal::Sealed for OnePassSig6 {}
2252impl Marshal for OnePassSig6 {
2253    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2254        write_byte(o, 6)?; // Version.
2255        write_byte(o, self.typ().into())?;
2256        write_byte(o, self.hash_algo().into())?;
2257        write_byte(o, self.pk_algo().into())?;
2258        write_byte(o, self.salt().len().try_into().map_err(
2259            |_| Error::InvalidArgument("Salt too large".into()))?)?;
2260        o.write_all(self.salt())?;
2261        if let Fingerprint::V6(bytes) = self.issuer() {
2262            o.write_all(bytes)?;
2263        } else {
2264            return Err(Error::InvalidArgument(
2265                "Need a v6 fingerprint as issuer".into()).into());
2266        }
2267        write_byte(o, self.last_raw())?;
2268
2269        Ok(())
2270    }
2271}
2272
2273impl NetLength for OnePassSig6 {
2274    fn net_len(&self) -> usize {
2275        1 // Version.
2276            + 1 // Signature type.
2277            + 1 // Hash algorithm
2278            + 1 // PK algorithm.
2279            + 1 // The salt length.
2280            + self.salt().len() // The salt.
2281            + 32 // Issuer fingerprint.
2282            + 1 // Last.
2283    }
2284}
2285
2286impl MarshalInto for OnePassSig6 {
2287    fn serialized_len(&self) -> usize {
2288        self.net_len()
2289    }
2290
2291    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2292        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2293    }
2294}
2295
2296impl<P: key::KeyParts, R: key::KeyRole> seal::Sealed for Key<P, R> {}
2297impl<P: key::KeyParts, R: key::KeyRole> Marshal for Key<P, R> {
2298    fn serialize(&self, o: &mut dyn io::Write) -> Result<()> {
2299        match self {
2300            Key::V4(ref p) => p.serialize(o),
2301            Key::V6(ref p) => p.serialize(o),
2302        }
2303    }
2304}
2305
2306impl<P: key::KeyParts, R: key::KeyRole> MarshalInto for Key<P, R> {
2307    fn serialized_len(&self) -> usize {
2308        match self {
2309            Key::V4(ref p) => p.serialized_len(),
2310            Key::V6(ref p) => p.serialized_len(),
2311        }
2312    }
2313
2314    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2315        match self {
2316            Key::V4(ref p) => p.serialize_into(buf),
2317            Key::V6(ref p) => p.serialize_into(buf),
2318        }
2319    }
2320}
2321
2322impl<P: key::KeyParts, R: key::KeyRole> NetLength for Key<P, R> {
2323    fn net_len(&self) -> usize {
2324        match self {
2325            Key::V4(ref p) => p.net_len(),
2326            Key::V6(ref p) => p.net_len(),
2327        }
2328    }
2329}
2330impl<P, R> seal::Sealed for Key4<P, R>
2331    where P: key::KeyParts,
2332          R: key::KeyRole,
2333{}
2334impl<P, R> Marshal for Key4<P, R>
2335    where P: key::KeyParts,
2336          R: key::KeyRole,
2337{
2338    fn serialize(&self, o: &mut dyn io::Write) -> Result<()> {
2339        let have_secret_key = P::significant_secrets() && self.has_secret();
2340
2341        write_byte(o, 4)?; // Version.
2342        write_be_u32(o, self.creation_time_raw().into())?;
2343        write_byte(o, self.pk_algo().into())?;
2344        self.mpis().serialize(o)?;
2345
2346        if have_secret_key {
2347            use crypto::mpi::SecretKeyChecksum;
2348            match self.optional_secret().unwrap() {
2349                SecretKeyMaterial::Unencrypted(ref u) => u.map(|mpis| -> Result<()> {
2350                    write_byte(o, 0)?; // S2K usage.
2351                    mpis.serialize_with_checksum(o, SecretKeyChecksum::Sum16)
2352                })?,
2353                SecretKeyMaterial::Encrypted(ref e) => {
2354                    if let (Some(aead_algo), Some(aead_iv)) =
2355                        (e.aead_algo(), e.aead_iv())
2356                    {
2357                        o.write_all(&[
2358                            253, // S2K usage.
2359                            // No Parameter length for v4 packets.
2360                            e.algo().into(),
2361                            aead_algo.into(),
2362                        ])?;
2363                        e.s2k().serialize(o)?;
2364                        o.write_all(aead_iv)?;
2365                        o.write_all(e.raw_ciphertext())?;
2366                    } else {
2367                        // S2K usage
2368                        #[allow(deprecated)]
2369                        if let S2K::Implicit = e.s2k() {
2370                            // When the legacy implicit S2K mechanism is
2371                            // in use, the symmetric algorithm octet below
2372                            // takes the place of the S2K usage octet.
2373                        } else {
2374                            write_byte(o, match e.checksum() {
2375                                Some(SecretKeyChecksum::SHA1) => 254,
2376                                Some(SecretKeyChecksum::Sum16) => 255,
2377                                None => return Err(Error::InvalidOperation(
2378                                    "In Key4 packets, CFB encrypted secret keys must be \
2379                                     checksummed".into()).into()),
2380                            })?;
2381                        }
2382                        write_byte(o, e.algo().into())?;
2383                        e.s2k().serialize(o)?;
2384                        o.write_all(e.raw_ciphertext())?;
2385                    }
2386                },
2387            }
2388        }
2389
2390        Ok(())
2391    }
2392}
2393
2394impl<P, R> NetLength for Key4<P, R>
2395    where P: key::KeyParts,
2396          R: key::KeyRole,
2397{
2398    #[allow(deprecated)]
2399    fn net_len(&self) -> usize {
2400        let have_secret_key = P::significant_secrets() && self.has_secret();
2401
2402        1 // Version.
2403            + 4 // Creation time.
2404            + 1 // PK algo.
2405            + self.mpis().serialized_len()
2406            + if have_secret_key {
2407                1 + match self.optional_secret().unwrap() {
2408                    SecretKeyMaterial::Unencrypted(ref u) =>
2409                        u.map(|mpis| mpis.serialized_len())
2410                        + 2, // Two octet checksum.
2411                    SecretKeyMaterial::Encrypted(ref e) =>
2412                        matches!(e.s2k(), S2K::Implicit)
2413                        .then_some(0).unwrap_or(1)
2414                        + if e.aead_algo().is_some() { 1 } else { 0 }
2415                        + e.s2k().serialized_len()
2416                        + e.aead_iv().map(|iv| iv.len()).unwrap_or(0)
2417                        + e.raw_ciphertext().len(),
2418                }
2419            } else {
2420                0
2421            }
2422    }
2423}
2424
2425impl<P, R> MarshalInto for Key4<P, R>
2426    where P: key::KeyParts,
2427          R: key::KeyRole,
2428{
2429    fn serialized_len(&self) -> usize {
2430        self.net_len()
2431    }
2432
2433    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2434        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2435    }
2436}
2437
2438impl<P, R> seal::Sealed for Key6<P, R>
2439    where P: key::KeyParts,
2440          R: key::KeyRole,
2441{}
2442
2443impl<P, R> Marshal for Key6<P, R>
2444    where P: key::KeyParts,
2445          R: key::KeyRole,
2446{
2447    fn serialize(&self, o: &mut dyn io::Write) -> Result<()> {
2448        let have_secret_key = P::significant_secrets() && self.has_secret();
2449
2450        write_byte(o, 6)?; // Version.
2451        write_be_u32(o, self.creation_time_raw().into())?;
2452        write_byte(o, self.pk_algo().into())?;
2453        write_be_u32(o, self.mpis().serialized_len() as u32)?;
2454        self.mpis().serialize(o)?;
2455
2456        if have_secret_key {
2457            use crypto::mpi::SecretKeyChecksum;
2458            match self.optional_secret().unwrap() {
2459                SecretKeyMaterial::Unencrypted(u) => u.map(|mpis| {
2460                    write_byte(o, 0)?; // S2K usage.
2461                    mpis.serialize(o)
2462                })?,
2463                SecretKeyMaterial::Encrypted(e) => {
2464                    if let (Some(aead_algo), Some(aead_iv)) =
2465                        (e.aead_algo(), e.aead_iv())
2466                    {
2467                        o.write_all(&[
2468                            253, // S2K usage.
2469                            (1 + 1 + 1 + e.s2k().serialized_len() + aead_iv.len())
2470                                .try_into().unwrap_or(0),
2471                            e.algo().into(),
2472                            aead_algo.into(),
2473                            e.s2k().serialized_len().try_into().unwrap_or(0),
2474                        ])?;
2475                        e.s2k().serialize(o)?;
2476                        o.write_all(aead_iv)?;
2477                        o.write_all(e.raw_ciphertext())?;
2478                    } else {
2479                        o.write_all(&[
2480                            // S2K usage.
2481                            match e.checksum() {
2482                                Some(SecretKeyChecksum::SHA1) => 254,
2483                                Some(SecretKeyChecksum::Sum16) => 255,
2484                                None => return Err(Error::InvalidOperation(
2485                                    "In Key6 packets, CFB encrypted secret keys \
2486                                     must be checksummed".into()).into()),
2487                            },
2488                            // Parameter length octet.
2489                            (1 + 1 + e.s2k().serialized_len()
2490                             + e.cfb_iv_len())
2491                                .try_into().unwrap_or(0),
2492                            // Cipher octet.
2493                            e.algo().into(),
2494                            // S2k length octet.
2495                            e.s2k().serialized_len().try_into().unwrap_or(0),
2496                        ])?;
2497                        e.s2k().serialize(o)?;
2498                        o.write_all(e.raw_ciphertext())?;
2499                    }
2500                },
2501            }
2502        }
2503
2504        Ok(())
2505    }
2506}
2507
2508impl<P, R> NetLength for Key6<P, R>
2509    where P: key::KeyParts,
2510          R: key::KeyRole,
2511{
2512    fn net_len(&self) -> usize {
2513        let have_secret_key = P::significant_secrets() && self.has_secret();
2514
2515        1 // Version.
2516            + 4 // Creation time.
2517            + 1 // PK algo.
2518            + 4 // Size of the public key material.
2519            + self.mpis().serialized_len()
2520            + if have_secret_key {
2521                1 // S2K method octet.
2522                    + match self.optional_secret().unwrap() {
2523                        SecretKeyMaterial::Unencrypted(u) =>
2524                            u.map(|mpis| mpis.serialized_len()),
2525                        SecretKeyMaterial::Encrypted(e) =>
2526                            1 // Parameter length octet.
2527                            + 1 // Cipher octet
2528                            + if e.aead_algo().is_some() { 1 } else { 0 }
2529                            + 1 // S2K length octet
2530                            + e.s2k().serialized_len()
2531                            + e.aead_iv().map(|iv| iv.len()).unwrap_or(0)
2532                            + e.raw_ciphertext().len(),
2533                }
2534            } else {
2535                0
2536            }
2537    }
2538}
2539
2540impl<P, R> MarshalInto for Key6<P, R>
2541    where P: key::KeyParts,
2542          R: key::KeyRole,
2543{
2544    fn serialized_len(&self) -> usize {
2545        self.net_len()
2546    }
2547
2548    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2549        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2550    }
2551}
2552
2553impl seal::Sealed for Marker {}
2554impl Marshal for Marker {
2555    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2556        o.write_all(Marker::BODY)?;
2557        Ok(())
2558    }
2559}
2560
2561impl NetLength for Marker {
2562    fn net_len(&self) -> usize {
2563        Marker::BODY.len()
2564    }
2565}
2566
2567impl MarshalInto for Marker {
2568    fn serialized_len(&self) -> usize {
2569        self.net_len()
2570    }
2571
2572    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2573        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2574    }
2575}
2576
2577impl seal::Sealed for Trust {}
2578impl Marshal for Trust {
2579    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2580        o.write_all(self.value())?;
2581        Ok(())
2582    }
2583}
2584
2585impl NetLength for Trust {
2586    fn net_len(&self) -> usize {
2587        self.value().len()
2588    }
2589}
2590
2591impl MarshalInto for Trust {
2592    fn serialized_len(&self) -> usize {
2593        self.net_len()
2594    }
2595
2596    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2597        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2598    }
2599}
2600
2601impl seal::Sealed for UserID {}
2602impl Marshal for UserID {
2603    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2604        o.write_all(self.value())?;
2605        Ok(())
2606    }
2607}
2608
2609impl NetLength for UserID {
2610    fn net_len(&self) -> usize {
2611        self.value().len()
2612    }
2613}
2614
2615impl MarshalInto for UserID {
2616    fn serialized_len(&self) -> usize {
2617        self.net_len()
2618    }
2619
2620    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2621        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2622    }
2623}
2624
2625impl seal::Sealed for UserAttribute {}
2626impl Marshal for UserAttribute {
2627    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2628        o.write_all(self.value())?;
2629        Ok(())
2630    }
2631}
2632
2633impl NetLength for UserAttribute {
2634    fn net_len(&self) -> usize {
2635        self.value().len()
2636    }
2637}
2638
2639impl MarshalInto for UserAttribute {
2640    fn serialized_len(&self) -> usize {
2641        self.net_len()
2642    }
2643
2644    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2645        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2646    }
2647}
2648
2649impl seal::Sealed for user_attribute::Subpacket {}
2650impl Marshal for user_attribute::Subpacket {
2651    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2652        let body_len = match self {
2653            user_attribute::Subpacket::Image(image) =>
2654                image.serialized_len(),
2655            user_attribute::Subpacket::Unknown(_tag, data) =>
2656                data.len(),
2657        };
2658        BodyLength::Full(1 + body_len as u32).serialize(o)?;
2659        match self {
2660            user_attribute::Subpacket::Image(image) => {
2661                write_byte(o, 1)?;
2662                image.serialize(o)?;
2663            },
2664            user_attribute::Subpacket::Unknown(tag, data) => {
2665                write_byte(o, *tag)?;
2666                o.write_all(&data[..])?;
2667            }
2668        }
2669
2670        Ok(())
2671    }
2672}
2673
2674impl MarshalInto for user_attribute::Subpacket {
2675    fn serialized_len(&self) -> usize {
2676        let body_len = match self {
2677            user_attribute::Subpacket::Image(image) =>
2678                image.serialized_len(),
2679            user_attribute::Subpacket::Unknown(_tag, data) =>
2680                data.len(),
2681        };
2682        let header_len =
2683            BodyLength::Full(1 + body_len as u32).serialized_len();
2684        header_len + 1 + body_len
2685    }
2686
2687    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2688        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2689    }
2690}
2691
2692impl seal::Sealed for user_attribute::Image {}
2693impl Marshal for user_attribute::Image {
2694    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2695        const V1HEADER_TOP: [u8; 3] = [0x10, 0x00, 0x01];
2696        const V1HEADER_PAD: [u8; 12] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2697        match self {
2698            user_attribute::Image::JPEG(data) => {
2699                o.write_all(&V1HEADER_TOP[..])?;
2700                write_byte(o, 1)?;
2701                o.write_all(&V1HEADER_PAD[..])?;
2702                o.write_all(&data[..])?;
2703            }
2704            user_attribute::Image::Unknown(tag, data)
2705            | user_attribute::Image::Private(tag, data) => {
2706                o.write_all(&V1HEADER_TOP[..])?;
2707                write_byte(o, *tag)?;
2708                o.write_all(&V1HEADER_PAD[..])?;
2709                o.write_all(&data[..])?;
2710            }
2711        }
2712
2713        Ok(())
2714    }
2715}
2716
2717impl MarshalInto for user_attribute::Image {
2718    fn serialized_len(&self) -> usize {
2719        const V1HEADER_LEN: usize =
2720            2     /* Length */
2721            + 1   /* Version */
2722            + 1   /* Tag */
2723            + 12; /* Reserved padding */
2724        match self {
2725            user_attribute::Image::JPEG(data)
2726            | user_attribute::Image::Unknown(_, data)
2727            | user_attribute::Image::Private(_, data) =>
2728                V1HEADER_LEN + data.len(),
2729        }
2730    }
2731
2732    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2733        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2734    }
2735}
2736
2737impl Literal {
2738    /// Writes the headers of the `Literal` data packet to `o`.
2739    pub(crate) fn serialize_headers(&self, o: &mut dyn std::io::Write,
2740                                    write_tag: bool) -> Result<()>
2741    {
2742        let filename = if let Some(filename) = self.filename() {
2743            let len = cmp::min(filename.len(), 255) as u8;
2744            &filename[..len as usize]
2745        } else {
2746            &b""[..]
2747        };
2748
2749        let date = if let Some(d) = self.date() {
2750            Timestamp::try_from(d)?.into()
2751        } else {
2752            0
2753        };
2754
2755        if write_tag {
2756            let len = 1 + (1 + filename.len()) + 4
2757                + self.body().len();
2758            CTB::new(Tag::Literal).serialize(o)?;
2759            BodyLength::Full(len as u32).serialize(o)?;
2760        }
2761        write_byte(o, self.format().into())?;
2762        write_byte(o, filename.len() as u8)?;
2763        o.write_all(filename)?;
2764        write_be_u32(o, date)?;
2765        Ok(())
2766    }
2767}
2768
2769impl seal::Sealed for Literal {}
2770impl Marshal for Literal {
2771    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2772        let body = self.body();
2773        if TRACE {
2774            let prefix = &body[..cmp::min(body.len(), 20)];
2775            eprintln!("Literal::serialize({}{}, {} bytes)",
2776                      String::from_utf8_lossy(prefix),
2777                      if body.len() > 20 { "..." } else { "" },
2778                      body.len());
2779        }
2780
2781        self.serialize_headers(o, false)?;
2782        o.write_all(body)?;
2783
2784        Ok(())
2785    }
2786}
2787
2788impl NetLength for Literal {
2789    fn net_len(&self) -> usize {
2790        1 + (1 + self.filename().map(|f| f.len()).unwrap_or(0)) + 4
2791            + self.body().len()
2792    }
2793}
2794
2795impl MarshalInto for Literal {
2796    fn serialized_len(&self) -> usize {
2797        self.net_len()
2798    }
2799
2800    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2801        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2802    }
2803}
2804
2805impl seal::Sealed for CompressedData {}
2806impl Marshal for CompressedData {
2807    /// Writes a serialized version of the specified `CompressedData`
2808    /// packet to `o`.
2809    ///
2810    /// This function works recursively: if the `CompressedData` packet
2811    /// contains any packets, they are also serialized.
2812    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2813        // The streaming serialization framework requires the sink to
2814        // be Send + Sync, but `o` is not.  Knowing that we create the
2815        // message here and don't keep the message object around, we
2816        // can cheat by creating a shim that is Send + Sync.
2817        struct Shim<'a>(&'a mut dyn std::io::Write);
2818        impl std::io::Write for Shim<'_> {
2819            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
2820                self.0.write(buf)
2821            }
2822            fn flush(&mut self) -> std::io::Result<()> {
2823                self.0.flush()
2824            }
2825        }
2826        unsafe impl Send for Shim<'_> {}
2827        unsafe impl Sync for Shim<'_> {}
2828
2829        match self.body() {
2830            Body::Unprocessed(bytes) => {
2831                if TRACE {
2832                    eprintln!("CompressedData::serialize(\
2833                               algo: {}, {} bytes of unprocessed body)",
2834                              self.algo(), bytes.len());
2835                }
2836
2837                o.write_all(&[self.algo().into()])?;
2838                o.write_all(bytes)?;
2839            },
2840
2841            Body::Processed(bytes) => {
2842                if TRACE {
2843                    eprintln!("CompressedData::serialize(\
2844                               algo: {}, {} bytes of processed body)",
2845                              self.algo(), bytes.len());
2846                }
2847
2848                let o = stream::Message::new(Shim(o));
2849                let mut o = stream::Compressor::new_naked(
2850                    o, self.algo(), Default::default(), 0)?;
2851                o.write_all(bytes)?;
2852                o.finalize()?;
2853            },
2854
2855            Body::Structured(children) => {
2856                if TRACE {
2857                    eprintln!("CompressedData::serialize(\
2858                               algo: {}, {:?} children)",
2859                              self.algo(), children.len());
2860                }
2861
2862                let o = stream::Message::new(Shim(o));
2863                let mut o = stream::Compressor::new_naked(
2864                    o, self.algo(), Default::default(), 0)?;
2865
2866                // Serialize the packets.
2867                for p in children {
2868                    (p as &dyn Marshal).serialize(&mut o)?;
2869                }
2870
2871                o.finalize()?;
2872            },
2873        }
2874        Ok(())
2875    }
2876}
2877
2878impl NetLength for CompressedData {
2879    fn net_len(&self) -> usize {
2880        // Worst case, the data gets larger.  Account for that.
2881        // Experiments suggest that the overhead of compressing random
2882        // data is worse for BZIP2, but it converges to 20% starting
2883        // at ~2k of random data.
2884        let compressed = |l| l + cmp::max(l / 5, 4096);
2885
2886        match self.body() {
2887            Body::Unprocessed(bytes) => 1 /* Algo */ + bytes.len(),
2888            Body::Processed(bytes) => 1 /* Algo */ + compressed(bytes.len()),
2889            Body::Structured(packets) =>
2890                1 // Algo
2891                + compressed(packets.iter().map(|p| {
2892                    (p as &dyn MarshalInto).serialized_len()
2893                }).sum::<usize>()),
2894        }
2895    }
2896}
2897
2898impl MarshalInto for CompressedData {
2899    /// Computes the maximal length of the serialized representation.
2900    ///
2901    /// The size of the serialized compressed data packet is tricky to
2902    /// predict.  First, it depends on the data being compressed.
2903    /// Second, we emit partial body encoded data.
2904    ///
2905    /// This function tries overestimates the length.  However, it may
2906    /// happen that `serialize_into()` fails.
2907    ///
2908    /// # Errors
2909    ///
2910    /// If serialization would fail, this function returns 0.
2911    fn serialized_len(&self) -> usize {
2912        self.net_len()
2913    }
2914
2915    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2916        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2917    }
2918}
2919
2920impl seal::Sealed for PKESK {}
2921impl Marshal for PKESK {
2922    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2923        match self {
2924            PKESK::V3(ref p) => p.serialize(o),
2925            PKESK::V6(p) => p.serialize(o),
2926        }
2927    }
2928}
2929
2930impl NetLength for PKESK {
2931    fn net_len(&self) -> usize {
2932        match self {
2933            PKESK::V3(p) => p.net_len(),
2934            PKESK::V6(p) => p.net_len(),
2935        }
2936    }
2937}
2938
2939impl MarshalInto for PKESK {
2940    fn serialized_len(&self) -> usize {
2941        match self {
2942            PKESK::V3(ref p) => p.serialized_len(),
2943            PKESK::V6(p) => p.serialized_len(),
2944        }
2945    }
2946
2947    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2948        match self {
2949            PKESK::V3(p) =>
2950                generic_serialize_into(p, MarshalInto::serialized_len(p), buf),
2951            PKESK::V6(p) =>
2952                generic_serialize_into(p, MarshalInto::serialized_len(p), buf),
2953        }
2954    }
2955}
2956
2957impl seal::Sealed for PKESK3 {}
2958impl Marshal for PKESK3 {
2959    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2960        write_byte(o, 3)?; // Version.
2961        let wildcard = KeyID::wildcard();
2962        (self.recipient().unwrap_or(&wildcard) as &dyn Marshal).serialize(o)?;
2963        write_byte(o, self.pk_algo().into())?;
2964        self.esk().serialize(o)?;
2965
2966        Ok(())
2967    }
2968}
2969
2970impl NetLength for PKESK3 {
2971    fn net_len(&self) -> usize {
2972        1 // Version.
2973            + 8 // Recipient's key id.
2974            + 1 // Algo.
2975            + self.esk().serialized_len()
2976    }
2977}
2978
2979impl MarshalInto for PKESK3 {
2980    fn serialized_len(&self) -> usize {
2981        self.net_len()
2982    }
2983
2984    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
2985        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
2986    }
2987}
2988
2989impl seal::Sealed for PKESK6 {}
2990impl Marshal for PKESK6 {
2991    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
2992        write_byte(o, 6)?; // Version.
2993        if let Some(recipient) = self.recipient() {
2994             // Recipient length.
2995            write_byte(o, ((recipient as &dyn MarshalInto).serialized_len() + 1) as u8)?;
2996            match recipient {
2997                Fingerprint::V4(_) => write_byte(o, 4)?,
2998                Fingerprint::V6(_) => write_byte(o, 6)?,
2999                Fingerprint::Unknown { version, .. } =>
3000                    write_byte(o, version.unwrap_or(0xff))?,
3001            }
3002            (recipient as &dyn Marshal).serialize(o)?;
3003        } else {
3004            // No recipient.
3005            write_byte(o, 0)?;
3006        }
3007
3008        write_byte(o, self.pk_algo().into())?;
3009        self.esk().serialize(o)?;
3010
3011        Ok(())
3012    }
3013}
3014
3015impl NetLength for PKESK6 {
3016    fn net_len(&self) -> usize {
3017        1 // Version.
3018            + 1 // Recipient length.
3019            // Recipient's versioned fingerprint, if any:
3020            + self.recipient().map(|r| r.as_bytes().len() + 1).unwrap_or(0)
3021            + 1 // Algo.
3022            + self.esk().serialized_len()
3023    }
3024}
3025
3026impl MarshalInto for PKESK6 {
3027    fn serialized_len(&self) -> usize {
3028        self.net_len()
3029    }
3030
3031    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3032        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3033    }
3034}
3035
3036impl seal::Sealed for SKESK {}
3037impl Marshal for SKESK {
3038    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3039        match self {
3040            SKESK::V4(ref s) => s.serialize(o),
3041            SKESK::V6(ref s) => s.serialize(o),
3042        }
3043    }
3044}
3045
3046impl NetLength for SKESK {
3047    fn net_len(&self) -> usize {
3048        match self {
3049            SKESK::V4(ref s) => s.net_len(),
3050            SKESK::V6(ref s) => s.net_len(),
3051        }
3052    }
3053}
3054
3055impl MarshalInto for SKESK {
3056    fn serialized_len(&self) -> usize {
3057        match self {
3058            SKESK::V4(ref s) => s.serialized_len(),
3059            SKESK::V6(ref s) => s.serialized_len(),
3060        }
3061    }
3062
3063    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3064        match self {
3065            SKESK::V4(s) =>
3066                generic_serialize_into(s, MarshalInto::serialized_len(s), buf),
3067            SKESK::V6(s) =>
3068                generic_serialize_into(s, MarshalInto::serialized_len(s), buf),
3069        }
3070    }
3071}
3072
3073impl seal::Sealed for SKESK4 {}
3074impl Marshal for SKESK4 {
3075    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3076        write_byte(o, 4)?; // Version.
3077        write_byte(o, self.symmetric_algo().into())?;
3078        self.s2k().serialize(o)?;
3079        o.write_all(self.raw_esk())?;
3080        Ok(())
3081    }
3082}
3083
3084impl NetLength for SKESK4 {
3085    fn net_len(&self) -> usize {
3086        1 // Version.
3087            + 1 // Algo.
3088            + self.s2k().serialized_len()
3089            + self.raw_esk().len()
3090    }
3091}
3092
3093impl MarshalInto for SKESK4 {
3094    fn serialized_len(&self) -> usize {
3095        self.net_len()
3096    }
3097
3098    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3099        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3100    }
3101}
3102
3103impl seal::Sealed for SKESK6 {}
3104impl Marshal for SKESK6 {
3105    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3106        let s2k_len = self.s2k().serialized_len();
3107
3108        write_byte(o, 6)?; // Version.
3109        // Parameter octet count.
3110        write_byte(o, (1   // Symmetric algorithm.
3111                       + 1 // AEAD mode.
3112                       + 1 // S2K octet count.
3113                       + s2k_len
3114                       + self.aead_iv().len()) as u8)?;
3115        write_byte(o, self.symmetric_algo().into())?;
3116        write_byte(o, self.aead_algo().into())?;
3117        // S2K octet count.
3118        write_byte(o, s2k_len as u8)?;
3119        self.s2k().serialize(o)?;
3120        o.write_all(self.aead_iv())?;
3121        o.write_all(self.esk())?;
3122
3123        Ok(())
3124    }
3125}
3126
3127impl NetLength for SKESK6 {
3128    fn net_len(&self) -> usize {
3129        1 // Version.
3130            + 1 // Parameter octet count.
3131            + 1 // Cipher algo.
3132            + 1 // AEAD algo.
3133            + 1 // S2K octet count.
3134            + self.s2k().serialized_len()
3135            + self.aead_iv().len()
3136            + self.esk().len()
3137    }
3138}
3139
3140impl MarshalInto for SKESK6 {
3141    fn serialized_len(&self) -> usize {
3142        self.net_len()
3143    }
3144
3145    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3146        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3147    }
3148}
3149
3150impl seal::Sealed for SEIP {}
3151impl Marshal for SEIP {
3152    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3153        match self {
3154            SEIP::V1(p) => p.serialize(o),
3155            SEIP::V2(p) => p.serialize(o),
3156        }
3157    }
3158}
3159
3160impl NetLength for SEIP {
3161    fn net_len(&self) -> usize {
3162        match self {
3163            SEIP::V1(p) => p.net_len(),
3164            SEIP::V2(p) => p.net_len(),
3165        }
3166    }
3167}
3168
3169impl MarshalInto for SEIP {
3170    fn serialized_len(&self) -> usize {
3171        self.net_len()
3172    }
3173
3174    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3175        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3176    }
3177}
3178
3179impl seal::Sealed for SEIP1 {}
3180impl Marshal for SEIP1 {
3181    /// Writes a serialized version of the specified `SEIP1`
3182    /// packet to `o`.
3183    ///
3184    /// # Errors
3185    ///
3186    /// Returns `Error::InvalidOperation` if this packet has children.
3187    /// To construct an encrypted message, use
3188    /// `serialize::stream::Encryptor`.
3189    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3190        match self.body() {
3191            Body::Unprocessed(bytes) => {
3192                o.write_all(&[1])?;
3193                o.write_all(bytes)?;
3194                Ok(())
3195            },
3196            _ => Err(Error::InvalidOperation(
3197                "Cannot encrypt, use serialize::stream::Encryptor".into())
3198                     .into()),
3199        }
3200    }
3201}
3202
3203impl NetLength for SEIP1 {
3204    fn net_len(&self) -> usize {
3205        match self.body() {
3206            Body::Unprocessed(bytes) => 1 /* Version */ + bytes.len(),
3207            _ => 0,
3208        }
3209    }
3210}
3211
3212impl MarshalInto for SEIP1 {
3213    fn serialized_len(&self) -> usize {
3214        self.net_len()
3215    }
3216
3217    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3218        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3219    }
3220}
3221
3222impl SEIP2 {
3223    /// Writes the headers of the `SEIP2` data packet to `o`.
3224    fn serialize_headers(&self, o: &mut dyn std::io::Write) -> Result<()> {
3225        o.write_all(&[2, // Version.
3226                      self.symmetric_algo().into(),
3227                      self.aead().into(),
3228                      self.chunk_size().trailing_zeros() as u8 - 6])?;
3229        o.write_all(self.salt())?;
3230        Ok(())
3231    }
3232}
3233
3234impl seal::Sealed for SEIP2 {}
3235impl Marshal for SEIP2 {
3236    /// Writes a serialized version of the specified `SEIPv2`
3237    /// packet to `o`.
3238    ///
3239    /// # Errors
3240    ///
3241    /// Returns `Error::InvalidOperation` if this packet has children.
3242    /// To construct an encrypted message, use
3243    /// `serialize::stream::Encryptor`.
3244    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3245        match self.body() {
3246            Body::Unprocessed(bytes) => {
3247                self.serialize_headers(o)?;
3248                o.write_all(bytes)?;
3249                Ok(())
3250            },
3251            _ => Err(Error::InvalidOperation(
3252                "Cannot encrypt, use serialize::stream::Encryptor".into())
3253                     .into()),
3254        }
3255    }
3256}
3257
3258impl NetLength for SEIP2 {
3259    fn net_len(&self) -> usize {
3260        match self.body() {
3261            Body::Unprocessed(bytes) =>
3262                4 // Headers.
3263                + self.salt().len()
3264                + bytes.len(),
3265            _ => 0,
3266        }
3267    }
3268}
3269
3270impl MarshalInto for SEIP2 {
3271    fn serialized_len(&self) -> usize {
3272        self.net_len()
3273    }
3274
3275    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3276        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3277    }
3278}
3279
3280impl seal::Sealed for MDC {}
3281impl Marshal for MDC {
3282    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3283        o.write_all(self.digest())?;
3284        Ok(())
3285    }
3286}
3287
3288impl NetLength for MDC {
3289    fn net_len(&self) -> usize {
3290        20
3291    }
3292}
3293
3294impl MarshalInto for MDC {
3295    fn serialized_len(&self) -> usize {
3296        self.net_len()
3297    }
3298
3299    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3300        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3301    }
3302}
3303
3304impl seal::Sealed for Padding {}
3305impl Marshal for Padding {
3306    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3307        o.write_all(self.value())?;
3308        Ok(())
3309    }
3310}
3311
3312impl NetLength for Padding {
3313    fn net_len(&self) -> usize {
3314        self.value().len()
3315    }
3316}
3317
3318impl MarshalInto for Padding {
3319    fn serialized_len(&self) -> usize {
3320        self.net_len()
3321    }
3322
3323    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3324        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3325    }
3326}
3327
3328impl Serialize for Packet {}
3329impl seal::Sealed for Packet {}
3330impl Marshal for Packet {
3331    /// Writes a serialized version of the specified `Packet` to `o`.
3332    ///
3333    /// This function works recursively: if the packet contains any
3334    /// packets, they are also serialized.
3335    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3336        CTB::new(self.tag()).serialize(o)?;
3337
3338        // Special-case the compressed data packet, because we need
3339        // the accurate length, and CompressedData::net_len()
3340        // overestimates the size.
3341        if let Packet::CompressedData(ref p) = self {
3342            let mut body = Vec::new();
3343            p.serialize(&mut body)?;
3344            BodyLength::Full(body.len() as u32).serialize(o)?;
3345            o.write_all(&body)?;
3346            return Ok(());
3347        }
3348
3349        BodyLength::Full(self.net_len() as u32).serialize(o)?;
3350        match self {
3351            Packet::Unknown(ref p) => p.serialize(o),
3352            Packet::Signature(ref p) => p.serialize(o),
3353            Packet::OnePassSig(ref p) => p.serialize(o),
3354            Packet::PublicKey(ref p) => p.serialize(o),
3355            Packet::PublicSubkey(ref p) => p.serialize(o),
3356            Packet::SecretKey(ref p) => p.serialize(o),
3357            Packet::SecretSubkey(ref p) => p.serialize(o),
3358            Packet::Marker(ref p) => p.serialize(o),
3359            Packet::Trust(ref p) => p.serialize(o),
3360            Packet::UserID(ref p) => p.serialize(o),
3361            Packet::UserAttribute(ref p) => p.serialize(o),
3362            Packet::Literal(ref p) => p.serialize(o),
3363            Packet::CompressedData(_) => unreachable!("handled above"),
3364            Packet::PKESK(ref p) => p.serialize(o),
3365            Packet::SKESK(ref p) => p.serialize(o),
3366            Packet::SEIP(ref p) => p.serialize(o),
3367            #[allow(deprecated)]
3368            Packet::MDC(ref p) => p.serialize(o),
3369            Packet::Padding(p) => p.serialize(o),
3370        }
3371    }
3372
3373    /// Exports a serialized version of the specified `Packet` to `o`.
3374    ///
3375    /// This function works recursively: if the packet contains any
3376    /// packets, they are also serialized.
3377    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
3378        CTB::new(self.tag()).serialize(o)?;
3379
3380        // Special-case the compressed data packet, because we need
3381        // the accurate length, and CompressedData::net_len()
3382        // overestimates the size.
3383        if let Packet::CompressedData(ref p) = self {
3384            let mut body = Vec::new();
3385            p.export(&mut body)?;
3386            BodyLength::Full(body.len() as u32).export(o)?;
3387            o.write_all(&body)?;
3388            return Ok(());
3389        }
3390
3391        BodyLength::Full(self.net_len() as u32).export(o)?;
3392        match self {
3393            Packet::Unknown(ref p) => p.export(o),
3394            Packet::Signature(ref p) => p.export(o),
3395            Packet::OnePassSig(ref p) => p.export(o),
3396            Packet::PublicKey(ref p) => p.export(o),
3397            Packet::PublicSubkey(ref p) => p.export(o),
3398            Packet::SecretKey(ref p) => p.export(o),
3399            Packet::SecretSubkey(ref p) => p.export(o),
3400            Packet::Marker(ref p) => p.export(o),
3401            Packet::Trust(ref p) => p.export(o),
3402            Packet::UserID(ref p) => p.export(o),
3403            Packet::UserAttribute(ref p) => p.export(o),
3404            Packet::Literal(ref p) => p.export(o),
3405            Packet::CompressedData(_) => unreachable!("handled above"),
3406            Packet::PKESK(ref p) => p.export(o),
3407            Packet::SKESK(ref p) => p.export(o),
3408            Packet::SEIP(ref p) => p.export(o),
3409            #[allow(deprecated)]
3410            Packet::MDC(ref p) => p.export(o),
3411            Packet::Padding(p) => p.export(o),
3412        }
3413    }
3414}
3415
3416impl NetLength for Packet {
3417    fn net_len(&self) -> usize {
3418        match self {
3419            Packet::Unknown(ref p) => p.net_len(),
3420            Packet::Signature(ref p) => p.net_len(),
3421            Packet::OnePassSig(ref p) => p.net_len(),
3422            Packet::PublicKey(ref p) => p.net_len(),
3423            Packet::PublicSubkey(ref p) => p.net_len(),
3424            Packet::SecretKey(ref p) => p.net_len(),
3425            Packet::SecretSubkey(ref p) => p.net_len(),
3426            Packet::Marker(ref p) => p.net_len(),
3427            Packet::Trust(ref p) => p.net_len(),
3428            Packet::UserID(ref p) => p.net_len(),
3429            Packet::UserAttribute(ref p) => p.net_len(),
3430            Packet::Literal(ref p) => p.net_len(),
3431            Packet::CompressedData(ref p) => p.net_len(),
3432            Packet::PKESK(ref p) => p.net_len(),
3433            Packet::SKESK(ref p) => p.net_len(),
3434            Packet::SEIP(ref p) => p.net_len(),
3435            #[allow(deprecated)]
3436            Packet::MDC(ref p) => p.net_len(),
3437            Packet::Padding(p) => p.net_len(),
3438        }
3439    }
3440}
3441
3442impl SerializeInto for Packet {}
3443impl MarshalInto for Packet {
3444    fn serialized_len(&self) -> usize {
3445        self.gross_len()
3446    }
3447
3448    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3449        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3450    }
3451
3452    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
3453        generic_export_into(self, MarshalInto::serialized_len(self), buf)
3454    }
3455}
3456
3457/// References packet bodies.
3458///
3459/// Like [`openpgp::Packet`], but instead of owning the packet's bodies,
3460/// they are referenced.  `PacketRef` is only used to serialize packet
3461/// bodies (like [`packet::Signature`]) encapsulating them in OpenPGP
3462/// frames.
3463///
3464/// [`openpgp::Packet`]: super::Packet
3465/// [`packet::Signature`]: crate::packet::Signature
3466#[allow(dead_code)]
3467enum PacketRef<'a> {
3468    /// Unknown packet.
3469    Unknown(&'a packet::Unknown),
3470    /// Signature packet.
3471    Signature(&'a packet::Signature),
3472    /// One pass signature packet.
3473    OnePassSig(&'a packet::OnePassSig),
3474    /// Public key packet.
3475    PublicKey(&'a packet::key::PublicKey),
3476    /// Public subkey packet.
3477    PublicSubkey(&'a packet::key::PublicSubkey),
3478    /// Public/Secret key pair.
3479    SecretKey(&'a packet::key::SecretKey),
3480    /// Public/Secret subkey pair.
3481    SecretSubkey(&'a packet::key::SecretSubkey),
3482    /// Marker packet.
3483    Marker(&'a packet::Marker),
3484    /// Trust packet.
3485    Trust(&'a packet::Trust),
3486    /// User ID packet.
3487    UserID(&'a packet::UserID),
3488    /// User attribute packet.
3489    UserAttribute(&'a packet::UserAttribute),
3490    /// Literal data packet.
3491    Literal(&'a packet::Literal),
3492    /// Compressed literal data packet.
3493    CompressedData(&'a packet::CompressedData),
3494    /// Public key encrypted data packet.
3495    PKESK(&'a packet::PKESK),
3496    /// Symmetric key encrypted data packet.
3497    SKESK(&'a packet::SKESK),
3498    /// Symmetric key encrypted, integrity protected data packet.
3499    SEIP(&'a packet::SEIP),
3500    /// Modification detection code packet.
3501    MDC(&'a packet::MDC),
3502    /// Padding packet.
3503    Padding(&'a packet::Padding),
3504}
3505
3506impl<'a> PacketRef<'a> {
3507    /// Returns the `PacketRef's` corresponding OpenPGP tag.
3508    ///
3509    /// Tags are explained in [Section 5 of RFC 9580].
3510    ///
3511    ///   [Section 5 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5
3512    fn tag(&self) -> packet::Tag {
3513        match self {
3514            PacketRef::Unknown(packet) => packet.tag(),
3515            PacketRef::Signature(_) => Tag::Signature,
3516            PacketRef::OnePassSig(_) => Tag::OnePassSig,
3517            PacketRef::PublicKey(_) => Tag::PublicKey,
3518            PacketRef::PublicSubkey(_) => Tag::PublicSubkey,
3519            PacketRef::SecretKey(_) => Tag::SecretKey,
3520            PacketRef::SecretSubkey(_) => Tag::SecretSubkey,
3521            PacketRef::Marker(_) => Tag::Marker,
3522            PacketRef::Trust(_) => Tag::Trust,
3523            PacketRef::UserID(_) => Tag::UserID,
3524            PacketRef::UserAttribute(_) => Tag::UserAttribute,
3525            PacketRef::Literal(_) => Tag::Literal,
3526            PacketRef::CompressedData(_) => Tag::CompressedData,
3527            PacketRef::PKESK(_) => Tag::PKESK,
3528            PacketRef::SKESK(_) => Tag::SKESK,
3529            PacketRef::SEIP(_) => Tag::SEIP,
3530            PacketRef::MDC(_) => Tag::MDC,
3531            PacketRef::Padding(_) => Tag::Padding,
3532        }
3533    }
3534}
3535
3536impl<'a> Serialize for PacketRef<'a> {}
3537impl<'a> seal::Sealed for PacketRef<'a> {}
3538impl<'a> Marshal for PacketRef<'a> {
3539    /// Writes a serialized version of the specified `Packet` to `o`.
3540    ///
3541    /// This function works recursively: if the packet contains any
3542    /// packets, they are also serialized.
3543    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3544        CTB::new(self.tag()).serialize(o)?;
3545
3546        // Special-case the compressed data packet, because we need
3547        // the accurate length, and CompressedData::net_len()
3548        // overestimates the size.
3549        if let PacketRef::CompressedData(p) = self {
3550            let mut body = Vec::new();
3551            p.serialize(&mut body)?;
3552            BodyLength::Full(body.len() as u32).serialize(o)?;
3553            o.write_all(&body)?;
3554            return Ok(());
3555        }
3556
3557        BodyLength::Full(self.net_len() as u32).serialize(o)?;
3558        match self {
3559            PacketRef::Unknown(p) => p.serialize(o),
3560            PacketRef::Signature(p) => p.serialize(o),
3561            PacketRef::OnePassSig(p) => p.serialize(o),
3562            PacketRef::PublicKey(p) => p.serialize(o),
3563            PacketRef::PublicSubkey(p) => p.serialize(o),
3564            PacketRef::SecretKey(p) => p.serialize(o),
3565            PacketRef::SecretSubkey(p) => p.serialize(o),
3566            PacketRef::Marker(p) => p.serialize(o),
3567            PacketRef::Trust(p) => p.serialize(o),
3568            PacketRef::UserID(p) => p.serialize(o),
3569            PacketRef::UserAttribute(p) => p.serialize(o),
3570            PacketRef::Literal(p) => p.serialize(o),
3571            PacketRef::CompressedData(_) => unreachable!("handled above"),
3572            PacketRef::PKESK(p) => p.serialize(o),
3573            PacketRef::SKESK(p) => p.serialize(o),
3574            PacketRef::SEIP(p) => p.serialize(o),
3575            PacketRef::MDC(p) => p.serialize(o),
3576            PacketRef::Padding(p) => p.serialize(o),
3577        }
3578    }
3579
3580    /// Exports a serialized version of the specified `Packet` to `o`.
3581    ///
3582    /// This function works recursively: if the packet contains any
3583    /// packets, they are also serialized.
3584    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
3585        CTB::new(self.tag()).serialize(o)?;
3586
3587        // Special-case the compressed data packet, because we need
3588        // the accurate length, and CompressedData::net_len()
3589        // overestimates the size.
3590        if let PacketRef::CompressedData(p) = self {
3591            let mut body = Vec::new();
3592            p.export(&mut body)?;
3593            BodyLength::Full(body.len() as u32).export(o)?;
3594            o.write_all(&body)?;
3595            return Ok(());
3596        }
3597
3598        BodyLength::Full(self.net_len() as u32).export(o)?;
3599        match self {
3600            PacketRef::Unknown(p) => p.export(o),
3601            PacketRef::Signature(p) => p.export(o),
3602            PacketRef::OnePassSig(p) => p.export(o),
3603            PacketRef::PublicKey(p) => p.export(o),
3604            PacketRef::PublicSubkey(p) => p.export(o),
3605            PacketRef::SecretKey(p) => p.export(o),
3606            PacketRef::SecretSubkey(p) => p.export(o),
3607            PacketRef::Marker(p) => p.export(o),
3608            PacketRef::Trust(p) => p.export(o),
3609            PacketRef::UserID(p) => p.export(o),
3610            PacketRef::UserAttribute(p) => p.export(o),
3611            PacketRef::Literal(p) => p.export(o),
3612            PacketRef::CompressedData(_) => unreachable!("handled above"),
3613            PacketRef::PKESK(p) => p.export(o),
3614            PacketRef::SKESK(p) => p.export(o),
3615            PacketRef::SEIP(p) => p.export(o),
3616            PacketRef::MDC(p) => p.export(o),
3617            PacketRef::Padding(p) => p.export(o),
3618        }
3619    }
3620}
3621
3622impl<'a> NetLength for PacketRef<'a> {
3623    fn net_len(&self) -> usize {
3624        match self {
3625            PacketRef::Unknown(p) => p.net_len(),
3626            PacketRef::Signature(p) => p.net_len(),
3627            PacketRef::OnePassSig(p) => p.net_len(),
3628            PacketRef::PublicKey(p) => p.net_len(),
3629            PacketRef::PublicSubkey(p) => p.net_len(),
3630            PacketRef::SecretKey(p) => p.net_len(),
3631            PacketRef::SecretSubkey(p) => p.net_len(),
3632            PacketRef::Marker(p) => p.net_len(),
3633            PacketRef::Trust(p) => p.net_len(),
3634            PacketRef::UserID(p) => p.net_len(),
3635            PacketRef::UserAttribute(p) => p.net_len(),
3636            PacketRef::Literal(p) => p.net_len(),
3637            PacketRef::CompressedData(p) => p.net_len(),
3638            PacketRef::PKESK(p) => p.net_len(),
3639            PacketRef::SKESK(p) => p.net_len(),
3640            PacketRef::SEIP(p) => p.net_len(),
3641            PacketRef::MDC(p) => p.net_len(),
3642            PacketRef::Padding(p) => p.net_len(),
3643        }
3644    }
3645}
3646
3647impl<'a> SerializeInto for PacketRef<'a> {}
3648impl<'a> MarshalInto for PacketRef<'a> {
3649    fn serialized_len(&self) -> usize {
3650        self.gross_len()
3651    }
3652
3653    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3654        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3655    }
3656
3657    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
3658        generic_export_into(self, MarshalInto::serialized_len(self), buf)
3659    }
3660}
3661
3662impl Serialize for PacketPile {}
3663impl seal::Sealed for PacketPile {}
3664impl Marshal for PacketPile {
3665    /// Writes a serialized version of the specified `PacketPile` to `o`.
3666    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3667        for p in self.children() {
3668            (p as &dyn Marshal).serialize(o)?;
3669        }
3670
3671        Ok(())
3672    }
3673
3674    /// Exports a serialized version of the specified `PacketPile` to `o`.
3675    fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
3676        for p in self.children() {
3677            (p as &dyn Marshal).export(o)?;
3678        }
3679
3680        Ok(())
3681    }
3682}
3683
3684impl SerializeInto for PacketPile {}
3685impl MarshalInto for PacketPile {
3686    fn serialized_len(&self) -> usize {
3687        self.children().map(|p| {
3688            (p as &dyn MarshalInto).serialized_len()
3689        }).sum()
3690    }
3691
3692    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3693        generic_serialize_into(self, MarshalInto::serialized_len(self), buf)
3694    }
3695
3696    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
3697        generic_export_into(self, MarshalInto::serialized_len(self), buf)
3698    }
3699}
3700
3701impl Serialize for Message {}
3702impl seal::Sealed for Message {}
3703impl Marshal for Message {
3704    /// Writes a serialized version of the specified `Message` to `o`.
3705    fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
3706        Marshal::serialize(self.packets(), o)
3707    }
3708}
3709
3710impl SerializeInto for Message {}
3711impl MarshalInto for Message {
3712    fn serialized_len(&self) -> usize {
3713        MarshalInto::serialized_len(self.packets())
3714    }
3715
3716    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
3717        MarshalInto::serialize_into(self.packets(), buf)
3718    }
3719
3720    fn export_into(&self, buf: &mut [u8]) -> Result<usize> {
3721        MarshalInto::export_into(self.packets(), buf)
3722    }
3723}
3724
3725#[cfg(test)]
3726mod test {
3727    use super::*;
3728    use crate::types::CompressionAlgorithm;
3729    use crate::parse::to_unknown_packet;
3730    use crate::parse::PacketParserBuilder;
3731    use crate::parse::Parse;
3732
3733    // A convenient function to dump binary data to stdout.
3734    fn binary_pp(data: &[u8]) -> String {
3735        let mut output = Vec::new();
3736        crate::fmt::hex::Dumper::new(&mut output, "")
3737            .write_ascii(data).unwrap();
3738        // We know the content is valid UTF-8.
3739        String::from_utf8(output).unwrap()
3740    }
3741
3742    // Does a bit-wise comparison of two packets ignoring the CTB
3743    // format, the body length encoding, and whether partial body
3744    // length encoding was used.
3745    fn packets_bitwise_compare(filename: &str, packet: &Packet,
3746                               expected: &[u8], got: &[u8]) {
3747        let expected = to_unknown_packet(expected).unwrap();
3748        let got = to_unknown_packet(got).unwrap();
3749
3750        let expected_body = expected.body();
3751        let got_body = got.body();
3752
3753        let mut fail = false;
3754        if expected.tag() != got.tag() {
3755            eprintln!("Expected a {:?}, got a {:?}", expected.tag(), got.tag());
3756            fail = true;
3757        }
3758        if expected_body != got_body {
3759            eprintln!("Packet contents don't match (for {}):",
3760                      filename);
3761            eprintln!("Expected ({} bytes):\n{}",
3762                      expected_body.len(), binary_pp(expected_body));
3763            eprintln!("Got ({} bytes):\n{}",
3764                      got_body.len(), binary_pp(got_body));
3765            eprintln!("Packet: {:#?}", packet);
3766            fail = true;
3767        }
3768        if fail {
3769            panic!("Packets don't match (for {}).", filename);
3770        }
3771    }
3772
3773    #[test]
3774    fn serialize_test_1() {
3775        // Given a packet in serialized form:
3776        //
3777        // - Parse and reserialize it;
3778        //
3779        // - Do a bitwise comparison (modulo the body length encoding)
3780        //   of the original and reserialized data.
3781        //
3782        // Note: This test only works on messages with a single packet.
3783        //
3784        // Note: This test does not work with non-deterministic
3785        // packets, like compressed data packets, since the serialized
3786        // forms may be different.
3787
3788        let filenames = [
3789            "literal-mode-b.pgp",
3790            "literal-mode-t-partial-body.pgp",
3791
3792            "sig.pgp",
3793
3794            "public-key-bare.pgp",
3795            "public-subkey-bare.pgp",
3796            "userid-bare.pgp",
3797
3798            "s2k/mode-0-password-1234.pgp",
3799            "s2k/mode-0-password-1234.pgp",
3800            "s2k/mode-1-password-123456-1.pgp",
3801            "s2k/mode-1-password-foobar-2.pgp",
3802            "s2k/mode-3-aes128-password-13-times-0123456789.pgp",
3803            "s2k/mode-3-aes192-password-123.pgp",
3804            "s2k/mode-3-encrypted-key-password-bgtyhn.pgp",
3805            "s2k/mode-3-password-9876-2.pgp",
3806            "s2k/mode-3-password-qwerty-1.pgp",
3807            "s2k/mode-3-twofish-password-13-times-0123456789.pgp",
3808        ];
3809
3810        for filename in filenames.iter() {
3811            // 1. Read the message byte stream into a local buffer.
3812            let data = crate::tests::message(filename);
3813
3814            // 2. Parse the message.
3815            let pile = PacketPile::from_bytes(data).unwrap();
3816
3817            // The following test only works if the message has a
3818            // single top-level packet.
3819            assert_eq!(pile.children().len(), 1);
3820
3821            // 3. Serialize the packet it into a local buffer.
3822            let p = pile.descendants().next().unwrap();
3823            let mut buffer = Vec::new();
3824            match p {
3825                Packet::Literal(_) | Packet::Signature(_)
3826                    | Packet::PublicKey(_) | Packet::PublicSubkey(_)
3827                    | Packet::UserID(_) | Packet::SKESK(_) => (),
3828                p => {
3829                    panic!("Didn't expect a {:?} packet.", p.tag());
3830                },
3831            }
3832            (p as &dyn Marshal).serialize(&mut buffer).unwrap();
3833
3834            // 4. Modulo the body length encoding, check that the
3835            // reserialized content is identical to the original data.
3836            packets_bitwise_compare(filename, p, data, &buffer[..]);
3837        }
3838    }
3839
3840    #[test]
3841    fn serialize_test_1_unknown() {
3842        // This is an variant of serialize_test_1 that tests the
3843        // unknown packet serializer.
3844        let filenames = [
3845            "compressed-data-algo-1.pgp",
3846            "compressed-data-algo-2.pgp",
3847            "compressed-data-algo-3.pgp",
3848            "recursive-2.pgp",
3849            "recursive-3.pgp",
3850        ];
3851
3852        for filename in filenames.iter() {
3853            // 1. Read the message byte stream into a local buffer.
3854            let data = crate::tests::message(filename);
3855
3856            // 2. Parse the message.
3857            let u = Packet::Unknown(to_unknown_packet(data).unwrap());
3858
3859            // 3. Serialize the packet it into a local buffer.
3860            let data2 = (&u as &dyn MarshalInto).to_vec().unwrap();
3861
3862            // 4. Modulo the body length encoding, check that the
3863            // reserialized content is identical to the original data.
3864            packets_bitwise_compare(filename, &u, data, &data2[..]);
3865        }
3866
3867    }
3868
3869    #[test]
3870    fn serialize_test_2() {
3871        // Given a packet in serialized form:
3872        //
3873        // - Parse, reserialize, and reparse it;
3874        //
3875        // - Compare the messages.
3876        //
3877        // Note: This test only works on messages with a single packet
3878        // top-level packet.
3879        //
3880        // Note: serialize_test_1 is a better test, because it
3881        // compares the serialized data, but serialize_test_1 doesn't
3882        // work if the content is non-deterministic.
3883        let filenames = [
3884            "compressed-data-algo-1.pgp",
3885            "compressed-data-algo-2.pgp",
3886            "compressed-data-algo-3.pgp",
3887            "recursive-2.pgp",
3888            "recursive-3.pgp",
3889        ];
3890
3891        for filename in filenames.iter() {
3892            eprintln!("{}...", filename);
3893
3894            // 1. Read the message into a local buffer.
3895            let data = crate::tests::message(filename);
3896
3897            // 2. Do a shallow parse of the message.  In other words,
3898            // never recurse so that the resulting message only
3899            // contains the top-level packets.  Any containers will
3900            // have their raw content stored in packet.content.
3901            let pile = PacketParserBuilder::from_bytes(data).unwrap()
3902                .max_recursion_depth(0)
3903                .buffer_unread_content()
3904                //.trace()
3905                .into_packet_pile().unwrap();
3906
3907            // 3. Get the first packet.
3908            let po = pile.descendants().next();
3909            if let Some(&Packet::CompressedData(ref cd)) = po {
3910                if ! cd.algo().is_supported() {
3911                    eprintln!("Skipping {} because {} is not supported.",
3912                              filename, cd.algo());
3913                    continue;
3914                }
3915
3916                // 4. Serialize the container.
3917                let buffer =
3918                    (&Packet::CompressedData(cd.clone()) as &dyn MarshalInto)
3919                        .to_vec().unwrap();
3920
3921                // 5. Reparse it.
3922                let pile2 = PacketParserBuilder::from_bytes(&buffer[..]).unwrap()
3923                    .max_recursion_depth(0)
3924                    .buffer_unread_content()
3925                    //.trace()
3926                    .into_packet_pile().unwrap();
3927
3928                // 6. Make sure the original message matches the
3929                // serialized and reparsed message.
3930                if pile != pile2 {
3931                    eprintln!("Orig:");
3932                    let p = pile.children().next().unwrap();
3933                    eprintln!("{:?}", p);
3934                    let body = p.processed_body().unwrap();
3935                    eprintln!("Body: {}", body.len());
3936                    eprintln!("{}", binary_pp(body));
3937
3938                    eprintln!("Reparsed:");
3939                    let p = pile2.children().next().unwrap();
3940                    eprintln!("{:?}", p);
3941                    let body = p.processed_body().unwrap();
3942                    eprintln!("Body: {}", body.len());
3943                    eprintln!("{}", binary_pp(body));
3944
3945                    assert_eq!(pile, pile2);
3946                }
3947            } else {
3948                panic!("Expected a compressed data data packet.");
3949            }
3950        }
3951    }
3952
3953    // Create some crazy nesting structures, serialize the messages,
3954    // reparse them, and make sure we get the same result.
3955    #[test]
3956    fn serialize_test_3() {
3957        use crate::types::DataFormat::Unicode as T;
3958
3959        // serialize_test_1 and serialize_test_2 parse a byte stream.
3960        // This tests creates the message, and then serializes and
3961        // reparses it.
3962
3963        let mut messages = Vec::new();
3964
3965        // 1: CompressedData(CompressedData { algo: 0 })
3966        //  1: Literal(Literal { body: "one (3 bytes)" })
3967        //  2: Literal(Literal { body: "two (3 bytes)" })
3968        // 2: Literal(Literal { body: "three (5 bytes)" })
3969        let mut one = Literal::new(T);
3970        one.set_body(b"one".to_vec());
3971        let mut two = Literal::new(T);
3972        two.set_body(b"two".to_vec());
3973        let mut three = Literal::new(T);
3974        three.set_body(b"three".to_vec());
3975        let mut four = Literal::new(T);
3976        four.set_body(b"four".to_vec());
3977        let mut five = Literal::new(T);
3978        five.set_body(b"five".to_vec());
3979        let mut six = Literal::new(T);
3980        six.set_body(b"six".to_vec());
3981
3982        let top_level = vec![
3983            CompressedData::new(CompressionAlgorithm::Uncompressed)
3984                .push(one.clone().into())
3985                .push(two.clone().into())
3986                .into(),
3987            three.clone().into(),
3988        ];
3989        messages.push(top_level);
3990
3991        // 1: CompressedData(CompressedData { algo: 0 })
3992        //  1: CompressedData(CompressedData { algo: 0 })
3993        //   1: Literal(Literal { body: "one (3 bytes)" })
3994        //   2: Literal(Literal { body: "two (3 bytes)" })
3995        //  2: CompressedData(CompressedData { algo: 0 })
3996        //   1: Literal(Literal { body: "three (5 bytes)" })
3997        //   2: Literal(Literal { body: "four (4 bytes)" })
3998        let top_level = vec![
3999            CompressedData::new(CompressionAlgorithm::Uncompressed)
4000                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4001                      .push(one.clone().into())
4002                      .push(two.clone().into())
4003                      .into())
4004                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4005                      .push(three.clone().into())
4006                      .push(four.clone().into())
4007                      .into())
4008                .into(),
4009        ];
4010        messages.push(top_level);
4011
4012        // 1: CompressedData(CompressedData { algo: 0 })
4013        //  1: CompressedData(CompressedData { algo: 0 })
4014        //   1: CompressedData(CompressedData { algo: 0 })
4015        //    1: CompressedData(CompressedData { algo: 0 })
4016        //     1: Literal(Literal { body: "one (3 bytes)" })
4017        //     2: Literal(Literal { body: "two (3 bytes)" })
4018        //  2: CompressedData(CompressedData { algo: 0 })
4019        //   1: CompressedData(CompressedData { algo: 0 })
4020        //    1: Literal(Literal { body: "three (5 bytes)" })
4021        //   2: Literal(Literal { body: "four (4 bytes)" })
4022        let top_level = vec![
4023            CompressedData::new(CompressionAlgorithm::Uncompressed)
4024                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4025                    .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4026                        .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4027                            .push(one.clone().into())
4028                            .push(two.clone().into())
4029                            .into())
4030                        .into())
4031                    .into())
4032                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4033                    .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
4034                        .push(three.clone().into())
4035                        .into())
4036                    .push(four.clone().into())
4037                    .into())
4038                .into(),
4039        ];
4040        messages.push(top_level);
4041
4042        // 1: CompressedData(CompressedData { algo: 0 })
4043        //  1: Literal(Literal { body: "one (3 bytes)" })
4044        //  2: Literal(Literal { body: "two (3 bytes)" })
4045        // 2: Literal(Literal { body: "three (5 bytes)" })
4046        // 3: Literal(Literal { body: "four (4 bytes)" })
4047        // 4: CompressedData(CompressedData { algo: 0 })
4048        //  1: Literal(Literal { body: "five (4 bytes)" })
4049        //  2: Literal(Literal { body: "six (3 bytes)" })
4050        let top_level = vec![
4051            CompressedData::new(CompressionAlgorithm::Uncompressed)
4052                .push(one.clone().into())
4053                .push(two.clone().into())
4054                .into(),
4055            three.clone().into(),
4056            four.clone().into(),
4057            CompressedData::new(CompressionAlgorithm::Uncompressed)
4058                .push(five.into())
4059                .push(six.into())
4060                .into(),
4061        ];
4062        messages.push(top_level);
4063
4064        // 1: UserID(UserID { value: "Foo" })
4065        let mut top_level = Vec::new();
4066        let uid = UserID::from("Foo");
4067        top_level.push(uid.into());
4068        messages.push(top_level);
4069
4070        for m in messages.into_iter() {
4071            // 1. The message.
4072            let pile = PacketPile::from(m);
4073
4074            pile.pretty_print();
4075
4076            // 2. Serialize the message into a buffer.
4077            let mut buffer = Vec::new();
4078            (&pile as &dyn Marshal).serialize(&mut buffer).unwrap();
4079
4080            // 3. Reparse it.
4081            let pile2 = PacketParserBuilder::from_bytes(&buffer[..]).unwrap()
4082                //.trace()
4083                .buffer_unread_content()
4084                .into_packet_pile().unwrap();
4085
4086            // 4. Compare the messages.
4087            if pile != pile2 {
4088                eprintln!("ORIG...");
4089                pile.pretty_print();
4090                eprintln!("REPARSED...");
4091                pile2.pretty_print();
4092                panic!("Reparsed packet does not match original packet!");
4093            }
4094        }
4095    }
4096
4097    #[test]
4098    fn body_length_edge_cases() {
4099        {
4100            let mut buf = vec![];
4101            BodyLength::Full(0).serialize(&mut buf).unwrap();
4102            assert_eq!(&buf[..], &b"\x00"[..]);
4103        }
4104
4105        {
4106            let mut buf = vec![];
4107            BodyLength::Full(1).serialize(&mut buf).unwrap();
4108            assert_eq!(&buf[..], &b"\x01"[..]);
4109        }
4110        {
4111            let mut buf = vec![];
4112            BodyLength::Full(191).serialize(&mut buf).unwrap();
4113            assert_eq!(&buf[..], &b"\xbf"[..]);
4114        }
4115        {
4116            let mut buf = vec![];
4117            BodyLength::Full(192).serialize(&mut buf).unwrap();
4118            assert_eq!(&buf[..], &b"\xc0\x00"[..]);
4119        }
4120        {
4121            let mut buf = vec![];
4122            BodyLength::Full(193).serialize(&mut buf).unwrap();
4123            assert_eq!(&buf[..], &b"\xc0\x01"[..]);
4124        }
4125        {
4126            let mut buf = vec![];
4127            BodyLength::Full(8383).serialize(&mut buf).unwrap();
4128            assert_eq!(&buf[..], &b"\xdf\xff"[..]);
4129        }
4130        {
4131            let mut buf = vec![];
4132            BodyLength::Full(8384).serialize(&mut buf).unwrap();
4133            assert_eq!(&buf[..], &b"\xff\x00\x00\x20\xc0"[..]);
4134        }
4135        {
4136            let mut buf = vec![];
4137            BodyLength::Full(0xffffffff).serialize(&mut buf).unwrap();
4138            assert_eq!(&buf[..], &b"\xff\xff\xff\xff\xff"[..]);
4139        }
4140    }
4141
4142    #[test]
4143    fn export_signature() {
4144        use crate::cert::prelude::*;
4145
4146        let (cert, _) = CertBuilder::new().generate().unwrap();
4147        let mut keypair = cert.primary_key().key().clone().parts_into_secret()
4148            .unwrap().into_keypair().unwrap();
4149        let uid = UserID::from("foo");
4150
4151        // Make a signature w/o an exportable certification subpacket.
4152        let sig = uid.bind(
4153            &mut keypair, &cert,
4154            signature::SignatureBuilder::new(SignatureType::GenericCertification))
4155            .unwrap();
4156
4157        // The signature is exportable.  Try to export it in
4158        // various ways.
4159        sig.export(&mut Vec::new()).unwrap();
4160        sig.export_into(&mut vec![0; sig.serialized_len()]).unwrap();
4161        sig.export_to_vec().unwrap();
4162        (&PacketRef::Signature(&sig) as &dyn Marshal)
4163            .export(&mut Vec::new()).unwrap();
4164        (&PacketRef::Signature(&sig) as &dyn MarshalInto).export_into(
4165            &mut vec![0; (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4166                             .serialized_len()]).unwrap();
4167        (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4168            .export_to_vec().unwrap();
4169        let p = Packet::Signature(sig);
4170        (&p as &dyn Marshal).export(&mut Vec::new()).unwrap();
4171        (&p as &dyn MarshalInto)
4172            .export_into(
4173                &mut vec![0; (&p as &dyn MarshalInto).serialized_len()])
4174            .unwrap();
4175        (&p as &dyn MarshalInto).export_to_vec().unwrap();
4176        let pp = PacketPile::from(vec![p]);
4177        (&pp as &dyn Marshal).export(&mut Vec::new()).unwrap();
4178        (&pp as &dyn MarshalInto)
4179            .export_into(
4180                &mut vec![0; (&pp as &dyn MarshalInto).serialized_len()])
4181            .unwrap();
4182        (&pp as &dyn MarshalInto).export_to_vec().unwrap();
4183
4184        // Make a signature that is explicitly marked as exportable.
4185        let sig = uid.bind(
4186            &mut keypair, &cert,
4187            signature::SignatureBuilder::new(SignatureType::GenericCertification)
4188                .set_exportable_certification(true).unwrap()).unwrap();
4189
4190        // The signature is exportable.  Try to export it in
4191        // various ways.
4192        sig.export(&mut Vec::new()).unwrap();
4193        sig.export_into(&mut vec![0; sig.serialized_len()]).unwrap();
4194        sig.export_to_vec().unwrap();
4195        (&PacketRef::Signature(&sig) as &dyn Marshal)
4196            .export(&mut Vec::new()).unwrap();
4197        (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4198            .export_into(
4199                &mut vec![0; (&PacketRef::Signature(&sig)
4200                              as &dyn MarshalInto).serialized_len()])
4201            .unwrap();
4202        (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4203            .export_to_vec().unwrap();
4204        let p = Packet::Signature(sig);
4205        (&p as &dyn Marshal).export(&mut Vec::new()).unwrap();
4206        (&p as &dyn MarshalInto)
4207            .export_into(
4208                &mut vec![0; (&p as &dyn MarshalInto).serialized_len()])
4209            .unwrap();
4210        (&p as &dyn MarshalInto).export_to_vec().unwrap();
4211        let pp = PacketPile::from(vec![p]);
4212        (&pp as &dyn Marshal).export(&mut Vec::new()).unwrap();
4213        (&pp as &dyn MarshalInto)
4214            .export_into(
4215                &mut vec![0; (&pp as &dyn MarshalInto).serialized_len()])
4216            .unwrap();
4217        (&pp as &dyn MarshalInto).export_to_vec().unwrap();
4218
4219        // Make a non-exportable signature.
4220        let sig = uid.bind(
4221            &mut keypair, &cert,
4222            signature::SignatureBuilder::new(SignatureType::GenericCertification)
4223                .set_exportable_certification(false).unwrap()).unwrap();
4224
4225        // The signature is not exportable.  Try to export it in
4226        // various ways.
4227        sig.export(&mut Vec::new()).unwrap_err();
4228        sig.export_into(&mut vec![0; sig.serialized_len()]).unwrap_err();
4229        sig.export_to_vec().unwrap_err();
4230        (&PacketRef::Signature(&sig) as &dyn Marshal)
4231            .export(&mut Vec::new()).unwrap_err();
4232        (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4233            .export_into(
4234                &mut vec![0; (&PacketRef::Signature(&sig)
4235                              as &dyn MarshalInto).serialized_len()])
4236            .unwrap_err();
4237        (&PacketRef::Signature(&sig) as &dyn MarshalInto)
4238            .export_to_vec().unwrap_err();
4239        let p = Packet::Signature(sig);
4240        (&p as &dyn Marshal).export(&mut Vec::new()).unwrap_err();
4241        (&p as &dyn MarshalInto)
4242            .export_into(&mut vec![0; (&p as &dyn MarshalInto).serialized_len()])
4243            .unwrap_err();
4244        (&p as &dyn MarshalInto).export_to_vec().unwrap_err();
4245        let pp = PacketPile::from(vec![p]);
4246        (&pp as &dyn Marshal).export(&mut Vec::new()).unwrap_err();
4247        (&pp as &dyn MarshalInto)
4248            .export_into(
4249                &mut vec![0; (&pp as &dyn MarshalInto).serialized_len()])
4250            .unwrap_err();
4251        (&pp as &dyn MarshalInto).export_to_vec().unwrap_err();
4252    }
4253
4254    quickcheck! {
4255        /// Checks that SerializeInto::serialized_len computes the
4256        /// exact size (except for CompressedData packets where we may
4257        /// overestimate the size).
4258        fn packet_serialized_len(p: Packet) -> bool {
4259            let p_as_vec = SerializeInto::to_vec(&p).unwrap();
4260            if let Packet::CompressedData(_) = p {
4261                // serialized length may be an over-estimate
4262                assert!(SerializeInto::serialized_len(&p) >= p_as_vec.len());
4263            } else {
4264                // serialized length should be exact
4265                assert_eq!(SerializeInto::serialized_len(&p), p_as_vec.len());
4266            }
4267            true
4268        }
4269    }
4270}