sequoia_openpgp/parse/stream.rs
1//! Streaming decryption and verification.
2//!
3//! This module provides convenient filters for decryption and
4//! verification of OpenPGP messages (see [Section 10.3 of RFC 9580]).
5//! It is the preferred interface to process OpenPGP messages:
6//!
7//! [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
8//!
9//! - Use the [`Verifier`] to verify a signed message,
10//! - [`DetachedVerifier`] to verify a detached signature,
11//! - or [`Decryptor`] to decrypt and verify an encrypted and
12//! possibly signed message.
13//!
14//!
15//! Consuming OpenPGP messages is more difficult than producing them.
16//! When we produce the message, we control the packet structure being
17//! generated using our programs control flow. However, when we
18//! consume a message, the control flow is determined by the message
19//! being processed.
20//!
21//! To use Sequoia's streaming [`Verifier`] and [`Decryptor`], you
22//! need to provide an object that implements [`VerificationHelper`],
23//! and for the [`Decryptor`] also [`DecryptionHelper`].
24//!
25//!
26//! The [`VerificationHelper`] trait give certificates for the
27//! signature verification to the [`Verifier`] or [`Decryptor`], let
28//! you inspect the message structure (see [Section 10.3 of RFC
29//! 9580]), and implements the signature verification policy.
30//!
31//! The [`DecryptionHelper`] trait is concerned with producing the
32//! session key to decrypt a message, most commonly by decrypting one
33//! of the messages' [`PKESK`] or [`SKESK`] packets. It could also
34//! use a cached session key, or one that has been explicitly provided
35//! to the decryption operation.
36//!
37//! [`PKESK`]: crate::packet::PKESK
38//! [`SKESK`]: crate::packet::SKESK
39//!
40//! The [`Verifier`] and [`Decryptor`] are filters: they consume
41//! OpenPGP data from a reader, file, or bytes, and implement
42//! [`io::Read`] that can be used to read the verified and/or
43//! decrypted data.
44//!
45//! [`io::Read`]: std::io::Read
46//!
47//! [`DetachedVerifier`] does not provide the [`io::Read`] interface,
48//! because in this case, the data to be verified is easily available
49//! without any transformation. Not providing a filter-like interface
50//! allows for a very performant implementation of the verification.
51//!
52//! # Examples
53//!
54//! This example demonstrates how to use the streaming interface using
55//! the [`Verifier`]. For brevity, no certificates are fed to the
56//! verifier, and the message structure is not verified, i.e. this
57//! merely extracts the literal data. See the [`Verifier` examples]
58//! and the [`Decryptor` examples] for how to verify the message and
59//! its structure.
60//!
61//! [`Verifier` examples]: Verifier#examples
62//! [`Decryptor` examples]: Decryptor#examples
63//!
64//! ```
65//! # fn main() -> sequoia_openpgp::Result<()> {
66//! use std::io::Read;
67//! use sequoia_openpgp as openpgp;
68//! use openpgp::{KeyHandle, Cert, Result};
69//! use openpgp::parse::{Parse, stream::*};
70//! use openpgp::policy::StandardPolicy;
71//!
72//! let p = &StandardPolicy::new();
73//!
74//! // This fetches keys and computes the validity of the verification.
75//! struct Helper {}
76//! impl VerificationHelper for Helper {
77//! fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>> {
78//! Ok(Vec::new()) // Feed the Certs to the verifier here...
79//! }
80//! fn check(&mut self, structure: MessageStructure) -> Result<()> {
81//! Ok(()) // Implement your verification policy here.
82//! }
83//! }
84//!
85//! let message =
86//! b"-----BEGIN PGP MESSAGE-----
87//!
88//! xA0DAAoWBpwMNI3YLBkByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoAJwWCW37P
89//! 8RahBI6MM/pGJjN5dtl5eAacDDSN2CwZCZAGnAw0jdgsGQAAeZQA/2amPbBXT96Q
90//! O7PFms9DRuehsVVrFkaDtjN2WSxI4RGvAQDq/pzNdCMpy/Yo7AZNqZv5qNMtDdhE
91//! b2WH5lghfKe/AQ==
92//! =DjuO
93//! -----END PGP MESSAGE-----";
94//!
95//! let h = Helper {};
96//! let mut v = VerifierBuilder::from_bytes(&message[..])?
97//! .with_policy(p, None, h)?;
98//!
99//! let mut content = Vec::new();
100//! v.read_to_end(&mut content)?;
101//! assert_eq!(content, b"Hello World!");
102//! # Ok(()) }
103//! ```
104use std::cmp;
105use std::io;
106use std::path::Path;
107use std::time;
108
109use buffered_reader::BufferedReader;
110use crate::{
111 Error,
112 Fingerprint,
113 types::{
114 AEADAlgorithm,
115 CompressionAlgorithm,
116 RevocationStatus,
117 SymmetricAlgorithm,
118 },
119 packet::{
120 key,
121 OnePassSig,
122 PKESK,
123 SEIP,
124 SKESK,
125 },
126 KeyHandle,
127 Packet,
128 Result,
129 packet,
130 packet::{Signature, Unknown},
131 cert::prelude::*,
132 crypto::{
133 SessionKey,
134 mem::Protected,
135 },
136 policy::Policy,
137};
138use crate::parse::{
139 Cookie,
140 HashingMode,
141 PacketParser,
142 PacketParserBuilder,
143 PacketParserResult,
144 Parse,
145};
146
147/// Whether to trace execution by default (on stderr).
148const TRACE : bool = false;
149
150/// Indentation level for tracing in this module.
151const TRACE_INDENT: isize = 5;
152
153/// How much data to buffer before giving it to the caller.
154///
155/// Signature verification and detection of ciphertext tampering
156/// requires processing the whole message first. Therefore, OpenPGP
157/// implementations supporting streaming operations necessarily must
158/// output unverified data. This has been a source of problems in the
159/// past. To alleviate this, we buffer the message first (up to 25
160/// megabytes of net message data by default), and verify the
161/// signatures if the message fits into our buffer. Nevertheless it
162/// is important to treat the data as unverified and untrustworthy
163/// until you have seen a positive verification.
164///
165/// The default can be changed using [`VerifierBuilder::buffer_size`]
166/// and [`DecryptorBuilder::buffer_size`].
167///
168/// [`VerifierBuilder::buffer_size`]: VerifierBuilder::buffer_size()
169/// [`DecryptorBuilder::buffer_size`]: DecryptorBuilder::buffer_size()
170pub const DEFAULT_BUFFER_SIZE: usize = 25 * 1024 * 1024;
171
172/// Result of a signature verification.
173///
174/// A signature verification is either successful yielding a
175/// [`GoodChecksum`], or there was some [`VerificationError`]
176/// explaining the verification failure.
177///
178pub type VerificationResult<'a> =
179 std::result::Result<GoodChecksum<'a>, VerificationError<'a>>;
180
181/// A good signature.
182///
183/// Represents the result of a successful signature verification. It
184/// includes the signature and the signing key with all the necessary
185/// context (i.e. certificate, time, policy) to evaluate the
186/// trustworthiness of the signature using a trust model.
187///
188/// `GoodChecksum` is used in [`VerificationResult`]. See also
189/// [`VerificationError`].
190///
191///
192/// A signature is considered good if and only if all the following
193/// conditions are met:
194///
195/// - The signature has a Signature Creation Time subpacket.
196///
197/// - The signature is alive at the specified time (the time
198/// parameter passed to, e.g., [`VerifierBuilder::with_policy`]).
199///
200/// [`VerifierBuilder::with_policy`]: VerifierBuilder::with_policy()
201///
202/// - The certificate is alive and not revoked as of the signature's
203/// creation time.
204///
205/// - The signing key is alive, not revoked, and signing capable as
206/// of the signature's creation time.
207///
208/// - The signature was generated by the signing key.
209///
210/// **Note**: This doesn't mean that the key that generated the
211/// signature is in any way trustworthy in the sense that it
212/// belongs to the person or entity that the user thinks it
213/// belongs to. This property can only be evaluated within a
214/// trust model, such as the [web of trust] (WoT). This policy is
215/// normally implemented in the [`VerificationHelper::check`]
216/// method.
217///
218/// [web of trust]: https://en.wikipedia.org/wiki/Web_of_trust
219#[derive(Debug)]
220pub struct GoodChecksum<'a> {
221 /// The signature.
222 pub sig: &'a Signature,
223
224 /// The signing key that made the signature.
225 ///
226 /// The amalgamation of the signing key includes the necessary
227 /// context (i.e. certificate, time, policy) to evaluate the
228 /// trustworthiness of the signature using a trust model.
229 pub ka: ValidErasedKeyAmalgamation<'a, key::PublicParts>,
230}
231assert_send_and_sync!(GoodChecksum<'_>);
232
233/// A bad signature.
234///
235/// Represents the result of an unsuccessful signature verification.
236/// It contains all the context that could be gathered until the
237/// verification process failed.
238///
239/// `VerificationError` is used in [`VerificationResult`]. See also
240/// [`GoodChecksum`].
241///
242///
243/// You can either explicitly match on the variants, or convert to
244/// [`Error`] using [`From`].
245///
246/// [`Error`]: super::super::Error
247/// [`From`]: std::convert::From
248#[non_exhaustive]
249#[derive(Debug)]
250pub enum VerificationError<'a> {
251 /// Missing Key
252 MissingKey {
253 /// The signature.
254 sig: &'a Signature,
255 },
256 /// Unbound key.
257 ///
258 /// There is no valid binding signature at the time the signature
259 /// was created under the given policy.
260 UnboundKey {
261 /// The signature.
262 sig: &'a Signature,
263
264 /// The certificate that made the signature.
265 cert: &'a Cert,
266
267 /// The reason why the key is not bound.
268 error: anyhow::Error,
269 },
270 /// Bad key (have a key, but it is not alive, etc.)
271 BadKey {
272 /// The signature.
273 sig: &'a Signature,
274
275 /// The signing key that made the signature.
276 ka: ValidErasedKeyAmalgamation<'a, key::PublicParts>,
277
278 /// The reason why the key is bad.
279 error: anyhow::Error,
280 },
281 /// Bad signature (have a valid key, but the signature didn't check out)
282 BadSignature {
283 /// The signature.
284 sig: &'a Signature,
285
286 /// The signing key that made the signature.
287 ka: ValidErasedKeyAmalgamation<'a, key::PublicParts>,
288
289 /// The reason why the signature is bad.
290 error: anyhow::Error,
291 },
292
293 /// Malformed signature (no signature creation subpacket, etc.).
294 MalformedSignature {
295 /// The signature.
296 sig: &'a Signature,
297
298 /// The reason why the signature is malformed.
299 error: anyhow::Error,
300 },
301
302 /// A signature that failed to parse at all.
303 UnknownSignature {
304 /// The signature parsed into an [`crate::packet::Unknown`]
305 /// packet.
306 sig: &'a Unknown,
307 }
308}
309assert_send_and_sync!(VerificationError<'_>);
310
311impl<'a> std::fmt::Display for VerificationError<'a> {
312 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
313 use self::VerificationError::*;
314 match self {
315 MalformedSignature { error, .. } =>
316 write!(f, "Malformed signature: {}", error),
317 UnknownSignature { sig, .. } =>
318 write!(f, "Malformed signature: {}", sig.error()),
319 MissingKey { sig } =>
320 if let Some(issuer) = sig.get_issuers().get(0) {
321 write!(f, "Missing key: {}", issuer)
322 } else {
323 write!(f, "Missing key")
324 },
325 UnboundKey { cert, error, .. } =>
326 write!(f, "Subkey of {} not bound: {}", cert, error),
327 BadKey { ka, error, .. } =>
328 write!(f, "Subkey of {} is bad: {}", ka.cert(), error),
329 BadSignature { error, .. } =>
330 write!(f, "Bad signature: {}", error),
331 }
332 }
333}
334
335impl<'a> std::error::Error for VerificationError<'a> {
336 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
337 use self::VerificationError::*;
338 match self {
339 MissingKey { .. } => None,
340 UnboundKey { error, .. } =>
341 Some(error.as_ref()),
342 BadKey { error, .. } =>
343 Some(error.as_ref()),
344 BadSignature { error, .. } =>
345 Some(error.as_ref()),
346 MalformedSignature { error, .. } =>
347 Some(error.as_ref()),
348 UnknownSignature { .. } => None,
349 }
350 }
351}
352
353impl<'a> From<VerificationError<'a>> for Error {
354 fn from(e: VerificationError<'a>) -> Self {
355 use self::VerificationError::*;
356 match e {
357 MalformedSignature { .. } =>
358 Error::MalformedPacket(e.to_string()),
359 UnknownSignature { sig } =>
360 Error::MalformedPacket(sig.error().to_string()),
361 MissingKey { .. } =>
362 Error::InvalidKey(e.to_string()),
363 UnboundKey { .. } =>
364 Error::InvalidKey(e.to_string()),
365 BadKey { .. } =>
366 Error::InvalidKey(e.to_string()),
367 BadSignature { .. } =>
368 Error::BadSignature(e.to_string()),
369 }
370 }
371}
372
373/// Like VerificationError, but without referencing the signature.
374///
375/// This avoids borrowing the signature, so that we can continue to
376/// mutably borrow the signature trying other keys. After all keys
377/// are tried, we attach the reference to the signature, yielding a
378/// `VerificationError`.
379enum VerificationErrorInternal<'a> {
380 // MalformedSignature is not used, so it is omitted here.
381
382 /// Missing Key
383 MissingKey {
384 },
385 /// Unbound key.
386 ///
387 /// There is no valid binding signature at the time the signature
388 /// was created under the given policy.
389 UnboundKey {
390 /// The certificate that made the signature.
391 cert: &'a Cert,
392
393 /// The reason why the key is not bound.
394 error: anyhow::Error,
395 },
396 /// Bad key (have a key, but it is not alive, etc.)
397 BadKey {
398 /// The signing key that made the signature.
399 ka: ValidErasedKeyAmalgamation<'a, key::PublicParts>,
400
401 /// The reason why the key is bad.
402 error: anyhow::Error,
403 },
404 /// Bad signature (have a valid key, but the signature didn't check out)
405 BadSignature {
406 /// The signing key that made the signature.
407 ka: ValidErasedKeyAmalgamation<'a, key::PublicParts>,
408
409 /// The reason why the signature is bad.
410 error: anyhow::Error,
411 },
412}
413
414impl<'a> VerificationErrorInternal<'a> {
415 fn attach_sig(self, sig: &'a Signature) -> VerificationError<'a> {
416 use self::VerificationErrorInternal::*;
417 match self {
418 MissingKey {} =>
419 VerificationError::MissingKey { sig },
420 UnboundKey { cert, error } =>
421 VerificationError::UnboundKey { sig, cert, error },
422 BadKey { ka, error } =>
423 VerificationError::BadKey { sig, ka, error },
424 BadSignature { ka, error } =>
425 VerificationError::BadSignature { sig, ka, error },
426 }
427 }
428}
429
430/// Communicates the message structure to the VerificationHelper.
431///
432/// A valid OpenPGP message contains one literal data packet with
433/// optional [encryption, signing, and compression layers] freely
434/// combined on top. This structure is passed to
435/// [`VerificationHelper::check`] for verification.
436///
437/// [encryption, signing, and compression layers]: MessageLayer
438///
439/// The most common structure is an optionally encrypted, optionally
440/// compressed, and optionally signed message, i.e. if the message is
441/// encrypted, then the encryption is the outermost layer; if the
442/// message is signed, then the signature group is the innermost
443/// layer. This is a sketch of such a message:
444///
445/// ```text
446/// [ encryption layer: [ compression layer: [ signature group: [ literal data ]]]]
447/// ```
448///
449/// However, OpenPGP allows encryption, signing, and compression
450/// operations to be freely combined (see [Section 10.3 of RFC 9580]).
451/// This is represented as a stack of [`MessageLayer`]s, where
452/// signatures of the same level (i.e. those over the same data:
453/// either directly over the literal data, or over other signatures
454/// and the literal data) are grouped into one layer. See also
455/// [`Signature::level`].
456///
457/// [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
458/// [`Signature::level`]: crate::packet::Signature#method.level
459///
460/// Consider the following structure. This is a set of notarizing
461/// signatures *N* over a set of signatures *S* over the literal data:
462///
463/// ```text
464/// [ signature group: [ signature group: [ literal data ]]]
465/// ```
466///
467/// The notarizing signatures *N* are said to be of level 1,
468/// i.e. signatures over the signatures *S* and the literal data. The
469/// signatures *S* are level 0 signatures, i.e. signatures over the
470/// literal data.
471///
472/// OpenPGP's flexibility allows adaption to new use cases, but also
473/// presents a challenge to implementations and downstream users. The
474/// message structure must be both validated, and possibly
475/// communicated to the application's user. Note that if
476/// compatibility is a concern, generated messages must be restricted
477/// to a narrow subset of possible structures, see this [test of
478/// unusual message structures].
479///
480/// [test of unusual message structures]: https://tests.sequoia-pgp.org/#Unusual_Message_Structure
481#[derive(Debug)]
482pub struct MessageStructure<'a> {
483 layers: Vec<MessageLayer<'a>>,
484 processed_csf_message: bool,
485}
486assert_send_and_sync!(MessageStructure<'_>);
487
488impl<'a> MessageStructure<'a> {
489 fn new(processed_csf_message: bool) -> Self {
490 MessageStructure {
491 layers: Vec::new(),
492 processed_csf_message,
493 }
494 }
495
496 fn new_compression_layer(&mut self, algo: CompressionAlgorithm) {
497 self.layers.push(MessageLayer::Compression {
498 algo,
499 })
500 }
501
502 fn new_encryption_layer(&mut self, sym_algo: SymmetricAlgorithm,
503 aead_algo: Option<AEADAlgorithm>) {
504 self.layers.push(MessageLayer::Encryption {
505 sym_algo,
506 aead_algo,
507 })
508 }
509
510 fn new_signature_group(&mut self) {
511 self.layers.push(MessageLayer::SignatureGroup {
512 results: Vec::new(),
513 })
514 }
515
516 fn push_verification_result(&mut self, sig: VerificationResult<'a>) {
517 if let Some(MessageLayer::SignatureGroup { ref mut results }) =
518 self.layers.iter_mut().last()
519 {
520 results.push(sig);
521 } else {
522 panic!("cannot push to encryption or compression layer");
523 }
524 }
525
526 /// Returns an iterator over the message layers.
527 pub fn iter(&self) -> impl Iterator<Item=&MessageLayer<'a>> {
528 self.layers.iter()
529 }
530
531 /// Returns whether we processed a signed message using the
532 /// Cleartext Signature Framework.
533 ///
534 /// This function returns whether the parser parsed a cleartext
535 /// signature using the cleartext transformation.
536 pub fn processed_csf_message(&self) -> bool {
537 self.processed_csf_message
538 }
539}
540
541impl<'a> IntoIterator for MessageStructure<'a> {
542 type Item = MessageLayer<'a>;
543 type IntoIter = std::vec::IntoIter<MessageLayer<'a>>;
544
545 fn into_iter(self) -> Self::IntoIter {
546 self.layers.into_iter()
547 }
548}
549
550/// Represents a layer of the message structure.
551///
552/// A valid OpenPGP message contains one literal data packet with
553/// optional encryption, signing, and compression layers freely
554/// combined on top (see [Section 10.3 of RFC 9580]). This enum
555/// represents the layers. The [`MessageStructure`] is communicated
556/// to the [`VerificationHelper::check`]. Iterating over the
557/// [`MessageStructure`] yields the individual message layers.
558///
559/// [Section 10.3 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3
560#[derive(Debug)]
561pub enum MessageLayer<'a> {
562 /// Represents a compression container.
563 ///
564 /// Compression is usually transparent in OpenPGP, though it may
565 /// sometimes be interesting for advanced users to indicate that
566 /// the message was compressed, and how (see [Section 5.6 of RFC
567 /// 9580]).
568 ///
569 /// [Section 5.6 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.6
570 Compression {
571 /// Compression algorithm used.
572 algo: CompressionAlgorithm,
573 },
574 /// Represents an encryption container.
575 ///
576 /// Indicates the fact that the message was encrypted (see
577 /// [Section 5.13 of RFC 9580]). If you expect encrypted
578 /// messages, make sure that there is at least one encryption
579 /// container present.
580 ///
581 /// [Section 5.13 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.13
582 Encryption {
583 /// Symmetric algorithm used.
584 sym_algo: SymmetricAlgorithm,
585 /// AEAD algorithm used, if any.
586 aead_algo: Option<AEADAlgorithm>,
587 },
588 /// Represents a signature group.
589 ///
590 /// A signature group consists of all signatures with the same
591 /// level (see [Section 5.2 of RFC 9580]). Each
592 /// [`VerificationResult`] represents the result of a single
593 /// signature verification. In your [`VerificationHelper::check`]
594 /// method, iterate over the verification results, see if it meets
595 /// your policies' demands, and communicate it to the user, if
596 /// applicable.
597 ///
598 /// [Section 5.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2
599 SignatureGroup {
600 /// The results of the signature verifications.
601 results: Vec<VerificationResult<'a>>,
602 }
603}
604assert_send_and_sync!(MessageLayer<'_>);
605
606/// Internal version of the message structure.
607///
608/// In contrast to MessageStructure, this owns unverified
609/// signature packets.
610#[derive(Debug)]
611struct IMessageStructure {
612 layers: Vec<IMessageLayer>,
613
614 // We insert a SignatureGroup layer every time we see a OnePassSig
615 // packet with the last flag.
616 //
617 // However, we need to make sure that we insert a SignatureGroup
618 // layer even if the OnePassSig packet has the last flag set to
619 // false. To do that, we keep track of the fact that we saw such
620 // a OPS packet.
621 sig_group_counter: usize,
622}
623
624impl IMessageStructure {
625 fn new() -> Self {
626 IMessageStructure {
627 layers: Vec::new(),
628 sig_group_counter: 0,
629 }
630 }
631
632 fn new_compression_layer(&mut self, algo: CompressionAlgorithm) {
633 tracer!(TRACE, "IMessageStructure::new_compression_layer", TRACE_INDENT);
634 t!("pushing a {:?} layer", algo);
635
636 self.insert_missing_signature_group();
637 self.layers.push(IMessageLayer::Compression {
638 algo,
639 });
640 }
641
642 fn new_encryption_layer(&mut self,
643 depth: isize,
644 expect_mdc: bool,
645 sym_algo: SymmetricAlgorithm,
646 aead_algo: Option<AEADAlgorithm>) {
647 tracer!(TRACE, "IMessageStructure::new_encryption_layer", TRACE_INDENT);
648 t!("pushing a {:?}/{:?} layer", sym_algo, aead_algo);
649
650 self.insert_missing_signature_group();
651 self.layers.push(IMessageLayer::Encryption {
652 depth,
653 expect_mdc,
654 sym_algo,
655 aead_algo,
656 });
657 }
658
659 /// Returns whether we expect an MDC packet in an
660 /// encryption container at this recursion depth.
661 ///
662 /// Handling MDC packets has to be done carefully, otherwise, we
663 /// may create a decryption oracle.
664 fn expect_mdc_at(&self, at: isize) -> bool {
665 for l in &self.layers {
666 match l {
667 IMessageLayer::Encryption {
668 depth,
669 expect_mdc,
670 ..
671 } if *depth == at && *expect_mdc => return true,
672 _ => (),
673 }
674 }
675 false
676 }
677
678 /// Makes sure that we insert a signature group even if the
679 /// previous OPS packet had the last flag set to false.
680 fn insert_missing_signature_group(&mut self) {
681 tracer!(TRACE, "IMessageStructure::insert_missing_signature_group",
682 TRACE_INDENT);
683
684 if self.sig_group_counter > 0 {
685 t!("implicit insert of signature group for {} sigs",
686 self.sig_group_counter);
687
688 self.layers.push(IMessageLayer::SignatureGroup {
689 sigs: Vec::new(),
690 count: self.sig_group_counter,
691 });
692 }
693 self.sig_group_counter = 0;
694 }
695
696 fn push_ops(&mut self, ops: &OnePassSig) {
697 tracer!(TRACE, "IMessageStructure::push_ops", TRACE_INDENT);
698 t!("Pushing {:?}", ops);
699
700 self.sig_group_counter += 1;
701 if ops.last() {
702 self.layers.push(IMessageLayer::SignatureGroup {
703 sigs: Vec::new(),
704 count: self.sig_group_counter,
705 });
706 self.sig_group_counter = 0;
707 }
708 }
709
710 fn push_signature(&mut self, sig: MaybeSignature, csf_message: bool) {
711 tracer!(TRACE, "IMessageStructure::push_signature", TRACE_INDENT);
712 t!("Pushing {:?}", sig);
713 if csf_message {
714 t!("Cleartext Signature Framework transformation enabled");
715 }
716
717 for (i, layer) in self.layers.iter_mut().enumerate().rev() {
718 t!("{}: {:?}", i, layer);
719 match layer {
720 IMessageLayer::SignatureGroup {
721 ref mut sigs, ref mut count,
722 } if *count > 0 => {
723 t!("Layer {} is a signature group with {} outstanding sigs",
724 i, *count);
725
726 sigs.push(sig);
727 if csf_message {
728 // The CSF transformation does not know how
729 // many signatures will follow, so we may end
730 // up with too few synthesized OPS packets.
731 // But, we only have one layer anyway, and no
732 // notarizations, so we don't need to concern
733 // ourselves with the counter.
734 } else {
735 *count -= 1;
736 }
737 return;
738 },
739 _ => (),
740 }
741 }
742
743 // As a last resort, push a new signature group for this
744 // signature. This may not accurately describe the structure,
745 // but if we get to this point, we failed to grasp the message
746 // structure in some way, so there is nothing we can do really.
747 t!("signature unaccounted for");
748 self.layers.push(IMessageLayer::SignatureGroup {
749 sigs: vec![sig],
750 count: 0,
751 });
752 }
753
754 fn push_bare_signature(&mut self, sig: MaybeSignature) {
755 if let Some(IMessageLayer::SignatureGroup { .. }) = self.layers.iter().last() {
756 // The last layer is a SignatureGroup. We will append the
757 // signature there without accounting for it.
758 } else {
759 // The last layer is not a SignatureGroup, or there is no
760 // layer at all. Create one.
761 self.layers.push(IMessageLayer::SignatureGroup {
762 sigs: Vec::new(),
763 count: 0,
764 });
765 }
766
767 if let IMessageLayer::SignatureGroup { ref mut sigs, .. } =
768 self.layers.iter_mut().last().expect("just checked or created")
769 {
770 sigs.push(sig);
771 } else {
772 unreachable!("just checked or created")
773 }
774 }
775
776}
777
778/// Internal version of a layer of the message structure.
779///
780/// In contrast to MessageLayer, this owns unverified signature packets.
781#[derive(Debug)]
782enum IMessageLayer {
783 Compression {
784 algo: CompressionAlgorithm,
785 },
786 Encryption {
787 /// Recursion depth of this container.
788 depth: isize,
789 /// Do we expect an MDC packet?
790 ///
791 /// I.e. is this a SEIPv1 container?
792 expect_mdc: bool,
793 sym_algo: SymmetricAlgorithm,
794 aead_algo: Option<AEADAlgorithm>,
795 },
796 SignatureGroup {
797 sigs: Vec<MaybeSignature>,
798 count: usize,
799 }
800}
801
802/// Represents [`Signature`]s and those that failed to parse in the
803/// form of [`Unknown`] packets.
804type MaybeSignature = std::result::Result<Signature, Unknown>;
805
806/// Helper for signature verification.
807///
808/// This trait abstracts over signature and message structure
809/// verification. It allows us to provide the [`Verifier`],
810/// [`DetachedVerifier`], and [`Decryptor`] without imposing a policy
811/// on how certificates for signature verification are looked up, or
812/// what message structure is considered acceptable.
813///
814///
815/// It also allows you to inspect each packet that is processed during
816/// verification or decryption, optionally providing a [`Map`] for
817/// each packet.
818///
819/// [`Map`]: super::map::Map
820pub trait VerificationHelper {
821 /// Inspects the message.
822 ///
823 /// Called once per packet. Can be used to inspect and dump
824 /// packets in encrypted messages.
825 ///
826 /// The default implementation does nothing.
827 fn inspect(&mut self, pp: &PacketParser) -> Result<()> {
828 // Do nothing.
829 let _ = pp;
830 Ok(())
831 }
832
833 /// Retrieves the certificates containing the specified keys.
834 ///
835 /// When implementing this method, you should return as many
836 /// certificates corresponding to the `ids` as you can.
837 ///
838 /// If an identifier is ambiguous, because, for instance, there
839 /// are multiple certificates with the same Key ID, then you
840 /// should return all of them.
841 ///
842 /// You should only return an error if processing should be
843 /// aborted. In general, you shouldn't return an error if you
844 /// don't have a certificate for a given identifier: if there are
845 /// multiple signatures, then, depending on your policy, verifying
846 /// a subset of them may be sufficient.
847 ///
848 /// This method will be called at most once per message.
849 ///
850 /// # Examples
851 ///
852 /// This example demonstrates how to look up the certificates for
853 /// the signature verification given the list of signature
854 /// issuers.
855 ///
856 /// ```
857 /// use sequoia_openpgp as openpgp;
858 /// use openpgp::{KeyHandle, Cert, Result};
859 /// use openpgp::parse::stream::*;
860 /// # fn lookup_cert_by_handle(_: &KeyHandle) -> Result<Cert> {
861 /// # unimplemented!()
862 /// # }
863 ///
864 /// struct Helper { /* ... */ }
865 /// impl VerificationHelper for Helper {
866 /// fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
867 /// let mut certs = Vec::new();
868 /// for id in ids {
869 /// certs.push(lookup_cert_by_handle(id)?);
870 /// }
871 /// Ok(certs)
872 /// }
873 /// // ...
874 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
875 /// # unimplemented!()
876 /// # }
877 /// }
878 /// ```
879 fn get_certs(&mut self, ids: &[crate::KeyHandle]) -> Result<Vec<Cert>>;
880
881 /// Validates the message structure.
882 ///
883 /// This function must validate the message's structure according
884 /// to an application specific policy. For example, it could
885 /// check that the required number of signatures or notarizations
886 /// were confirmed as good, and evaluate every signature's
887 /// validity under a trust model.
888 ///
889 /// A valid OpenPGP message contains one literal data packet with
890 /// optional encryption, signing, and compression layers on top.
891 /// Notably, the message structure contains the results of
892 /// signature verifications. See [`MessageStructure`] for more
893 /// information.
894 ///
895 ///
896 /// When verifying a message, this callback will be called exactly
897 /// once per message *after* the last signature has been verified
898 /// and *before* all the data has been returned. Any error
899 /// returned by this function will abort reading, and the error
900 /// will be propagated via the [`io::Read`] operation.
901 ///
902 /// [`io::Read`]: std::io::Read
903 ///
904 /// After this method was called, [`Verifier::message_processed`]
905 /// and [`Decryptor::message_processed`] return `true`.
906 ///
907 /// [`Verifier::message_processed`]: Verifier::message_processed()
908 /// [`Decryptor::message_processed`]: Decryptor::message_processed()
909 ///
910 /// When verifying a detached signature using the
911 /// [`DetachedVerifier`], this method will be called with a
912 /// [`MessageStructure`] containing exactly one layer, a signature
913 /// group.
914 ///
915 ///
916 /// # Examples
917 ///
918 /// This example demonstrates how to verify that the message is an
919 /// encrypted, optionally compressed, and signed message that has
920 /// at least one valid signature.
921 ///
922 /// ```
923 /// use sequoia_openpgp as openpgp;
924 /// use openpgp::{KeyHandle, Cert, Result};
925 /// use openpgp::parse::stream::*;
926 ///
927 /// struct Helper { /* ... */ }
928 /// impl VerificationHelper for Helper {
929 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
930 /// # unimplemented!();
931 /// # }
932 /// fn check(&mut self, structure: MessageStructure) -> Result<()> {
933 /// for (i, layer) in structure.into_iter().enumerate() {
934 /// match layer {
935 /// MessageLayer::Encryption { .. } if i == 0 => (),
936 /// MessageLayer::Compression { .. } if i == 1 => (),
937 /// MessageLayer::SignatureGroup { ref results }
938 /// if i == 1 || i == 2 =>
939 /// {
940 /// if ! results.iter().any(|r| r.is_ok()) {
941 /// return Err(anyhow::anyhow!(
942 /// "No valid signature"));
943 /// }
944 /// }
945 /// _ => return Err(anyhow::anyhow!(
946 /// "Unexpected message structure")),
947 /// }
948 /// }
949 /// Ok(())
950 /// }
951 /// // ...
952 /// }
953 /// ```
954 fn check(&mut self, structure: MessageStructure) -> Result<()>;
955}
956
957/// Wraps a VerificationHelper and adds a non-functional
958/// DecryptionHelper implementation.
959struct NoDecryptionHelper<V: VerificationHelper> {
960 v: V,
961}
962
963impl<V: VerificationHelper> VerificationHelper for NoDecryptionHelper<V> {
964 fn get_certs(&mut self, ids: &[crate::KeyHandle]) -> Result<Vec<Cert>>
965 {
966 self.v.get_certs(ids)
967 }
968 fn check(&mut self, structure: MessageStructure) -> Result<()>
969 {
970 self.v.check(structure)
971 }
972 fn inspect(&mut self, pp: &PacketParser) -> Result<()> {
973 self.v.inspect(pp)
974 }
975}
976
977impl<V: VerificationHelper> DecryptionHelper for NoDecryptionHelper<V> {
978 fn decrypt(&mut self, _: &[PKESK], _: &[SKESK],
979 _: Option<SymmetricAlgorithm>,
980 _: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
981 -> Result<Option<Cert>>
982 {
983 unreachable!("This is not used for verifications")
984 }
985}
986
987/// Verifies a signed OpenPGP message.
988///
989/// To create a `Verifier`, create a [`VerifierBuilder`] using
990/// [`Parse`], and customize it to your needs.
991///
992/// [`Parse`]: super::Parse
993///
994/// Signature verification requires processing the whole message
995/// first. Therefore, OpenPGP implementations supporting streaming
996/// operations necessarily must output unverified data. This has been
997/// a source of problems in the past. To alleviate this, we buffer
998/// the message first (up to 25 megabytes of net message data by
999/// default, see [`DEFAULT_BUFFER_SIZE`]), and verify the signatures
1000/// if the message fits into our buffer. Nevertheless it is important
1001/// to treat the data as unverified and untrustworthy until you have
1002/// seen a positive verification. See [`Verifier::message_processed`]
1003/// for more information.
1004///
1005/// [`Verifier::message_processed`]: Verifier::message_processed()
1006///
1007/// See [`GoodChecksum`] for what it means for a signature to be
1008/// considered valid.
1009///
1010///
1011/// # Examples
1012///
1013/// ```
1014/// # fn main() -> sequoia_openpgp::Result<()> {
1015/// use std::io::Read;
1016/// use sequoia_openpgp as openpgp;
1017/// use openpgp::{KeyHandle, Cert, Result};
1018/// use openpgp::parse::{Parse, stream::*};
1019/// use openpgp::policy::StandardPolicy;
1020/// # fn lookup_cert_by_handle(_: &KeyHandle) -> Result<Cert> {
1021/// # Cert::from_bytes(
1022/// # &b"-----BEGIN PGP PUBLIC KEY BLOCK-----
1023/// #
1024/// # xjMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
1025/// # lcBgLJrNMVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
1026/// # cGxlLm9yZz7CkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
1027/// # BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
1028/// # 5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
1029/// # CJG8sDyO2FhzDs44BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
1030/// # mKQ5PeqXJbWEtVrUtVJaPwMBCAfCeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
1031/// # fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
1032/// # W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
1033/// # =QetZ
1034/// # -----END PGP PUBLIC KEY BLOCK-----"[..])
1035/// # }
1036///
1037/// let p = &StandardPolicy::new();
1038///
1039/// // This fetches keys and computes the validity of the verification.
1040/// struct Helper {}
1041/// impl VerificationHelper for Helper {
1042/// fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1043/// let mut certs = Vec::new();
1044/// for id in ids {
1045/// certs.push(lookup_cert_by_handle(id)?);
1046/// }
1047/// Ok(certs)
1048/// }
1049///
1050/// fn check(&mut self, structure: MessageStructure) -> Result<()> {
1051/// for (i, layer) in structure.into_iter().enumerate() {
1052/// match layer {
1053/// MessageLayer::Encryption { .. } if i == 0 => (),
1054/// MessageLayer::Compression { .. } if i == 1 => (),
1055/// MessageLayer::SignatureGroup { ref results } => {
1056/// if ! results.iter().any(|r| r.is_ok()) {
1057/// return Err(anyhow::anyhow!(
1058/// "No valid signature"));
1059/// }
1060/// }
1061/// _ => return Err(anyhow::anyhow!(
1062/// "Unexpected message structure")),
1063/// }
1064/// }
1065/// Ok(())
1066/// }
1067/// }
1068///
1069/// let message =
1070/// b"-----BEGIN PGP MESSAGE-----
1071///
1072/// xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1073/// AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1074/// UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1075/// YmAFv/UfO0vYBw==
1076/// =+l94
1077/// -----END PGP MESSAGE-----
1078/// ";
1079///
1080/// let h = Helper {};
1081/// let mut v = VerifierBuilder::from_bytes(&message[..])?
1082/// .with_policy(p, None, h)?;
1083///
1084/// let mut content = Vec::new();
1085/// v.read_to_end(&mut content)?;
1086/// assert_eq!(content, b"Hello World!");
1087/// # Ok(()) }
1088pub struct Verifier<'a, H: VerificationHelper> {
1089 decryptor: Decryptor<'a, NoDecryptionHelper<H>>,
1090}
1091assert_send_and_sync!(Verifier<'_, H> where H: VerificationHelper);
1092
1093/// A builder for `Verifier`.
1094///
1095/// This allows the customization of [`Verifier`], which can
1096/// be built using [`VerifierBuilder::with_policy`].
1097///
1098/// [`VerifierBuilder::with_policy`]: VerifierBuilder::with_policy()
1099pub struct VerifierBuilder<'a> {
1100 message: Box<dyn BufferedReader<Cookie> + 'a>,
1101 buffer_size: usize,
1102 mapping: bool,
1103}
1104assert_send_and_sync!(VerifierBuilder<'_>);
1105
1106impl<'a> Parse<'a, VerifierBuilder<'a>>
1107 for VerifierBuilder<'a>
1108{
1109 fn from_buffered_reader<R>(reader: R) -> Result<VerifierBuilder<'a>>
1110 where
1111 R: BufferedReader<Cookie> + 'a,
1112 {
1113 VerifierBuilder::new(reader)
1114 }
1115}
1116
1117impl<'a> crate::seal::Sealed for VerifierBuilder<'a> {}
1118
1119impl<'a> VerifierBuilder<'a> {
1120 fn new<B>(signatures: B) -> Result<Self>
1121 where B: buffered_reader::BufferedReader<Cookie> + 'a
1122 {
1123 Ok(VerifierBuilder {
1124 message: Box::new(signatures),
1125 buffer_size: DEFAULT_BUFFER_SIZE,
1126 mapping: false,
1127 })
1128 }
1129
1130 /// Changes the amount of buffered data.
1131 ///
1132 /// By default, we buffer up to 25 megabytes of net message data
1133 /// (see [`DEFAULT_BUFFER_SIZE`]). This changes the default.
1134 ///
1135 ///
1136 /// # Examples
1137 ///
1138 /// ```
1139 /// # fn main() -> sequoia_openpgp::Result<()> {
1140 /// use sequoia_openpgp as openpgp;
1141 /// # use openpgp::{KeyHandle, Cert, Result};
1142 /// use openpgp::parse::{Parse, stream::*};
1143 /// use openpgp::policy::StandardPolicy;
1144 ///
1145 /// let p = &StandardPolicy::new();
1146 ///
1147 /// struct Helper {}
1148 /// impl VerificationHelper for Helper {
1149 /// // ...
1150 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1151 /// # Ok(Vec::new())
1152 /// # }
1153 /// #
1154 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1155 /// # Ok(())
1156 /// # }
1157 /// }
1158 ///
1159 /// let message =
1160 /// // ...
1161 /// # &b"-----BEGIN PGP MESSAGE-----
1162 /// #
1163 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1164 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1165 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1166 /// # YmAFv/UfO0vYBw==
1167 /// # =+l94
1168 /// # -----END PGP MESSAGE-----
1169 /// # "[..];
1170 ///
1171 /// let h = Helper {};
1172 /// let mut v = VerifierBuilder::from_bytes(message)?
1173 /// .buffer_size(1 << 12)
1174 /// .with_policy(p, None, h)?;
1175 /// # let _ = v;
1176 /// # Ok(()) }
1177 /// ```
1178 pub fn buffer_size(mut self, size: usize) -> Self {
1179 self.buffer_size = size;
1180 self
1181 }
1182
1183 /// Enables mapping.
1184 ///
1185 /// If mapping is enabled, the packet parser will create a [`Map`]
1186 /// of the packets that can be inspected in
1187 /// [`VerificationHelper::inspect`]. Note that this buffers the
1188 /// packets contents, and is not recommended unless you know that
1189 /// the packets are small.
1190 ///
1191 /// [`Map`]: super::map::Map
1192 ///
1193 /// # Examples
1194 ///
1195 /// ```
1196 /// # fn main() -> sequoia_openpgp::Result<()> {
1197 /// use sequoia_openpgp as openpgp;
1198 /// # use openpgp::{KeyHandle, Cert, Result};
1199 /// use openpgp::parse::{Parse, stream::*};
1200 /// use openpgp::policy::StandardPolicy;
1201 ///
1202 /// let p = &StandardPolicy::new();
1203 ///
1204 /// struct Helper {}
1205 /// impl VerificationHelper for Helper {
1206 /// // ...
1207 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1208 /// # Ok(Vec::new())
1209 /// # }
1210 /// #
1211 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1212 /// # Ok(())
1213 /// # }
1214 /// }
1215 ///
1216 /// let message =
1217 /// // ...
1218 /// # &b"-----BEGIN PGP MESSAGE-----
1219 /// #
1220 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1221 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1222 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1223 /// # YmAFv/UfO0vYBw==
1224 /// # =+l94
1225 /// # -----END PGP MESSAGE-----
1226 /// # "[..];
1227 ///
1228 /// let h = Helper {};
1229 /// let mut v = VerifierBuilder::from_bytes(message)?
1230 /// .mapping(true)
1231 /// .with_policy(p, None, h)?;
1232 /// # let _ = v;
1233 /// # Ok(()) }
1234 /// ```
1235 pub fn mapping(mut self, enabled: bool) -> Self {
1236 self.mapping = enabled;
1237 self
1238 }
1239
1240 /// Creates the `Verifier`.
1241 ///
1242 /// Signature verifications are done under the given `policy` and
1243 /// relative to time `time`, or the current time, if `time` is
1244 /// `None`. `helper` is the [`VerificationHelper`] to use.
1245 ///
1246 ///
1247 /// # Examples
1248 ///
1249 /// ```
1250 /// # fn main() -> sequoia_openpgp::Result<()> {
1251 /// use sequoia_openpgp as openpgp;
1252 /// # use openpgp::{KeyHandle, Cert, Result};
1253 /// use openpgp::parse::{Parse, stream::*};
1254 /// use openpgp::policy::StandardPolicy;
1255 ///
1256 /// let p = &StandardPolicy::new();
1257 ///
1258 /// struct Helper {}
1259 /// impl VerificationHelper for Helper {
1260 /// // ...
1261 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1262 /// # Ok(Vec::new())
1263 /// # }
1264 /// #
1265 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1266 /// # Ok(())
1267 /// # }
1268 /// }
1269 ///
1270 /// let message =
1271 /// // ...
1272 /// # &b"-----BEGIN PGP MESSAGE-----
1273 /// #
1274 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1275 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1276 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1277 /// # YmAFv/UfO0vYBw==
1278 /// # =+l94
1279 /// # -----END PGP MESSAGE-----
1280 /// # "[..];
1281 ///
1282 /// let h = Helper {};
1283 /// let mut v = VerifierBuilder::from_bytes(message)?
1284 /// // Customize the `Verifier` here.
1285 /// .with_policy(p, None, h)?;
1286 /// # let _ = v;
1287 /// # Ok(()) }
1288 /// ```
1289 pub fn with_policy<T, H>(self, policy: &'a dyn Policy, time: T, helper: H)
1290 -> Result<Verifier<'a, H>>
1291 where H: VerificationHelper,
1292 T: Into<Option<time::SystemTime>>,
1293 {
1294 // Do not eagerly map `t` to the current time.
1295 let t = time.into();
1296 Ok(Verifier {
1297 decryptor: Decryptor::from_cookie_reader(
1298 policy,
1299 self.message,
1300 NoDecryptionHelper { v: helper, },
1301 t, Mode::Verify, self.buffer_size, self.mapping, true)?,
1302 })
1303 }
1304}
1305
1306impl<'a, H: VerificationHelper> Verifier<'a, H> {
1307 /// Returns a reference to the helper.
1308 pub fn helper_ref(&self) -> &H {
1309 &self.decryptor.helper_ref().v
1310 }
1311
1312 /// Returns a mutable reference to the helper.
1313 pub fn helper_mut(&mut self) -> &mut H {
1314 &mut self.decryptor.helper_mut().v
1315 }
1316
1317 /// Recovers the helper.
1318 pub fn into_helper(self) -> H {
1319 self.decryptor.into_helper().v
1320 }
1321
1322 /// Returns true if the whole message has been processed and
1323 /// authenticated.
1324 ///
1325 /// If the function returns `true`, the whole message has been
1326 /// processed, the signatures are verified, and the message
1327 /// structure has been passed to [`VerificationHelper::check`].
1328 /// Data read from this `Verifier` using [`io::Read`] has been
1329 /// authenticated.
1330 ///
1331 /// [`io::Read`]: std::io::Read
1332 ///
1333 /// If the function returns `false`, the message did not fit into
1334 /// the internal buffer, and therefore data read from this
1335 /// `Verifier` using [`io::Read`] has **not yet been
1336 /// authenticated**. It is important to treat this data as
1337 /// attacker controlled and not use it until it has been
1338 /// authenticated.
1339 ///
1340 /// # Examples
1341 ///
1342 /// This example demonstrates how to verify a message in a
1343 /// streaming fashion, writing the data to a temporary file and
1344 /// only commit the result once the data is authenticated.
1345 ///
1346 /// ```
1347 /// # fn main() -> sequoia_openpgp::Result<()> {
1348 /// use std::io::{Read, Seek, SeekFrom};
1349 /// use sequoia_openpgp as openpgp;
1350 /// use openpgp::{KeyHandle, Cert, Result};
1351 /// use openpgp::parse::{Parse, stream::*};
1352 /// use openpgp::policy::StandardPolicy;
1353 /// #
1354 /// # // Mock of `tempfile::tempfile`.
1355 /// # mod tempfile {
1356 /// # pub fn tempfile() -> sequoia_openpgp::Result<std::fs::File> {
1357 /// # unimplemented!()
1358 /// # }
1359 /// # }
1360 ///
1361 /// let p = &StandardPolicy::new();
1362 ///
1363 /// // This fetches keys and computes the validity of the verification.
1364 /// struct Helper {}
1365 /// impl VerificationHelper for Helper {
1366 /// // ...
1367 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1368 /// # Ok(Vec::new())
1369 /// # }
1370 /// # fn check(&mut self, _: MessageStructure) -> Result<()> {
1371 /// # Ok(())
1372 /// # }
1373 /// }
1374 ///
1375 /// let mut source =
1376 /// // ...
1377 /// # std::io::Cursor::new(&b"-----BEGIN PGP MESSAGE-----
1378 /// #
1379 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1380 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1381 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1382 /// # YmAFv/UfO0vYBw==
1383 /// # =+l94
1384 /// # -----END PGP MESSAGE-----
1385 /// # "[..]);
1386 ///
1387 /// fn consume(r: &mut dyn Read) -> Result<()> {
1388 /// // ...
1389 /// # let _ = r; Ok(())
1390 /// }
1391 ///
1392 /// let h = Helper {};
1393 /// let mut v = VerifierBuilder::from_reader(&mut source)?
1394 /// .with_policy(p, None, h)?;
1395 ///
1396 /// if v.message_processed() {
1397 /// // The data has been authenticated.
1398 /// consume(&mut v)?;
1399 /// } else {
1400 /// let mut tmp = tempfile::tempfile()?;
1401 /// std::io::copy(&mut v, &mut tmp)?;
1402 ///
1403 /// // If the copy succeeds, the message has been fully
1404 /// // processed and the data has been authenticated.
1405 /// assert!(v.message_processed());
1406 ///
1407 /// // Rewind and consume.
1408 /// tmp.seek(SeekFrom::Start(0))?;
1409 /// consume(&mut tmp)?;
1410 /// }
1411 /// # Ok(()) }
1412 /// ```
1413 pub fn message_processed(&self) -> bool {
1414 self.decryptor.message_processed()
1415 }
1416
1417 /// Returns if we are processing a signed message using the
1418 /// Cleartext Signature Framework.
1419 ///
1420 /// This function returns `None` if we don't know yet (i.e.,
1421 /// before we've started parsing the packets). Once the first
1422 /// packet has been parsed, this will return `Some`.
1423 pub fn processing_csf_message(&self) -> Option<bool> {
1424 self.decryptor.processing_csf_message.clone()
1425 }
1426}
1427
1428impl<'a, H: VerificationHelper> io::Read for Verifier<'a, H> {
1429 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1430 self.decryptor.read(buf)
1431 }
1432}
1433
1434
1435/// Verifies a detached signature.
1436///
1437/// To create a `DetachedVerifier`, create a
1438/// [`DetachedVerifierBuilder`] using [`Parse`], and customize it to
1439/// your needs.
1440///
1441/// [`Parse`]: super::Parse
1442///
1443/// See [`GoodChecksum`] for what it means for a signature to be
1444/// considered valid. When the signature(s) are processed,
1445/// [`VerificationHelper::check`] will be called with a
1446/// [`MessageStructure`] containing exactly one layer, a signature
1447/// group.
1448///
1449///
1450/// # Examples
1451///
1452/// ```
1453/// # fn main() -> sequoia_openpgp::Result<()> {
1454/// use std::io::{self, Read};
1455/// use sequoia_openpgp as openpgp;
1456/// use openpgp::{KeyHandle, Cert, Result};
1457/// use openpgp::parse::{Parse, stream::*};
1458/// use sequoia_openpgp::policy::StandardPolicy;
1459///
1460/// let p = &StandardPolicy::new();
1461///
1462/// // This fetches keys and computes the validity of the verification.
1463/// struct Helper {}
1464/// impl VerificationHelper for Helper {
1465/// fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1466/// Ok(Vec::new()) // Feed the Certs to the verifier here...
1467/// }
1468/// fn check(&mut self, structure: MessageStructure) -> Result<()> {
1469/// Ok(()) // Implement your verification policy here.
1470/// }
1471/// }
1472///
1473/// let signature =
1474/// b"-----BEGIN PGP SIGNATURE-----
1475///
1476/// wnUEABYKACcFglt+z/EWoQSOjDP6RiYzeXbZeXgGnAw0jdgsGQmQBpwMNI3YLBkA
1477/// AHmUAP9mpj2wV0/ekDuzxZrPQ0bnobFVaxZGg7YzdlksSOERrwEA6v6czXQjKcv2
1478/// KOwGTamb+ajTLQ3YRG9lh+ZYIXynvwE=
1479/// =IJ29
1480/// -----END PGP SIGNATURE-----";
1481///
1482/// let data = b"Hello World!";
1483/// let h = Helper {};
1484/// let mut v = DetachedVerifierBuilder::from_bytes(&signature[..])?
1485/// .with_policy(p, None, h)?;
1486/// v.verify_bytes(data)?;
1487/// # Ok(()) }
1488pub struct DetachedVerifier<'a, H: VerificationHelper> {
1489 decryptor: Decryptor<'a, NoDecryptionHelper<H>>,
1490}
1491assert_send_and_sync!(DetachedVerifier<'_, H> where H: VerificationHelper);
1492
1493/// A builder for `DetachedVerifier`.
1494///
1495/// This allows the customization of [`DetachedVerifier`], which can
1496/// be built using [`DetachedVerifierBuilder::with_policy`].
1497///
1498/// [`DetachedVerifierBuilder::with_policy`]: DetachedVerifierBuilder::with_policy()
1499pub struct DetachedVerifierBuilder<'a> {
1500 signatures: Box<dyn BufferedReader<Cookie> + 'a>,
1501 mapping: bool,
1502}
1503assert_send_and_sync!(DetachedVerifierBuilder<'_>);
1504
1505impl<'a> Parse<'a, DetachedVerifierBuilder<'a>>
1506 for DetachedVerifierBuilder<'a>
1507{
1508 fn from_buffered_reader<R>(reader: R) -> Result<DetachedVerifierBuilder<'a>>
1509 where
1510 R: BufferedReader<Cookie> + 'a,
1511 {
1512 DetachedVerifierBuilder::new(reader)
1513 }
1514}
1515
1516impl<'a> crate::seal::Sealed for DetachedVerifierBuilder<'a> {}
1517
1518impl<'a> DetachedVerifierBuilder<'a> {
1519 fn new<B>(signatures: B) -> Result<Self>
1520 where B: buffered_reader::BufferedReader<Cookie> + 'a
1521 {
1522 Ok(DetachedVerifierBuilder {
1523 signatures: Box::new(signatures),
1524 mapping: false,
1525 })
1526 }
1527
1528 /// Enables mapping.
1529 ///
1530 /// If mapping is enabled, the packet parser will create a [`Map`]
1531 /// of the packets that can be inspected in
1532 /// [`VerificationHelper::inspect`]. Note that this buffers the
1533 /// packets contents, and is not recommended unless you know that
1534 /// the packets are small.
1535 ///
1536 /// [`Map`]: super::map::Map
1537 ///
1538 /// # Examples
1539 ///
1540 /// ```
1541 /// # fn main() -> sequoia_openpgp::Result<()> {
1542 /// use sequoia_openpgp as openpgp;
1543 /// # use openpgp::{KeyHandle, Cert, Result};
1544 /// use openpgp::parse::{Parse, stream::*};
1545 /// use openpgp::policy::StandardPolicy;
1546 ///
1547 /// let p = &StandardPolicy::new();
1548 ///
1549 /// struct Helper {}
1550 /// impl VerificationHelper for Helper {
1551 /// // ...
1552 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1553 /// # Ok(Vec::new())
1554 /// # }
1555 /// #
1556 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1557 /// # Ok(())
1558 /// # }
1559 /// }
1560 ///
1561 /// let signature =
1562 /// // ...
1563 /// # b"-----BEGIN PGP SIGNATURE-----
1564 /// #
1565 /// # wnUEABYKACcFglt+z/EWoQSOjDP6RiYzeXbZeXgGnAw0jdgsGQmQBpwMNI3YLBkA
1566 /// # AHmUAP9mpj2wV0/ekDuzxZrPQ0bnobFVaxZGg7YzdlksSOERrwEA6v6czXQjKcv2
1567 /// # KOwGTamb+ajTLQ3YRG9lh+ZYIXynvwE=
1568 /// # =IJ29
1569 /// # -----END PGP SIGNATURE-----";
1570 ///
1571 /// let h = Helper {};
1572 /// let mut v = DetachedVerifierBuilder::from_bytes(&signature[..])?
1573 /// .mapping(true)
1574 /// .with_policy(p, None, h)?;
1575 /// # let _ = v;
1576 /// # Ok(()) }
1577 /// ```
1578 pub fn mapping(mut self, enabled: bool) -> Self {
1579 self.mapping = enabled;
1580 self
1581 }
1582
1583 /// Creates the `DetachedVerifier`.
1584 ///
1585 /// Signature verifications are done under the given `policy` and
1586 /// relative to time `time`, or the current time, if `time` is
1587 /// `None`. `helper` is the [`VerificationHelper`] to use.
1588 /// [`VerificationHelper::check`] will be called with a
1589 /// [`MessageStructure`] containing exactly one layer, a signature
1590 /// group.
1591 ///
1592 ///
1593 /// # Examples
1594 ///
1595 /// ```
1596 /// # fn main() -> sequoia_openpgp::Result<()> {
1597 /// use sequoia_openpgp as openpgp;
1598 /// # use openpgp::{KeyHandle, Cert, Result};
1599 /// use openpgp::parse::{Parse, stream::*};
1600 /// use openpgp::policy::StandardPolicy;
1601 ///
1602 /// let p = &StandardPolicy::new();
1603 ///
1604 /// struct Helper {}
1605 /// impl VerificationHelper for Helper {
1606 /// // ...
1607 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1608 /// # Ok(Vec::new())
1609 /// # }
1610 /// #
1611 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1612 /// # Ok(())
1613 /// # }
1614 /// }
1615 ///
1616 /// let signature =
1617 /// // ...
1618 /// # b"-----BEGIN PGP SIGNATURE-----
1619 /// #
1620 /// # wnUEABYKACcFglt+z/EWoQSOjDP6RiYzeXbZeXgGnAw0jdgsGQmQBpwMNI3YLBkA
1621 /// # AHmUAP9mpj2wV0/ekDuzxZrPQ0bnobFVaxZGg7YzdlksSOERrwEA6v6czXQjKcv2
1622 /// # KOwGTamb+ajTLQ3YRG9lh+ZYIXynvwE=
1623 /// # =IJ29
1624 /// # -----END PGP SIGNATURE-----";
1625 ///
1626 /// let h = Helper {};
1627 /// let mut v = DetachedVerifierBuilder::from_bytes(&signature[..])?
1628 /// // Customize the `DetachedVerifier` here.
1629 /// .with_policy(p, None, h)?;
1630 /// # let _ = v;
1631 /// # Ok(()) }
1632 /// ```
1633 pub fn with_policy<T, H>(self, policy: &'a dyn Policy, time: T, helper: H)
1634 -> Result<DetachedVerifier<'a, H>>
1635 where H: VerificationHelper,
1636 T: Into<Option<time::SystemTime>>,
1637 {
1638 // Do not eagerly map `t` to the current time.
1639 let t = time.into();
1640 Ok(DetachedVerifier {
1641 decryptor: Decryptor::from_cookie_reader(
1642 policy,
1643 self.signatures,
1644 NoDecryptionHelper { v: helper, },
1645 t, Mode::VerifyDetached, 0, self.mapping, false)?,
1646 })
1647 }
1648}
1649
1650impl<'a, H: VerificationHelper> DetachedVerifier<'a, H> {
1651 /// Verifies the given data.
1652 pub fn verify_buffered_reader<R>(&mut self, reader: R)
1653 -> Result<()>
1654 where
1655 R: BufferedReader<Cookie>,
1656 {
1657 self.decryptor.verify_detached(reader.into_boxed())
1658 }
1659
1660 /// Verifies the given data.
1661 pub fn verify_reader<R: io::Read + Send + Sync>(&mut self, reader: R) -> Result<()> {
1662 self.verify_buffered_reader(buffered_reader::Generic::with_cookie(
1663 reader, None, Default::default()))
1664 }
1665
1666 /// Verifies the given data.
1667 pub fn verify_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
1668 self.verify_buffered_reader(buffered_reader::File::with_cookie(
1669 path, Default::default())?)
1670 }
1671
1672 /// Verifies the given data.
1673 pub fn verify_bytes<B: AsRef<[u8]>>(&mut self, buf: B) -> Result<()> {
1674 self.verify_buffered_reader(buffered_reader::Memory::with_cookie(
1675 buf.as_ref(), Default::default()))
1676 }
1677
1678 /// Returns a reference to the helper.
1679 pub fn helper_ref(&self) -> &H {
1680 &self.decryptor.helper_ref().v
1681 }
1682
1683 /// Returns a mutable reference to the helper.
1684 pub fn helper_mut(&mut self) -> &mut H {
1685 &mut self.decryptor.helper_mut().v
1686 }
1687
1688 /// Recovers the helper.
1689 pub fn into_helper(self) -> H {
1690 self.decryptor.into_helper().v
1691 }
1692}
1693
1694
1695/// Modes of operation for the Decryptor.
1696#[derive(Debug, PartialEq, Eq)]
1697enum Mode {
1698 Decrypt,
1699 Verify,
1700 VerifyDetached,
1701}
1702
1703/// Decrypts and verifies an encrypted and optionally signed OpenPGP
1704/// message.
1705///
1706/// To create a `Decryptor`, create a [`DecryptorBuilder`] using
1707/// [`Parse`], and customize it to your needs.
1708///
1709/// [`Parse`]: super::Parse
1710///
1711/// Signature verification and detection of ciphertext tampering
1712/// requires processing the whole message first. Therefore, OpenPGP
1713/// implementations supporting streaming operations necessarily must
1714/// output unverified data. This has been a source of problems in the
1715/// past. To alleviate this, we buffer the message first (up to 25
1716/// megabytes of net message data by default, see
1717/// [`DEFAULT_BUFFER_SIZE`]), and verify the signatures if the message
1718/// fits into our buffer. Nevertheless it is important to treat the
1719/// data as unverified and untrustworthy until you have seen a
1720/// positive verification. See [`Decryptor::message_processed`] for
1721/// more information.
1722///
1723/// [`Decryptor::message_processed`]: Decryptor::message_processed()
1724///
1725/// See [`GoodChecksum`] for what it means for a signature to be
1726/// considered valid.
1727///
1728///
1729/// # Examples
1730///
1731/// ```
1732/// # fn main() -> sequoia_openpgp::Result<()> {
1733/// use std::io::Read;
1734/// use sequoia_openpgp as openpgp;
1735/// use openpgp::crypto::SessionKey;
1736/// use openpgp::types::SymmetricAlgorithm;
1737/// use openpgp::{KeyID, Cert, Result, packet::{Key, PKESK, SKESK}};
1738/// use openpgp::parse::{Parse, stream::*};
1739/// use sequoia_openpgp::policy::StandardPolicy;
1740///
1741/// let p = &StandardPolicy::new();
1742///
1743/// // This fetches keys and computes the validity of the verification.
1744/// struct Helper {}
1745/// impl VerificationHelper for Helper {
1746/// fn get_certs(&mut self, _ids: &[openpgp::KeyHandle]) -> Result<Vec<Cert>> {
1747/// Ok(Vec::new()) // Feed the Certs to the verifier here...
1748/// }
1749/// fn check(&mut self, structure: MessageStructure) -> Result<()> {
1750/// Ok(()) // Implement your verification policy here.
1751/// }
1752/// }
1753/// impl DecryptionHelper for Helper {
1754/// fn decrypt(&mut self, _: &[PKESK], skesks: &[SKESK],
1755/// _sym_algo: Option<SymmetricAlgorithm>,
1756/// decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
1757/// -> Result<Option<Cert>>
1758/// {
1759/// skesks[0].decrypt(&"streng geheim".into())
1760/// .map(|(algo, session_key)| decrypt(algo, &session_key));
1761/// Ok(None)
1762/// }
1763/// }
1764///
1765/// let message =
1766/// b"-----BEGIN PGP MESSAGE-----
1767///
1768/// wy4ECQMIY5Zs8RerVcXp85UgoUKjKkevNPX3WfcS5eb7rkT9I6kw6N2eEc5PJUDh
1769/// 0j0B9mnPKeIwhp2kBHpLX/en6RfNqYauX9eSeia7aqsd/AOLbO9WMCLZS5d2LTxN
1770/// rwwb8Aggyukj13Mi0FF5
1771/// =OB/8
1772/// -----END PGP MESSAGE-----";
1773///
1774/// let h = Helper {};
1775/// let mut v = DecryptorBuilder::from_bytes(&message[..])?
1776/// .with_policy(p, None, h)?;
1777///
1778/// let mut content = Vec::new();
1779/// v.read_to_end(&mut content)?;
1780/// assert_eq!(content, b"Hello World!");
1781/// # Ok(()) }
1782pub struct Decryptor<'a, H: VerificationHelper + DecryptionHelper> {
1783 helper: H,
1784
1785 /// The issuers collected from OPS and Signature packets.
1786 issuers: Vec<KeyHandle>,
1787
1788 /// The certificates used for signature verification.
1789 certs: Vec<Cert>,
1790
1791 oppr: Option<PacketParserResult<'a>>,
1792 identity: Option<Fingerprint>,
1793 structure: IMessageStructure,
1794
1795 /// We want to hold back some data until the signatures checked
1796 /// out. We buffer this here, cursor is the offset of unread
1797 /// bytes in the buffer.
1798 buffer_size: usize,
1799 reserve: Option<Protected>,
1800 cursor: usize,
1801
1802 /// The mode of operation.
1803 mode: Mode,
1804
1805 /// Whether we are actually processing a cleartext signature
1806 /// framework message. If so, we need to tweak our behavior a
1807 /// bit.
1808 processing_csf_message: Option<bool>,
1809
1810 /// Signature verification relative to this time.
1811 ///
1812 /// This is needed for checking the signature's liveness.
1813 ///
1814 /// We want the same semantics as `Subpacket::signature_alive`.
1815 /// Specifically, when using the current time, we want to tolerate
1816 /// some clock skew, but when using some specific time, we don't.
1817 /// (See `Subpacket::signature_alive` for an explanation.)
1818 ///
1819 /// These semantics can be realized by making `time` an
1820 /// `Option<time::SystemTime>` and passing that as is to
1821 /// `Subpacket::signature_alive`. But that approach has two new
1822 /// problems. First, if we are told to use the current time, then
1823 /// we want to use the time at which the Verifier was
1824 /// instantiated, not the time at which we call
1825 /// `Subpacket::signature_alive`. Second, if we call
1826 /// `Subpacket::signature_alive` multiple times, they should all
1827 /// use the same time. To work around these issues, when a
1828 /// Verifier is instantiated, we evaluate `time` and we record how
1829 /// much we want to tolerate clock skew in the same way as
1830 /// `Subpacket::signature_alive`.
1831 time: time::SystemTime,
1832 clock_skew_tolerance: time::Duration,
1833
1834 policy: &'a dyn Policy,
1835}
1836assert_send_and_sync!(Decryptor<'_, H>
1837 where H: VerificationHelper + DecryptionHelper);
1838
1839/// A builder for `Decryptor`.
1840///
1841/// This allows the customization of [`Decryptor`], which can
1842/// be built using [`DecryptorBuilder::with_policy`].
1843///
1844/// [`DecryptorBuilder::with_policy`]: DecryptorBuilder::with_policy()
1845pub struct DecryptorBuilder<'a> {
1846 message: Box<dyn BufferedReader<Cookie> + 'a>,
1847 buffer_size: usize,
1848 mapping: bool,
1849}
1850assert_send_and_sync!(DecryptorBuilder<'_>);
1851
1852impl<'a> Parse<'a, DecryptorBuilder<'a>>
1853 for DecryptorBuilder<'a>
1854{
1855 fn from_buffered_reader<R>(reader: R) -> Result<DecryptorBuilder<'a>>
1856 where
1857 R: BufferedReader<Cookie> + 'a,
1858 {
1859 DecryptorBuilder::new(reader)
1860 }
1861}
1862
1863impl<'a> crate::seal::Sealed for DecryptorBuilder<'a> {}
1864
1865impl<'a> DecryptorBuilder<'a> {
1866 fn new<B>(signatures: B) -> Result<Self>
1867 where B: buffered_reader::BufferedReader<Cookie> + 'a
1868 {
1869 Ok(DecryptorBuilder {
1870 message: Box::new(signatures),
1871 buffer_size: DEFAULT_BUFFER_SIZE,
1872 mapping: false,
1873 })
1874 }
1875
1876 /// Changes the amount of buffered data.
1877 ///
1878 /// By default, we buffer up to 25 megabytes of net message data
1879 /// (see [`DEFAULT_BUFFER_SIZE`]). This changes the default.
1880 ///
1881 ///
1882 /// # Examples
1883 ///
1884 /// ```
1885 /// # fn main() -> sequoia_openpgp::Result<()> {
1886 /// use sequoia_openpgp as openpgp;
1887 /// # use openpgp::{*, crypto::*, packet::prelude::*, types::*};
1888 /// use openpgp::parse::{Parse, stream::*};
1889 /// use openpgp::policy::StandardPolicy;
1890 ///
1891 /// let p = &StandardPolicy::new();
1892 ///
1893 /// struct Helper {}
1894 /// impl VerificationHelper for Helper {
1895 /// // ...
1896 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1897 /// # Ok(Vec::new())
1898 /// # }
1899 /// #
1900 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1901 /// # Ok(())
1902 /// # }
1903 /// }
1904 /// impl DecryptionHelper for Helper {
1905 /// // ...
1906 /// # fn decrypt(&mut self, _: &[PKESK], skesks: &[SKESK],
1907 /// # _sym_algo: Option<SymmetricAlgorithm>,
1908 /// # decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
1909 /// # -> Result<Option<Cert>>
1910 /// # {
1911 /// # Ok(None)
1912 /// # }
1913 /// }
1914 ///
1915 /// let message =
1916 /// // ...
1917 /// # &b"-----BEGIN PGP MESSAGE-----
1918 /// #
1919 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1920 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1921 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1922 /// # YmAFv/UfO0vYBw==
1923 /// # =+l94
1924 /// # -----END PGP MESSAGE-----
1925 /// # "[..];
1926 ///
1927 /// let h = Helper {};
1928 /// let mut v = DecryptorBuilder::from_bytes(message)?
1929 /// .buffer_size(1 << 12)
1930 /// .with_policy(p, None, h)?;
1931 /// # let _ = v;
1932 /// # Ok(()) }
1933 /// ```
1934 pub fn buffer_size(mut self, size: usize) -> Self {
1935 self.buffer_size = size;
1936 self
1937 }
1938
1939 /// Enables mapping.
1940 ///
1941 /// If mapping is enabled, the packet parser will create a [`Map`]
1942 /// of the packets that can be inspected in
1943 /// [`VerificationHelper::inspect`]. Note that this buffers the
1944 /// packets contents, and is not recommended unless you know that
1945 /// the packets are small.
1946 ///
1947 /// [`Map`]: super::map::Map
1948 ///
1949 /// # Examples
1950 ///
1951 /// ```
1952 /// # fn main() -> sequoia_openpgp::Result<()> {
1953 /// use sequoia_openpgp as openpgp;
1954 /// # use openpgp::{*, crypto::*, packet::prelude::*, types::*};
1955 /// use openpgp::parse::{Parse, stream::*};
1956 /// use openpgp::policy::StandardPolicy;
1957 ///
1958 /// let p = &StandardPolicy::new();
1959 ///
1960 /// struct Helper {}
1961 /// impl VerificationHelper for Helper {
1962 /// // ...
1963 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
1964 /// # Ok(Vec::new())
1965 /// # }
1966 /// #
1967 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
1968 /// # Ok(())
1969 /// # }
1970 /// }
1971 /// impl DecryptionHelper for Helper {
1972 /// // ...
1973 /// # fn decrypt(&mut self, _: &[PKESK], skesks: &[SKESK],
1974 /// # _sym_algo: Option<SymmetricAlgorithm>,
1975 /// # decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
1976 /// # -> Result<Option<Cert>>
1977 /// # {
1978 /// # Ok(None)
1979 /// # }
1980 /// }
1981 ///
1982 /// let message =
1983 /// // ...
1984 /// # &b"-----BEGIN PGP MESSAGE-----
1985 /// #
1986 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
1987 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
1988 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
1989 /// # YmAFv/UfO0vYBw==
1990 /// # =+l94
1991 /// # -----END PGP MESSAGE-----
1992 /// # "[..];
1993 ///
1994 /// let h = Helper {};
1995 /// let mut v = DecryptorBuilder::from_bytes(message)?
1996 /// .mapping(true)
1997 /// .with_policy(p, None, h)?;
1998 /// # let _ = v;
1999 /// # Ok(()) }
2000 /// ```
2001 pub fn mapping(mut self, enabled: bool) -> Self {
2002 self.mapping = enabled;
2003 self
2004 }
2005
2006 /// Creates the `Decryptor`.
2007 ///
2008 /// Signature verifications are done under the given `policy` and
2009 /// relative to time `time`, or the current time, if `time` is
2010 /// `None`. `helper` is the [`VerificationHelper`] and
2011 /// [`DecryptionHelper`] to use.
2012 ///
2013 ///
2014 /// # Examples
2015 ///
2016 /// ```
2017 /// # fn main() -> sequoia_openpgp::Result<()> {
2018 /// use sequoia_openpgp as openpgp;
2019 /// # use openpgp::{*, crypto::*, packet::prelude::*, types::*};
2020 /// use openpgp::parse::{Parse, stream::*};
2021 /// use openpgp::policy::StandardPolicy;
2022 ///
2023 /// let p = &StandardPolicy::new();
2024 ///
2025 /// struct Helper {}
2026 /// impl VerificationHelper for Helper {
2027 /// // ...
2028 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
2029 /// # Ok(Vec::new())
2030 /// # }
2031 /// #
2032 /// # fn check(&mut self, structure: MessageStructure) -> Result<()> {
2033 /// # Ok(())
2034 /// # }
2035 /// }
2036 /// impl DecryptionHelper for Helper {
2037 /// // ...
2038 /// # fn decrypt(&mut self, _: &[PKESK], skesks: &[SKESK],
2039 /// # _sym_algo: Option<SymmetricAlgorithm>,
2040 /// # decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
2041 /// # -> Result<Option<Cert>>
2042 /// # {
2043 /// # Ok(None)
2044 /// # }
2045 /// }
2046 ///
2047 /// let message =
2048 /// // ...
2049 /// # &b"-----BEGIN PGP MESSAGE-----
2050 /// #
2051 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
2052 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
2053 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
2054 /// # YmAFv/UfO0vYBw==
2055 /// # =+l94
2056 /// # -----END PGP MESSAGE-----
2057 /// # "[..];
2058 ///
2059 /// let h = Helper {};
2060 /// let mut v = DecryptorBuilder::from_bytes(message)?
2061 /// // Customize the `Decryptor` here.
2062 /// .with_policy(p, None, h)?;
2063 /// # let _ = v;
2064 /// # Ok(()) }
2065 /// ```
2066 pub fn with_policy<T, H>(self, policy: &'a dyn Policy, time: T, helper: H)
2067 -> Result<Decryptor<'a, H>>
2068 where H: VerificationHelper + DecryptionHelper,
2069 T: Into<Option<time::SystemTime>>,
2070 {
2071 // Do not eagerly map `t` to the current time.
2072 let t = time.into();
2073 Decryptor::from_cookie_reader(
2074 policy,
2075 self.message,
2076 helper,
2077 t, Mode::Decrypt, self.buffer_size, self.mapping, false)
2078 }
2079}
2080
2081/// Helper for decrypting messages.
2082///
2083/// This trait abstracts over session key decryption. It allows us to
2084/// provide the [`Decryptor`] without imposing any policy on how the
2085/// session key is decrypted.
2086///
2087pub trait DecryptionHelper {
2088 /// Decrypts the message.
2089 ///
2090 /// This function is called with every [`PKESK`] and [`SKESK`]
2091 /// packet found in the message. The implementation must decrypt
2092 /// the symmetric algorithm and session key from one of the
2093 /// [`PKESK`] packets, the [`SKESK`] packets, or retrieve it from
2094 /// a cache, and then call `decrypt` with the symmetric algorithm
2095 /// and session key. `decrypt` returns `true` if the decryption
2096 /// was successful.
2097 ///
2098 /// [`PKESK`]: crate::packet::PKESK
2099 /// [`SKESK`]: crate::packet::SKESK
2100 ///
2101 /// If a symmetric algorithm is given, it should be passed on to
2102 /// [`PKESK::decrypt`].
2103 ///
2104 /// [`PKESK::decrypt`]: crate::packet::PKESK#method.decrypt
2105 ///
2106 /// If the message is decrypted using a [`PKESK`] packet, then the
2107 /// fingerprint of the certificate containing the encryption
2108 /// subkey should be returned. This is used in conjunction with
2109 /// the intended recipient subpacket (see [Intended Recipient
2110 /// Fingerprint]) to prevent [*Surreptitious Forwarding*].
2111 ///
2112 /// [Intended Recipient Fingerprint]: https://www.rfc-editor.org/rfc/rfc9580.html#name-intended-recipient-fingerpr
2113 /// [*Surreptitious Forwarding*]: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html
2114 ///
2115 /// This method will be called once per encryption layer.
2116 ///
2117 /// # Examples
2118 ///
2119 /// This example demonstrates how to decrypt a message using local
2120 /// keys (i.e. excluding remote keys like smart cards) while
2121 /// maximizing convenience for the user.
2122 ///
2123 /// ```
2124 /// use sequoia_openpgp as openpgp;
2125 /// use openpgp::{Cert, Fingerprint, KeyHandle, KeyID, Result};
2126 /// use openpgp::crypto::SessionKey;
2127 /// use openpgp::types::SymmetricAlgorithm;
2128 /// use openpgp::packet::{PKESK, SKESK};
2129 /// # use openpgp::packet::{Key, key::*};
2130 /// use openpgp::parse::stream::*;
2131 /// # fn lookup_cache(_: &[PKESK], _: &[SKESK])
2132 /// # -> Option<(Option<Cert>, Option<SymmetricAlgorithm>, SessionKey)> {
2133 /// # unimplemented!()
2134 /// # }
2135 /// # fn lookup_key(_: Option<KeyHandle>)
2136 /// # -> Option<(Cert, Key<SecretParts, UnspecifiedRole>)> {
2137 /// # unimplemented!()
2138 /// # }
2139 /// # fn all_keys() -> impl Iterator<Item = (Cert, Key<SecretParts, UnspecifiedRole>)> {
2140 /// # Vec::new().into_iter()
2141 /// # }
2142 ///
2143 /// struct Helper { /* ... */ }
2144 /// impl DecryptionHelper for Helper {
2145 /// fn decrypt(&mut self, pkesks: &[PKESK], skesks: &[SKESK],
2146 /// sym_algo: Option<SymmetricAlgorithm>,
2147 /// decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
2148 /// -> Result<Option<Cert>>
2149 /// {
2150 /// // Try to decrypt, from the most convenient method to the
2151 /// // least convenient one.
2152 ///
2153 /// // First, see if it is in the cache.
2154 /// if let Some((cert, algo, sk)) = lookup_cache(pkesks, skesks) {
2155 /// if decrypt(algo, &sk) {
2156 /// return Ok(cert);
2157 /// }
2158 /// }
2159 ///
2160 /// // Second, we try those keys that we can use without
2161 /// // prompting for a password.
2162 /// for pkesk in pkesks {
2163 /// if let Some((cert, key)) = lookup_key(pkesk.recipient()) {
2164 /// if ! key.secret().is_encrypted() {
2165 /// let mut keypair = key.clone().into_keypair()?;
2166 /// if pkesk.decrypt(&mut keypair, sym_algo)
2167 /// .map(|(algo, sk)| decrypt(algo, &sk))
2168 /// .unwrap_or(false)
2169 /// {
2170 /// return Ok(Some(cert));
2171 /// }
2172 /// }
2173 /// }
2174 /// }
2175 ///
2176 /// // Third, we try to decrypt PKESK packets with
2177 /// // wildcard recipients using those keys that we can
2178 /// // use without prompting for a password.
2179 /// for pkesk in pkesks.iter().filter(
2180 /// |p| p.recipient().is_none())
2181 /// {
2182 /// for (cert, key) in all_keys() {
2183 /// if ! key.secret().is_encrypted() {
2184 /// let mut keypair = key.clone().into_keypair()?;
2185 /// if pkesk.decrypt(&mut keypair, sym_algo)
2186 /// .map(|(algo, sk)| decrypt(algo, &sk))
2187 /// .unwrap_or(false)
2188 /// {
2189 /// return Ok(Some(cert));
2190 /// }
2191 /// }
2192 /// }
2193 /// }
2194 ///
2195 /// // Fourth, we try to decrypt all PKESK packets that we
2196 /// // need encrypted keys for.
2197 /// // [...]
2198 ///
2199 /// // Fifth, we try to decrypt all PKESK packets with
2200 /// // wildcard recipients using encrypted keys.
2201 /// // [...]
2202 ///
2203 /// // At this point, we have exhausted our options at
2204 /// // decrypting the PKESK packets.
2205 /// if skesks.is_empty() {
2206 /// return
2207 /// Err(anyhow::anyhow!("No key to decrypt message"));
2208 /// }
2209 ///
2210 /// // Finally, try to decrypt using the SKESKs.
2211 /// loop {
2212 /// let password = // Prompt for a password.
2213 /// # "".into();
2214 ///
2215 /// for skesk in skesks {
2216 /// if skesk.decrypt(&password)
2217 /// .map(|(algo, sk)| decrypt(algo, &sk))
2218 /// .unwrap_or(false)
2219 /// {
2220 /// return Ok(None);
2221 /// }
2222 /// }
2223 ///
2224 /// eprintln!("Bad password.");
2225 /// }
2226 /// }
2227 /// }
2228 /// ```
2229 fn decrypt(&mut self, pkesks: &[PKESK], skesks: &[SKESK],
2230 sym_algo: Option<SymmetricAlgorithm>,
2231 decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
2232 -> Result<Option<Cert>>;
2233}
2234
2235impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
2236 /// Returns a reference to the helper.
2237 pub fn helper_ref(&self) -> &H {
2238 &self.helper
2239 }
2240
2241 /// Returns a mutable reference to the helper.
2242 pub fn helper_mut(&mut self) -> &mut H {
2243 &mut self.helper
2244 }
2245
2246 /// Recovers the helper.
2247 pub fn into_helper(self) -> H {
2248 self.helper
2249 }
2250
2251 /// Returns true if the whole message has been processed and
2252 /// authenticated.
2253 ///
2254 /// If the function returns `true`, the whole message has been
2255 /// processed, the signatures are verified, and the message
2256 /// structure has been passed to [`VerificationHelper::check`].
2257 /// Data read from this `Verifier` using [`io::Read`] has been
2258 /// authenticated.
2259 ///
2260 /// [`io::Read`]: std::io::Read
2261 ///
2262 /// If the function returns `false`, the message did not fit into
2263 /// the internal buffer, and therefore data read from this
2264 /// `Verifier` using [`io::Read`] has **not yet been
2265 /// authenticated**. It is important to treat this data as
2266 /// attacker controlled and not use it until it has been
2267 /// authenticated.
2268 ///
2269 /// # Examples
2270 ///
2271 /// This example demonstrates how to verify a message in a
2272 /// streaming fashion, writing the data to a temporary file and
2273 /// only commit the result once the data is authenticated.
2274 ///
2275 /// ```
2276 /// # fn main() -> sequoia_openpgp::Result<()> {
2277 /// use std::io::{Read, Seek, SeekFrom};
2278 /// use sequoia_openpgp as openpgp;
2279 /// use openpgp::{KeyHandle, Cert, Result};
2280 /// use openpgp::parse::{Parse, stream::*};
2281 /// use openpgp::policy::StandardPolicy;
2282 /// #
2283 /// # // Mock of `tempfile::tempfile`.
2284 /// # mod tempfile {
2285 /// # pub fn tempfile() -> sequoia_openpgp::Result<std::fs::File> {
2286 /// # unimplemented!()
2287 /// # }
2288 /// # }
2289 ///
2290 /// let p = &StandardPolicy::new();
2291 ///
2292 /// // This fetches keys and computes the validity of the verification.
2293 /// struct Helper {}
2294 /// impl VerificationHelper for Helper {
2295 /// // ...
2296 /// # fn get_certs(&mut self, ids: &[KeyHandle]) -> Result<Vec<Cert>> {
2297 /// # Ok(Vec::new())
2298 /// # }
2299 /// # fn check(&mut self, _: MessageStructure) -> Result<()> {
2300 /// # Ok(())
2301 /// # }
2302 /// }
2303 ///
2304 /// let mut source =
2305 /// // ...
2306 /// # std::io::Cursor::new(&b"-----BEGIN PGP MESSAGE-----
2307 /// #
2308 /// # xA0DAAoW+zdR8Vh9rvEByxJiAAAAAABIZWxsbyBXb3JsZCHCdQQAFgoABgWCXrLl
2309 /// # AQAhCRD7N1HxWH2u8RYhBDnRAKtn1b2MBAECBfs3UfFYfa7xRUsBAJaxkU/RCstf
2310 /// # UD7TM30IorO1Mb9cDa/hPRxyzipulT55AQDN1m9LMqi9yJDjHNHwYYVwxDcg+pLY
2311 /// # YmAFv/UfO0vYBw==
2312 /// # =+l94
2313 /// # -----END PGP MESSAGE-----
2314 /// # "[..]);
2315 ///
2316 /// fn consume(r: &mut dyn Read) -> Result<()> {
2317 /// // ...
2318 /// # let _ = r; Ok(())
2319 /// }
2320 ///
2321 /// let h = Helper {};
2322 /// let mut v = VerifierBuilder::from_reader(&mut source)?
2323 /// .with_policy(p, None, h)?;
2324 ///
2325 /// if v.message_processed() {
2326 /// // The data has been authenticated.
2327 /// consume(&mut v)?;
2328 /// } else {
2329 /// let mut tmp = tempfile::tempfile()?;
2330 /// std::io::copy(&mut v, &mut tmp)?;
2331 ///
2332 /// // If the copy succeeds, the message has been fully
2333 /// // processed and the data has been authenticated.
2334 /// assert!(v.message_processed());
2335 ///
2336 /// // Rewind and consume.
2337 /// tmp.seek(SeekFrom::Start(0))?;
2338 /// consume(&mut tmp)?;
2339 /// }
2340 /// # Ok(()) }
2341 /// ```
2342 pub fn message_processed(&self) -> bool {
2343 // oppr is only None after we've processed the packet sequence.
2344 self.oppr.is_none()
2345 }
2346
2347 /// Creates the `Decryptor`, and buffers the data up to `buffer_size`.
2348 fn from_cookie_reader<T>(
2349 policy: &'a dyn Policy,
2350 bio: Box<dyn BufferedReader<Cookie> + 'a>,
2351 helper: H, time: T,
2352 mode: Mode,
2353 buffer_size: usize,
2354 mapping: bool,
2355 csf_transformation: bool,
2356 )
2357 -> Result<Decryptor<'a, H>>
2358 where T: Into<Option<time::SystemTime>>
2359 {
2360 tracer!(TRACE, "Decryptor::from_cookie_reader", TRACE_INDENT);
2361
2362 let time = time.into();
2363 let tolerance = time
2364 .map(|_| time::Duration::new(0, 0))
2365 .unwrap_or(
2366 crate::packet::signature::subpacket::CLOCK_SKEW_TOLERANCE);
2367 let time = time.unwrap_or_else(crate::now);
2368
2369 let mut ppr = PacketParserBuilder::from_cookie_reader(bio)?
2370 .map(mapping)
2371 .process_csf_message(csf_transformation)
2372 .build()?;
2373
2374 let mut v = Decryptor {
2375 helper,
2376 issuers: Vec::new(),
2377 certs: Vec::new(),
2378 oppr: None,
2379 identity: None,
2380 structure: IMessageStructure::new(),
2381 buffer_size,
2382 reserve: None,
2383 cursor: 0,
2384 mode,
2385 time,
2386 clock_skew_tolerance: tolerance,
2387 policy,
2388 processing_csf_message: None, // We don't know yet.
2389 };
2390
2391 let mut pkesks: Vec<packet::PKESK> = Vec::new();
2392 let mut skesks: Vec<packet::SKESK> = Vec::new();
2393
2394 while let PacketParserResult::Some(mut pp) = ppr {
2395 match &pp.packet {
2396 Packet::PKESK(p) =>
2397 t!("Found a {:?}v{} at depth {}",
2398 pp.packet.tag(), p.version(),
2399 pp.recursion_depth()),
2400 Packet::SKESK(p) =>
2401 t!("Found a {:?}v{} at depth {}",
2402 pp.packet.tag(), p.version(),
2403 pp.recursion_depth()),
2404 Packet::SEIP(p) =>
2405 t!("Found a {:?}v{} at depth {}",
2406 pp.packet.tag(), p.version(),
2407 pp.recursion_depth()),
2408 _ =>
2409 t!("Found a {:?} at depth {}", pp.packet.tag(),
2410 pp.recursion_depth()),
2411 }
2412
2413 // Check whether we are actually processing a cleartext
2414 // signature framework message.
2415 if v.processing_csf_message.is_none() {
2416 v.processing_csf_message = Some(pp.processing_csf_message());
2417 }
2418
2419 v.policy.packet(&pp.packet)?;
2420 v.helper.inspect(&pp)?;
2421
2422 // When verifying detached signatures, we parse only the
2423 // signatures here, which on their own are not a valid
2424 // message.
2425 if v.mode == Mode::VerifyDetached {
2426 if pp.packet.tag() != packet::Tag::Signature
2427 && pp.packet.tag() != packet::Tag::Marker
2428 {
2429 return Err(Error::MalformedMessage(
2430 format!("Expected signature, got {}", pp.packet.tag()))
2431 .into());
2432 }
2433 } else if let Err(err) = pp.possible_message() {
2434 if v.processing_csf_message.expect("set by now") {
2435 // Our CSF transformation yields just one OPS
2436 // packet per encountered 'Hash' algorithm header,
2437 // and it cannot know how many signatures are in
2438 // fact following. Therefore, the message will
2439 // not be well-formed according to the grammar.
2440 // But, since we created the message structure
2441 // during the transformation, we know it is good,
2442 // even if it is a little out of spec.
2443 } else {
2444 t!("Malformed message: {}", err);
2445 return Err(err.context("Malformed OpenPGP message"));
2446 }
2447 }
2448
2449 let sym_algo_hint = match &pp.packet {
2450 Packet::SEIP(SEIP::V2(seip)) => Some(seip.symmetric_algo()),
2451 _ => None,
2452 };
2453
2454 match pp.packet {
2455 Packet::CompressedData(ref p) =>
2456 v.structure.new_compression_layer(p.algo()),
2457 Packet::SEIP(ref seip) if v.mode == Mode::Decrypt => {
2458 t!("Found the encryption container");
2459
2460 // Bail early (and provide a useful error message)
2461 // if we can't decrypt the SEIP packet.
2462 if let SEIP::V2(seipv2) = seip {
2463 if ! seipv2.symmetric_algo().is_supported() {
2464 return Err(Error::UnsupportedSymmetricAlgorithm(
2465 seipv2.symmetric_algo()).into());
2466 }
2467 if ! seipv2.aead().is_supported() {
2468 return Err(Error::UnsupportedAEADAlgorithm(
2469 seipv2.aead()).into());
2470 }
2471 }
2472
2473 // Get the symmetric algorithm from the decryption
2474 // proxy function. This is necessary because we
2475 // cannot get the algorithm from the SEIP packet.
2476 let mut sym_algo = None;
2477 {
2478 let mut decryption_proxy = |algo, secret: &SessionKey| {
2479 // Take the algo from the SEIPDv2 packet over
2480 // the dummy one from the SKESK6 packet.
2481 let algo = sym_algo_hint.or(algo);
2482 let result = pp.decrypt(algo, secret);
2483 t!("pp.decrypt({:?}, {:?}) => {:?}",
2484 algo, secret, result);
2485 if let Ok(_) = result {
2486 sym_algo = Some(algo);
2487 true
2488 } else {
2489 false
2490 }
2491 };
2492
2493 v.identity =
2494 v.helper.decrypt(&pkesks[..], &skesks[..],
2495 sym_algo_hint,
2496 &mut decryption_proxy)?
2497 .map(|cert| cert.fingerprint());
2498 }
2499 if ! pp.processed() {
2500 return Err(
2501 Error::MissingSessionKey(
2502 "No session key decrypted".into()).into());
2503 }
2504
2505 let sym_algo = if let Some(Some(a)) = sym_algo {
2506 a
2507 } else {
2508 return Err(Error::InvalidOperation(
2509 "No symmetric algorithm known".into()).into());
2510 };
2511
2512 v.policy.symmetric_algorithm(sym_algo)?;
2513 if let Packet::SEIP(SEIP::V2(p)) = &pp.packet {
2514 v.policy.aead_algorithm(p.aead())?;
2515 }
2516
2517 v.structure.new_encryption_layer(
2518 pp.recursion_depth(),
2519 pp.packet.tag() == packet::Tag::SEIP
2520 && pp.packet.version() == Some(1),
2521 sym_algo,
2522 if let Packet::SEIP(SEIP::V2(p)) = &pp.packet {
2523 Some(p.aead())
2524 } else {
2525 None
2526 });
2527 },
2528 Packet::OnePassSig(ref ops) => {
2529 v.structure.push_ops(ops);
2530 v.push_issuer(ops.issuer().clone());
2531 },
2532 Packet::Literal(_) => {
2533 v.structure.insert_missing_signature_group();
2534 v.oppr = Some(PacketParserResult::Some(pp));
2535 v.finish_maybe()?;
2536
2537 return Ok(v);
2538 },
2539 #[allow(deprecated)]
2540 Packet::MDC(ref mdc) => if ! mdc.valid() {
2541 return Err(Error::ManipulatedMessage.into());
2542 },
2543 _ => (),
2544 }
2545
2546 let (p, ppr_tmp) = pp.recurse()?;
2547 match p {
2548 Packet::PKESK(pkesk) => pkesks.push(pkesk),
2549 Packet::SKESK(skesk) => skesks.push(skesk),
2550 Packet::Signature(sig) => {
2551 // The following structure is allowed:
2552 //
2553 // SIG LITERAL
2554 //
2555 // In this case, we get the issuer from the
2556 // signature itself.
2557 sig.get_issuers().into_iter()
2558 .for_each(|i| v.push_issuer(i));
2559 v.structure.push_bare_signature(Ok(sig));
2560 },
2561
2562 Packet::Unknown(u) if u.tag() == packet::Tag::Signature => {
2563 v.structure.push_bare_signature(Err(u));
2564 },
2565
2566 _ => (),
2567 }
2568 ppr = ppr_tmp;
2569 }
2570
2571 if v.mode == Mode::VerifyDetached && !v.structure.layers.is_empty() {
2572 return Ok(v);
2573 }
2574
2575 // We can only get here if we didn't encounter a literal data
2576 // packet.
2577 Err(Error::MalformedMessage(
2578 "Malformed OpenPGP message".into()).into())
2579 }
2580
2581 /// Verifies the given data in detached verification mode.
2582 fn verify_detached<'d>(&mut self,
2583 data: Box<dyn BufferedReader<Cookie> + 'd>)
2584 -> Result<()>
2585 {
2586 assert_eq!(self.mode, Mode::VerifyDetached);
2587
2588 let sigs = if let IMessageLayer::SignatureGroup {
2589 sigs, .. } = &mut self.structure.layers[0] {
2590 sigs
2591 } else {
2592 unreachable!("There is exactly one signature group layer")
2593 };
2594
2595 // Compute the necessary hashes.
2596 let algos: Vec<_> = sigs.iter().filter_map(|s| {
2597 let s = s.as_ref().ok()?;
2598 let h = s.hash_algo();
2599 Some(HashingMode::for_signature(h, s))
2600 }).collect();
2601 let hashes =
2602 crate::parse::hashed_reader::hash_buffered_reader(data, &algos)?;
2603
2604 // Attach the digests.
2605 for sig in sigs.iter_mut().filter_map(|s| s.as_ref().ok()) {
2606 let need_hash =
2607 HashingMode::for_signature(sig.hash_algo(), sig);
2608 // Note: |hashes| < 10, most likely 1.
2609 for mode in hashes.iter()
2610 .filter(|m| m.map(|c| c.algo()) == need_hash)
2611 {
2612 // Clone the hash context, update it with the
2613 // signature.
2614 use crate::crypto::hash::Hash;
2615 let mut hash = mode.as_ref().clone();
2616 sig.hash(&mut hash)?;
2617
2618 // Attach digest to the signature.
2619 let mut digest = vec![0; hash.digest_size()];
2620 let _ = hash.digest(&mut digest);
2621 sig.set_computed_digest(Some(digest));
2622 }
2623 }
2624
2625 self.verify_signatures()
2626 }
2627
2628 /// Stashes the given Signature (if it is one) for later
2629 /// verification.
2630 fn push_sig(&mut self, p: Packet) -> Result<()> {
2631 match p {
2632 Packet::Signature(sig) => {
2633 sig.get_issuers().into_iter().for_each(|i| self.push_issuer(i));
2634 self.structure.push_signature(
2635 Ok(sig), self.processing_csf_message.expect("set by now"));
2636 },
2637 Packet::Unknown(sig) if sig.tag() == packet::Tag::Signature => {
2638 self.structure.push_signature(
2639 Err(sig), self.processing_csf_message.expect("set by now"));
2640 },
2641 _ => (),
2642 }
2643 Ok(())
2644 }
2645
2646 /// Records the issuer for the later certificate lookup.
2647 fn push_issuer<I: Into<KeyHandle>>(&mut self, issuer: I) {
2648 let issuer = issuer.into();
2649 match issuer {
2650 KeyHandle::KeyID(id) if id.is_wildcard() => {
2651 // Ignore, they are not useful for lookups.
2652 },
2653
2654 KeyHandle::KeyID(_) => {
2655 for known in self.issuers.iter() {
2656 if known.aliases(&issuer) {
2657 return;
2658 }
2659 }
2660
2661 // Unknown, record.
2662 self.issuers.push(issuer);
2663 },
2664
2665 KeyHandle::Fingerprint(_) => {
2666 for known in self.issuers.iter_mut() {
2667 if known.aliases(&issuer) {
2668 // Replace. We may upgrade a KeyID to a
2669 // Fingerprint.
2670 *known = issuer;
2671 return;
2672 }
2673 }
2674
2675 // Unknown, record.
2676 self.issuers.push(issuer);
2677 },
2678 }
2679 }
2680
2681 // If the amount of remaining data does not exceed the reserve,
2682 // finish processing the OpenPGP packet sequence.
2683 //
2684 // Note: once this call succeeds, you may not call it again.
2685 fn finish_maybe(&mut self) -> Result<()> {
2686 tracer!(TRACE, "Decryptor::finish_maybe", TRACE_INDENT);
2687 if let Some(PacketParserResult::Some(mut pp)) = self.oppr.take() {
2688 // Check if we hit EOF.
2689 let data_len = pp.data(self.buffer_size + 1)?.len();
2690 if data_len - self.cursor <= self.buffer_size {
2691 // Stash the reserve.
2692 t!("Hit eof with {} bytes of the current buffer consumed.",
2693 self.cursor);
2694 pp.consume(self.cursor);
2695 self.cursor = 0;
2696 self.reserve = Some(Protected::from(pp.steal_eof()?));
2697
2698 // Process the rest of the packets.
2699 let mut ppr = PacketParserResult::Some(pp);
2700 let mut first = true;
2701 while let PacketParserResult::Some(pp) = ppr {
2702 t!("Found a {:?} at depth {}", pp.packet.tag(),
2703 pp.recursion_depth());
2704
2705 // The literal data packet was already inspected.
2706 if first {
2707 assert_eq!(pp.packet.tag(), packet::Tag::Literal);
2708 first = false;
2709 } else {
2710 self.helper.inspect(&pp)?;
2711 }
2712
2713 let possible_message = pp.possible_message();
2714
2715 // If we are ascending, and the packet was the
2716 // last packet in a SEIP container, we need to be
2717 // extra careful with reporting errors to avoid
2718 // creating a decryption oracle.
2719
2720 let last_recursion_depth = pp.recursion_depth();
2721 let (p, ppr_tmp) = match pp.recurse() {
2722 Ok(v) => v,
2723 Err(e) => {
2724 // Assuming we just tried to ascend,
2725 // should there have been a MDC packet?
2726 // If so, this may be an attack.
2727 if self.structure.expect_mdc_at(
2728 last_recursion_depth - 1)
2729 {
2730 return Err(Error::ManipulatedMessage.into());
2731 } else {
2732 return Err(e);
2733 }
2734 },
2735 };
2736 ppr = ppr_tmp;
2737 let recursion_depth = ppr.as_ref()
2738 .map(|pp| pp.recursion_depth()).unwrap_or(0);
2739
2740 // Did we just ascend?
2741 if recursion_depth + 1 == last_recursion_depth
2742 && self.structure.expect_mdc_at(recursion_depth)
2743 {
2744 match &p {
2745 #[allow(deprecated)]
2746 Packet::MDC(mdc) if mdc.valid() =>
2747 (), // Good.
2748 _ => // Bad.
2749 return Err(Error::ManipulatedMessage.into()),
2750 }
2751
2752 if possible_message.is_err() {
2753 return Err(Error::ManipulatedMessage.into());
2754 }
2755 }
2756
2757 if let Err(_err) = possible_message {
2758 if self.processing_csf_message.expect("set by now") {
2759 // CSF transformation creates slightly out
2760 // of spec message structure. See above
2761 // for longer explanation.
2762 } else {
2763 return Err(Error::ManipulatedMessage.into());
2764 }
2765 }
2766
2767 self.push_sig(p)?;
2768 }
2769
2770 // If we finished parsing, validate the message structure.
2771 if let PacketParserResult::EOF(eof) = ppr {
2772 // If we parse a signed message synthesized from a
2773 // cleartext signature framework message, we don't
2774 // quite get the structure right, so relax the
2775 // requirement in this case.
2776 if ! self.processing_csf_message.expect("set by now") {
2777 eof.is_message()?;
2778 }
2779 }
2780
2781 self.verify_signatures()
2782 } else {
2783 t!("Didn't hit EOF.");
2784 self.oppr = Some(PacketParserResult::Some(pp));
2785 Ok(())
2786 }
2787 } else {
2788 panic!("No ppr.");
2789 }
2790 }
2791
2792 /// Verifies the signatures.
2793 fn verify_signatures(&mut self) -> Result<()> {
2794 tracer!(TRACE, "Decryptor::verify_signatures", TRACE_INDENT);
2795 t!("called");
2796
2797 self.certs = self.helper.get_certs(&self.issuers)?;
2798 t!("VerificationHelper::get_certs produced {} certs", self.certs.len());
2799
2800 let mut results = MessageStructure::new(
2801 self.processing_csf_message.unwrap_or(false));
2802 for layer in self.structure.layers.iter_mut() {
2803 match layer {
2804 IMessageLayer::Compression { algo } =>
2805 results.new_compression_layer(*algo),
2806 IMessageLayer::Encryption { sym_algo, aead_algo, .. } =>
2807 results.new_encryption_layer(*sym_algo, *aead_algo),
2808 IMessageLayer::SignatureGroup { sigs, .. } => {
2809 results.new_signature_group();
2810 'sigs: for sig in sigs.iter_mut() {
2811 let sig = match sig {
2812 Ok(s) => s,
2813 Err(u) => {
2814 // Unparsablee signature.
2815 t!("Unparsablee signature: {}", u.error());
2816 results.push_verification_result(
2817 Err(VerificationError::UnknownSignature {
2818 sig: u,
2819 }));
2820 continue;
2821 }
2822 };
2823
2824 let sigid = *sig.digest_prefix();
2825
2826 let sig_time = if let Some(t) = sig.signature_creation_time() {
2827 t
2828 } else {
2829 // Invalid signature.
2830 results.push_verification_result(
2831 Err(VerificationError::MalformedSignature {
2832 sig,
2833 error: Error::MalformedPacket(
2834 "missing a Signature Creation Time \
2835 subpacket"
2836 .into()).into(),
2837 }));
2838 t!("{:02X}{:02X}: Missing a signature creation time subpacket",
2839 sigid[0], sigid[1]);
2840 continue;
2841 };
2842
2843 let mut err = VerificationErrorInternal::MissingKey {};
2844
2845 let issuers = sig.get_issuers();
2846 // Note: If there are no issuers, the only way
2847 // to verify the signature is to try every key
2848 // that could possibly have created the
2849 // signature. While this may be feasible if
2850 // the set of potential signing keys is small,
2851 // the use case of hiding the signer's
2852 // identity seems better solved using
2853 // encryption. Furthermore, no other OpenPGP
2854 // implementation seems to support this kind
2855 // of wildcard signatures.
2856 let no_issuers = issuers.is_empty();
2857
2858 for ka in self.certs.iter().flat_map(
2859 |c| c.keys().key_handles(issuers.clone()))
2860 {
2861 if no_issuers {
2862 // Slightly awkward control flow
2863 // change. Below this loop, we still
2864 // have to add this signature to the
2865 // results with the default error,
2866 // `VerificationError::MissingKey`.
2867 break;
2868 }
2869
2870 let cert = ka.cert();
2871 let fingerprint = ka.key().fingerprint();
2872 let ka = match ka.with_policy(self.policy, sig_time) {
2873 Err(policy_err) => {
2874 t!("{:02X}{:02X}: key {} rejected by policy: {}",
2875 sigid[0], sigid[1], fingerprint, policy_err);
2876 err = VerificationErrorInternal::UnboundKey {
2877 cert,
2878 error: policy_err,
2879 };
2880 continue;
2881 }
2882 Ok(ka) => {
2883 t!("{:02X}{:02X}: key {} accepted by policy",
2884 sigid[0], sigid[1], fingerprint);
2885 ka
2886 }
2887 };
2888
2889 err = if let Err(error) = ka.valid_cert().alive() {
2890 t!("{:02X}{:02X}: cert {} not alive: {}",
2891 sigid[0], sigid[1], ka.cert().fingerprint(), error);
2892 VerificationErrorInternal::BadKey {
2893 ka,
2894 error,
2895 }
2896 } else if let Err(error) = ka.alive() {
2897 t!("{:02X}{:02X}: key {} not alive: {}",
2898 sigid[0], sigid[1], ka.key().fingerprint(), error);
2899 VerificationErrorInternal::BadKey {
2900 ka,
2901 error,
2902 }
2903 } else if let
2904 RevocationStatus::Revoked(rev) = ka.valid_cert().revocation_status()
2905 {
2906 t!("{:02X}{:02X}: cert {} revoked: {:?}",
2907 sigid[0], sigid[1], ka.cert().fingerprint(), rev);
2908 VerificationErrorInternal::BadKey {
2909 ka,
2910 error: Error::InvalidKey(
2911 "certificate is revoked".into())
2912 .into(),
2913 }
2914 } else if let
2915 RevocationStatus::Revoked(rev) = ka.revocation_status()
2916 {
2917 t!("{:02X}{:02X}: key {} revoked: {:?}",
2918 sigid[0], sigid[1], ka.key().fingerprint(), rev);
2919 VerificationErrorInternal::BadKey {
2920 ka,
2921 error: Error::InvalidKey(
2922 "signing key is revoked".into())
2923 .into(),
2924 }
2925 } else if ! ka.for_signing() {
2926 t!("{:02X}{:02X}: key {} not signing capable",
2927 sigid[0], sigid[1], ka.key().fingerprint());
2928 VerificationErrorInternal::BadKey {
2929 ka,
2930 error: Error::InvalidKey(
2931 "key is not signing capable".into())
2932 .into(),
2933 }
2934 } else if let Err(error) = sig.signature_alive(
2935 self.time, self.clock_skew_tolerance)
2936 {
2937 t!("{:02X}{:02X}: Signature not alive: {}",
2938 sigid[0], sigid[1], error);
2939 VerificationErrorInternal::BadSignature {
2940 ka,
2941 error,
2942 }
2943 } else if self.identity.as_ref().map(|identity| {
2944 let (have_one, contains_identity) =
2945 sig.intended_recipients()
2946 .fold((false, false),
2947 |(_, contains_one), ir| {
2948 (
2949 true,
2950 contains_one || identity == ir
2951 )
2952 });
2953 have_one && ! contains_identity
2954 }).unwrap_or(false) {
2955 // The signature contains intended
2956 // recipients, but we are not one.
2957 // Treat the signature as bad.
2958 t!("{:02X}{:02X}: not an intended recipient",
2959 sigid[0], sigid[1]);
2960 VerificationErrorInternal::BadSignature {
2961 ka,
2962 error: Error::BadSignature(
2963 "Not an intended recipient".into())
2964 .into(),
2965 }
2966 } else {
2967 match sig.verify_document(ka.key()) {
2968 Ok(()) => {
2969 if let Err(error)
2970 = self.policy.signature(
2971 sig, Default::default())
2972 {
2973 t!("{:02X}{:02X}: signature rejected by policy: {}",
2974 sigid[0], sigid[1], error);
2975 VerificationErrorInternal::BadSignature {
2976 ka,
2977 error,
2978 }
2979 } else {
2980 t!("{:02X}{:02X}: good checksum using {}",
2981 sigid[0], sigid[1], ka.key().fingerprint());
2982 results.push_verification_result(
2983 Ok(GoodChecksum {
2984 sig,
2985 ka,
2986 }));
2987 // Continue to the next sig.
2988 continue 'sigs;
2989 }
2990 }
2991 Err(error) => {
2992 t!("{:02X}{:02X} using {}: error: {}",
2993 sigid[0], sigid[1], ka.key().fingerprint(), error);
2994 VerificationErrorInternal::BadSignature {
2995 ka,
2996 error,
2997 }
2998 }
2999 }
3000 }
3001 }
3002
3003 let err = err.attach_sig(sig);
3004 t!("{:02X}{:02X}: returning: {:?}", sigid[0], sigid[1], err);
3005 results.push_verification_result(Err(err));
3006 }
3007 }
3008 }
3009 }
3010
3011 let r = self.helper.check(results);
3012 t!("-> {:?}", r);
3013 r
3014 }
3015
3016 /// Like `io::Read::read()`, but returns our `Result`.
3017 fn read_helper(&mut self, buf: &mut [u8]) -> Result<usize> {
3018 tracer!(TRACE, "Decryptor::read_helper", TRACE_INDENT);
3019 t!("read(buf of {} bytes)", buf.len());
3020
3021 if buf.is_empty() {
3022 return Ok(0);
3023 }
3024
3025 if let Some(ref mut reserve) = self.reserve {
3026 // The message has been verified. We can now drain the
3027 // reserve.
3028 t!("Message verified, draining reserve.");
3029 assert!(self.oppr.is_none());
3030 assert!(self.cursor <= reserve.len());
3031 let n = cmp::min(buf.len(), reserve.len() - self.cursor);
3032 buf[..n]
3033 .copy_from_slice(&reserve[self.cursor..n + self.cursor]);
3034 self.cursor += n;
3035 return Ok(n);
3036 }
3037
3038 // Read the data from the Literal data packet.
3039 if let Some(PacketParserResult::Some(mut pp)) = self.oppr.take() {
3040 // Be careful to not read from the reserve.
3041 if self.cursor >= self.buffer_size {
3042 // Consume the active part of the buffer.
3043 t!("Consuming first part of the buffer.");
3044 pp.consume(self.buffer_size);
3045 self.cursor -= self.buffer_size;
3046 }
3047
3048 // We request two times what our buffer size is, the first
3049 // part is the one we give out, the second part is the one
3050 // we hold back.
3051 let data_len = pp.data(2 * self.buffer_size)?.len();
3052 t!("Read {} bytes.", data_len);
3053 if data_len - self.cursor <= self.buffer_size {
3054 self.oppr = Some(PacketParserResult::Some(pp));
3055 self.finish_maybe()?;
3056 self.read_helper(buf)
3057 } else {
3058 let data = pp.data(2 * self.buffer_size - self.cursor)?;
3059 assert_eq!(data.len(), data_len);
3060
3061 let n =
3062 buf.len().min(data_len - self.buffer_size - self.cursor);
3063 buf[..n].copy_from_slice(&data[self.cursor..self.cursor + n]);
3064 self.cursor += n;
3065 self.oppr = Some(PacketParserResult::Some(pp));
3066 t!("Copied {} bytes from buffer, cursor is {}.", n, self.cursor);
3067 Ok(n)
3068 }
3069 } else {
3070 panic!("No ppr.");
3071 }
3072 }
3073}
3074
3075impl<'a, H: VerificationHelper + DecryptionHelper> io::Read for Decryptor<'a, H>
3076{
3077 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
3078 match self.read_helper(buf) {
3079 Ok(n) => Ok(n),
3080 Err(e) => match e.downcast::<io::Error>() {
3081 // An io::Error. Pass as-is.
3082 Ok(e) => Err(e),
3083 // A failure. Wrap it.
3084 Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
3085 },
3086 }
3087 }
3088}
3089
3090#[cfg(test)]
3091pub(crate) mod test {
3092 use std::io::Read;
3093 use super::*;
3094 use std::convert::TryFrom;
3095 use crate::parse::Parse;
3096 use crate::policy::{NullPolicy as NP, StandardPolicy as P};
3097 use crate::serialize::Serialize;
3098 use crate::{
3099 crypto::Password,
3100 };
3101
3102 /// Verification helper for the tests.
3103 #[derive(Clone)]
3104 pub struct VHelper {
3105 good: usize,
3106 unknown: usize,
3107 bad: usize,
3108 error: usize,
3109 expect_csf_message: bool,
3110 certs: Vec<Cert>,
3111 keys: Vec<Cert>,
3112 passwords: Vec<Password>,
3113 for_decryption: bool,
3114 error_out: bool,
3115 pub packets: Vec<Packet>,
3116 }
3117
3118 impl std::fmt::Debug for VHelper {
3119 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3120 f.debug_struct("VHelper")
3121 .field("good", &self.good)
3122 .field("unknown", &self.unknown)
3123 .field("bad", &self.bad)
3124 .field("error", &self.error)
3125 .field("error_out", &self.error_out)
3126 .field("expect_csf_message", &self.expect_csf_message)
3127 .finish()
3128 }
3129 }
3130
3131 impl VHelper {
3132 /// Creates a new verification helper.
3133 pub fn new(good: usize, unknown: usize, bad: usize, error: usize,
3134 expect_csf_message: bool, certs: Vec<Cert>)
3135 -> Self {
3136 VHelper {
3137 good,
3138 unknown,
3139 bad,
3140 error,
3141 expect_csf_message,
3142 certs,
3143 keys: Default::default(),
3144 passwords: Default::default(),
3145 for_decryption: false,
3146 error_out: true,
3147 packets: Default::default(),
3148 }
3149 }
3150
3151 /// Creates a new decryption helper.
3152 pub fn for_decryption(good: usize, unknown: usize, bad: usize,
3153 error: usize,
3154 certs: Vec<Cert>,
3155 keys: Vec<Cert>,
3156 passwords: Vec<Password>)
3157 -> Self {
3158 VHelper {
3159 good,
3160 unknown,
3161 bad,
3162 error,
3163 expect_csf_message: false,
3164 certs,
3165 keys,
3166 passwords,
3167 for_decryption: true,
3168 error_out: true,
3169 packets: Default::default(),
3170 }
3171 }
3172
3173 /// Compares the stats.
3174 pub fn assert_stats_eq(&self, other: &Self) {
3175 assert_eq!(self.good, other.good);
3176 assert_eq!(self.unknown, other.unknown);
3177 assert_eq!(self.bad, other.bad);
3178 assert_eq!(self.error, other.error);
3179 }
3180 }
3181
3182 impl VerificationHelper for VHelper {
3183 fn inspect(&mut self, pp: &PacketParser<'_>) -> Result<()> {
3184 self.packets.push(pp.packet.clone());
3185 Ok(())
3186 }
3187
3188 fn get_certs(&mut self, _ids: &[crate::KeyHandle]) -> Result<Vec<Cert>> {
3189 Ok(self.certs.clone())
3190 }
3191
3192 fn check(&mut self, structure: MessageStructure) -> Result<()> {
3193 use self::VerificationError::*;
3194 for layer in structure.iter() {
3195 match layer {
3196 MessageLayer::SignatureGroup { ref results } =>
3197 for result in results {
3198 match result {
3199 Ok(_) => self.good += 1,
3200 Err(MissingKey { .. }) => self.unknown += 1,
3201 Err(UnboundKey { .. }) => self.unknown += 1,
3202 Err(MalformedSignature { .. }) => self.bad += 1,
3203 Err(UnknownSignature { .. }) => self.bad += 1,
3204 Err(BadKey { .. }) => self.bad += 1,
3205 Err(BadSignature { error, .. }) => {
3206 eprintln!("error: {}", error);
3207 self.bad += 1;
3208 },
3209 }
3210 }
3211 MessageLayer::Compression { .. } => (),
3212 MessageLayer::Encryption { .. } => (),
3213 }
3214 }
3215
3216 if self.expect_csf_message != structure.processed_csf_message() {
3217 if self.expect_csf_message {
3218 return Err(anyhow::anyhow!(
3219 "Expected CSF, but didn't get it"));
3220 } else {
3221 return Err(anyhow::anyhow!(
3222 "Didn't expect CSF, but got it"));
3223 }
3224 }
3225
3226 if ! self.error_out || (self.good > 0 && self.bad == 0)
3227 || (self.for_decryption && self.certs.is_empty())
3228 {
3229 Ok(())
3230 } else {
3231 Err(anyhow::anyhow!("Verification failed: {:?}", self))
3232 }
3233 }
3234 }
3235
3236 impl DecryptionHelper for VHelper {
3237 fn decrypt(&mut self, pkesks: &[PKESK], skesks: &[SKESK],
3238 sym_algo: Option<SymmetricAlgorithm>,
3239 decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
3240 -> Result<Option<Cert>>
3241 {
3242 tracer!(TRACE, "VHelper::decrypt", TRACE_INDENT);
3243
3244 let p = P::new();
3245 if ! self.for_decryption {
3246 unreachable!("Shouldn't be called for verifications");
3247 }
3248
3249 t!("Trying SKESKS: {:?}", skesks);
3250 for (i, skesk) in skesks.iter().enumerate() {
3251 for p in &self.passwords {
3252 let r = skesk.decrypt(p);
3253 t!("decrypting SKESK {}: {:?}", i, r);
3254 if let Ok((algo, sk)) = r {
3255 if decrypt(algo, &sk) {
3256 t!("successfully decrypted encryption container");
3257 return Ok(None);
3258 }
3259 }
3260 }
3261 }
3262
3263 t!("Trying PKESKS: {:?}", pkesks);
3264 for pkesk in pkesks.iter().filter(|p| p.recipient().is_some()) {
3265 for key in &self.keys {
3266 for subkey in key.with_policy(&p, None)?.keys().secret()
3267 .key_handles(pkesk.recipient())
3268 {
3269 t!("Trying to decrypt {:?} with {:?}", pkesk, subkey);
3270 if let Some((algo, sk)) =
3271 subkey.key().clone().into_keypair().ok()
3272 .and_then(|mut k| pkesk.decrypt(&mut k, sym_algo))
3273 {
3274 if decrypt(algo, &sk) {
3275 t!("successfully decrypted encryption container");
3276 return Ok(None);
3277 }
3278 }
3279 }
3280 }
3281 }
3282
3283 t!("decryption of session key failed");
3284 Err(Error::MissingSessionKey("Decryption failed".into()).into())
3285 }
3286 }
3287
3288 #[test]
3289 fn verifier() -> Result<()> {
3290 let p = P::new();
3291
3292 let certs = [
3293 "keys/neal.pgp",
3294 "keys/testy-new.pgp",
3295 "keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp",
3296 "crypto-refresh/v6-minimal-cert.key",
3297 ].iter()
3298 .map(|f| Cert::from_bytes(crate::tests::file(f)).unwrap())
3299 .collect::<Vec<_>>();
3300 let tests = &[
3301 // Signed messages.
3302 (crate::tests::message("signed-1.pgp").to_vec(),
3303 crate::tests::manifesto().to_vec(),
3304 true,
3305 Some(crate::frozen_time()),
3306 VHelper::new(1, 0, 0, 0, false, certs.clone())),
3307 // The same, but with a marker packet.
3308 ({
3309 let pp = crate::PacketPile::from_bytes(
3310 crate::tests::message("signed-1.pgp"))?;
3311 let mut buf = Vec::new();
3312 Packet::Marker(Default::default()).serialize(&mut buf)?;
3313 pp.serialize(&mut buf)?;
3314 buf
3315 },
3316 crate::tests::manifesto().to_vec(),
3317 true,
3318 Some(crate::frozen_time()),
3319 VHelper::new(1, 0, 0, 0, false, certs.clone())),
3320 (crate::tests::message("signed-1-sha256-testy.pgp").to_vec(),
3321 crate::tests::manifesto().to_vec(),
3322 true,
3323 Some(crate::frozen_time()),
3324 VHelper::new(0, 1, 0, 0, false, certs.clone())),
3325 (crate::tests::message("signed-1-notarized-by-ed25519.pgp")
3326 .to_vec(),
3327 crate::tests::manifesto().to_vec(),
3328 true,
3329 Some(crate::frozen_time()),
3330 VHelper::new(2, 0, 0, 0, false, certs.clone())),
3331 // Signed messages using the Cleartext Signature Framework.
3332 (crate::tests::message("a-cypherpunks-manifesto.txt.cleartext.sig")
3333 .to_vec(),
3334 {
3335 // The test vector, created by GnuPG, does not preserve
3336 // the final newline.
3337 //
3338 // The transformation process trims trailing whitespace,
3339 // and the manifesto has a trailing whitespace right at
3340 // the end.
3341 let mut manifesto = crate::tests::manifesto().to_vec();
3342 assert_eq!(manifesto.pop(), Some(b'\n'));
3343 assert_eq!(manifesto.pop(), Some(b' '));
3344 manifesto
3345 },
3346 false,
3347 None,
3348 VHelper::new(1, 0, 0, 0, true, certs.clone())),
3349 (crate::tests::message("a-problematic-poem.txt.cleartext.sig")
3350 .to_vec(),
3351 {
3352 // The test vector, created by GnuPG, does not preserve
3353 // the final newline.
3354 let mut reference =
3355 crate::tests::message("a-problematic-poem.txt").to_vec();
3356 assert_eq!(reference.pop(), Some(b'\n'));
3357 reference
3358 },
3359 false,
3360 None,
3361 VHelper::new(1, 0, 0, 0, true, certs.clone())),
3362 (crate::tests::file("crypto-refresh/cleartext-signed-message.txt")
3363 .to_vec(),
3364 crate::tests::file("crypto-refresh/cleartext-signed-message.txt.plain")
3365 .to_vec(),
3366 false,
3367 None,
3368 VHelper::new(1, 0, 0, 0, true, certs.clone())),
3369 // A key as example of an invalid message.
3370 (crate::tests::key("neal.pgp").to_vec(),
3371 crate::tests::manifesto().to_vec(),
3372 true,
3373 Some(crate::frozen_time()),
3374 VHelper::new(0, 0, 0, 1, false, certs.clone())),
3375 // A signed message where the signature type is text and a
3376 // crlf straddles two chunks.
3377 (crate::tests::message("crlf-straddles-chunks.txt.sig").to_vec(),
3378 crate::tests::message("crlf-straddles-chunks.txt").to_vec(),
3379 false,
3380 None,
3381 VHelper::new(1, 0, 0, 0, false, certs.clone())),
3382 // Like crlf-straddles-chunks, but the signature includes a
3383 // notation with a '\n'. Make sure it is not converted to
3384 // a '\r\n'.
3385 (crate::tests::message("text-signature-notation-has-lf.txt.sig").to_vec(),
3386 crate::tests::message("text-signature-notation-has-lf.txt").to_vec(),
3387 false,
3388 None,
3389 VHelper::new(1, 0, 0, 0, false, certs.clone())),
3390 ];
3391
3392 for (i, (signed, reference, test_decryptor, time, r))
3393 in tests.iter().enumerate()
3394 {
3395 eprintln!("{}...", i);
3396
3397 // Test Verifier.
3398 let h = VHelper::new(0, 0, 0, 0, r.expect_csf_message, certs.clone());
3399 let mut v =
3400 match VerifierBuilder::from_bytes(&signed)?
3401 .with_policy(&p, *time, h) {
3402 Ok(v) => v,
3403 Err(e) => if r.error > 0 || r.unknown > 0 {
3404 // Expected error. No point in trying to read
3405 // something.
3406 continue;
3407 } else {
3408 panic!("{}: {}", i, e);
3409 },
3410 };
3411 assert!(v.message_processed());
3412 r.assert_stats_eq(v.helper_ref());
3413
3414 if v.helper_ref().error > 0 {
3415 // Expected error. No point in trying to read
3416 // something.
3417 continue;
3418 }
3419
3420 let mut content = Vec::new();
3421 v.read_to_end(&mut content).unwrap();
3422 assert_eq!(reference.len(), content.len());
3423 assert_eq!(&reference[..], &content[..]);
3424
3425 if ! test_decryptor {
3426 continue;
3427 }
3428
3429 // Test Decryptor.
3430 let h = VHelper::new(0, 0, 0, 0, r.expect_csf_message, certs.clone());
3431 let mut v = match DecryptorBuilder::from_bytes(&signed)?
3432 .with_policy(&p, *time, h) {
3433 Ok(v) => v,
3434 Err(e) => if r.error > 0 || r.unknown > 0 {
3435 // Expected error. No point in trying to read
3436 // something.
3437 continue;
3438 } else {
3439 panic!("{}: {}", i, e);
3440 },
3441 };
3442 assert!(v.message_processed());
3443 r.assert_stats_eq(v.helper_ref());
3444
3445 if v.helper_ref().error > 0 {
3446 // Expected error. No point in trying to read
3447 // something.
3448 continue;
3449 }
3450
3451 let mut content = Vec::new();
3452 v.read_to_end(&mut content).unwrap();
3453 assert_eq!(reference.len(), content.len());
3454 assert_eq!(&reference[..], &content[..]);
3455 }
3456 Ok(())
3457 }
3458
3459 #[test]
3460 fn decryptor() -> Result<()> {
3461 let p = P::new();
3462 for (key_file, message, plaintext) in &[
3463 ("messages/encrypted/rsa.sec.pgp",
3464 "messages/encrypted/rsa.msg.pgp",
3465 "Hello World!\n"),
3466 ("messages/encrypted/elg.sec.pgp",
3467 "messages/encrypted/elg.msg.pgp",
3468 "Hello World!\n"),
3469 ("messages/encrypted/cv25519.sec.pgp",
3470 "messages/encrypted/cv25519.msg.pgp",
3471 "Hello World!\n"),
3472 ("messages/encrypted/cv25519.unclamped.sec.pgp",
3473 "messages/encrypted/cv25519.unclamped.msg.pgp",
3474 "дружба"),
3475 ("messages/encrypted/nistp256.sec.pgp",
3476 "messages/encrypted/nistp256.msg.pgp",
3477 "Hello World!\n"),
3478 ("messages/encrypted/nistp384.sec.pgp",
3479 "messages/encrypted/nistp384.msg.pgp",
3480 "Hello World!\n"),
3481 ("messages/encrypted/nistp521.sec.pgp",
3482 "messages/encrypted/nistp521.msg.pgp",
3483 "Hello World!\n"),
3484 ("messages/encrypted/brainpoolP256r1.sec.pgp",
3485 "messages/encrypted/brainpoolP256r1.msg.pgp",
3486 "Hello World!\n"),
3487 ("messages/encrypted/brainpoolP384r1.sec.pgp",
3488 "messages/encrypted/brainpoolP384r1.msg.pgp",
3489 "Hello World!\n"),
3490 ("messages/encrypted/brainpoolP512r1.sec.pgp",
3491 "messages/encrypted/brainpoolP512r1.msg.pgp",
3492 "Hello World!\n"),
3493 ("messages/encrypted/secp256k1.sec.pgp",
3494 "messages/encrypted/secp256k1.msg.pgp",
3495 "Hello World!\n"),
3496 ("messages/encrypted/x448.sec.pgp",
3497 "messages/encrypted/x448.msg.pgp",
3498 "Hello World!\n"),
3499
3500 ("pqc/ietf/v6-eddsa-sample-sk.pgp",
3501 "pqc/ietf/v6-eddsa-sample-message.pgp",
3502 "Testing\n"),
3503 ("pqc/ietf/v4-eddsa-sample-sk.pgp",
3504 "pqc/ietf/v4-eddsa-sample-message-v1.pgp",
3505 "Testing\n"),
3506 ("pqc/ietf/v4-eddsa-sample-sk.pgp",
3507 "pqc/ietf/v4-eddsa-sample-message-v2.pgp",
3508 "Testing\n"),
3509 ("pqc/ietf/v6-mldsa-65-sample-sk.pgp",
3510 "pqc/ietf/v6-mldsa-65-sample-message.pgp",
3511 "Testing\n"),
3512 ("pqc/ietf/v6-mldsa-87-sample-sk.pgp",
3513 "pqc/ietf/v6-mldsa-87-sample-message.pgp",
3514 "Testing\n"),
3515 ("pqc/ietf/v6-slhdsa-128s-sample-sk.pgp",
3516 "pqc/ietf/v6-slhdsa-128s-sample-message.pgp",
3517 "Testing\n"),
3518
3519 // rpgp artifacts
3520 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519_bob_sk.pgp",
3521 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519_message.pgp",
3522 "Hello World\n"),
3523 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-ed25519-mlkem768x25519_bob_sk.pgp",
3524 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-ed25519-mlkem768x25519_message.pgp",
3525 "Hello World\n"),
3526 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa65ed25519-mlkem768x25519_bob_sk.pgp",
3527 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa65ed25519-mlkem768x25519_message.pgp",
3528 "Hello World\n"),
3529 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa87ed448-mlkem1024x448_bob_sk.pgp",
3530 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa87ed448-mlkem1024x448_message.pgp",
3531 "Hello World\n"),
3532 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128f-mlkem768x25519_bob_sk.pgp",
3533 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128f-mlkem768x25519_message.pgp",
3534 "Hello World\n"),
3535 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128s-mlkem768x25519_bob_sk.pgp",
3536 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128s-mlkem768x25519_message.pgp",
3537 "Hello World\n"),
3538 ("pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake256s-mlkem1024x448_bob_sk.pgp",
3539 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake256s-mlkem1024x448_message.pgp",
3540 "Hello World\n"),
3541
3542 // gopenpgp artifacts
3543 ("pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09_bob_sk.pgp",
3544 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09_message.pgp",
3545 "Hello World\n"),
3546 ("pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09-high-security_bob_sk.pgp",
3547 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09-high-security_message.pgp",
3548 "Hello World\n"),
3549
3550 ] {
3551 eprintln!("Test vector {:?}...", key_file);
3552 let key = Cert::from_bytes(crate::tests::file(key_file))?;
3553 if ! key.primary_key().key().pk_algo().is_supported() {
3554 eprintln!("Skipping {} because we don't support {}",
3555 key, key.primary_key().key().pk_algo());
3556 continue;
3557 }
3558
3559 if let Some(k) =
3560 key.with_policy(&p, None)?.keys().subkeys().supported().last()
3561 {
3562 use crate::crypto::mpi::PublicKey;
3563 match k.key().mpis() {
3564 PublicKey::ECDH { curve, .. } if ! curve.is_supported() => {
3565 eprintln!("Skipping {} because we don't support \
3566 the curve {}", key_file, curve);
3567 continue;
3568 },
3569 _ => (),
3570 }
3571 } else {
3572 eprintln!("Skipping {} because we don't support the algorithm",
3573 key_file);
3574 continue;
3575 }
3576
3577 let h = VHelper::for_decryption(0, 0, 0, 0, Vec::new(),
3578 vec![key], Vec::new());
3579 let mut d = DecryptorBuilder::from_bytes(crate::tests::file(message))?
3580 .with_policy(&p, None, h)?;
3581 assert!(d.message_processed());
3582
3583 if d.helper_ref().error > 0 {
3584 // Expected error. No point in trying to read
3585 // something.
3586 continue;
3587 }
3588
3589 let mut content = Vec::new();
3590 d.read_to_end(&mut content).unwrap();
3591 let content = String::from_utf8(content).unwrap();
3592 eprintln!("decrypted {:?} using {}", content, key_file);
3593 assert_eq!(&content[..], &plaintext[..]);
3594 }
3595
3596 Ok(())
3597 }
3598
3599 /// Tests legacy two-pass signature scheme, corner cases.
3600 ///
3601 /// XXX: This test needs to be adapted once
3602 /// https://gitlab.com/sequoia-pgp/sequoia/-/issues/128 is
3603 /// implemented.
3604 #[test]
3605 fn verifier_legacy() -> Result<()> {
3606 let packets = crate::PacketPile::from_bytes(
3607 crate::tests::message("signed-1.pgp")
3608 )?
3609 .into_children()
3610 .collect::<Vec<_>>();
3611
3612 fn check(msg: &str, buf: &[u8], expect_good: usize) -> Result<()> {
3613 eprintln!("{}...", msg);
3614 let p = P::new();
3615
3616 let certs = [
3617 "neal.pgp",
3618 ]
3619 .iter()
3620 .map(|f| Cert::from_bytes(crate::tests::key(f)).unwrap())
3621 .collect::<Vec<_>>();
3622
3623 let mut h = VHelper::new(0, 0, 0, 0, false, certs.clone());
3624 h.error_out = false;
3625 let mut v = VerifierBuilder::from_bytes(buf)?
3626 .with_policy(&p, crate::frozen_time(), h)?;
3627 assert!(v.message_processed());
3628 assert_eq!(v.processing_csf_message(), Some(false));
3629 assert_eq!(v.helper_ref().good, expect_good);
3630
3631 let mut content = Vec::new();
3632 v.read_to_end(&mut content).unwrap();
3633 let reference = crate::tests::manifesto();
3634 assert_eq!(reference.len(), content.len());
3635 assert_eq!(reference, &content[..]);
3636 Ok(())
3637 }
3638
3639 // Bare legacy signed message: SIG Literal
3640 let mut o = Vec::new();
3641 packets[2].serialize(&mut o)?;
3642 packets[1].serialize(&mut o)?;
3643 check("bare", &o, 0 /* XXX: should be 1 once #128 is implemented. */)?;
3644
3645 // Legacy signed message, two signatures: SIG SIG Literal
3646 let mut o = Vec::new();
3647 packets[2].serialize(&mut o)?;
3648 packets[2].serialize(&mut o)?;
3649 packets[1].serialize(&mut o)?;
3650 check("double", &o, 0 /* XXX: should be 2 once #128 is implemented. */)?;
3651
3652 // Weird legacy signed message: OPS SIG Literal SIG
3653 let mut o = Vec::new();
3654 packets[0].serialize(&mut o)?;
3655 packets[2].serialize(&mut o)?;
3656 packets[1].serialize(&mut o)?;
3657 packets[2].serialize(&mut o)?;
3658 check("weird", &o, 0 /* XXX: should be 2 once #128 is implemented. */)?;
3659
3660 // Fubar legacy signed message: SIG OPS Literal SIG
3661 let mut o = Vec::new();
3662 packets[2].serialize(&mut o)?;
3663 packets[0].serialize(&mut o)?;
3664 packets[1].serialize(&mut o)?;
3665 packets[2].serialize(&mut o)?;
3666 check("fubar", &o, 1 /* XXX: should be 2 once #128 is implemented. */)?;
3667
3668 Ok(())
3669 }
3670
3671 /// Tests the order of signatures given to
3672 /// VerificationHelper::check().
3673 #[test]
3674 fn verifier_levels() -> Result<()> {
3675 let p = P::new();
3676
3677 struct VHelper(());
3678 impl VerificationHelper for VHelper {
3679 fn get_certs(&mut self, _ids: &[crate::KeyHandle])
3680 -> Result<Vec<Cert>> {
3681 Ok(Vec::new())
3682 }
3683
3684 fn check(&mut self, structure: MessageStructure) -> Result<()> {
3685 assert_eq!(structure.iter().count(), 2);
3686 for (i, layer) in structure.into_iter().enumerate() {
3687 match layer {
3688 MessageLayer::SignatureGroup { results } => {
3689 assert_eq!(results.len(), 1);
3690 if let Err(VerificationError::MissingKey {
3691 sig, ..
3692 }) = &results[0] {
3693 assert_eq!(
3694 &sig.issuer_fingerprints().next().unwrap()
3695 .to_hex(),
3696 match i {
3697 0 => "8E8C33FA4626337976D97978069C0C348DD82C19",
3698 1 => "C03FA6411B03AE12576461187223B56678E02528",
3699 _ => unreachable!(),
3700 }
3701 );
3702 } else {
3703 unreachable!()
3704 }
3705 },
3706 _ => unreachable!(),
3707 }
3708 }
3709 Ok(())
3710 }
3711 }
3712 impl DecryptionHelper for VHelper {
3713 fn decrypt(&mut self, _: &[PKESK], _: &[SKESK],
3714 _: Option<SymmetricAlgorithm>,
3715 _: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
3716 -> Result<Option<Cert>>
3717 {
3718 unreachable!();
3719 }
3720 }
3721
3722 // Test verifier.
3723 let v = VerifierBuilder::from_bytes(
3724 crate::tests::message("signed-1-notarized-by-ed25519.pgp"))?
3725 .with_policy(&p, crate::frozen_time(), VHelper(()))?;
3726 assert!(v.message_processed());
3727 assert_eq!(v.processing_csf_message(), Some(false));
3728
3729 // Test decryptor.
3730 let v = DecryptorBuilder::from_bytes(
3731 crate::tests::message("signed-1-notarized-by-ed25519.pgp"))?
3732 .with_policy(&p, crate::frozen_time(), VHelper(()))?;
3733 assert!(v.message_processed());
3734 Ok(())
3735 }
3736
3737 #[test]
3738 fn detached_verifier() -> Result<()> {
3739 fn zeros() -> &'static [u8] {
3740 use std::sync::OnceLock;
3741 static ZEROS: OnceLock<Vec<u8>> = OnceLock::new();
3742 ZEROS.get_or_init(|| vec![0; 100 * 1024 * 1024])
3743 }
3744
3745 let p = P::new();
3746
3747 struct Test<'a> {
3748 sig: Vec<u8>,
3749 content: &'a [u8],
3750 reference: time::SystemTime,
3751 }
3752 let tests = [
3753 Test {
3754 sig: crate::tests::message(
3755 "a-cypherpunks-manifesto.txt.ed25519.sig").to_vec(),
3756 content: crate::tests::manifesto(),
3757 reference: crate::frozen_time(),
3758 },
3759 // The same, but with a marker packet.
3760 Test {
3761 sig: {
3762 let sig = crate::PacketPile::from_bytes(
3763 crate::tests::message(
3764 "a-cypherpunks-manifesto.txt.ed25519.sig"))?;
3765 let mut buf = Vec::new();
3766 Packet::Marker(Default::default()).serialize(&mut buf)?;
3767 sig.serialize(&mut buf)?;
3768 buf
3769 },
3770 content: crate::tests::manifesto(),
3771 reference: crate::frozen_time(),
3772 },
3773 Test {
3774 sig: crate::tests::message(
3775 "emmelie-dorothea-dina-samantha-awina-detached-signature-of-100MB-of-zeros.sig")
3776 .to_vec(),
3777 content: zeros(),
3778 reference:
3779 crate::types::Timestamp::try_from(1572602018).unwrap().into(),
3780 },
3781 ];
3782
3783 let certs = [
3784 "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"
3785 ].iter()
3786 .map(|f| Cert::from_bytes(crate::tests::key(f)).unwrap())
3787 .collect::<Vec<_>>();
3788
3789 for test in tests.iter() {
3790 let sig = &test.sig;
3791 let content = test.content;
3792 let reference = test.reference;
3793
3794 let h = VHelper::new(0, 0, 0, 0, false, certs.clone());
3795 let mut v = DetachedVerifierBuilder::from_bytes(sig).unwrap()
3796 .with_policy(&p, reference, h).unwrap();
3797 v.verify_bytes(content).unwrap();
3798
3799 let h = v.into_helper();
3800 assert_eq!(h.good, 1);
3801 assert_eq!(h.bad, 0);
3802 }
3803 Ok(())
3804 }
3805
3806 #[test]
3807 fn issue_682() -> Result<()> {
3808 let p = P::new();
3809 let sig = crate::tests::message("signature-with-broken-mpis.sig");
3810
3811 let h = VHelper::new(0, 0, 0, 0, false, vec![]);
3812 let mut v = DetachedVerifierBuilder::from_bytes(sig)?
3813 .with_policy(&p, None, h)?;
3814
3815 assert!(v.verify_bytes(b"").is_err());
3816
3817 let h = v.into_helper();
3818 assert_eq!(h.bad, 1);
3819
3820 Ok(())
3821 }
3822
3823 #[test]
3824 fn verify_long_message() -> Result<()> {
3825 use std::io::Write;
3826 use crate::serialize::stream::{LiteralWriter, Signer, Message};
3827
3828 let p = &P::new();
3829
3830 let (cert, _) = CertBuilder::new()
3831 .set_cipher_suite(CipherSuite::Cv25519)
3832 .add_signing_subkey()
3833 .generate().unwrap();
3834
3835 // sign 3MiB message
3836 let mut buf = vec![];
3837 {
3838 let key = cert.keys().with_policy(p, None).for_signing().next().unwrap().key();
3839 let keypair =
3840 key.clone().parts_into_secret().unwrap()
3841 .into_keypair().unwrap();
3842
3843 let m = Message::new(&mut buf);
3844 let signer = Signer::new(m, keypair)?.build().unwrap();
3845 let mut ls = LiteralWriter::new(signer).build().unwrap();
3846
3847 ls.write_all(&mut vec![42u8; 3 * 1024 * 1024]).unwrap();
3848 ls.finalize().unwrap();
3849 }
3850
3851 // Test Verifier.
3852 let h = VHelper::new(0, 0, 0, 0, false, vec![cert.clone()]);
3853 let mut v = VerifierBuilder::from_bytes(&buf)?
3854 .buffer_size(2 * 2usize.pow(20))
3855 .with_policy(p, None, h)?;
3856
3857 assert!(!v.message_processed());
3858 assert!(v.helper_ref().good == 0);
3859 assert!(v.helper_ref().bad == 0);
3860 assert!(v.helper_ref().unknown == 0);
3861 assert!(v.helper_ref().error == 0);
3862
3863 let mut message = Vec::new();
3864
3865 v.read_to_end(&mut message).unwrap();
3866
3867 assert!(v.message_processed());
3868 assert_eq!(v.processing_csf_message(), Some(false));
3869 assert_eq!(3 * 1024 * 1024, message.len());
3870 assert!(message.iter().all(|&b| b == 42));
3871 assert!(v.helper_ref().good == 1);
3872 assert!(v.helper_ref().bad == 0);
3873 assert!(v.helper_ref().unknown == 0);
3874 assert!(v.helper_ref().error == 0);
3875
3876 // Try the same, but this time we let .check() fail.
3877 let h = VHelper::new(0, 0, /* makes check() fail: */ 1, 0,
3878 false, vec![cert.clone()]);
3879 let mut v = VerifierBuilder::from_bytes(&buf)?
3880 .buffer_size(2 * 2usize.pow(20))
3881 .with_policy(p, None, h)?;
3882
3883 assert!(!v.message_processed());
3884 assert_eq!(v.processing_csf_message(), Some(false));
3885 assert!(v.helper_ref().good == 0);
3886 assert!(v.helper_ref().bad == 1);
3887 assert!(v.helper_ref().unknown == 0);
3888 assert!(v.helper_ref().error == 0);
3889
3890 let mut message = Vec::new();
3891 let r = v.read_to_end(&mut message);
3892 assert!(r.is_err());
3893
3894 // Check that we only got a truncated message.
3895 assert!(v.message_processed());
3896 assert_eq!(v.processing_csf_message(), Some(false));
3897 assert!(!message.is_empty());
3898 assert!(message.len() <= 1 * 1024 * 1024);
3899 assert!(message.iter().all(|&b| b == 42));
3900 assert!(v.helper_ref().good == 1);
3901 assert!(v.helper_ref().bad == 1);
3902 assert!(v.helper_ref().unknown == 0);
3903 assert!(v.helper_ref().error == 0);
3904
3905 // Test Decryptor.
3906 let h = VHelper::new(0, 0, 0, 0, false, vec![cert.clone()]);
3907 let mut v = DecryptorBuilder::from_bytes(&buf)?
3908 .buffer_size(2 * 2usize.pow(20))
3909 .with_policy(p, None, h)?;
3910
3911 assert!(!v.message_processed());
3912 assert!(v.helper_ref().good == 0);
3913 assert!(v.helper_ref().bad == 0);
3914 assert!(v.helper_ref().unknown == 0);
3915 assert!(v.helper_ref().error == 0);
3916
3917 let mut message = Vec::new();
3918
3919 v.read_to_end(&mut message).unwrap();
3920
3921 assert!(v.message_processed());
3922 assert_eq!(3 * 1024 * 1024, message.len());
3923 assert!(message.iter().all(|&b| b == 42));
3924 assert!(v.helper_ref().good == 1);
3925 assert!(v.helper_ref().bad == 0);
3926 assert!(v.helper_ref().unknown == 0);
3927 assert!(v.helper_ref().error == 0);
3928
3929 // Try the same, but this time we let .check() fail.
3930 let h = VHelper::new(0, 0, /* makes check() fail: */ 1, 0,
3931 false, vec![cert.clone()]);
3932 let mut v = DecryptorBuilder::from_bytes(&buf)?
3933 .buffer_size(2 * 2usize.pow(20))
3934 .with_policy(p, None, h)?;
3935
3936 assert!(!v.message_processed());
3937 assert!(v.helper_ref().good == 0);
3938 assert!(v.helper_ref().bad == 1);
3939 assert!(v.helper_ref().unknown == 0);
3940 assert!(v.helper_ref().error == 0);
3941
3942 let mut message = Vec::new();
3943 let r = v.read_to_end(&mut message);
3944 assert!(r.is_err());
3945
3946 // Check that we only got a truncated message.
3947 assert!(v.message_processed());
3948 assert!(!message.is_empty());
3949 assert!(message.len() <= 1 * 1024 * 1024);
3950 assert!(message.iter().all(|&b| b == 42));
3951 assert!(v.helper_ref().good == 1);
3952 assert!(v.helper_ref().bad == 1);
3953 assert!(v.helper_ref().unknown == 0);
3954 assert!(v.helper_ref().error == 0);
3955 Ok(())
3956 }
3957
3958 /// Checks that tampering with the MDC yields a uniform error
3959 /// response.
3960 #[test]
3961 fn issue_693() -> Result<()> {
3962 struct H();
3963 impl VerificationHelper for H {
3964 fn get_certs(&mut self, _ids: &[crate::KeyHandle])
3965 -> Result<Vec<Cert>> {
3966 Ok(Vec::new())
3967 }
3968
3969 fn check(&mut self, _: MessageStructure)
3970 -> Result<()> {
3971 Ok(())
3972 }
3973 }
3974 impl DecryptionHelper for H {
3975 fn decrypt(&mut self, _: &[PKESK], s: &[SKESK],
3976 _: Option<SymmetricAlgorithm>,
3977 decrypt: &mut dyn FnMut(Option<SymmetricAlgorithm>, &SessionKey) -> bool)
3978 -> Result<Option<Cert>>
3979 {
3980 let (algo, sk) = s[0].decrypt(&"123".into()).unwrap();
3981 let r = decrypt(algo, &sk);
3982 assert!(r);
3983 Ok(None)
3984 }
3985 }
3986
3987 fn check(m: &str) -> Result<()> {
3988 let doit = || -> Result<()> {
3989 let p = &P::new();
3990 let mut decryptor = DecryptorBuilder::from_bytes(m.as_bytes())?
3991 .with_policy(p, None, H())?;
3992 let mut b = Vec::new();
3993 decryptor.read_to_end(&mut b)?;
3994 Ok(())
3995 };
3996
3997 let e = doit().unwrap_err();
3998 match e.downcast::<io::Error>() {
3999 Ok(e) =>
4000 assert_eq!(e.into_inner().unwrap().downcast().unwrap(),
4001 Box::new(Error::ManipulatedMessage)),
4002 Err(e) =>
4003 assert_eq!(e.downcast::<Error>().unwrap(),
4004 Error::ManipulatedMessage),
4005 };
4006 Ok(())
4007 }
4008
4009 // Bad hash.
4010 check("-----BEGIN PGP MESSAGE-----
4011
4012wx4EBwMI7dKRUiOYGCUAWmzhiYGS8Pn/16QkyTous6vSOgFMcilte26C7kej
4013rKhvjj6uYNT+mt+L2Yg/FHFvpgVF3KfP0fb+9jZwgt4qpDkTMY7AWPTK6wXX
4014Jo8=
4015=LS8u
4016-----END PGP MESSAGE-----
4017")?;
4018
4019 // Bad header.
4020 check("-----BEGIN PGP MESSAGE-----
4021
4022wx4EBwMI7sPTdlgQwd8AogIcbF/hLVrYbvVbgj4EC6/SOgGNaCyffrR4Fuwl
4023Ft2w56/hB/gTaGEhCgDGXg8NiFGIURqF3eIwxxdKWghUutYmsGwqOZmdJ49a
40249gE=
4025=DzKF
4026-----END PGP MESSAGE-----
4027")?;
4028
4029 // Bad header matching other packet type.
4030 check("-----BEGIN PGP MESSAGE-----
4031
4032wx4EBwMIhpEGBh3v0oMAYgGcj+4CG1mcWQwmyGIDRdvSOgFSHlL2GZ1ZKeXS
403329kScqGg2U8N6ZF9vmj/9Sn7CFtO5PGXn2owQVsopeUSTofV3BNUBpxaBDCO
4034EK8=
4035=TgeJ
4036-----END PGP MESSAGE-----
4037")?;
4038
4039 Ok(())
4040 }
4041
4042 /// Tests samples of messages signed with the cleartext signature
4043 /// framework.
4044 #[test]
4045 fn csf_verification() -> Result<()> {
4046 struct H(Vec<Cert>, bool);
4047 impl VerificationHelper for H {
4048 fn get_certs(&mut self, _ids: &[crate::KeyHandle])
4049 -> Result<Vec<Cert>> {
4050 Ok(std::mem::take(&mut self.0))
4051 }
4052
4053 fn check(&mut self, m: MessageStructure)
4054 -> Result<()> {
4055 for (i, layer) in m.into_iter().enumerate() {
4056 assert_eq!(i, 0);
4057 if let MessageLayer::SignatureGroup { results } = layer {
4058 assert!(! results.is_empty());
4059 for result in results {
4060 result.unwrap();
4061 }
4062 self.1 = true;
4063 } else {
4064 panic!();
4065 }
4066 }
4067
4068 Ok(())
4069 }
4070 }
4071
4072 for (m, c) in [
4073 ("InRelease", "InRelease.signers.pgp"),
4074 ("InRelease.msft", "InRelease.msft.signers.pgp"),
4075 ("InRelease.v3", "InRelease.v3.signers.pgp"),
4076 ] {
4077 let certs = crate::cert::CertParser::from_bytes(
4078 crate::tests::key(c))?.collect::<Result<Vec<_>>>()?;
4079
4080 // The Microsoft cert uses SHA-1.
4081 let p = unsafe { &NP::new() };
4082 eprintln!("Parsing {}...", m);
4083 let mut verifier = VerifierBuilder::from_bytes(
4084 crate::tests::message(m))?
4085 .with_policy(p, None, H(certs, false))?;
4086 let mut b = Vec::new();
4087 verifier.read_to_end(&mut b)?;
4088 assert_eq!(verifier.processing_csf_message(), Some(true));
4089 let h = verifier.into_helper();
4090 assert!(h.1);
4091 }
4092
4093 Ok(())
4094 }
4095
4096 /// Tests whether messages using the cleartext signature framework
4097 /// with multiple signatures and signers are correctly handled.
4098 #[test]
4099 fn csf_multiple_signers() -> Result<()> {
4100 struct H(bool);
4101 impl VerificationHelper for H {
4102 fn get_certs(&mut self, _ids: &[crate::KeyHandle])
4103 -> Result<Vec<Cert>> {
4104 crate::cert::CertParser::from_bytes(
4105 crate::tests::key("InRelease.signers.pgp"))?
4106 .collect()
4107 }
4108
4109 fn check(&mut self, m: MessageStructure)
4110 -> Result<()> {
4111 for (i, layer) in m.into_iter().enumerate() {
4112 assert_eq!(i, 0);
4113 if let MessageLayer::SignatureGroup { results } = layer {
4114 assert_eq!(results.len(), 3);
4115 for result in results {
4116 assert!(result.is_ok());
4117 }
4118 self.0 = true;
4119 } else {
4120 panic!();
4121 }
4122 }
4123
4124 Ok(())
4125 }
4126 }
4127
4128 let p = &P::new();
4129 let mut verifier = VerifierBuilder::from_bytes(
4130 crate::tests::message("InRelease"))?
4131 .with_policy(p, None, H(false))?;
4132 let mut b = Vec::new();
4133 verifier.read_to_end(&mut b)?;
4134 assert_eq!(verifier.processing_csf_message(), Some(true));
4135 let h = verifier.into_helper();
4136 assert!(h.0);
4137 Ok(())
4138 }
4139
4140 /// This sample from our test suite generated using GnuPG.
4141 #[test]
4142 fn v4skesk_v1seip_aes128() -> Result<()> {
4143 test_password_encrypted_message(
4144 SymmetricAlgorithm::AES128,
4145 "messages/encrypted-aes128-password-123456789.pgp",
4146 "123456789",
4147 crate::tests::manifesto())
4148 }
4149
4150 /// This sample from our test suite generated using GnuPG.
4151 #[test]
4152 fn v4skesk_v1seip_aes192() -> Result<()> {
4153 test_password_encrypted_message(
4154 SymmetricAlgorithm::AES192,
4155 "messages/encrypted-aes192-password-123456.pgp",
4156 "123456",
4157 crate::tests::manifesto())
4158 }
4159
4160 /// This sample from our test suite generated using GnuPG.
4161 #[test]
4162 fn v4skesk_v1seip_aes256() -> Result<()> {
4163 test_password_encrypted_message(
4164 SymmetricAlgorithm::AES256,
4165 "messages/encrypted-aes256-password-123.pgp",
4166 "123",
4167 crate::tests::manifesto())
4168 }
4169
4170 fn test_password_encrypted_message(cipher: SymmetricAlgorithm,
4171 name: &str,
4172 password: &str,
4173 plaintext: &[u8])
4174 -> Result<()> {
4175 if ! cipher.is_supported() {
4176 eprintln!("Skipping test vector {:?}...", name);
4177 return Ok(());
4178 }
4179
4180 eprintln!("Test vector {:?}...", name);
4181
4182 let p = &P::new();
4183 let password: Password = String::from(password).into();
4184
4185 let h = VHelper::for_decryption(0, 0, 0, 0, vec![], vec![],
4186 vec![password]);
4187 let mut d = DecryptorBuilder::from_bytes(crate::tests::file(name))?
4188 .with_policy(p, None, h)?;
4189 assert!(d.message_processed());
4190
4191 let mut content = Vec::new();
4192 d.read_to_end(&mut content).unwrap();
4193 assert_eq!(&content, plaintext);
4194
4195 Ok(())
4196 }
4197
4198 /// Checks for a crash with signatures that are unaccounted for.
4199 #[test]
4200 fn unaccounted_signatures() -> Result<()> {
4201 let p = P::new();
4202 let m = b"-----BEGIN PGP MESSAGE-----
4203
4204wgoEAAAAAAB6CkAAxADLBq8AAKurq8IKBCC/CAAAAAD0sA==
4205=KRn6
4206-----END PGP MESSAGE-----
4207";
4208
4209 let mut h = VHelper::new(0, 0, 0, 0, false, vec![
4210 Cert::from_bytes(crate::tests::key("testy.pgp"))?,
4211 ]);
4212 h.error_out = false;
4213 VerifierBuilder::from_bytes(m)?
4214 .with_policy(&p, None, h)
4215 .unwrap();
4216 Ok(())
4217 }
4218
4219 /// Checks for a crash related to HashedReader's HashingMode.
4220 #[test]
4221 fn csf_hashing_mode_assertion_failure() -> Result<()> {
4222 let p = P::new();
4223 let m = b"-----BEGIN PGP SIGNED MESSAGE-----
4224---BEGIN PGP SIGNATURE
42250iHUEARYIAB0QCyUHMcArrZbte9msAndEO9clJG5wpCAEA2/";
4226
4227 let mut h = VHelper::new(0, 0, 0, 0, true, vec![
4228 Cert::from_bytes(crate::tests::key("testy.pgp"))?,
4229 ]);
4230 h.error_out = false;
4231 let _ = VerifierBuilder::from_bytes(m)?
4232 .with_policy(&p, None, h);
4233 Ok(())
4234 }
4235
4236 /// Checks for a crash related to HashedReader's assumptions about
4237 /// the number of signature groups.
4238 #[test]
4239 fn csf_sig_group_count_assertion_failure() -> Result<()> {
4240 let p = P::new();
4241 let m = b"-----BEGIN PGP SIGNED MESSAGE-----
4242-----BEGIN PGP SIGNATURE-----
4243xHUDBRY0WIQ+50WENDPP";
4244
4245 let mut h = VHelper::new(0, 0, 0, 0, true, vec![
4246 Cert::from_bytes(crate::tests::key("testy.pgp"))?,
4247 ]);
4248 h.error_out = false;
4249 let _ = VerifierBuilder::from_bytes(m)?
4250 .with_policy(&p, None, h);
4251 Ok(())
4252 }
4253
4254 /// Tests that the message structure is checked at the end of
4255 /// parsing the packet stream.
4256 #[test]
4257 fn message_grammar_check() -> Result<()> {
4258 let p = P::new();
4259 let certs = vec![Cert::from_bytes(crate::tests::key("neal.pgp"))?];
4260 let helper = VHelper::new(1, 0, 0, 0, false, certs.clone());
4261
4262 let pp = crate::PacketPile::from_bytes(
4263 crate::tests::message("signed-1-notarized-by-ed25519.pgp"))?;
4264 let mut buf = Vec::new();
4265 assert_eq!(pp.children().count(), 5);
4266 // Drop the last signature packet! Now the OPS and Signature
4267 // packets no longer bracket.
4268 pp.children().take(4).for_each(|p| p.serialize(&mut buf).unwrap());
4269
4270 // Test verifier.
4271 let do_it = || -> Result<()> {
4272 let v = VerifierBuilder::from_bytes(&buf)?
4273 .with_policy(&p, crate::frozen_time(), helper.clone())?;
4274 assert!(v.message_processed());
4275 Ok(())
4276 };
4277 assert!(do_it().is_err());
4278
4279 // Test decryptor.
4280 let do_it = || -> Result<()> {
4281 let v = DecryptorBuilder::from_bytes(&buf)?
4282 .with_policy(&p, crate::frozen_time(), helper)?;
4283 assert!(v.message_processed());
4284 Ok(())
4285 };
4286 assert!(do_it().is_err());
4287
4288 Ok(())
4289 }
4290
4291 /// Tests that an inline-signed message using two different hash
4292 /// algorithms verifies correctly.
4293 #[test]
4294 fn inline_signed_two_hashes() -> Result<()> {
4295 use crate::{
4296 types::{DataFormat, HashAlgorithm, SignatureType},
4297 packet::Literal,
4298 parse::SignatureBuilder,
4299 };
4300 let p = P::new();
4301 let cert = Cert::from_bytes(crate::tests::key("testy-private.pgp"))?;
4302 let helper = VHelper::new(0, 0, 0, 0, false, vec![cert.clone()]);
4303 let mut signer = cert.primary_key().key().clone().parts_into_secret()?
4304 .into_keypair()?;
4305 let msg = b"Hello, world!";
4306 let sig0 = SignatureBuilder::new(SignatureType::Binary)
4307 .set_signature_creation_time(crate::frozen_time())?
4308 .set_hash_algo(HashAlgorithm::SHA256)
4309 .sign_message(&mut signer, msg)?;
4310 let sig1 = SignatureBuilder::new(SignatureType::Binary)
4311 .set_signature_creation_time(crate::frozen_time())?
4312 .set_hash_algo(HashAlgorithm::SHA512)
4313 .sign_message(&mut signer, msg)?;
4314 let packets: Vec<Packet> = vec![
4315 OnePassSig::try_from(&sig0)?.into(),
4316 {
4317 let mut ops = OnePassSig::try_from(&sig1)?;
4318 ops.set_last(true);
4319 ops.into()
4320 },
4321 {
4322 let mut lit = Literal::new(DataFormat::Binary);
4323 lit.set_body((*msg).into());
4324 lit.into()
4325 },
4326 sig1.into(),
4327 sig0.into(),
4328 ];
4329 let mut buf = Vec::new();
4330 packets.iter().for_each(|p| p.serialize(&mut buf).unwrap());
4331 let v = VerifierBuilder::from_bytes(&buf)?
4332 .with_policy(&p, crate::frozen_time(), helper)?;
4333 assert_eq!(v.processing_csf_message(), Some(false));
4334 assert!(v.message_processed());
4335 assert_eq!(v.helper_ref().good, 2);
4336
4337 Ok(())
4338 }
4339
4340 /// This sample packet is from RFC9580.
4341 #[test]
4342 fn v6skesk_v2seip_aes128_ocb() -> Result<()> {
4343 sample_skesk6_packet(
4344 SymmetricAlgorithm::AES128,
4345 AEADAlgorithm::OCB,
4346 "password",
4347 "crypto-refresh/v6skesk-aes128-ocb.pgp",
4348 b"Hello, world!")
4349 }
4350
4351 /// This sample packet is from RFC9580.
4352 #[test]
4353 fn v6skesk_v2seip_aes128_eax() -> Result<()> {
4354 sample_skesk6_packet(
4355 SymmetricAlgorithm::AES128,
4356 AEADAlgorithm::EAX,
4357 "password",
4358 "crypto-refresh/v6skesk-aes128-eax.pgp",
4359 b"Hello, world!")
4360 }
4361
4362 /// This sample packet is from RFC9580.
4363 #[test]
4364 fn v6skesk_v2seip_aes128_gcm() -> Result<()> {
4365 sample_skesk6_packet(
4366 SymmetricAlgorithm::AES128,
4367 AEADAlgorithm::GCM,
4368 "password",
4369 "crypto-refresh/v6skesk-aes128-gcm.pgp",
4370 b"Hello, world!")
4371 }
4372
4373 fn sample_skesk6_packet(cipher: SymmetricAlgorithm,
4374 aead: AEADAlgorithm,
4375 password: &str,
4376 name: &str,
4377 plaintext: &[u8])
4378 -> Result<()> {
4379 use crate::crypto::backend::{Backend, interface::Aead};
4380 if ! Backend::supports_algo_with_symmetric(aead, cipher)
4381 {
4382 eprintln!("Skipping test vector {:?}...", name);
4383 return Ok(());
4384 }
4385
4386 eprintln!("Test vector {:?}...", name);
4387
4388 let p = &P::new();
4389 let password: Password = String::from(password).into();
4390
4391 let h = VHelper::for_decryption(0, 0, 0, 0, vec![], vec![],
4392 vec![password]);
4393 let mut d = DecryptorBuilder::from_bytes(crate::tests::file(name))?
4394 .with_policy(p, None, h)?;
4395 assert!(d.message_processed());
4396
4397 let mut content = Vec::new();
4398 d.read_to_end(&mut content).unwrap();
4399 assert_eq!(&content, plaintext);
4400
4401 Ok(())
4402 }
4403
4404 // Check that the `signature` over `data` can be verified using
4405 // `cert`.
4406 fn check_detached_sig(cert: &str, sig: &str, data: &[u8])
4407 -> Result<()>
4408 {
4409 eprintln!("Test vector {}/{}...", cert, sig);
4410
4411 let cert = Cert::from_bytes(crate::tests::file(cert))?;
4412 eprintln!("Cert: {:?}", cert.fingerprint());
4413
4414 if let Some(unknown) = cert.keys().find_map(|ka| {
4415 if ka.key().pk_algo().is_supported() {
4416 None
4417 } else {
4418 Some(ka.key().pk_algo())
4419 }
4420 })
4421 {
4422 eprintln!("{}: {} is not supported, skipping.",
4423 cert, unknown);
4424 return Ok(());
4425 }
4426
4427 let h = VHelper::new(0, 0, 0, 0, false, vec![cert]);
4428 let p = &P::new();
4429 let mut v = DetachedVerifierBuilder::from_bytes(
4430 crate::tests::file(sig))?
4431 .with_policy(p, None, h)?;
4432
4433 let result = v.verify_bytes(data);
4434 eprintln!("Result: {:?}", result);
4435
4436 result.expect("valid signature");
4437
4438 let h = v.into_helper();
4439 assert_eq!(h.good, 1);
4440
4441 Ok(())
4442 }
4443
4444 #[test]
4445 fn test_detached_sigs() -> Result<()> {
4446 let detached_sigs = vec![
4447 // ietf draft test vectors
4448 (
4449 "pqc/ietf/v6-mldsa-65-sample-pk.pgp",
4450 "pqc/ietf/v6-mldsa-65-sample-signature.pgp",
4451 "Testing\n"
4452 ),
4453 (
4454 "pqc/ietf/v6-mldsa-87-sample-pk.pgp",
4455 "pqc/ietf/v6-mldsa-87-sample-signature.pgp",
4456 "Testing\n"
4457 ),
4458 (
4459 "pqc/ietf/v6-slhdsa-128s-sample-pk.pgp",
4460 "pqc/ietf/v6-slhdsa-128s-sample-signature.pgp",
4461 "Testing\n"
4462 ),
4463 (
4464 "pqc/ietf/v6-slhdsa-128f-sample-pk.pgp",
4465 "pqc/ietf/v6-slhdsa-128f-sample-signature.pgp",
4466 "Testing\n"
4467 ),
4468 (
4469 "pqc/ietf/v6-slhdsa-256s-sample-pk.pgp",
4470 "pqc/ietf/v6-slhdsa-256s-sample-signature.pgp",
4471 "Testing\n"
4472 ),
4473 // rpgp artifacts
4474 (
4475 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519_alice_pk.pgp",
4476 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519_detached_sig.pgp",
4477 "Hello World\n"
4478 ),
4479 (
4480 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-ed25519-mlkem768x25519_alice_pk.pgp",
4481 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-ed25519-mlkem768x25519_detached_sig.pgp",
4482 "Hello World\n"
4483 ),
4484 (
4485 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa65ed25519-mlkem768x25519_alice_pk.pgp",
4486 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa65ed25519-mlkem768x25519_detached_sig.pgp",
4487 "Hello World\n"
4488 ),
4489 (
4490 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa87ed448-mlkem1024x448_alice_pk.pgp",
4491 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-mldsa87ed448-mlkem1024x448_detached_sig.pgp",
4492 "Hello World\n"
4493 ),
4494 (
4495 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128f-mlkem768x25519_alice_pk.pgp",
4496 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128f-mlkem768x25519_detached_sig.pgp",
4497 "Hello World\n"
4498 ),
4499 (
4500 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128s-mlkem768x25519_alice_pk.pgp",
4501 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake128s-mlkem768x25519_detached_sig.pgp",
4502 "Hello World\n"
4503 ),
4504 (
4505 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake256s-mlkem1024x448_alice_pk.pgp",
4506 "pqc/rpgp/rsop_draft-ietf-openpgp-pqc-08-v6-slhdsashake256s-mlkem1024x448_detached_sig.pgp",
4507 "Hello World\n"
4508 ),
4509 // gopenpgp artifacts
4510 (
4511 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09_alice_pk.pgp",
4512 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09_detached_sig.pgp",
4513 "Hello World\n"
4514 ),
4515 (
4516 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09-high-security_alice_pk.pgp",
4517 "pqc/gopenpgp/gosop_draft-ietf-openpgp-pqc-09-high-security_detached_sig.pgp",
4518 "Hello World\n"
4519 ),
4520 ];
4521
4522 for (cert_file, detached_sig, data) in detached_sigs {
4523 check_detached_sig(cert_file, detached_sig, data.as_bytes())
4524 .expect("valid signature");
4525 }
4526 Ok(())
4527 }
4528}