sequoia_openpgp/cert/raw.rs
1//! Functionality for dealing with mostly unparsed certificates.
2//!
3//! Parsing a certificate is not cheap. When reading a keyring, most
4//! certificates are discarded or never used as they are not relevant.
5//! This module provides the [`RawCertParser`] and [`RawCert`] data
6//! structures that can help reduce the amount of unnecessary
7//! computation.
8//!
9//! [`RawCertParser`] splits a keyring into [`RawCert`]s by looking
10//! primarily at the packet framing and the packet headers. This is
11//! much faster than parsing the packets' contents, as the
12//! [`CertParser`] does.
13//!
14//! [`CertParser`]: crate::cert::CertParser
15//!
16//! [`RawCert`] exposes just enough functionality to allow the user to
17//! quickly check if a certificate is not relevant. Note: to check if
18//! a certificate is really relevant, the check usually needs to be
19//! repeated after canonicalizing it (by using, e.g., [`Cert::from`])
20//! and validating it (by using [`Cert::with_policy`]).
21//!
22//! [`Cert::from`]: From<RawCert>
23//!
24//! # Examples
25//!
26//! Search for a specific certificate in a keyring:
27//!
28//! ```rust
29//! # use std::convert::TryFrom;
30//! #
31//! use sequoia_openpgp as openpgp;
32//!
33//! # use openpgp::Result;
34//! use openpgp::cert::prelude::*;
35//! use openpgp::cert::raw::RawCertParser;
36//! use openpgp::parse::Parse;
37//! # use openpgp::serialize::Serialize;
38//! #
39//! # fn main() -> Result<()> {
40//! # fn doit() -> Result<Cert> {
41//! # let (cert, _) = CertBuilder::new()
42//! # .generate()?;
43//! # let fpr = cert.fingerprint();
44//! #
45//! # let mut bytes = Vec::new();
46//! # cert.serialize(&mut bytes);
47//! for cert in RawCertParser::from_bytes(&bytes)? {
48//! /// Ignore corrupt and invalid certificates.
49//! let cert = if let Ok(cert) = cert {
50//! cert
51//! } else {
52//! continue;
53//! };
54//!
55//! if cert.fingerprint() == fpr {
56//! // Found it! Try to convert it to a Cert.
57//! return Cert::try_from(cert);
58//! }
59//! }
60//!
61//! // Not found.
62//! return Err(anyhow::anyhow!("Not found!").into());
63//! # }
64//! # doit().expect("Found the certificate");
65//! # Ok(())
66//! # }
67//! ```
68use std::borrow::Cow;
69use std::convert::TryFrom;
70use std::fmt;
71
72use buffered_reader::{BufferedReader, Dup, EOF, Memory};
73
74use crate::Fingerprint;
75use crate::KeyID;
76use crate::Result;
77use crate::armor;
78use crate::cert::Cert;
79use crate::packet::Header;
80use crate::packet::Key;
81use crate::packet::Packet;
82use crate::packet::Tag;
83use crate::packet::UserID;
84use crate::packet::header::BodyLength;
85use crate::packet::header::CTB;
86use crate::packet::key;
87use crate::parse::Cookie;
88use crate::parse::PacketParser;
89use crate::parse::Parse;
90use crate::parse::RECOVERY_THRESHOLD;
91
92use super::TRACE;
93
94mod iter;
95pub use iter::KeyIter;
96
97/// A mostly unparsed `Packet`.
98///
99/// This is returned by [`RawCert::packets`].
100///
101/// The data includes the OpenPGP framing (i.e., the CTB, and length
102/// information). [`RawPacket::body`] returns just the bytes
103/// corresponding to the packet's body, i.e., without the OpenPGP
104/// framing.
105///
106/// You can convert it to a [`Packet`] using `TryFrom`.
107///
108/// # Examples
109///
110/// ```rust
111/// use sequoia_openpgp as openpgp;
112/// # use openpgp::Result;
113/// # use openpgp::cert::prelude::*;
114/// # use openpgp::cert::raw::RawCert;
115/// use openpgp::packet::Packet;
116/// use openpgp::packet::Tag;
117/// # use openpgp::parse::Parse;
118/// # use openpgp::serialize::Serialize;
119/// #
120/// # fn main() -> Result<()> {
121/// # let (cert, _) = CertBuilder::new()
122/// # .add_signing_subkey()
123/// # .add_certification_subkey()
124/// # .add_transport_encryption_subkey()
125/// # .add_storage_encryption_subkey()
126/// # .add_authentication_subkey()
127/// # .generate()?;
128/// #
129/// # let mut bytes = Vec::new();
130/// # cert.as_tsk().serialize(&mut bytes);
131/// # let mut count = 0;
132/// #
133/// # let rawcert = RawCert::from_bytes(&bytes)?;
134/// for p in rawcert.packets() {
135/// if p.tag() == Tag::SecretSubkey {
136/// if let Ok(packet) = Packet::try_from(p) {
137/// // Do something with the packet.
138/// # count += 1;
139/// }
140/// # else { panic!("Failed to parse packet"); }
141/// }
142/// }
143/// # assert_eq!(count, 5);
144/// # Ok(())
145/// # }
146/// ```
147#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
148pub struct RawPacket<'a> {
149 tag: Tag,
150 header_len: usize,
151 data: &'a [u8],
152}
153assert_send_and_sync!(RawPacket<'_>);
154
155impl fmt::Debug for RawPacket<'_> {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 f.debug_struct("RawPacket")
158 .field("tag", &self.tag)
159 .field("data (bytes)", &self.data.len())
160 .finish()
161 }
162}
163
164impl<'a> RawPacket<'a> {
165 fn new(tag: Tag, header_len: usize, bytes: &'a [u8]) -> Self {
166 Self {
167 tag,
168 header_len,
169 data: bytes,
170 }
171 }
172
173 /// Returns the packet's tag.
174 pub fn tag(&self) -> Tag {
175 self.tag
176 }
177
178 /// Returns the packet's bytes.
179 pub fn as_bytes(&self) -> &[u8] {
180 self.data
181 }
182
183 /// Return the packet's body without the OpenPGP framing.
184 pub fn body(&self) -> &[u8] {
185 &self.data[self.header_len..]
186 }
187}
188
189impl<'a> TryFrom<RawPacket<'a>> for Packet {
190 type Error = anyhow::Error;
191
192 fn try_from(p: RawPacket<'a>) -> Result<Self> {
193 Packet::from_bytes(p.as_bytes())
194 }
195}
196
197impl<'a> crate::seal::Sealed for RawPacket<'a> {}
198impl<'a> crate::serialize::Marshal for RawPacket<'a> {
199 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
200 o.write_all(self.as_bytes())?;
201 Ok(())
202 }
203}
204
205/// A mostly unparsed `Cert`.
206///
207/// This data structure contains the unparsed packets for a
208/// certificate or key. The packet sequence is well-formed in the
209/// sense that the sequence of tags conforms to the [Transferable
210/// Public Key grammar] or [Transferable Secret Key grammar], and that
211/// it can extract the primary key's fingerprint. Beyond that, the
212/// packets are not guaranteed to be valid.
213///
214/// [Transferable Public Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1
215/// [Transferable Secret Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.2
216///
217/// This data structure exists to quickly split a large keyring, and
218/// only parse those certificates that appear to be relevant.
219#[derive(Clone)]
220pub struct RawCert<'a> {
221 data: Cow<'a, [u8]>,
222
223 primary_key: Key<key::PublicParts, key::PrimaryRole>,
224
225 // The packet's tag, the length of the header, and the offset of
226 // the start of the packet (including the header) into data.
227 packets: Vec<(Tag, usize, usize)>,
228}
229assert_send_and_sync!(RawCert<'_>);
230
231impl<'a> fmt::Debug for RawCert<'a> {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 f.debug_struct("RawCert")
234 .field("fingerprint", &self.fingerprint())
235 .field("packets",
236 &self.packets
237 .iter()
238 .map(|p| format!("{} (offset: {})", p.0, p.1))
239 .collect::<Vec<String>>()
240 .join(", "))
241 .field("data (bytes)", &self.data.as_ref().len())
242 .finish()
243 }
244}
245
246impl<'a> PartialEq for RawCert<'a> {
247 fn eq(&self, other: &Self) -> bool {
248 self.data == other.data
249 }
250}
251
252impl<'a> Eq for RawCert<'a> {
253}
254
255impl<'a> RawCert<'a> {
256 /// Returns the certificate's bytes.
257 ///
258 /// If you want an individual packet's bytes, use
259 /// [`RawCert::packet`] or [`RawCert::packets`], and then call
260 /// [`RawPacket::as_bytes`].
261 pub fn as_bytes(&'a self) -> &'a [u8] {
262 self.data.as_ref()
263 }
264
265 /// Returns the certificate's fingerprint.
266 pub fn fingerprint(&self) -> Fingerprint {
267 self.primary_key.fingerprint()
268 }
269
270 /// Returns the certificate's Key ID.
271 pub fn keyid(&self) -> KeyID {
272 KeyID::from(self.fingerprint())
273 }
274
275 /// Returns the ith packet.
276 pub fn packet(&self, i: usize) -> Option<RawPacket> {
277 let data: &[u8] = self.data.as_ref();
278
279 let &(tag, header_len, start) = self.packets.get(i)?;
280 let following = self.packets
281 .get(i + 1)
282 .map(|&(_, _, offset)| offset)
283 .unwrap_or(data.len());
284
285 Some(RawPacket::new(tag, header_len, &data[start..following]))
286 }
287
288 /// Returns an iterator over each raw packet.
289 pub fn packets(&self) -> impl Iterator<Item=RawPacket> {
290 let data: &[u8] = self.data.as_ref();
291
292 let count = self.packets.len();
293 (0..count)
294 .map(move |i| {
295 let (tag, header_len, start) = self.packets[i];
296 let following = self.packets
297 .get(i + 1)
298 .map(|&(_, _, offset)| offset)
299 .unwrap_or(data.len());
300
301 RawPacket::new(tag, header_len, &data[start..following])
302 })
303 }
304
305 /// Returns the number of packets.
306 pub fn count(&self) -> usize {
307 self.packets.len()
308 }
309
310 /// Returns an iterator over the certificate's keys.
311 ///
312 /// Note: this parses the key packets, but it does not verify any
313 /// binding signatures. As such, this can only be used as part of
314 /// a precheck. If the certificate appears to match, then the
315 /// caller must convert the [`RawCert`] to a [`Cert`] or a
316 /// [`ValidCert`], depending on the requirements, and perform the
317 /// check again.
318 ///
319 /// [`ValidCert`]: crate::cert::ValidCert
320 ///
321 /// Use [`subkeys`] to just return the subkeys. This function
322 /// also changes the return type. Instead of the iterator
323 /// returning a [`Key`] whose role is [`key::UnspecifiedRole`],
324 /// the role is [`key::SubordinateRole`].
325 ///
326 /// [`subkeys`]: KeyIter::subkeys
327 ///
328 /// # Examples
329 ///
330 /// ```rust
331 /// use sequoia_openpgp as openpgp;
332 //
333 /// # use openpgp::Result;
334 /// # use openpgp::cert::prelude::*;
335 /// use openpgp::cert::raw::RawCertParser;
336 /// use openpgp::parse::Parse;
337 /// # use openpgp::serialize::Serialize;
338 /// #
339 /// # fn main() -> Result<()> {
340 /// # let (cert, _) = CertBuilder::new()
341 /// # .add_signing_subkey()
342 /// # .add_certification_subkey()
343 /// # .add_transport_encryption_subkey()
344 /// # .add_storage_encryption_subkey()
345 /// # .add_authentication_subkey()
346 /// # .generate()?;
347 /// #
348 /// # let mut bytes = Vec::new();
349 /// # cert.serialize(&mut bytes);
350 /// # let mut certs = 0;
351 /// # let mut keys = 0;
352 /// for cert in RawCertParser::from_bytes(&bytes)? {
353 /// /// Ignore corrupt and invalid certificates.
354 /// let cert = if let Ok(cert) = cert {
355 /// cert
356 /// } else {
357 /// continue;
358 /// };
359 ///
360 /// // Iterate over the keys. Note: this parses the Key
361 /// // packets.
362 /// for key in cert.keys() {
363 /// println!("{}", key.fingerprint());
364 /// # keys += 1;
365 /// }
366 /// # certs += 1;
367 /// }
368 /// # assert_eq!(certs, 1);
369 /// # assert_eq!(keys, 6);
370 /// # Ok(())
371 /// # }
372 /// ```
373 pub fn keys(&self) -> KeyIter<key::PublicParts, key::UnspecifiedRole> {
374 KeyIter::new(self)
375 }
376
377 // Returns an iterator over the certificate's keys.
378 //
379 // This is used by `KeyIter`, which implements a number of
380 // filters.
381 fn keys_internal(&self)
382 -> impl Iterator<Item=Key<key::PublicParts, key::UnspecifiedRole>> + '_
383 {
384 std::iter::once(self.primary_key().clone().role_into_unspecified())
385 .chain(self.packets()
386 .filter(|p| matches!(p.tag(),
387 Tag::PublicKey | Tag::PublicSubkey
388 | Tag::SecretKey | Tag::SecretSubkey))
389 .skip(1) // The primary key.
390 .filter_map(|p| Key::from_bytes(p.body())
391 .ok()
392 .map(|k| k.parts_into_public())))
393 }
394
395 /// Returns the certificate's primary key.
396 ///
397 /// Note: this parses the primary key packet, but it does not
398 /// verify any binding signatures. As such, this can only be used
399 /// as part of a precheck. If the certificate appears to match,
400 /// then the caller must convert the [`RawCert`] to a [`Cert`] or
401 /// a [`ValidCert`], depending on the requirements, and perform
402 /// the check again.
403 ///
404 /// [`ValidCert`]: crate::cert::ValidCert
405 pub fn primary_key(&self) -> Key<key::PublicParts, key::PrimaryRole> {
406 self.primary_key.clone()
407 }
408
409 /// Returns the certificate's User IDs.
410 ///
411 /// Note: this parses the User ID packets, but it does not verify
412 /// any binding signatures. That is, there is no guarantee that
413 /// the User IDs should actually be associated with the primary
414 /// key. As such, this can only be used as part of a precheck.
415 /// If a User ID appears to match, then the caller must convert
416 /// the [`RawCert`] to a [`Cert`] or a [`ValidCert`], depending on
417 /// the requirements, and perform the check again.
418 ///
419 /// [`ValidCert`]: crate::cert::ValidCert
420 pub fn userids(&self) -> impl Iterator<Item=UserID> + '_
421 {
422 self.packets()
423 .filter_map(|p| {
424 if p.tag() == Tag::UserID {
425 UserID::try_from(p.body()).ok()
426 } else {
427 None
428 }
429 })
430 }
431
432 /// Changes the `RawCert`'s lifetime to the static lifetime.
433 ///
434 /// Returns a `RawCert` with a static lifetime by copying any
435 /// referenced data.
436 ///
437 /// [`RawCertParser::next`] returns a `RawCert` with the same
438 /// lifetime as its reader. In certain situations,
439 /// `RawCertParser::next` can take advantage of this to avoid
440 /// copying data. Tying the `RawCert`'s lifetime to the reader is
441 /// inconvenient when the `RawCert` needs to outlive the reader,
442 /// however. This function copies any referenced data thereby
443 /// breaking the dependency.
444 ///
445 /// ```
446 /// # use sequoia_openpgp::Result;
447 /// # use sequoia_openpgp::cert::raw::RawCert;
448 /// # use sequoia_openpgp::cert::raw::RawCertParser;
449 /// # use sequoia_openpgp::parse::Parse;
450 ///
451 /// # fn main() -> Result<()> {
452 /// fn read_certs<'a>() -> Result<Vec<RawCert<'static>>> {
453 /// let input = // ...
454 /// # Vec::new();
455 ///
456 /// // The lifetime of the returned certs is tied to input.
457 /// // We use into_owned to break the dependency.
458 /// let parser = RawCertParser::from_bytes(&input)?;
459 /// let certs = parser
460 /// .map(|r| r.map(|c| c.into_owned()))
461 /// .collect::<Result<Vec<_>>>()?;
462 /// Ok(certs)
463 /// }
464 ///
465 /// let cert = read_certs()?;
466 /// # assert_eq!(cert.len(), 0);
467 /// # Ok(()) }
468 /// ```
469 pub fn into_owned(self) -> RawCert<'static> {
470 match self.data {
471 Cow::Owned(data) => {
472 RawCert {
473 data: Cow::Owned(data),
474 primary_key: self.primary_key,
475 packets: self.packets,
476 }
477 }
478 Cow::Borrowed(data) => {
479 RawCert {
480 data: Cow::Owned(data.to_vec()),
481 primary_key: self.primary_key,
482 packets: self.packets,
483 }
484 }
485 }
486 }
487}
488
489impl<'a> TryFrom<&RawCert<'a>> for Cert {
490 type Error = anyhow::Error;
491
492 fn try_from(c: &RawCert) -> Result<Self> {
493 Cert::from_bytes(c.as_bytes())
494 }
495}
496
497impl<'a> TryFrom<RawCert<'a>> for Cert {
498 type Error = anyhow::Error;
499
500 fn try_from(c: RawCert) -> Result<Self> {
501 Cert::try_from(&c)
502 }
503}
504
505impl<'a> Parse<'a, RawCert<'a>> for RawCert<'a> {
506 /// Returns the first RawCert encountered in the reader.
507 ///
508 /// Returns an error if there are multiple certificates.
509 fn from_buffered_reader<R>(reader: R) -> Result<RawCert<'a>>
510 where
511 R: BufferedReader<Cookie> + 'a
512 {
513 fn parse<'a>(reader: Box<dyn BufferedReader<Cookie> + 'a>) -> Result<RawCert<'a>> {
514 let mut parser = RawCertParser::from_buffered_reader(reader)?;
515 if let Some(cert_result) = parser.next() {
516 if parser.next().is_some() {
517 Err(crate::Error::MalformedCert(
518 "Additional packets found, is this a keyring?".into()
519 ).into())
520 } else {
521 cert_result
522 }
523 } else {
524 Err(crate::Error::MalformedCert("No data".into()).into())
525 }
526 }
527
528 parse(reader.into_boxed())
529 }
530}
531
532impl<'a> crate::seal::Sealed for RawCert<'a> {}
533impl<'a> crate::serialize::Marshal for RawCert<'a> {
534 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
535 o.write_all(self.as_bytes())?;
536 Ok(())
537 }
538}
539
540/// An iterator over a sequence of unparsed certificates, i.e., an
541/// OpenPGP keyring.
542///
543/// A `RawCertParser` returns each certificate that it encounters.
544///
545/// It implements the same state machine as [`CertParser`], however, a
546/// `CertParser` is stricter. Specifically, a `CertParser` performs
547/// some sanity checks on the content of the packets whereas a
548/// `RawCertParser` doesn't do those checks, because it avoids parsing
549/// the packets' contents; it primarily looks at the packets' framing,
550/// and their headers.
551///
552/// [`CertParser`]: crate::cert::CertParser
553///
554/// `RawCertParser` checks that the packet sequence is well-formed in
555/// the sense that the sequence of tags conforms to the [Transferable
556/// Public Key grammar] or [Transferable Secret Key grammar], and it
557/// performs a few basic checks. See the documentation for
558/// [`RawCert`] for details.
559///
560/// [Transferable Public Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1
561/// [Transferable Secret Key grammar]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.2
562///
563/// Because a `RawCertParser` doesn't parse the contents of the
564/// packets, it is significantly faster than a [`CertParser`] when
565/// many of the certificates in a keyring are irrelevant.
566///
567/// # Examples
568///
569/// Search for a specific certificate in a keyring:
570///
571/// ```rust
572/// # use std::convert::TryFrom;
573/// #
574/// use sequoia_openpgp as openpgp;
575///
576/// # use openpgp::Result;
577/// use openpgp::cert::prelude::*;
578/// use openpgp::cert::raw::RawCertParser;
579/// use openpgp::parse::Parse;
580/// # use openpgp::serialize::Serialize;
581/// #
582/// # fn main() -> Result<()> {
583/// # fn doit() -> Result<Cert> {
584/// # let (cert, _) = CertBuilder::new()
585/// # .generate()?;
586/// # let fpr = cert.fingerprint();
587/// #
588/// # let mut bytes = Vec::new();
589/// # cert.serialize(&mut bytes);
590/// for cert in RawCertParser::from_bytes(&bytes)? {
591/// /// Ignore corrupt and invalid certificates.
592/// let cert = if let Ok(cert) = cert {
593/// cert
594/// } else {
595/// continue;
596/// };
597///
598/// if cert.fingerprint() == fpr {
599/// // Found it! Try to convert it to a Cert.
600/// if let cert = Cert::try_from(cert) {
601/// return cert;
602/// }
603/// }
604/// }
605///
606/// // Not found.
607/// return Err(anyhow::anyhow!("Not found!").into());
608/// # }
609/// # doit().expect("Found the certificate");
610/// # Ok(())
611/// # }
612/// ```
613pub struct RawCertParser<'a>
614{
615 // If the data is being read from a slice, then the slice. This
616 // is used to avoid copying the data into the RawCert.
617 slice: Option<&'a [u8]>,
618
619 // Where `RawCertParser` reads the data. When reading from a
620 // slice, this is a `buffered_reader::Memory`. Note: the slice
621 // field will not be set, if the input needs to be transferred
622 // (i.e., dearmored).
623 reader: Box<dyn BufferedReader<Cookie> + 'a>,
624
625 // Whether we are dearmoring the input.
626 dearmor: bool,
627
628 // The total number of bytes read.
629 bytes_read: usize,
630
631 // Any pending error.
632 pending_error: Option<anyhow::Error>,
633
634 // Whether there was an unrecoverable error.
635 done: bool,
636}
637assert_send_and_sync!(RawCertParser<'_>);
638
639impl<'a> RawCertParser<'a> {
640 fn new(reader: Box<dyn BufferedReader<Cookie> + 'a>) -> Result<Self>
641 {
642 // Check that we can read the first header and that it is
643 // reasonable. Note: an empty keyring is not an error; we're
644 // just checking for bad data here. If not, try again after
645 // dearmoring the input.
646 let mut dearmor = false;
647 let mut dup = Dup::with_cookie(reader, Default::default());
648 if ! dup.eof() {
649 match Header::parse(&mut dup) {
650 Ok(header) => {
651 let tag = header.ctb().tag();
652 if matches!(tag, Tag::Unknown(_) | Tag::Private(_)) {
653 return Err(crate::Error::MalformedCert(
654 format!("A certificate must start with a \
655 public key or a secret key packet, \
656 got a {}",
657 tag))
658 .into());
659 }
660 }
661 Err(_err) => {
662 // We failed to read a header. Try to dearmor the
663 // input.
664 dearmor = true;
665 }
666 }
667 }
668
669 // Strip the Dup reader.
670 let mut reader = dup.into_boxed().into_inner().expect("inner");
671
672 if dearmor {
673 reader = armor::Reader::from_cookie_reader(
674 reader, armor::ReaderMode::Tolerant(None),
675 Default::default()).into_boxed();
676
677 let mut dup = Dup::with_cookie(reader, Default::default());
678 match Header::parse(&mut dup) {
679 Ok(header) => {
680 let tag = header.ctb().tag();
681 if matches!(tag, Tag::Unknown(_) | Tag::Private(_)) {
682 return Err(crate::Error::MalformedCert(
683 format!("A certificate must start with a \
684 public key or a secret key packet, \
685 got a {}",
686 tag))
687 .into());
688 }
689 }
690 Err(err) => {
691 return Err(err);
692 }
693 }
694
695 reader = dup.into_boxed().into_inner().expect("inner");
696 }
697
698 Ok(RawCertParser {
699 slice: None,
700 reader,
701 dearmor,
702 bytes_read: 0,
703 pending_error: None,
704 done: false,
705 })
706 }
707}
708
709impl<'a> Parse<'a, RawCertParser<'a>> for RawCertParser<'a>
710{
711 /// Initializes a `RawCertParser` from a `BufferedReader`.
712 fn from_buffered_reader<R>(reader: R) -> Result<RawCertParser<'a>>
713 where
714 R: BufferedReader<Cookie> + 'a
715 {
716 RawCertParser::new(reader.into_boxed())
717 }
718
719 /// Initializes a `RawCertParser` from a byte string.
720 fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(data: &'a D) -> Result<Self> {
721 let data = data.as_ref();
722 let mut p = RawCertParser::new(
723 Memory::with_cookie(data, Default::default()).into_boxed())?;
724
725 // If we are dearmoring the input, then the slice doesn't
726 // reflect the raw packets.
727 if ! p.dearmor {
728 p.slice = Some(data);
729 }
730 Ok(p)
731 }
732}
733
734impl<'a> crate::seal::Sealed for RawCertParser<'a> {}
735
736impl<'a> Iterator for RawCertParser<'a>
737{
738 type Item = Result<RawCert<'a>>;
739
740 fn next(&mut self) -> Option<Self::Item> {
741 tracer!(TRACE, "RawCertParser::next", 0);
742
743 // Return the pending error.
744 if let Some(err) = self.pending_error.take() {
745 t!("Returning the queued error: {}", err);
746 return Some(Err(err));
747 }
748
749 if self.done {
750 return None;
751 }
752
753 if self.reader.eof() && self.dearmor {
754 // We are dearmoring and hit EOF. Maybe there is a second
755 // armor block next to this one!
756
757 // Get the reader,
758 let reader = std::mem::replace(
759 &mut self.reader,
760 EOF::with_cookie(Default::default()).into_boxed());
761
762 // peel off the armor reader,
763 let reader = reader.into_inner().expect("the armor reader");
764
765 // and install a new one!
766 self.reader = armor::Reader::from_cookie_reader(
767 reader, armor::ReaderMode::Tolerant(None),
768 Default::default()).into_boxed();
769 }
770
771 if self.reader.eof() {
772 return None;
773 }
774
775 let mut reader = Dup::with_cookie(
776 std::mem::replace(&mut self.reader,
777 Box::new(EOF::with_cookie(Default::default()))),
778 Default::default());
779
780 // The absolute start of this certificate in the stream.
781 let cert_start_absolute = self.bytes_read;
782
783 // The number of bytes processed relative to the start of the
784 // dup'ed buffered reader. This may be less than the number
785 // of bytes read, e.g., when we encounter a new certificate,
786 // we read the header, but we don't necessarily want to
787 // consider it consumed.
788 let mut processed = 0;
789
790 // The certificate's span relative to the start of the dup'ed
791 // buffered reader. The start will be larger than zero when
792 // we skip a marker packet.
793 let mut cert_start = 0;
794 let mut cert_end = 0;
795
796 // (Tag, header length, offset from start of the certificate)
797 let mut packets: Vec<(Tag, usize, usize)> = Vec::new();
798 let mut primary_key = None;
799
800 let mut pending_error = None;
801 'packet_parser: loop {
802 if reader.eof() {
803 break;
804 }
805
806 let packet_start = reader.total_out();
807 processed = packet_start;
808
809 let mut skip = 0;
810 let mut header_len = 0;
811 let header = loop {
812 match Header::parse(&mut reader) {
813 Err(err) => {
814 if skip == 0 {
815 t!("Reading the next packet's header: {}", err);
816 }
817
818 if skip >= RECOVERY_THRESHOLD {
819 pending_error = Some(err.context(
820 format!("Splitting keyring at offset {}",
821 self.bytes_read + packet_start)));
822 processed = reader.total_out();
823
824 // We tried to recover and failed. Once
825 // we return the above error, we're done.
826 self.done = true;
827
828 break 'packet_parser;
829 } else if reader.eof() {
830 t!("EOF while trying to recover");
831 skip += 1;
832 break Header::new(CTB::new(Tag::Reserved),
833 BodyLength::Full(skip as u32));
834 } else {
835 skip += 1;
836 reader.rewind();
837 reader.consume(packet_start + skip);
838 }
839 }
840 Ok(header) if skip > 0 => {
841 if PacketParser::plausible_cert(&mut reader, &header)
842 .is_ok()
843 {
844 // We recovered. First return an error. The
845 // next time this function is called, we'll
846 // resume here.
847 t!("Found a valid header after {} bytes \
848 of junk: {:?}",
849 skip, header);
850
851 break Header::new(CTB::new(Tag::Reserved),
852 BodyLength::Full(skip as u32));
853 } else {
854 skip += 1;
855 reader.rewind();
856 reader.consume(packet_start + skip);
857 }
858 }
859 Ok(header) => {
860 header_len = reader.total_out() - packet_start;
861 break header;
862 }
863 }
864 };
865
866 if skip > 0 {
867 // Fabricate a header.
868 t!("Recovered after {} bytes of junk", skip);
869
870 pending_error = Some(crate::Error::MalformedPacket(
871 format!("Encountered {} bytes of junk at offset {}",
872 skip, self.bytes_read)).into());
873
874 // Be careful: if we recovered, then we
875 // reader.total_out() includes the good header.
876 processed += skip;
877
878 break;
879 }
880
881 let tag = header.ctb().tag();
882 t!("Found a {:?}, length: {:?}",
883 tag, header.length());
884
885 if packet_start > cert_start
886 && (tag == Tag::PublicKey || tag == Tag::SecretKey)
887 {
888 // Start of new cert. Note: we don't advanced
889 // processed! That would consume the header that
890 // we want to read the next time this function is
891 // called.
892 t!("Stopping: found the start of a new cert ({})", tag);
893 break;
894 }
895
896 match header.length() {
897 BodyLength::Full(l) => {
898 let l = *l as usize;
899
900 match reader.data_consume_hard(l) {
901 Err(err) => {
902 t!("Stopping: reading {}'s body: {}", tag, err);
903
904 // If we encountered an EOF while reading
905 // the packet body, then we're done.
906 if err.kind() == std::io::ErrorKind::UnexpectedEof {
907 t!("Got an unexpected EOF, done.");
908 self.done = true;
909 }
910
911 pending_error = Some(
912 anyhow::Error::from(err).context(format!(
913 "While reading {}'s body", tag)));
914
915 break;
916 }
917 Ok(data) => {
918 if tag == Tag::PublicKey
919 || tag == Tag::SecretKey
920 {
921 let data = &data[..l];
922 match Key::from_bytes(data) {
923 Err(err) => {
924 t!("Stopping: parsing public key: {}",
925 err);
926 primary_key = Some(Err(err));
927 }
928 Ok(key) => primary_key = Some(
929 Ok(key.parts_into_public()
930 .role_into_primary())),
931 }
932 }
933 }
934 }
935 }
936 BodyLength::Partial(_) => {
937 t!("Stopping: Partial body length not allowed \
938 for {} packets",
939 tag);
940 pending_error = Some(
941 crate::Error::MalformedPacket(
942 format!("Packet {} uses partial body length \
943 encoding, which is not allowed in \
944 certificates",
945 tag))
946 .into());
947 self.done = true;
948 break;
949 }
950 BodyLength::Indeterminate => {
951 t!("Stopping: Indeterminate length not allowed \
952 for {} packets",
953 tag);
954 pending_error = Some(
955 crate::Error::MalformedPacket(
956 format!("Packet {} uses intedeterminite length \
957 encoding, which is not allowed in \
958 certificates",
959 tag))
960 .into());
961 self.done = true;
962 break;
963 }
964 }
965
966 let end = reader.total_out();
967 processed = end;
968
969 let r = if packet_start == cert_start {
970 if tag == Tag::Marker {
971 // Silently skip marker packets at the start of a
972 // packet sequence.
973 cert_start = end;
974 Ok(())
975 } else {
976 packets.push((tag, header_len, packet_start));
977 Cert::valid_start(tag)
978 }
979 } else {
980 packets.push((tag, header_len, packet_start));
981 Cert::valid_packet(tag)
982 };
983 if let Err(err) = r {
984 t!("Stopping: {:?} => not a certificate: {}", header, err);
985 pending_error = Some(err);
986
987 if self.bytes_read == 0 && packet_start == cert_start
988 && matches!(tag, Tag::Unknown(_) | Tag::Private(_))
989 {
990 // The very first packet is not known. Don't
991 // bother to parse anything else.
992 self.done = true;
993 }
994
995 break;
996 }
997
998 cert_end = end;
999 }
1000
1001 t!("{} bytes processed; RawCert @ offset {}, {} bytes",
1002 processed,
1003 self.bytes_read + cert_start, cert_end - cert_start);
1004
1005 assert!(cert_start <= cert_end);
1006 assert!(cert_end <= processed);
1007 self.bytes_read += processed;
1008
1009 // Strip the buffered_reader::Dup.
1010 self.reader = Box::new(reader).into_inner()
1011 .expect("just put it there");
1012
1013 // Consume the data.
1014 let cert_data = &self.reader
1015 .data_consume_hard(processed)
1016 .expect("just read it")[cert_start..cert_end];
1017
1018 if let Some(err) = pending_error.take() {
1019 if cert_start == cert_end {
1020 // We didn't read anything.
1021 t!("Directly returning the error");
1022 return Some(Err(err));
1023 } else {
1024 t!("Queuing the error");
1025 self.pending_error = Some(err);
1026 }
1027 }
1028
1029 if cert_start == cert_end {
1030 t!("No data.");
1031 return None;
1032 }
1033
1034 match primary_key.expect("set") {
1035 Ok(primary_key) => Some(Ok(RawCert {
1036 data: if let Some(slice) = self.slice.as_ref() {
1037 let data = &slice[cert_start_absolute + cert_start
1038 ..cert_start_absolute + cert_end];
1039 assert_eq!(data, cert_data);
1040 Cow::Borrowed(data)
1041 } else {
1042 Cow::Owned(cert_data.to_vec())
1043 },
1044 primary_key,
1045 packets,
1046 })),
1047 Err(err) =>
1048 Some(Err(Error::UnsupportedCert(err, cert_data.into()).into())),
1049 }
1050 }
1051}
1052
1053/// Errors used in this module.
1054#[non_exhaustive]
1055#[derive(thiserror::Error, Debug)]
1056pub enum Error {
1057 /// Unsupported Cert.
1058 ///
1059 /// This usually occurs, because the primary key is in an
1060 /// unsupported format. In particular, Sequoia does not support
1061 /// version 3 keys.
1062 #[error("Unsupported Cert: {0}")]
1063 UnsupportedCert(anyhow::Error, Vec<u8>),
1064}
1065
1066#[cfg(test)]
1067mod test {
1068 use super::*;
1069
1070 use crate::cert::CertParser;
1071 use crate::cert::CertBuilder;
1072 use crate::packet::Literal;
1073 use crate::parse::RECOVERY_THRESHOLD;
1074 use crate::parse::PacketParserResult;
1075 use crate::serialize::Serialize;
1076 use crate::types::DataFormat;
1077 use crate::packet::Unknown;
1078 use crate::packet::CompressedData;
1079
1080 fn cert_cmp(a: Cert, b: Cert)
1081 {
1082 if a == b {
1083 return;
1084 }
1085
1086 let a = a.into_tsk().into_packets().collect::<Vec<_>>();
1087 let b = b.into_tsk().into_packets().collect::<Vec<_>>();
1088
1089 for (i, (a, b)) in a.iter().zip(b.iter()).enumerate() {
1090 if a != b {
1091 panic!("Differ at element #{}:\n {:?}\n {:?}",
1092 i, a, b);
1093 }
1094 }
1095 if a.len() > b.len() {
1096 eprintln!("Left has more packets:");
1097 for p in &a[b.len()..] {
1098 eprintln!(" - {}", p.tag());
1099 }
1100 }
1101 if b.len() > a.len() {
1102 eprintln!("Right has more packets:");
1103 for p in &b[a.len()..] {
1104 eprintln!(" - {}", p.tag());
1105 }
1106 }
1107 if a.len() != b.len() {
1108 panic!("Different lengths (common prefix identical): {} vs. {}",
1109 a.len(), b.len());
1110 }
1111 }
1112
1113 // Compares the result of a RawCertParser with the results of a
1114 // CertParser on a particular byte stream.
1115 fn compare_parse(bytes: &[u8]) -> Vec<RawCert> {
1116 let mut result = Vec::new();
1117
1118 // We do the comparison two times: once with a byte stream
1119 // (this exercises the Cow::Borrowed path), and one
1120 // with a buffered reader (this exercises the Cow::Owned
1121 // code path).
1122 for &from_bytes in [true, false].iter() {
1123 let cp = CertParser::from_bytes(bytes);
1124 let rp = if from_bytes {
1125 eprintln!("=== RawCertParser::from_bytes");
1126 RawCertParser::from_bytes(bytes)
1127 } else {
1128 eprintln!("=== RawCertParser::from_reader");
1129 RawCertParser::from_reader(std::io::Cursor::new(bytes))
1130 };
1131
1132 assert_eq!(cp.is_err(), rp.is_err(),
1133 "CertParser: {:?}; RawCertParser: {:?}",
1134 cp.map(|_| "Parsed"),
1135 rp.map(|_| "Parsed"));
1136 if cp.is_err() && rp.is_err() {
1137 return Vec::new();
1138 }
1139
1140 let mut cp = cp.expect("valid");
1141 let mut rp = rp.expect("valid");
1142
1143 let mut raw_certs = Vec::new();
1144 loop {
1145 eprintln!("=== NEXT CERTPARSER");
1146 let c = cp.next();
1147 eprintln!("=== END CERTPARSER");
1148 eprintln!("=== NEXT RAWCERTPARSER");
1149 let r = rp.next();
1150 eprintln!("=== END RAWCERTPARSER");
1151
1152 let (c, r) = match (c, r) {
1153 // Both return ok.
1154 (Some(Ok(c)), Some(Ok(r))) => (c, r),
1155 // Both return an error.
1156 (Some(Err(_)), Some(Err(_))) => continue,
1157 // Both return EOF.
1158 (None, None) => break,
1159 (c, r) => {
1160 panic!("\n\
1161 CertParser returned: {:?}\n\
1162 RawCertParser returned: {:?}",
1163 c, r);
1164 }
1165 };
1166
1167 assert_eq!(c.fingerprint(), r.fingerprint());
1168
1169 eprintln!("CertParser says:");
1170 for (i, p) in c.clone().into_tsk().into_packets().enumerate() {
1171 eprintln!(" - {}. {}", i, p.tag());
1172 }
1173
1174 let rp = Cert::from_bytes(r.as_bytes()).unwrap();
1175 eprintln!("RawCertParser says:");
1176 for (i, p) in rp.clone().into_tsk().into_packets().enumerate() {
1177 eprintln!(" - {}. {}", i, p.tag());
1178 }
1179
1180 cert_cmp(c.clone(), rp);
1181
1182 raw_certs.push(r);
1183 }
1184
1185 result = raw_certs;
1186 }
1187 result
1188 }
1189
1190 #[test]
1191 fn empty() {
1192 let bytes = &[];
1193
1194 let certs = compare_parse(bytes);
1195 assert_eq!(certs.len(), 0);
1196 }
1197
1198 #[test]
1199 fn a_cert() {
1200 let testy = crate::tests::key("testy.pgp");
1201
1202 let bytes = testy;
1203
1204 let certs = compare_parse(bytes);
1205 assert_eq!(certs.len(), 1);
1206 let cert = &certs[0];
1207 assert_eq!(cert.as_bytes(), testy);
1208
1209 let tags = &[ Tag::PublicKey,
1210 Tag::UserID, Tag::Signature,
1211 Tag::PublicSubkey, Tag::Signature
1212 ];
1213 assert_eq!(
1214 &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1215 tags);
1216
1217 // Check that we can parse the individual packets and that
1218 // they have the correct tag.
1219 for (p, tag) in cert.packets().zip(tags.iter()) {
1220 let ppr = PacketParser::from_bytes(p.as_bytes()).expect("valid");
1221 if let PacketParserResult::Some(pp) = ppr {
1222 let (p, pp) = pp.next().expect("valid");
1223 assert_eq!(p.tag(), *tag);
1224 assert!(matches!(pp, PacketParserResult::EOF(_)));
1225 } else {
1226 panic!("Unexpected EOF");
1227 }
1228 }
1229 }
1230
1231 #[test]
1232 fn two_certs() {
1233 let testy = crate::tests::key("testy.pgp");
1234
1235 let mut bytes = testy.to_vec();
1236 bytes.extend_from_slice(testy);
1237
1238 let certs = compare_parse(&bytes[..]);
1239 assert_eq!(certs.len(), 2);
1240 for cert in certs.into_iter() {
1241 assert_eq!(cert.as_bytes(), testy);
1242 assert_eq!(
1243 &cert.packets().map(|p| p.tag()).collect::<Vec<Tag>>()[..],
1244 &[ Tag::PublicKey,
1245 Tag::UserID, Tag::Signature,
1246 Tag::PublicSubkey, Tag::Signature
1247 ]);
1248 }
1249 }
1250
1251 #[test]
1252 fn marker_packet_ignored() {
1253 use crate::serialize::Serialize;
1254
1255 // Only a marker packet.
1256 let mut marker = Vec::new();
1257 Packet::Marker(Default::default())
1258 .serialize(&mut marker).unwrap();
1259 compare_parse(&marker[..]);
1260
1261 // Marker at the start.
1262 let mut testy_with_marker = Vec::new();
1263 Packet::Marker(Default::default())
1264 .serialize(&mut testy_with_marker).unwrap();
1265 testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1266 compare_parse(&testy_with_marker[..]);
1267
1268 // Marker at the end.
1269 let mut testy_with_marker = Vec::new();
1270 testy_with_marker.extend_from_slice(crate::tests::key("testy.pgp"));
1271 Packet::Marker(Default::default())
1272 .serialize(&mut testy_with_marker).unwrap();
1273 compare_parse(&testy_with_marker[..]);
1274 }
1275
1276 #[test]
1277 fn invalid_packets() -> Result<()> {
1278 tracer!(TRACE, "invalid_packets", 0);
1279
1280 let (cert, _) =
1281 CertBuilder::general_purpose(Some("alice@example.org"))
1282 .generate()?;
1283 let cert = cert.into_packets().collect::<Vec<_>>();
1284
1285 // A userid packet.
1286 let userid : Packet = cert.clone()
1287 .into_iter()
1288 .filter(|p| p.tag() == Tag::UserID)
1289 .next()
1290 .unwrap();
1291
1292 // An unknown packet.
1293 let tag = Tag::Private(61);
1294 let unknown : Packet
1295 = Unknown::new(tag, crate::Error::UnsupportedPacketType(tag).into())
1296 .into();
1297
1298 // A literal packet. (This is a valid OpenPGP Message.)
1299 let mut lit = Literal::new(DataFormat::Unicode);
1300 lit.set_body(b"test".to_vec());
1301 let lit = Packet::from(lit);
1302
1303 // A compressed data packet containing a literal data packet.
1304 // (This is a valid OpenPGP Message.)
1305 let cd = {
1306 use crate::types::CompressionAlgorithm;
1307 use crate::packet;
1308 use crate::PacketPile;
1309 use crate::serialize::Serialize;
1310 use crate::parse::Parse;
1311
1312 let mut cd = CompressedData::new(
1313 CompressionAlgorithm::Uncompressed);
1314 let mut body = Vec::new();
1315 lit.serialize(&mut body)?;
1316 cd.set_body(packet::Body::Processed(body));
1317 let cd = Packet::from(cd);
1318
1319 // Make sure we created the message correctly: serialize,
1320 // parse it, and then check its form.
1321 let mut bytes = Vec::new();
1322 cd.serialize(&mut bytes)?;
1323
1324 let pp = PacketPile::from_bytes(&bytes[..])?;
1325
1326 assert_eq!(pp.descendants().count(), 2);
1327 assert_eq!(pp.path_ref(&[ 0 ]).unwrap().tag(),
1328 packet::Tag::CompressedData);
1329 assert_eq!(pp.path_ref(&[ 0, 0 ]), Some(&lit));
1330
1331 cd
1332 };
1333
1334 fn check(input: impl Iterator<Item=Packet>) {
1335 let mut bytes = Vec::new();
1336 for p in input {
1337 p.serialize(&mut bytes).unwrap();
1338 }
1339
1340 compare_parse(&bytes[..]);
1341 }
1342
1343 fn interleave(cert: &Vec<Packet>, p: &Packet) {
1344 t!("A certificate, a {}.", p.tag());
1345 check(
1346 cert.clone().into_iter()
1347 .chain(p.clone()));
1348
1349 t!("A certificate, two {}.", p.tag());
1350 check(
1351 cert.clone().into_iter()
1352 .chain(p.clone())
1353 .chain(p.clone()));
1354
1355 t!("A {}, a certificate.", p.tag());
1356 check(
1357 p.clone().into_iter()
1358 .chain(cert.clone()));
1359
1360 t!("Two {}, a certificate.", p.tag());
1361 check(
1362 p.clone().into_iter()
1363 .chain(p.clone())
1364 .chain(cert.clone()));
1365
1366 t!("Two {}, a certificate, two {}.", p.tag(), p.tag());
1367 check(
1368 p.clone().into_iter()
1369 .chain(p.clone())
1370 .chain(cert.clone())
1371 .chain(p.clone())
1372 .chain(p.clone()));
1373
1374 t!("Two {}, two certificates, two {}, a certificate.");
1375 check(
1376 p.clone().into_iter()
1377 .chain(p.clone())
1378 .chain(cert.clone())
1379 .chain(cert.clone())
1380 .chain(p.clone())
1381 .chain(p.clone())
1382 .chain(cert.clone()));
1383 }
1384
1385 interleave(&cert, &lit);
1386
1387 // The certificate parser shouldn't recurse into containers.
1388 // So, the compressed data packets should show up as a single
1389 // error.
1390 interleave(&cert, &cd);
1391
1392
1393 // The certificate parser should treat unknown packets as
1394 // valid certificate components.
1395 let mut cert_plus = cert.clone();
1396 cert_plus.push(unknown.clone());
1397
1398 t!("A certificate, an unknown.");
1399 check(
1400 cert.clone().into_iter()
1401 .chain(unknown.clone()));
1402
1403 t!("An unknown, a certificate.");
1404 check(
1405 unknown.clone().into_iter()
1406 .chain(cert.clone()));
1407
1408 t!("A certificate, two unknowns.");
1409 check(
1410 cert.clone().into_iter()
1411 .chain(unknown.clone())
1412 .chain(unknown.clone()));
1413
1414 t!("A certificate, an unknown, a certificate.");
1415 check(
1416 cert.clone().into_iter()
1417 .chain(unknown.clone())
1418 .chain(cert.clone()));
1419
1420 t!("A Literal, two User IDs");
1421 check(
1422 lit.clone().into_iter()
1423 .chain(userid.clone())
1424 .chain(userid.clone()));
1425
1426 t!("A User ID, a certificate");
1427 check(
1428 userid.clone().into_iter()
1429 .chain(cert.clone()));
1430
1431 t!("Two User IDs, a certificate");
1432 check(
1433 userid.clone().into_iter()
1434 .chain(userid.clone())
1435 .chain(cert.clone()));
1436
1437 Ok(())
1438 }
1439
1440 fn parse_test(n: usize, literal: bool, bad: usize) -> Result<()> {
1441 tracer!(TRACE, "t", 0);
1442
1443 // Parses keyrings with different numbers of keys and
1444 // different errors.
1445
1446 // n: number of keys
1447 // literal: whether to interleave literal packets.
1448 // bad: whether to insert invalid data (NUL bytes where
1449 // the start of a certificate is expected).
1450 let nulls = vec![ 0; bad ];
1451
1452 t!("n: {}, literals: {}, bad data: {}",
1453 n, literal, bad);
1454
1455 let mut data = Vec::new();
1456
1457 let mut certs_orig = vec![];
1458 for i in 0..n {
1459 let (cert, _) =
1460 CertBuilder::general_purpose(
1461 Some(format!("{}@example.org", i)))
1462 .generate()?;
1463
1464 cert.as_tsk().serialize(&mut data)?;
1465 certs_orig.push(cert);
1466
1467 if literal {
1468 let mut lit = Literal::new(DataFormat::Unicode);
1469 lit.set_body(b"data".to_vec());
1470
1471 Packet::from(lit).serialize(&mut data)?;
1472 }
1473 // Push some NUL bytes.
1474 data.extend(&nulls[..bad]);
1475 }
1476 if n == 0 {
1477 // Push some NUL bytes even if we didn't add any packets.
1478 data.extend(&nulls[..bad]);
1479 }
1480 assert_eq!(certs_orig.len(), n);
1481
1482 t!("Start of data: {} {}",
1483 if let Some(x) = data.get(0) {
1484 format!("{:02X}", x)
1485 } else {
1486 "XX".into()
1487 },
1488 if let Some(x) = data.get(1) {
1489 format!("{:02X}", x)
1490 } else {
1491 "XX".into()
1492 });
1493
1494 compare_parse(&data);
1495
1496 Ok(())
1497 }
1498
1499 #[test]
1500 fn parse_keyring_simple() -> Result<()> {
1501 for n in [1, 100, 0].iter() {
1502 parse_test(*n, false, 0)?;
1503 }
1504
1505 Ok(())
1506 }
1507
1508 #[test]
1509 fn parse_keyring_interleaved_literals() -> Result<()> {
1510 for n in [1, 100, 0].iter() {
1511 parse_test(*n, true, 0)?;
1512 }
1513
1514 Ok(())
1515 }
1516
1517 #[test]
1518 fn parse_keyring_interleaved_small_junk() -> Result<()> {
1519 for n in [1, 100, 0].iter() {
1520 parse_test(*n, false, 1)?;
1521 }
1522
1523 Ok(())
1524 }
1525
1526 #[test]
1527 fn parse_keyring_interleaved_unrecoverable_junk() -> Result<()> {
1528 // PacketParser is pretty good at recovering from junk in the
1529 // middle: it will search the next RECOVERY_THRESHOLD bytes
1530 // for a valid packet. If it finds it, it will turn the junk
1531 // into a reserved packet and resume. Insert a lot of NULs to
1532 // prevent the recovery mechanism from working.
1533 for n in [1, 100, 0].iter() {
1534 parse_test(*n, false, 2 * RECOVERY_THRESHOLD)?;
1535 }
1536
1537 Ok(())
1538 }
1539
1540 #[test]
1541 fn parse_keyring_interleaved_literal_and_small_junk() -> Result<()> {
1542 for n in [1, 100, 0].iter() {
1543 parse_test(*n, true, 1)?;
1544 }
1545
1546 Ok(())
1547 }
1548
1549 #[test]
1550 fn parse_keyring_interleaved_literal_and_unrecoverable_junk() -> Result<()> {
1551 for n in [1, 100, 0].iter() {
1552 parse_test(*n, true, 2 * RECOVERY_THRESHOLD)?;
1553 }
1554
1555 Ok(())
1556 }
1557
1558 #[test]
1559 fn parse_keyring_no_public_key() -> Result<()> {
1560 tracer!(TRACE, "parse_keyring_no_public_key", 0);
1561
1562 // The first few packets are not the valid start of a
1563 // certificate. Each of those should return in an Error.
1564 // But, that shouldn't stop us from parsing the rest of the
1565 // keyring.
1566
1567 let (cert_1, _) =
1568 CertBuilder::general_purpose(
1569 Some("a@example.org"))
1570 .generate()?;
1571 let cert_1_packets: Vec<Packet>
1572 = cert_1.into_packets().collect();
1573
1574 let (cert_2, _) =
1575 CertBuilder::general_purpose(
1576 Some("b@example.org"))
1577 .generate()?;
1578
1579 for n in 1..cert_1_packets.len() {
1580 t!("n: {}", n);
1581
1582 let mut data = Vec::new();
1583
1584 for i in n..cert_1_packets.len() {
1585 cert_1_packets[i].serialize(&mut data)?;
1586 }
1587
1588 cert_2.as_tsk().serialize(&mut data)?;
1589
1590 compare_parse(&data);
1591 }
1592
1593 Ok(())
1594 }
1595
1596 #[test]
1597 fn accessors() {
1598 let testy = crate::tests::key("testy.pgp");
1599
1600 let certs = RawCertParser::from_bytes(testy)
1601 .expect("valid")
1602 .collect::<Result<Vec<RawCert>>>()
1603 .expect("valid");
1604 assert_eq!(certs.len(), 1);
1605 let cert = &certs[0];
1606 assert_eq!(cert.as_bytes(), testy);
1607
1608 assert_eq!(cert.primary_key().fingerprint(),
1609 "3E8877C877274692975189F5D03F6F865226FE8B"
1610 .parse().expect("valid"));
1611 assert_eq!(cert.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1612 vec![
1613 "3E8877C877274692975189F5D03F6F865226FE8B"
1614 .parse().expect("valid"),
1615 "01F187575BD45644046564C149E2118166C92632"
1616 .parse().expect("valid")
1617 ]);
1618 assert_eq!(cert.keys().subkeys()
1619 .map(|k| k.fingerprint()).collect::<Vec<_>>(),
1620 vec![
1621 "01F187575BD45644046564C149E2118166C92632"
1622 .parse().expect("valid")
1623 ]);
1624 assert_eq!(
1625 cert.userids()
1626 .map(|u| {
1627 String::from_utf8_lossy(u.value()).into_owned()
1628 })
1629 .collect::<Vec<_>>(),
1630 vec![ "Testy McTestface <testy@example.org>" ]);
1631 }
1632
1633 // Test the raw cert parser implementation.
1634 #[test]
1635 fn raw_cert_parser_impl() {
1636 // Read one certificate.
1637 let testy = crate::tests::key("testy.pgp");
1638
1639 let raw = RawCert::from_bytes(testy).expect("valid");
1640 let cert = Cert::from_bytes(testy).expect("valid");
1641
1642 assert_eq!(
1643 raw.keys().map(|k| k.fingerprint()).collect::<Vec<_>>(),
1644 cert.keys().map(|k| k.key().fingerprint()).collect::<Vec<_>>());
1645
1646 assert_eq!(
1647 raw.userids().collect::<Vec<_>>(),
1648 cert.userids().map(|ua| ua.userid().clone()).collect::<Vec<_>>());
1649
1650 // Parse zero certificates.
1651 eprintln!("Parsing 0 bytes");
1652 let raw = RawCert::from_bytes(b"");
1653 match &raw {
1654 Ok(_) => eprintln!("raw: Ok"),
1655 Err(err) => eprintln!("raw: {}", err),
1656 }
1657 let cert = Cert::from_bytes(b"");
1658 match &cert {
1659 Ok(_) => eprintln!("cert: Ok"),
1660 Err(err) => eprintln!("cert: {}", err),
1661 }
1662
1663 assert!(
1664 matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1665 Err(Ok(crate::Error::MalformedCert(_)))));
1666 assert!(
1667 matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1668 Err(Ok(crate::Error::MalformedCert(_)))));
1669
1670 // Parse two certificates.
1671 let mut bytes = Vec::new();
1672 bytes.extend(testy);
1673 bytes.extend(testy);
1674
1675 let parser = CertParser::from_bytes(&bytes).expect("valid");
1676 assert_eq!(parser.count(), 2);
1677
1678 eprintln!("Parsing two certificates");
1679 let raw = RawCert::from_bytes(&bytes);
1680 match &raw {
1681 Ok(_) => eprintln!("raw: Ok"),
1682 Err(err) => eprintln!("raw: {}", err),
1683 }
1684 let cert = Cert::from_bytes(&bytes);
1685 match &cert {
1686 Ok(_) => eprintln!("cert: Ok"),
1687 Err(err) => eprintln!("cert: {}", err),
1688 }
1689
1690 assert!(
1691 matches!(cert.map_err(|e| e.downcast::<crate::Error>()),
1692 Err(Ok(crate::Error::MalformedCert(_)))));
1693 assert!(
1694 matches!(raw.map_err(|e| e.downcast::<crate::Error>()),
1695 Err(Ok(crate::Error::MalformedCert(_)))));
1696 }
1697
1698 #[test]
1699 fn concatenated_armored_certs() -> Result<()> {
1700 let mut keyring = Vec::new();
1701 keyring.extend_from_slice(b"some\ntext\n");
1702 keyring.extend_from_slice(crate::tests::key("testy.asc"));
1703 keyring.extend_from_slice(crate::tests::key("testy.asc"));
1704 keyring.extend_from_slice(b"some\ntext\n");
1705 keyring.extend_from_slice(crate::tests::key("testy.asc"));
1706 keyring.extend_from_slice(b"some\ntext\n");
1707 let certs = RawCertParser::from_bytes(&keyring)?.collect::<Vec<_>>();
1708 assert_eq!(certs.len(), 3);
1709 assert!(certs.iter().all(|c| c.is_ok()));
1710 Ok(())
1711 }
1712}