summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-07-05 14:39:47 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-07-05 14:39:47 +0200
commit5b87166666ebfc97467946c58735b7c942451315 (patch)
tree422b334e828e84f170a63ed544655eff5627dc17
parent2fbb17945cf643298b807a77ad2e08d6924968a6 (diff)
openpgp: Fix serializing headers with legacy CTBs.
- Previously, we always serialized the length for use with new-style CTBs.
-rw-r--r--openpgp/src/serialize.rs38
1 files changed, 36 insertions, 2 deletions
diff --git a/openpgp/src/serialize.rs b/openpgp/src/serialize.rs
index 0d3e4df6..b30f0de0 100644
--- a/openpgp/src/serialize.rs
+++ b/openpgp/src/serialize.rs
@@ -756,6 +756,23 @@ impl BodyLength {
o.write_all(&buffer)?;
Ok(())
}
+
+ /// Computes the length of the length encoded for use with
+ /// old-style CTBs.
+ fn old_serialized_len(&self) -> usize {
+ // Assume an optimal encoding is desired.
+ match self {
+ BodyLength::Full(l) => {
+ match *l {
+ 0 ..= 0xFF => 1,
+ 0x1_00 ..= 0xFF_FF => 2,
+ _ => 4,
+ }
+ },
+ BodyLength::Indeterminate => 0,
+ BodyLength::Partial(_) => 0,
+ }
+ }
}
impl seal::Sealed for CTBNew {}
@@ -816,14 +833,21 @@ impl seal::Sealed for Header {}
impl Marshal for Header {
fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
self.ctb().serialize(o)?;
- self.length().serialize(o)?;
+ match self.ctb() {
+ CTB::New(_) => self.length().serialize(o)?,
+ CTB::Old(_) => self.length().serialize_old(o)?,
+ }
Ok(())
}
}
impl MarshalInto for Header {
fn serialized_len(&self) -> usize {
- self.ctb().serialized_len() + self.length().serialized_len()
+ self.ctb().serialized_len()
+ + match self.ctb() {
+ CTB::New(_) => self.length().serialized_len(),
+ CTB::Old(_) => self.length().old_serialized_len(),
+ }
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
@@ -831,6 +855,16 @@ impl MarshalInto for Header {
}
}
+#[test]
+fn legacy_header() -> Result<()> {
+ use crate::serialize::MarshalInto;
+ let len = BodyLength::Indeterminate;
+ let ctb = CTB::Old(CTBOld::new(Tag::Literal, len)?);
+ assert_eq!(&ctb.to_vec()?[..], &[0b1_0_1011_11]);
+ // Bit encoding: OpenPGP_Legacy_Literal_Indeterminate
+ Ok(())
+}
+
impl Serialize for KeyID {}
impl seal::Sealed for KeyID {}
impl Marshal for KeyID {