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