Skip to main content

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 packets = vec![
824            CompressedData::new(CompressionAlgorithm::Uncompressed)
825                .push(lit.clone().into())
826                .into(),
827        ];
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 packets = vec![
837            CompressedData::new(CompressionAlgorithm::Uncompressed)
838                .push(lit.clone().into())
839                .push(lit.clone().into())
840                .into(),
841        ];
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 packets = vec![
851            CompressedData::new(CompressionAlgorithm::Uncompressed)
852                .push(lit.clone().into())
853                .into(),
854            lit.clone().into(),
855        ];
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 packets = vec![
865            CompressedData::new(CompressionAlgorithm::Uncompressed)
866                .push(CompressedData::new(CompressionAlgorithm::Uncompressed)
867                      .push(lit.clone().into())
868                      .into())
869                .into(),
870        ];
871
872        let message = Message::try_from(packets);
873        assert!(message.is_ok(), "{:?}", message);
874    }
875
876    #[test]
877    fn one_pass_sig_part() {
878        let mut lit = Literal::new(Unicode);
879        lit.set_body(b"data".to_vec());
880
881        let hash = crate::types::HashAlgorithm::SHA512;
882        let key: key::SecretKey =
883            crate::packet::key::Key6::generate_ecc(true, crate::types::Curve::Ed25519)
884            .unwrap().into();
885        let mut pair = key.clone().into_keypair().unwrap();
886        let ctx =
887            hash.context().unwrap().for_signature(pair.public().version());
888        let sig = crate::packet::signature::SignatureBuilder::new(SignatureType::Binary)
889            .sign_hash(&mut pair, ctx).unwrap();
890
891        // 0: OnePassSig
892        // => bad.
893        let packets : Vec<Packet> = vec![
894            OnePassSig3::new(SignatureType::Binary).into(),
895        ];
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 packets : Vec<Packet> = vec![
904            OnePassSig3::new(SignatureType::Binary).into(),
905            lit.clone().into(),
906        ];
907
908        let message = Message::try_from(packets);
909        assert!(message.is_err(), "{:?}", message);
910
911        // 0: OnePassSig
912        // 1: Literal
913        // 2: Signature
914        // => good.
915        let packets : Vec<Packet> = vec![
916            OnePassSig3::new(SignatureType::Binary).into(),
917            lit.clone().into(),
918            sig.clone().into(),
919        ];
920
921        let message = Message::try_from(packets);
922        assert!(message.is_ok(), "{:?}", message);
923
924        // 0: OnePassSig
925        // 1: Literal
926        // 2: Signature
927        // 3: Signature
928        // => bad.
929        let packets : Vec<Packet> = vec![
930            OnePassSig3::new(SignatureType::Binary).into(),
931            lit.clone().into(),
932            sig.clone().into(),
933            sig.clone().into(),
934        ];
935
936        let message = Message::try_from(packets);
937        assert!(message.is_err(), "{:?}", message);
938
939        // 0: OnePassSig
940        // 1: OnePassSig
941        // 2: Literal
942        // 3: Signature
943        // 4: Signature
944        // => good.
945        let packets : Vec<Packet> = vec![
946            OnePassSig3::new(SignatureType::Binary).into(),
947            OnePassSig3::new(SignatureType::Binary).into(),
948            lit.clone().into(),
949            sig.clone().into(),
950            sig.clone().into(),
951        ];
952
953        let message = Message::try_from(packets);
954        assert!(message.is_ok(), "{:?}", message);
955
956        // 0: OnePassSig
957        // 1: OnePassSig
958        // 2: Literal
959        // 3: Literal
960        // 4: Signature
961        // 5: Signature
962        // => bad.
963        let packets : Vec<Packet> = vec![
964            OnePassSig3::new(SignatureType::Binary).into(),
965            OnePassSig3::new(SignatureType::Binary).into(),
966            lit.clone().into(),
967            lit.clone().into(),
968            sig.clone().into(),
969            sig.clone().into(),
970        ];
971
972        let message = Message::try_from(packets);
973        assert!(message.is_err(), "{:?}", message);
974
975        // 0: OnePassSig
976        // 1: OnePassSig
977        // 2: CompressedData
978        //  0: Literal
979        // 3: Signature
980        // 4: Signature
981        // => good.
982        let packets : Vec<Packet> = vec![
983            OnePassSig3::new(SignatureType::Binary).into(),
984            OnePassSig3::new(SignatureType::Binary).into(),
985            CompressedData::new(CompressionAlgorithm::Uncompressed)
986                .push(lit.clone().into())
987                .into(),
988            sig.clone().into(),
989            sig.clone().into()
990        ];
991
992        let message = Message::try_from(packets);
993        assert!(message.is_ok(), "{:?}", message);
994    }
995
996    #[test]
997    fn signature_part() {
998        let mut lit = Literal::new(Unicode);
999        lit.set_body(b"data".to_vec());
1000
1001        let hash = crate::types::HashAlgorithm::SHA512;
1002        let key: key::SecretKey =
1003            crate::packet::key::Key6::generate_ecc(true, crate::types::Curve::Ed25519)
1004            .unwrap().into();
1005        let mut pair = key.clone().into_keypair().unwrap();
1006        let ctx =
1007            hash.context().unwrap().for_signature(pair.public().version());
1008        let sig = crate::packet::signature::SignatureBuilder::new(SignatureType::Binary)
1009            .sign_hash(&mut pair, ctx).unwrap();
1010
1011        // 0: Signature
1012        // => bad.
1013        let packets : Vec<Packet> = vec![
1014            sig.clone().into(),
1015        ];
1016
1017        let message = Message::try_from(packets);
1018        assert!(message.is_err(), "{:?}", message);
1019
1020        // 0: Signature
1021        // 1: Literal
1022        // => good.
1023        let packets : Vec<Packet> = vec![
1024            sig.clone().into(),
1025            lit.clone().into(),
1026        ];
1027
1028        let message = Message::try_from(packets);
1029        assert!(message.is_ok(), "{:?}", message);
1030
1031        // 0: Signature
1032        // 1: Signature
1033        // 2: Literal
1034        // => good.
1035        let packets : Vec<Packet> = vec![
1036            sig.clone().into(),
1037            sig.clone().into(),
1038            lit.clone().into(),
1039        ];
1040
1041        let message = Message::try_from(packets);
1042        assert!(message.is_ok(), "{:?}", message);
1043    }
1044
1045    #[test]
1046    fn encrypted_part() {
1047        // There are no simple constructors for SEIP packets: they are
1048        // interleaved with SK-ESK and PK-ESK packets.  And, the
1049        // session key needs to be managed.  Instead, we use some
1050        // internal interfaces to progressively build up more
1051        // complicated messages.
1052
1053        let mut lit = Literal::new(Unicode);
1054        lit.set_body(b"data".to_vec());
1055
1056        // 0: SK-ESK
1057        // => bad.
1058        let mut packets : Vec<Packet> = Vec::new();
1059        let cipher = SymmetricAlgorithm::AES256;
1060        let sk =
1061            crate::crypto::SessionKey::new(cipher.key_size().unwrap()).unwrap();
1062        #[allow(deprecated)]
1063        packets.push(SKESK4::with_password(
1064            cipher,
1065            cipher,
1066            S2K::Simple { hash: HashAlgorithm::SHA256 },
1067            &sk,
1068            &"12345678".into()).unwrap().into());
1069        let message = Message::try_from(packets.clone());
1070        assert!(message.is_err(), "{:?}", message);
1071
1072        // 0: SK-ESK
1073        // 1: Literal
1074        // => bad.
1075        packets.push(lit.clone().into());
1076
1077        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1078                == [ Tag::SKESK, Tag::Literal ]);
1079
1080        let message = Message::try_from(packets.clone());
1081        assert!(message.is_err(), "{:?}", message);
1082
1083        // 0: SK-ESK
1084        // 1: SEIP
1085        //  0: Literal
1086        //  1: MDC
1087        // => good.
1088        let mut seip = SEIP1::new();
1089        seip.container_mut().children_mut().unwrap().push(
1090            lit.clone().into());
1091        seip.container_mut().children_mut().unwrap().push(
1092            MDC::from([0u8; 20]).into());
1093        packets[1] = seip.into();
1094
1095        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1096                == [ Tag::SKESK, Tag::SEIP ]);
1097
1098        let message = Message::try_from(packets.clone());
1099        assert!(message.is_ok(), "{:#?}", message);
1100
1101        // 0: SK-ESK
1102        // 1: SEIP
1103        //  0: Literal
1104        //  1: MDC
1105        // 2: SK-ESK
1106        // => bad.
1107        let skesk = packets[0].clone();
1108        packets.push(skesk);
1109
1110        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1111                == [ Tag::SKESK, Tag::SEIP, Tag::SKESK ]);
1112
1113        let message = Message::try_from(packets.clone());
1114        assert!(message.is_err(), "{:#?}", message);
1115
1116        // 0: SK-ESK
1117        // 1: SK-ESK
1118        // 2: SEIP
1119        //  0: Literal
1120        //  1: MDC
1121        // => good.
1122        packets.swap(1, 2);
1123
1124        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1125                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP ]);
1126
1127        let message = Message::try_from(packets.clone());
1128        assert!(message.is_ok(), "{:#?}", message);
1129
1130        // 0: SK-ESK
1131        // 1: SK-ESK
1132        // 2: SEIP
1133        //  0: Literal
1134        //  1: MDC
1135        // 3: SEIP
1136        //  0: Literal
1137        //  1: MDC
1138        // => bad.
1139        let seip = packets[2].clone();
1140        packets.push(seip);
1141
1142        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1143                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP, Tag::SEIP ]);
1144
1145        let message = Message::try_from(packets.clone());
1146        assert!(message.is_err(), "{:#?}", message);
1147
1148        // 0: SK-ESK
1149        // 1: SK-ESK
1150        // 2: SEIP
1151        //  0: Literal
1152        //  1: MDC
1153        // 3: Literal
1154        // => bad.
1155        packets[3] = lit.clone().into();
1156
1157        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1158                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP, Tag::Literal ]);
1159
1160        let message = Message::try_from(packets.clone());
1161        assert!(message.is_err(), "{:#?}", message);
1162
1163        // 0: SK-ESK
1164        // 1: SK-ESK
1165        // 2: SEIP
1166        //  0: Literal
1167        //  1: MDC
1168        //  2: Literal
1169        // => bad.
1170        packets.remove(3);
1171        packets[2].container_mut().unwrap()
1172            .children_mut().unwrap().push(lit.clone().into());
1173
1174        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1175                == [ Tag::SKESK, Tag::SKESK, Tag::SEIP ]);
1176
1177        let message = Message::try_from(packets.clone());
1178        assert!(message.is_err(), "{:#?}", message);
1179
1180        // 0: SK-ESK
1181        // 2: PK-ESK
1182        // 1: SK-ESK
1183        // 2: SEIP
1184        //  0: Literal
1185        // => good.
1186        packets[2].container_mut().unwrap()
1187            .children_mut().unwrap().pop().unwrap();
1188
1189        #[allow(deprecated)]
1190        packets.insert(
1191            1,
1192            PKESK3::new(
1193                Some("0000111122223333".parse().unwrap()),
1194                PublicKeyAlgorithm::RSAEncrypt,
1195                Ciphertext::RSA { c: MPI::new(&[]) }).unwrap().into());
1196
1197        assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>()
1198                == [ Tag::SKESK, Tag::PKESK, Tag::SKESK, Tag::SEIP ]);
1199
1200        let message = Message::try_from(packets.clone());
1201        assert!(message.is_ok(), "{:#?}", message);
1202    }
1203
1204    #[test]
1205    fn basic_message_validator() {
1206        use crate::message::{MessageValidator, MessageValidity, Token};
1207
1208        let mut l = MessageValidator::new();
1209        l.push_token(Token::Literal, &[0]);
1210        l.finish();
1211        assert!(matches!(l.check(), MessageValidity::Message));
1212    }
1213
1214    #[test]
1215    fn message_validator_push_token() {
1216        use crate::message::{MessageValidator, MessageValidity, Token};
1217
1218        let mut l = MessageValidator::new();
1219        l.push_token(Token::Literal, &[0]);
1220        l.finish();
1221
1222        assert!(matches!(l.check(), MessageValidity::Message));
1223    }
1224
1225    #[test]
1226    fn message_validator_push() {
1227        use crate::message::{MessageValidator, MessageValidity};
1228        use crate::packet::Tag;
1229
1230        let mut l = MessageValidator::new();
1231        l.push(Tag::Literal, None, &[0]);
1232        l.finish();
1233
1234        assert!(matches!(l.check(), MessageValidity::Message));
1235    }
1236
1237    #[test]
1238    fn message_validator_finish() {
1239        use crate::message::{MessageValidator, MessageValidity};
1240
1241        let mut l = MessageValidator::new();
1242        l.finish();
1243
1244        assert!(matches!(l.check(), MessageValidity::Error(_)));
1245    }
1246
1247    #[test]
1248    fn message_validator_check() {
1249        use crate::message::{MessageValidator, MessageValidity};
1250        use crate::packet::Tag;
1251
1252        // No packets will return an error.
1253        let mut l = MessageValidator::new();
1254        assert!(matches!(l.check(), MessageValidity::MessagePrefix));
1255        l.finish();
1256
1257        assert!(matches!(l.check(), MessageValidity::Error(_)));
1258
1259        // Simple one-literal message.
1260        let mut l = MessageValidator::new();
1261        l.push(Tag::Literal, None, &[0]);
1262        assert!(matches!(l.check(), MessageValidity::MessagePrefix));
1263        l.finish();
1264
1265        assert!(matches!(l.check(), MessageValidity::Message));
1266    }
1267}