sequoia_openpgp/message/
mod.rs

1//! Message support.
2//!
3//! An OpenPGP message is a sequence of OpenPGP packets that
4//! corresponds to an optionally signed, optionally encrypted,
5//! optionally compressed literal data packet.  The exact format of an
6//! OpenPGP message is described in [Section 11.3 of RFC 4880].
7//!
8//! This module provides support for validating and working with
9//! OpenPGP messages.
10//!
11//! Example of ASCII-armored OpenPGP message:
12//!
13//! ```txt
14//! -----BEGIN PGP MESSAGE-----
15//!
16//! yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
17//! vBSFjNSiVHsuAA==
18//! =njUN
19//! -----END PGP MESSAGE-----
20//! ```
21//!
22//! [Section 11.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.3
23
24// XXX: For Token.  Drop this once Token is private.
25#![allow(deprecated)]
26
27use std::convert::TryFrom;
28use std::fmt;
29use std::io;
30use std::path::Path;
31
32use buffered_reader::BufferedReader;
33
34use crate::Result;
35use crate::Error;
36use crate::Packet;
37use crate::PacketPile;
38use crate::packet::Literal;
39use crate::packet::Tag;
40use crate::parse::{Cookie, Parse};
41
42mod lexer;
43lalrpop_util::lalrpop_mod!(#[allow(clippy::all, deprecated)] grammar, "/message/grammar.rs");
44
45use self::lexer::{Lexer, LexicalError};
46pub use self::lexer::Token;
47
48use lalrpop_util::ParseError;
49
50use self::grammar::MessageParser;
51
52/// Errors that MessageValidator::check may return.
53///
54/// Note: This enum cannot be exhaustively matched to allow future
55/// extensions.
56#[non_exhaustive]
57#[derive(Debug, Clone)]
58pub enum MessageParserError {
59    /// A parser error.
60    Parser(ParseError<usize, Token, LexicalError>),
61    /// An OpenPGP error.
62    OpenPGP(Error),
63}
64assert_send_and_sync!(MessageParserError);
65
66impl From<MessageParserError> for anyhow::Error {
67    fn from(err: MessageParserError) -> Self {
68        match err {
69            MessageParserError::Parser(p) => p.into(),
70            MessageParserError::OpenPGP(p) => p.into(),
71        }
72    }
73}
74
75
76/// Represents the status of a parsed message.
77#[derive(Debug)]
78pub(crate) enum MessageValidity {
79    /// The packet sequence is a valid OpenPGP message.
80    Message,
81    /// The packet sequence appears to be a valid OpenPGP message that
82    /// has been truncated, i.e., the packet sequence is a valid
83    /// prefix of an OpenPGP message.
84    MessagePrefix,
85    /// The message is definitely not valid.
86    Error(anyhow::Error),
87}
88
89#[allow(unused)]
90impl MessageValidity {
91    /// Returns whether the packet sequence is a valid message.
92    ///
93    /// Note: a `MessageValidator` will only return this after
94    /// `MessageValidator::finish` has been called.
95    pub fn is_message(&self) -> bool {
96        matches!(self, MessageValidity::Message)
97    }
98
99    /// Returns whether the packet sequence forms a valid message
100    /// prefix.
101    ///
102    /// Note: a `MessageValidator` will only return this before
103    /// `MessageValidator::finish` has been called.
104    pub fn is_message_prefix(&self) -> bool {
105        matches!(self, MessageValidity::MessagePrefix)
106    }
107
108    /// Returns whether the packet sequence is definitely not a valid
109    /// OpenPGP Message.
110    pub fn is_err(&self) -> bool {
111        matches!(self, MessageValidity::Error(_))
112    }
113}
114
115/// Used to help validate a packet sequence is a valid OpenPGP message.
116#[derive(Debug)]
117pub(crate) struct MessageValidator {
118    tokens: Vec<Token>,
119    finished: bool,
120    // Once a raw token is pushed, this is set to None and pushing
121    // packet Tags is no longer supported.
122    depth: Option<isize>,
123
124    // If we know that the packet sequence is invalid.
125    error: Option<MessageParserError>,
126}
127
128impl Default for MessageValidator {
129    fn default() -> Self {
130        MessageValidator::new()
131    }
132}
133
134impl MessageValidator {
135    /// Instantiates a new `MessageValidator`.
136    pub fn new() -> Self {
137        MessageValidator {
138            tokens: vec![],
139            finished: false,
140            depth: Some(0),
141            error: None,
142        }
143    }
144
145    /// Adds a token to the token stream.
146    #[cfg(test)]
147    pub(crate) fn push_raw(&mut self, token: Token) {
148        assert!(!self.finished);
149
150        if self.error.is_some() {
151            return;
152        }
153
154        self.depth = None;
155        self.tokens.push(token);
156    }
157
158    /// Add the token `token` at position `path` to the token stream.
159    ///
160    /// Note: top-level packets are at `[n]`, their immediate
161    /// children are at `[n, m]`, etc.
162    ///
163    /// This function pushes any required `Token::Pop` tokens based on
164    /// changes in the `path`.
165    ///
166    /// Note: the token *must* correspond to a packet; this function
167    /// will panic if `token` is `Token::Pop`.
168    pub fn push_token(&mut self, token: Token, path: &[usize]) {
169        assert!(!self.finished);
170        assert!(self.depth.is_some());
171        assert!(token != Token::Pop);
172        assert!(!path.is_empty());
173
174        if self.error.is_some() {
175            return;
176        }
177
178        // We popped one or more containers.
179        let depth = path.len() as isize - 1;
180        if self.depth.unwrap() > depth {
181            for _ in 1..self.depth.unwrap() - depth + 1 {
182                self.tokens.push(Token::Pop);
183            }
184        }
185        self.depth = Some(depth);
186
187        self.tokens.push(token);
188    }
189
190    /// Add a packet of type `tag` at position `path` to the token
191    /// stream.
192    ///
193    /// Note: top-level packets are at `[n]`, their immediate
194    /// children are at `[n, m]`, etc.
195    ///
196    /// Unlike `push_token`, this function does not automatically
197    /// account for changes in the depth.  If you use this function
198    /// directly, you must push any required `Token::Pop` tokens.
199    pub fn push(&mut self, tag: Tag, version: Option<u8>, path: &[usize]) {
200        if self.error.is_some() {
201            return;
202        }
203
204        let token = match tag {
205            Tag::Literal => Token::Literal,
206            Tag::CompressedData => Token::CompressedData,
207            Tag::SKESK => Token::SKESK,
208            Tag::PKESK => Token::PKESK,
209            Tag::SEIP if version == Some(1) => Token::SEIPv1,
210            Tag::MDC => Token::MDC,
211            Tag::AED => Token::AED,
212            Tag::OnePassSig => Token::OPS,
213            Tag::Signature => Token::SIG,
214            Tag::Marker => {
215                // "[Marker packets] MUST be ignored when received.",
216                // section 5.8 of RFC4880.
217                return;
218            },
219            _ => {
220                // Unknown token.
221                self.error = Some(MessageParserError::OpenPGP(
222                    Error::MalformedMessage(
223                        format!("Invalid OpenPGP message: \
224                                 {:?} packet (at {:?}) not expected",
225                                tag, path))));
226                self.tokens.clear();
227                return;
228            }
229        };
230
231        self.push_token(token, path)
232    }
233
234    /// Note that the entire message has been seen.
235    pub fn finish(&mut self) {
236        assert!(!self.finished);
237
238        if let Some(depth) = self.depth {
239            // Pop any containers.
240            for _ in 0..depth {
241                self.tokens.push(Token::Pop);
242            }
243        }
244
245        self.finished = true;
246    }
247
248    /// Returns whether the token stream corresponds to a valid
249    /// OpenPGP message.
250    ///
251    /// This returns a tri-state: if the message is valid, it returns
252    /// MessageValidity::Message, if the message is invalid, then it
253    /// returns MessageValidity::Error.  If the message could be
254    /// valid, then it returns MessageValidity::MessagePrefix.
255    ///
256    /// Note: if MessageValidator::finish() *hasn't* been called, then
257    /// this function will only ever return either
258    /// MessageValidity::MessagePrefix or MessageValidity::Error.  Once
259    /// MessageValidity::finish() has been called, then only
260    /// MessageValidity::Message or MessageValidity::Error will be returned.
261    pub fn check(&self) -> MessageValidity {
262        if let Some(ref err) = self.error {
263            return MessageValidity::Error((*err).clone().into());
264        }
265
266        let r = MessageParser::new().parse(
267            Lexer::from_tokens(&self.tokens[..]));
268
269        if self.finished {
270            match r {
271                Ok(_) => MessageValidity::Message,
272                Err(ref err) =>
273                    MessageValidity::Error(
274                        MessageParserError::Parser((*err).clone()).into()),
275            }
276        } else {
277            match r {
278                Ok(_) => MessageValidity::MessagePrefix,
279                Err(ParseError::UnrecognizedEof { .. }) =>
280                    MessageValidity::MessagePrefix,
281                Err(ref err) =>
282                    MessageValidity::Error(
283                        MessageParserError::Parser((*err).clone()).into()),
284            }
285        }
286    }
287}
288
289/// A message.
290///
291/// An OpenPGP message is a structured sequence of OpenPGP packets.
292/// Basically, it's an optionally encrypted, optionally signed literal
293/// data packet.  The exact structure is defined in [Section 11.3 of RFC
294/// 4880].
295///
296///   [Section 11.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.3
297///
298/// [ASCII Armored Messages] are wrapped in `-----BEGIN PGP MESSAGE-----` header
299/// and `-----END PGP MESSAGE-----` tail lines:
300///
301/// ```txt
302/// -----BEGIN PGP MESSAGE-----
303///
304/// xA0DAAoW5saJekzviSQByxBiAAAAAADYtdiv2KfZgtipwnUEABYKACcFglwJHYoW
305/// IQRnpIdTo4Cms7fffcXmxol6TO+JJAkQ5saJekzviSQAAIJ6APwK6FxtHXn8txDl
306/// tBFsIXlOSLOs4BvArlZzZSMomIyFLAEAwCLJUChMICDxWXRlHxORqU5x6hlO3DdW
307/// sl/1DAbnRgI=
308/// =AqoO
309/// -----END PGP MESSAGE-----
310/// ```
311///
312/// [ASCII Armored Messages]: https://tools.ietf.org/html/rfc4880#section-6.6
313///
314/// # Examples
315///
316/// Creating a Message encrypted with a password.
317///
318/// ```
319/// # use sequoia_openpgp as openpgp;
320/// # fn main() -> sequoia_openpgp::Result<()> {
321/// use std::io::Write;
322/// use openpgp::serialize::stream::{Message, Encryptor, LiteralWriter};
323///
324/// let mut sink = vec![];
325/// let message = Encryptor::with_passwords(
326///     Message::new(&mut sink), Some("ściśle tajne")).build()?;
327/// let mut w = LiteralWriter::new(message).build()?;
328/// w.write_all(b"Hello world.")?;
329/// w.finalize()?;
330/// # Ok(()) }
331/// ```
332#[derive(PartialEq)]
333pub struct Message {
334    /// A message is just a validated packet pile.
335    pile: PacketPile,
336}
337assert_send_and_sync!(Message);
338
339impl fmt::Debug for Message {
340    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341        f.debug_struct("Message")
342            .field("pile", &self.pile)
343            .finish()
344    }
345}
346
347impl<'a> Parse<'a, Message> for Message {
348    /// Reads a `Message` from the specified reader.
349    ///
350    /// See [`Message::try_from`] for more details.
351    ///
352    ///   [`Message::try_from`]: Message::try_from()
353    fn from_buffered_reader<R>(reader: R) -> Result<Message>
354    where
355        R: BufferedReader<Cookie> + 'a,
356    {
357        Self::try_from(PacketPile::from_buffered_reader(reader)?)
358    }
359
360    /// Reads a `Message` from the specified reader.
361    ///
362    /// See [`Message::try_from`] for more details.
363    ///
364    ///   [`Message::try_from`]: Message::try_from()
365    fn from_reader<R: 'a + io::Read + Send + Sync>(reader: R) -> Result<Self> {
366        Self::try_from(PacketPile::from_reader(reader)?)
367    }
368
369    /// Reads a `Message` from the specified file.
370    ///
371    /// See [`Message::try_from`] for more details.
372    ///
373    ///   [`Message::try_from`]: Message::try_from()
374    fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
375        Self::try_from(PacketPile::from_file(path)?)
376    }
377
378    /// Reads a `Message` from `buf`.
379    ///
380    /// See [`Message::try_from`] for more details.
381    ///
382    ///   [`Message::try_from`]: Message::try_from()
383    fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(data: &'a D) -> Result<Self> {
384        Self::try_from(PacketPile::from_bytes(data)?)
385    }
386}
387
388impl std::str::FromStr for Message {
389    type Err = anyhow::Error;
390
391    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
392        Self::from_bytes(s.as_bytes())
393    }
394}
395
396impl Message {
397    /// Returns the body of the message.
398    ///
399    /// Returns `None` if no literal data packet is found.  This
400    /// happens if a SEIP container has not been decrypted.
401    ///
402    /// # Examples
403    ///
404    /// ```
405    /// # use sequoia_openpgp as openpgp;
406    /// # fn main() -> openpgp::Result<()> {
407    /// use std::io;
408    /// use std::io::Read;
409    /// use openpgp::Message;
410    /// use openpgp::armor::{Reader, ReaderMode};
411    /// use openpgp::parse::Parse;
412    ///
413    /// let data = "yxJiAAAAAABIZWxsbyB3b3JsZCE="; // base64 over literal data packet
414    ///
415    /// let mut cursor = io::Cursor::new(&data);
416    /// let mut reader = Reader::from_reader(&mut cursor, ReaderMode::VeryTolerant);
417    ///
418    /// let mut buf = Vec::new();
419    /// reader.read_to_end(&mut buf)?;
420    ///
421    /// let message = Message::from_bytes(&buf)?;
422    /// assert_eq!(message.body().unwrap().body(), b"Hello world!");
423    /// # Ok(())
424    /// # }
425    /// ```
426    pub fn body(&self) -> Option<&Literal> {
427        for packet in self.pile.descendants() {
428            if let Packet::Literal(ref l) = packet {
429                return Some(l);
430            }
431        }
432
433        // No literal data packet found.
434        None
435    }
436}
437
438impl TryFrom<PacketPile> for Message {
439    type Error = anyhow::Error;
440
441    /// Converts the `PacketPile` to a `Message`.
442    ///
443    /// Converting a `PacketPile` to a `Message` doesn't change the
444    /// packets; it asserts that the packet sequence is an optionally
445    /// encrypted, optionally signed, optionally compressed literal
446    /// data packet.  The exact grammar is defined in [Section 11.3 of
447    /// RFC 4880].
448    ///
449    /// Caveats: this function assumes that any still encrypted parts
450    /// or still compressed parts are valid messages.
451    ///
452    ///   [Section 11.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.3
453    fn try_from(pile: PacketPile) -> Result<Self> {
454        let mut v = MessageValidator::new();
455        for (mut path, packet) in pile.descendants().paths() {
456            match packet {
457                Packet::Unknown(ref u) =>
458                    return Err(MessageParserError::OpenPGP(
459                        Error::MalformedMessage(
460                            format!("Invalid OpenPGP message: \
461                                     {:?} packet (at {:?}) not expected: {}",
462                                    u.tag(), path, u.error())))
463                               .into()),
464                _ => v.push(packet.tag(), packet.version(), &path),
465            }
466
467            match packet {
468                Packet::CompressedData(_) | Packet::SEIP(_) | Packet::AED(_) =>
469                {
470                    // If a container's content is not unpacked, then
471                    // we treat the content as an opaque message.
472
473                    path.push(0);
474                    if packet.children().is_none() {
475                        v.push_token(Token::OpaqueContent, &path);
476                    }
477                }
478                _ => {}
479            }
480        }
481        v.finish();
482
483        match v.check() {
484            MessageValidity::Message => Ok(Message { pile }),
485            MessageValidity::MessagePrefix => unreachable!(),
486            // We really want to squash the lexer's error: it is an
487            // internal detail that may change, and meaningless even
488            // to an immediate user of this crate.
489            MessageValidity::Error(e) => Err(e),
490        }
491    }
492}
493
494impl TryFrom<Vec<Packet>> for Message {
495    type Error = anyhow::Error;
496
497    /// Converts the vector of `Packets` to a `Message`.
498    ///
499    /// See [`Message::try_from`] for more details.
500    ///
501    ///   [`Message::try_from`]: Message::try_from()
502    fn try_from(packets: Vec<Packet>) -> Result<Self> {
503        Self::try_from(PacketPile::from(packets))
504    }
505}
506
507impl From<Message> for PacketPile {
508    fn from(m: Message) -> Self {
509        m.pile
510    }
511}
512
513impl ::std::ops::Deref for Message {
514    type Target = PacketPile;
515
516    fn deref(&self) -> &Self::Target {
517        &self.pile
518    }
519}
520
521#[cfg(test)]
522mod tests {
523    use super::*;
524
525    use crate::types::DataFormat::Text;
526    use crate::HashAlgorithm;
527    use crate::types::CompressionAlgorithm;
528    use crate::SymmetricAlgorithm;
529    use crate::PublicKeyAlgorithm;
530    use crate::SignatureType;
531    use crate::crypto::S2K;
532    use crate::crypto::mpi::{Ciphertext, MPI};
533    use crate::packet::prelude::*;
534
535    #[test]
536    fn tokens() {
537        use self::lexer::{Token, Lexer};
538        use self::lexer::Token::*;
539        use self::grammar::MessageParser;
540
541        struct TestVector<'a> {
542            s: &'a [Token],
543            result: bool,
544        }
545
546        let test_vectors = [
547            TestVector {
548                s: &[Literal][..],
549                result: true,
550            },
551            TestVector {
552                s: &[CompressedData, Literal, Pop],
553                result: true,
554            },
555            TestVector {
556                s: &[CompressedData, CompressedData, Literal,
557                     Pop, Pop],
558                result: true,
559            },
560            TestVector {
561                s: &[SEIPv1, Literal, MDC, Pop],
562                result: true,
563            },
564            TestVector {
565                s: &[CompressedData, SEIPv1, Literal, MDC, Pop, Pop],
566                result: true,
567            },
568            TestVector {
569                s: &[CompressedData, SEIPv1, CompressedData, Literal,
570                     Pop, MDC, Pop, Pop],
571                result: true,
572            },
573            TestVector {
574                s: &[SEIPv1, MDC, Pop],
575                result: false,
576            },
577            TestVector {
578                s: &[SKESK, SEIPv1, Literal, MDC, Pop],
579                result: true,
580            },
581            TestVector {
582                s: &[PKESK, SEIPv1, Literal, MDC, Pop],
583                result: true,
584            },
585            TestVector {
586                s: &[SKESK, SKESK, SEIPv1, Literal, MDC, Pop],
587                result: true,
588            },
589
590            TestVector {
591                s: &[AED, Literal, Pop],
592                result: true,
593            },
594            TestVector {
595                s: &[CompressedData, AED, Literal, Pop, Pop],
596                result: true,
597            },
598            TestVector {
599                s: &[CompressedData, AED, CompressedData, Literal,
600                     Pop, Pop, Pop],
601                result: true,
602            },
603            TestVector {
604                s: &[AED, Pop],
605                result: false,
606            },
607            TestVector {
608                s: &[SKESK, AED, Literal, Pop],
609                result: true,
610            },
611            TestVector {
612                s: &[PKESK, AED, Literal, Pop],
613                result: true,
614            },
615            TestVector {
616                s: &[SKESK, SKESK, AED, Literal, Pop],
617                result: true,
618            },
619
620            TestVector {
621                s: &[OPS, Literal, SIG],
622                result: true,
623            },
624            TestVector {
625                s: &[OPS, OPS, Literal, SIG, SIG],
626                result: true,
627            },
628            TestVector {
629                s: &[OPS, OPS, Literal, SIG],
630                result: false,
631            },
632            TestVector {
633                s: &[OPS, OPS, SEIPv1, OPS, SEIPv1, Literal, MDC, Pop,
634                     SIG, MDC, Pop, SIG, SIG],
635                result: true,
636            },
637
638            TestVector {
639                s: &[CompressedData, OpaqueContent],
640                result: false,
641            },
642            TestVector {
643                s: &[CompressedData, OpaqueContent, Pop],
644                result: true,
645            },
646            TestVector {
647                s: &[CompressedData, CompressedData, OpaqueContent, Pop, Pop],
648                result: true,
649            },
650            TestVector {
651                s: &[SEIPv1, CompressedData, OpaqueContent, Pop, MDC, Pop],
652                result: true,
653            },
654            TestVector {
655                s: &[SEIPv1, OpaqueContent, Pop],
656                result: true,
657            },
658        ];
659
660        for v in &test_vectors {
661            if v.result {
662                let mut l = MessageValidator::new();
663                for token in v.s.iter() {
664                    l.push_raw(*token);
665                    assert_match!(MessageValidity::MessagePrefix = l.check());
666                }
667
668                l.finish();
669                assert_match!(MessageValidity::Message = l.check());
670            }
671
672            match MessageParser::new().parse(Lexer::from_tokens(v.s)) {
673                Ok(r) => assert!(v.result, "Parsing: {:?} => {:?}", v.s, r),
674                Err(e) => assert!(! v.result, "Parsing: {:?} => {:?}", v.s, e),
675            }
676        }
677    }
678
679    #[test]
680    fn tags() {
681        use crate::packet::Tag::*;
682
683        struct TestVector<'a> {
684            s: &'a [(Tag, Option<u8>, isize)],
685            result: bool,
686        }
687
688        let test_vectors = [
689            TestVector {
690                s: &[(Literal, None, 0)][..],
691                result: true,
692            },
693            TestVector {
694                s: &[(CompressedData, None, 0), (Literal, None, 1)],
695                result: true,
696            },
697            TestVector {
698                s: &[(CompressedData, None, 0), (CompressedData, None, 1),
699                     (Literal, None, 2)],
700                result: true,
701            },
702            TestVector {
703                s: &[(SEIP, Some(1), 0), (Literal, None, 1), (MDC, None, 1)],
704                result: true,
705            },
706            TestVector {
707                s: &[(CompressedData, None, 0), (SEIP, Some(1), 1),
708                     (Literal, None, 2), (MDC, None, 2)],
709                result: true,
710            },
711            TestVector {
712                s: &[(CompressedData, None, 0), (SEIP, Some(1), 1),
713                     (CompressedData, None, 2), (Literal, None, 3),
714                     (MDC, None, 2)],
715                result: true,
716            },
717            TestVector {
718                s: &[(CompressedData, None, 0), (SEIP, Some(1), 1),
719                     (CompressedData, None, 2), (Literal, None, 3),
720                     (MDC, None, 3)],
721                result: false,
722            },
723            TestVector {
724                s: &[(SEIP, Some(1), 0), (MDC, None, 0)],
725                result: false,
726            },
727            TestVector {
728                s: &[(SKESK, None, 0), (SEIP, Some(1), 0), (Literal, None, 1),
729                     (MDC, None, 1)],
730                result: true,
731            },
732            TestVector {
733                s: &[(PKESK, None, 0), (SEIP, Some(1), 0), (Literal, None, 1),
734                     (MDC, None, 1)],
735                result: true,
736            },
737            TestVector {
738                s: &[(PKESK, None, 0), (SEIP, Some(1), 0),
739                     (CompressedData, None, 1), (Literal, None, 2),
740                     (MDC, None, 1)],
741                result: true,
742            },
743            TestVector {
744                s: &[(SKESK, None, 0), (SKESK, None, 0), (SEIP, Some(1), 0),
745                     (Literal, None, 1), (MDC, None, 1)],
746                result: true,
747            },
748
749            TestVector {
750                s: &[(OnePassSig, None, 0), (Literal, None, 0),
751                     (Signature, None, 0)],
752                result: true,
753            },
754            TestVector {
755                s: &[(OnePassSig, None, 0), (CompressedData, None, 0),
756                     (Literal, None, 1),
757                     (Signature, None, 0)],
758                result: true,
759            },
760            TestVector {
761                s: &[(OnePassSig, None, 0), (OnePassSig, None, 0),
762                     (Literal, None, 0),
763                     (Signature, None, 0), (Signature, None, 0)],
764                result: true,
765            },
766            TestVector {
767                s: &[(OnePassSig, None, 0), (OnePassSig, None, 0),
768                     (Literal, None, 0),
769                     (Signature, None, 0)],
770                result: false,
771            },
772            TestVector {
773                s: &[(OnePassSig, None, 0), (OnePassSig, None, 0),
774                     (SEIP, Some(1), 0),
775                     (OnePassSig, None, 1), (SEIP, Some(1), 1),
776                     (Literal, None, 2), (MDC, None, 2),
777                     (Signature, None, 1), (MDC, None, 1), (Signature, None, 0),
778                     (Signature, None, 0)],
779                result: true,
780            },
781
782            // "[A Marker packet] MUST be ignored when received.  It
783            // may be placed at the beginning of a message that uses
784            // features not available in PGP 2.6.x in order to cause
785            // that version to report that newer software is necessary
786            // to process the message.", section 5.8 of RFC4880.
787            TestVector {
788                s: &[(Marker, None, 0),
789                     (OnePassSig, None, 0), (Literal, None, 0),
790                     (Signature, None, 0)],
791                result: true,
792            },
793            TestVector {
794                s: &[(OnePassSig, None, 0), (Literal, None, 0),
795                     (Signature, None, 0),
796                     (Marker, None, 0)],
797                result: true,
798            },
799        ];
800
801        for v in &test_vectors {
802            let mut l = MessageValidator::new();
803            for (token, version, depth) in v.s.iter() {
804                l.push(*token,
805                       *version,
806                       &(0..1 + *depth)
807                           .map(|x| x as usize)
808                           .collect::<Vec<_>>()[..]);
809                if v.result {
810                    assert_match!(MessageValidity::MessagePrefix = l.check());
811                }
812            }
813
814            l.finish();
815
816            if v.result {
817                assert_match!(MessageValidity::Message = l.check());
818            } else {
819                assert_match!(MessageValidity::Error(_) = l.check());
820            }
821        }
822    }
823
824    #[test]
825    fn basic() {
826        // Empty.
827        // => bad.
828        let message = Message::try_from(vec![]);
829        assert!(message.is_err(), "{:?}", message);
830
831        // 0: Literal
832        // => good.
833        let mut packets = Vec::new();
834        let mut lit = Literal::new(Text);
835        lit.set_body(b"data".to_vec());
836        packets.push(lit.into());
837
838        let message = Message::try_from(packets);
839        assert!(message.is_ok(), "{:?}", message);
840    }
841
842    #[test]
843    fn compressed_part() {
844        let mut lit = Literal::new(Text);
845        lit.set_body(b"data".to_vec());
846
847        // 0: CompressedData
848        //  0: Literal
849        // => good.
850        let mut packets = Vec::new();
851        packets.push(
852            CompressedData::new(CompressionAlgorithm::Uncompressed)
853                .push(lit.clone().into())
854                .into());
855
856        let message = Message::try_from(packets);
857        assert!(message.is_ok(), "{:?}", message);
858
859        // 0: CompressedData
860        //  0: Literal
861        //  1: Literal
862        // => bad.
863        let mut packets = Vec::new();
864        packets.push(
865            CompressedData::new(CompressionAlgorithm::Uncompressed)
866                .push(lit.clone().into())
867                .push(lit.clone().into())
868                .into());
869
870        let message = Message::try_from(packets);
871        assert!(message.is_err(), "{:?}", message);
872
873        // 0: CompressedData
874        //  0: Literal
875        // 1: Literal
876        // => bad.
877        let mut packets = Vec::new();
878        packets.push(
879            CompressedData::new(CompressionAlgorithm::Uncompressed)
880                .push(lit.clone().into())
881                .into());
882        packets.push(lit.clone().into());
883
884        let message = Message::try_from(packets);
885        assert!(message.is_err(), "{:?}", message);
886
887        // 0: CompressedData
888        //  0: CompressedData
889        //   0: Literal
890        // => good.
891        let mut packets = Vec::new();
892        packets.push(
893            CompressedData::new(CompressionAlgorithm::Uncompressed)
894                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
895                      .push(lit.clone()
896                            .into())
897                      .into())
898                .into());
899
900        let message = Message::try_from(packets);
901        assert!(message.is_ok(), "{:?}", message);
902    }
903
904    #[test]
905    fn one_pass_sig_part() {
906        let mut lit = Literal::new(Text);
907        lit.set_body(b"data".to_vec());
908
909        let hash = crate::types::HashAlgorithm::SHA512;
910        let key: key::SecretKey =
911            crate::packet::key::Key4::generate_ecc(true, crate::types::Curve::Ed25519)
912            .unwrap().into();
913        let mut pair = key.clone().into_keypair().unwrap();
914        let sig = crate::packet::signature::SignatureBuilder::new(SignatureType::Binary)
915            .sign_hash(&mut pair, hash.context().unwrap()).unwrap();
916
917        // 0: OnePassSig
918        // => bad.
919        let mut packets : Vec<Packet> = Vec::new();
920        packets.push(OnePassSig3::new(SignatureType::Binary).into());
921
922        let message = Message::try_from(packets);
923        assert!(message.is_err(), "{:?}", message);
924
925        // 0: OnePassSig
926        // 1: Literal
927        // => bad.
928        let mut packets : Vec<Packet> = Vec::new();
929        packets.push(OnePassSig3::new(SignatureType::Binary).into());
930        packets.push(lit.clone().into());
931
932        let message = Message::try_from(packets);
933        assert!(message.is_err(), "{:?}", message);
934
935        // 0: OnePassSig
936        // 1: Literal
937        // 2: Signature
938        // => good.
939        let mut packets : Vec<Packet> = Vec::new();
940        packets.push(OnePassSig3::new(SignatureType::Binary).into());
941        packets.push(lit.clone().into());
942        packets.push(sig.clone().into());
943
944        let message = Message::try_from(packets);
945        assert!(message.is_ok(), "{:?}", message);
946
947        // 0: OnePassSig
948        // 1: Literal
949        // 2: Signature
950        // 3: Signature
951        // => bad.
952        let mut packets : Vec<Packet> = Vec::new();
953        packets.push(OnePassSig3::new(SignatureType::Binary).into());
954        packets.push(lit.clone().into());
955        packets.push(sig.clone().into());
956        packets.push(sig.clone().into());
957
958        let message = Message::try_from(packets);
959        assert!(message.is_err(), "{:?}", message);
960
961        // 0: OnePassSig
962        // 1: OnePassSig
963        // 2: Literal
964        // 3: Signature
965        // 4: Signature
966        // => good.
967        let mut packets : Vec<Packet> = Vec::new();
968        packets.push(OnePassSig3::new(SignatureType::Binary).into());
969        packets.push(OnePassSig3::new(SignatureType::Binary).into());
970        packets.push(lit.clone().into());
971        packets.push(sig.clone().into());
972        packets.push(sig.clone().into());
973
974        let message = Message::try_from(packets);
975        assert!(message.is_ok(), "{:?}", message);
976
977        // 0: OnePassSig
978        // 1: OnePassSig
979        // 2: Literal
980        // 3: Literal
981        // 4: Signature
982        // 5: Signature
983        // => bad.
984        let mut packets : Vec<Packet> = Vec::new();
985        packets.push(OnePassSig3::new(SignatureType::Binary).into());
986        packets.push(OnePassSig3::new(SignatureType::Binary).into());
987        packets.push(lit.clone().into());
988        packets.push(lit.clone().into());
989        packets.push(sig.clone().into());
990        packets.push(sig.clone().into());
991
992        let message = Message::try_from(packets);
993        assert!(message.is_err(), "{:?}", message);
994
995        // 0: OnePassSig
996        // 1: OnePassSig
997        // 2: CompressedData
998        //  0: Literal
999        // 3: Signature
1000        // 4: Signature
1001        // => good.
1002        let mut packets : Vec<Packet> = Vec::new();
1003        packets.push(OnePassSig3::new(SignatureType::Binary).into());
1004        packets.push(OnePassSig3::new(SignatureType::Binary).into());
1005        packets.push(
1006            CompressedData::new(CompressionAlgorithm::Uncompressed)
1007                .push(lit.clone().into())
1008                .into());
1009        packets.push(sig.clone().into());
1010        packets.push(sig.clone().into());
1011
1012        let message = Message::try_from(packets);
1013        assert!(message.is_ok(), "{:?}", message);
1014    }
1015
1016    #[test]
1017    fn signature_part() {
1018        let mut lit = Literal::new(Text);
1019        lit.set_body(b"data".to_vec());
1020
1021        let hash = crate::types::HashAlgorithm::SHA512;
1022        let key: key::SecretKey =
1023            crate::packet::key::Key4::generate_ecc(true, crate::types::Curve::Ed25519)
1024            .unwrap().into();
1025        let mut pair = key.clone().into_keypair().unwrap();
1026        let sig = crate::packet::signature::SignatureBuilder::new(SignatureType::Binary)
1027            .sign_hash(&mut pair, hash.context().unwrap()).unwrap();
1028
1029        // 0: Signature
1030        // => bad.
1031        let mut packets : Vec<Packet> = Vec::new();
1032        packets.push(sig.clone().into());
1033
1034        let message = Message::try_from(packets);
1035        assert!(message.is_err(), "{:?}", message);
1036
1037        // 0: Signature
1038        // 1: Literal
1039        // => good.
1040        let mut packets : Vec<Packet> = Vec::new();
1041        packets.push(sig.clone().into());
1042        packets.push(lit.clone().into());
1043
1044        let message = Message::try_from(packets);
1045        assert!(message.is_ok(), "{:?}", message);
1046
1047        // 0: Signature
1048        // 1: Signature
1049        // 2: Literal
1050        // => good.
1051        let mut packets : Vec<Packet> = Vec::new();
1052        packets.push(sig.clone().into());
1053        packets.push(sig.clone().into());
1054        packets.push(lit.clone().into());
1055
1056        let message = Message::try_from(packets);
1057        assert!(message.is_ok(), "{:?}", message);
1058    }
1059
1060    #[test]
1061    fn encrypted_part() {
1062        // There are no simple constructors for SEIP packets: they are
1063        // interleaved with SK-ESK and PK-ESK packets.  And, the
1064        // session key needs to be managed.  Instead, we use some
1065        // internal interfaces to progressively build up more
1066        // complicated messages.
1067
1068        let mut lit = Literal::new(Text);
1069        lit.set_body(b"data".to_vec());
1070
1071        // 0: SK-ESK
1072        // => bad.
1073        let mut packets : Vec<Packet> = Vec::new();
1074        let cipher = SymmetricAlgorithm::AES256;
1075        let sk = crate::crypto::SessionKey::new(cipher.key_size().unwrap());
1076        #[allow(deprecated)]
1077        packets.push(SKESK4::with_password(
1078            cipher,
1079            cipher,
1080            S2K::Simple { hash: HashAlgorithm::SHA256 },
1081            &sk,
1082            &"12345678".into()).unwrap().into());
1083        let message = Message::try_from(packets.clone());
1084        assert!(message.is_err(), "{:?}", message);
1085
1086        // 0: SK-ESK
1087        // 1: Literal
1088        // => bad.
1089        packets.push(lit.clone().into());
1090
1091        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1092                == [ Tag::SKESK, Tag::Literal ]);
1093
1094        let message = Message::try_from(packets.clone());
1095        assert!(message.is_err(), "{:?}", message);
1096
1097        // 0: SK-ESK
1098        // 1: SEIP
1099        //  0: Literal
1100        //  1: MDC
1101        // => good.
1102        let mut seip = SEIP1::new();
1103        seip.children_mut().unwrap().push(
1104            lit.clone().into());
1105        seip.children_mut().unwrap().push(
1106            MDC::from([0u8; 20]).into());
1107        packets[1] = seip.into();
1108
1109        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1110                == [ Tag::SKESK, Tag::SEIP ]);
1111
1112        let message = Message::try_from(packets.clone());
1113        assert!(message.is_ok(), "{:#?}", message);
1114
1115        // 0: SK-ESK
1116        // 1: SEIP
1117        //  0: Literal
1118        //  1: MDC
1119        // 2: SK-ESK
1120        // => bad.
1121        let skesk = packets[0].clone();
1122        packets.push(skesk);
1123
1124        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1125                == [ Tag::SKESK, Tag::SEIP, Tag::SKESK ]);
1126
1127        let message = Message::try_from(packets.clone());
1128        assert!(message.is_err(), "{:#?}", message);
1129
1130        // 0: SK-ESK
1131        // 1: SK-ESK
1132        // 2: SEIP
1133        //  0: Literal
1134        //  1: MDC
1135        // => good.
1136        packets.swap(1, 2);
1137
1138        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1139                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP ]);
1140
1141        let message = Message::try_from(packets.clone());
1142        assert!(message.is_ok(), "{:#?}", message);
1143
1144        // 0: SK-ESK
1145        // 1: SK-ESK
1146        // 2: SEIP
1147        //  0: Literal
1148        //  1: MDC
1149        // 3: SEIP
1150        //  0: Literal
1151        //  1: MDC
1152        // => bad.
1153        let seip = packets[2].clone();
1154        packets.push(seip);
1155
1156        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1157                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP, Tag::SEIP ]);
1158
1159        let message = Message::try_from(packets.clone());
1160        assert!(message.is_err(), "{:#?}", message);
1161
1162        // 0: SK-ESK
1163        // 1: SK-ESK
1164        // 2: SEIP
1165        //  0: Literal
1166        //  1: MDC
1167        // 3: Literal
1168        // => bad.
1169        packets[3] = lit.clone().into();
1170
1171        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1172                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP, Tag::Literal ]);
1173
1174        let message = Message::try_from(packets.clone());
1175        assert!(message.is_err(), "{:#?}", message);
1176
1177        // 0: SK-ESK
1178        // 1: SK-ESK
1179        // 2: SEIP
1180        //  0: Literal
1181        //  1: MDC
1182        //  2: Literal
1183        // => bad.
1184        packets.remove(3);
1185        packets[2].container_mut().unwrap()
1186            .children_mut().unwrap().push(lit.clone().into());
1187
1188        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1189                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP ]);
1190
1191        let message = Message::try_from(packets.clone());
1192        assert!(message.is_err(), "{:#?}", message);
1193
1194        // 0: SK-ESK
1195        // 2: PK-ESK
1196        // 1: SK-ESK
1197        // 2: SEIP
1198        //  0: Literal
1199        // => good.
1200        packets[2].container_mut().unwrap()
1201            .children_mut().unwrap().pop().unwrap();
1202
1203        #[allow(deprecated)]
1204        packets.insert(
1205            1,
1206            PKESK3::new(
1207                "0000111122223333".parse().unwrap(),
1208                PublicKeyAlgorithm::RSAEncrypt,
1209                Ciphertext::RSA { c: MPI::new(&[]) }).unwrap().into());
1210
1211        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1212                == [ Tag::SKESK, Tag::PKESK, Tag::SKESK, Tag::SEIP ]);
1213
1214        let message = Message::try_from(packets.clone());
1215        assert!(message.is_ok(), "{:#?}", message);
1216    }
1217
1218    #[test]
1219    fn basic_message_validator() {
1220        use crate::message::{MessageValidator, MessageValidity, Token};
1221
1222        let mut l = MessageValidator::new();
1223        l.push_token(Token::Literal, &[0]);
1224        l.finish();
1225        assert!(matches!(l.check(), MessageValidity::Message));
1226    }
1227
1228    #[test]
1229    fn message_validator_push_token() {
1230        use crate::message::{MessageValidator, MessageValidity, Token};
1231
1232        let mut l = MessageValidator::new();
1233        l.push_token(Token::Literal, &[0]);
1234        l.finish();
1235
1236        assert!(matches!(l.check(), MessageValidity::Message));
1237    }
1238
1239    #[test]
1240    fn message_validator_push() {
1241        use crate::message::{MessageValidator, MessageValidity};
1242        use crate::packet::Tag;
1243
1244        let mut l = MessageValidator::new();
1245        l.push(Tag::Literal, None, &[0]);
1246        l.finish();
1247
1248        assert!(matches!(l.check(), MessageValidity::Message));
1249    }
1250
1251    #[test]
1252    fn message_validator_finish() {
1253        use crate::message::{MessageValidator, MessageValidity};
1254
1255        let mut l = MessageValidator::new();
1256        l.finish();
1257
1258        assert!(matches!(l.check(), MessageValidity::Error(_)));
1259    }
1260
1261    #[test]
1262    fn message_validator_check() {
1263        use crate::message::{MessageValidator, MessageValidity};
1264        use crate::packet::Tag;
1265
1266        // No packets will return an error.
1267        let mut l = MessageValidator::new();
1268        assert!(matches!(l.check(), MessageValidity::MessagePrefix));
1269        l.finish();
1270
1271        assert!(matches!(l.check(), MessageValidity::Error(_)));
1272
1273        // Simple one-literal message.
1274        let mut l = MessageValidator::new();
1275        l.push(Tag::Literal, None, &[0]);
1276        assert!(matches!(l.check(), MessageValidity::MessagePrefix));
1277        l.finish();
1278
1279        assert!(matches!(l.check(), MessageValidity::Message));
1280    }
1281}