1 //! Streaming packet serialization. 2 //! 3 //! This interface provides a convenient way to create signed and/or 4 //! encrypted OpenPGP messages (see [Section 11.3 of RFC 4880]) and is 5 //! the preferred interface to generate messages using Sequoia. It 6 //! takes advantage of OpenPGP's streaming nature to avoid unnecessary 7 //! buffering. 8 //! 9 //! [Section 11.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.3 10 //! 11 //! To use this interface, a sink implementing [`io::Write`] is 12 //! wrapped by [`Message::new`] returning a streaming [`Message`]. 13 //! The writer stack is a structure to compose filters that create the 14 //! desired message structure. There are a number of filters that can 15 //! be freely combined: 16 //! 17 //! - [`Armorer`] applies ASCII-Armor to the stream, 18 //! - [`Encryptor`] encrypts data fed into it, 19 //! - [`Compressor`] compresses data, 20 //! - [`Padder`] pads data, 21 //! - [`Signer`] signs data, 22 //! - [`LiteralWriter`] wraps literal data (i.e. the payload) into 23 //! a literal data packet, 24 //! - and finally, [`ArbitraryWriter`] can be used to create 25 //! arbitrary packets for testing purposes. 26 //! 27 //! [`io::Write`]: https://doc.rust-lang.org/nightly/std/io/trait.Write.html 28 //! [`Message::new`]: struct.Message.html#method.new 29 //! [`Message`]: struct.Message.html 30 //! [`Armorer`]: struct.Armorer.html 31 //! [`Encryptor`]: struct.Encryptor.html 32 //! [`Compressor`]: struct.Compressor.html 33 //! [`Padder`]: padding/struct.Padder.html 34 //! [`Signer`]: struct.Signer.html 35 //! [`LiteralWriter`]: struct.LiteralWriter.html 36 //! [`ArbitraryWriter`]: struct.ArbitraryWriter.html 37 //! 38 //! The most common structure is an optionally encrypted, optionally 39 //! compressed, and optionally signed message. This structure is 40 //! [supported] by all OpenPGP implementations, and applications 41 //! should only create messages of that structure to increase 42 //! compatibility. See the example below on how to create this 43 //! structure. This is a sketch of such a message: 44 //! 45 //! ```text 46 //! [ encryption layer: [ compression layer: [ signature group: [ literal data ]]]] 47 //! ``` 48 //! 49 //! [supported]: https://tests.sequoia-pgp.org/#Unusual_Message_Structure 50 //! 51 //! # Examples 52 //! 53 //! This example demonstrates how to create the simplest possible 54 //! OpenPGP message (see [Section 11.3 of RFC 4880]) containing just a 55 //! literal data packet (see [Section 5.9 of RFC 4880]): 56 //! 57 //! [Section 5.9 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.9 58 //! 59 //! ``` 60 //! # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 61 //! use std::io::Write; 62 //! use sequoia_openpgp as openpgp; 63 //! use openpgp::serialize::stream::{Message, LiteralWriter}; 64 //! 65 //! let mut sink = vec![]; 66 //! { 67 //! let message = Message::new(&mut sink); 68 //! let mut message = LiteralWriter::new(message).build()?; 69 //! message.write_all(b"Hello world.")?; 70 //! message.finalize()?; 71 //! } 72 //! assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", sink.as_slice()); 73 //! # Ok(()) } 74 //! ``` 75 //! 76 //! This example demonstrates how to create the most common OpenPGP 77 //! message structure (see [Section 11.3 of RFC 4880]). The plaintext 78 //! is first signed, then compressed, encrypted, and finally ASCII 79 //! armored. Our example pads the plaintext instead of compressing 80 //! it, but the resulting message structure is the same. 81 //! 82 //! ``` 83 //! # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 84 //! use std::io::Write; 85 //! use sequoia_openpgp as openpgp; 86 //! use openpgp::policy::StandardPolicy; 87 //! use openpgp::cert::prelude::*; 88 //! use openpgp::serialize::stream::{ 89 //! Message, Armorer, Encryptor, Signer, LiteralWriter, 90 //! padding::{Padder, padme}, 91 //! }; 92 //! # use openpgp::parse::Parse; 93 //! 94 //! let p = &StandardPolicy::new(); 95 //! 96 //! let sender: Cert = // ... 97 //! # Cert::from_bytes(&include_bytes!( 98 //! # "../../tests/data/keys/testy-new-private.pgp")[..])?; 99 //! let signing_keypair = sender.keys().secret() 100 //! .with_policy(p, None).alive().revoked(false).for_signing() 101 //! .nth(0).unwrap() 102 //! .key().clone().into_keypair()?; 103 //! 104 //! let recipient: Cert = // ... 105 //! # sender.clone(); 106 //! // Note: One certificate may contain several suitable encryption keys. 107 //! let recipients = 108 //! recipient.keys().with_policy(p, None).alive().revoked(false) 109 //! // Or `for_storage_encryption()`, for data at rest. 110 //! .for_transport_encryption() 111 //! .map(|ka| ka.key()); 112 //! 113 //! # let mut sink = vec![]; 114 //! let message = Message::new(&mut sink); 115 //! let message = Armorer::new(message).build()?; 116 //! let message = Encryptor::for_recipients(message, recipients).build()?; 117 //! // Reduce metadata leakage by concealing the message size. 118 //! let message = Padder::new(message, padme)?; 119 //! let message = Signer::new(message, signing_keypair) 120 //! // Prevent Surreptitious Forwarding. 121 //! .add_intended_recipient(&recipient) 122 //! .build()?; 123 //! let mut message = LiteralWriter::new(message).build()?; 124 //! message.write_all(b"Hello world.")?; 125 //! message.finalize()?; 126 //! # Ok(()) } 127 //! ``` 128 129 use std::fmt; 130 use std::io::{self, Write}; 131 use std::time::SystemTime; 132 133 use crate::{ 134 armor, 135 crypto, 136 Error, 137 Fingerprint, 138 HashAlgorithm, 139 KeyID, 140 Result, 141 crypto::Password, 142 crypto::SessionKey, 143 packet::prelude::*, 144 packet::signature, 145 packet::key, 146 cert::prelude::*, 147 }; 148 use crate::packet::header::CTB; 149 use crate::packet::header::BodyLength; 150 use super::{ 151 Marshal, 152 }; 153 use crate::types::{ 154 AEADAlgorithm, 155 CompressionAlgorithm, 156 CompressionLevel, 157 DataFormat, 158 SignatureType, 159 SymmetricAlgorithm, 160 }; 161 162 pub(crate) mod writer; 163 #[cfg(feature = "compression-deflate")] 164 pub mod padding; 165 mod partial_body; 166 use partial_body::PartialBodyFilter; 167 168 /// Cookie must be public because the writers are. 169 #[derive(Debug)] 170 struct Cookie { 171 level: usize, 172 private: Private, 173 } 174 175 #[derive(Debug)] 176 enum Private { 177 Nothing, 178 Signer, 179 } 180 181 impl Cookie { new(level: usize) -> Self182 fn new(level: usize) -> Self { 183 Cookie { 184 level, 185 private: Private::Nothing, 186 } 187 } 188 } 189 190 impl Default for Cookie { default() -> Self191 fn default() -> Self { 192 Cookie::new(0) 193 } 194 } 195 196 /// Streams an OpenPGP message. 197 /// 198 /// Wraps an [`io::Write`]r for use with the streaming subsystem. The 199 /// `Message` is a stack of filters that create the desired message 200 /// structure. Literal data must be framed using the 201 /// [`LiteralWriter`] filter. Once all the has been written, the 202 /// `Message` must be finalized using [`Message::finalize`]. 203 /// 204 /// [`io::Write`]: https://doc.rust-lang.org/nightly/std/io/trait.Write.html 205 /// [`LiteralWriter`]: struct.LiteralWriter.html 206 /// [`Message::finalize`]: #method.finalize 207 #[derive(Debug)] 208 pub struct Message<'a>(writer::BoxStack<'a, Cookie>); 209 210 impl<'a> Message<'a> { 211 /// Starts streaming an OpenPGP message. 212 /// 213 /// # Example 214 /// 215 /// ``` 216 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 217 /// use sequoia_openpgp as openpgp; 218 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 219 /// 220 /// # let mut sink = vec![]; // Vec<u8> implements io::Write. 221 /// let message = Message::new(&mut sink); 222 /// // Construct the writer stack here. 223 /// let mut message = LiteralWriter::new(message).build()?; 224 /// // Write literal data to `message` here. 225 /// // ... 226 /// // Finalize the message. 227 /// message.finalize()?; 228 /// # Ok(()) } 229 /// ``` new<W: 'a + io::Write>(w: W) -> Message<'a>230 pub fn new<W: 'a + io::Write>(w: W) -> Message<'a> { 231 writer::Generic::new(w, Cookie::new(0)) 232 } 233 234 /// Finalizes the topmost writer, returning the underlying writer. 235 /// 236 /// Finalizes the topmost writer, i.e. flushes any buffered data, 237 /// and pops it of the stack. This allows for fine-grained 238 /// control of the resulting message, but must be done with great 239 /// care. If done improperly, the resulting message may be 240 /// malformed. 241 /// 242 /// # Example 243 /// 244 /// This demonstrates how to create a compressed, signed message 245 /// from a detached signature. 246 /// 247 /// ``` 248 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 249 /// use std::io::Write; 250 /// use std::convert::TryFrom; 251 /// use sequoia_openpgp as openpgp; 252 /// use openpgp::packet::{Packet, Signature, one_pass_sig::OnePassSig3}; 253 /// # use openpgp::parse::Parse; 254 /// use openpgp::serialize::Serialize; 255 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter}; 256 /// 257 /// let data: &[u8] = // ... 258 /// # &include_bytes!( 259 /// # "../../tests/data/messages/a-cypherpunks-manifesto.txt")[..]; 260 /// let sig: Signature = // ... 261 /// # if let Packet::Signature(s) = Packet::from_bytes(&include_bytes!( 262 /// # "../../tests/data/messages/a-cypherpunks-manifesto.txt.ed25519.sig")[..])? 263 /// # { s } else { panic!() }; 264 /// 265 /// # let mut sink = vec![]; // Vec<u8> implements io::Write. 266 /// let message = Message::new(&mut sink); 267 /// let mut message = Compressor::new(message).build()?; 268 /// 269 /// // First, write a one-pass-signature packet. 270 /// Packet::from(OnePassSig3::try_from(&sig)?) 271 /// .serialize(&mut message)?; 272 /// 273 /// // Then, add the literal data. 274 /// let mut message = LiteralWriter::new(message).build()?; 275 /// message.write_all(data)?; 276 /// 277 /// // Finally, pop the `LiteralWriter` off the stack to write the 278 /// // signature. 279 /// let mut message = message.finalize_one()?.unwrap(); 280 /// Packet::from(sig).serialize(&mut message)?; 281 /// 282 /// // Finalize the message. 283 /// message.finalize()?; 284 /// # Ok(()) } 285 /// ``` finalize_one(self) -> Result<Option<Message<'a>>>286 pub fn finalize_one(self) -> Result<Option<Message<'a>>> { 287 Ok(self.0.into_inner()?.map(|bs| Self::from(bs))) 288 } 289 290 /// Finalizes the message. 291 /// 292 /// Finalizes all writers on the stack, flushing any buffered 293 /// data. 294 /// 295 /// # Note 296 /// 297 /// Failing to finalize the message may result in corrupted 298 /// messages. 299 /// 300 /// # Example 301 /// 302 /// ``` 303 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 304 /// use sequoia_openpgp as openpgp; 305 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 306 /// 307 /// # let mut sink = vec![]; // Vec<u8> implements io::Write. 308 /// let message = Message::new(&mut sink); 309 /// // Construct the writer stack here. 310 /// let mut message = LiteralWriter::new(message).build()?; 311 /// // Write literal data to `message` here. 312 /// // ... 313 /// // Finalize the message. 314 /// message.finalize()?; 315 /// # Ok(()) } 316 /// ``` finalize(self) -> Result<()>317 pub fn finalize(self) -> Result<()> { 318 let mut stack = self; 319 while let Some(s) = stack.finalize_one()? { 320 stack = s; 321 } 322 Ok(()) 323 } 324 } 325 326 impl<'a> From<&'a mut dyn io::Write> for Message<'a> { from(w: &'a mut dyn io::Write) -> Self327 fn from(w: &'a mut dyn io::Write) -> Self { 328 writer::Generic::new(w, Cookie::new(0)) 329 } 330 } 331 332 333 /// Applies ASCII Armor to the message. 334 /// 335 /// ASCII armored data (see [Section 6 of RFC 4880]) is a OpenPGP data 336 /// stream that has been base64-encoded and decorated with a header, 337 /// footer, and optional headers representing key-value pairs. It can 338 /// be safely transmitted over protocols that can only transmit 339 /// printable characters, and can handled by end users (e.g. copied 340 /// and pasted). 341 /// 342 /// [Section 6 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-6 343 pub struct Armorer<'a> { 344 kind: armor::Kind, 345 headers: Vec<(String, String)>, 346 inner: Message<'a>, 347 } 348 349 impl<'a> Armorer<'a> { 350 /// Creates a new armoring filter. 351 /// 352 /// By default, the type of the armored data is set to 353 /// [`armor::Kind`]`::Message`. To change it, use 354 /// [`Armorer::kind`]. To add headers to the armor, use 355 /// [`Armorer::add_header`]. 356 /// 357 /// [`armor::Kind`]: ../../armor/enum.Kind.html 358 /// [`Armorer::kind`]: #method.kind 359 /// [`Armorer::add_header`]: #method.add_header 360 /// 361 /// # Examples 362 /// 363 /// ``` 364 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 365 /// use std::io::Write; 366 /// use sequoia_openpgp as openpgp; 367 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter}; 368 /// 369 /// let mut sink = vec![]; 370 /// { 371 /// let message = Message::new(&mut sink); 372 /// let message = Armorer::new(message) 373 /// // Customize the `Armorer` here. 374 /// .build()?; 375 /// let mut message = LiteralWriter::new(message).build()?; 376 /// message.write_all(b"Hello world.")?; 377 /// message.finalize()?; 378 /// } 379 /// assert_eq!("-----BEGIN PGP MESSAGE-----\n\ 380 /// \n\ 381 /// yxJiAAAAAABIZWxsbyB3b3JsZC4=\n\ 382 /// =6nHv\n\ 383 /// -----END PGP MESSAGE-----\n", 384 /// std::str::from_utf8(&sink)?); 385 /// # Ok(()) } new(inner: Message<'a>) -> Self386 pub fn new(inner: Message<'a>) -> Self { 387 Self { 388 kind: armor::Kind::Message, 389 headers: Vec::with_capacity(0), 390 inner, 391 } 392 } 393 394 /// Changes the kind of armoring. 395 /// 396 /// The armor header and footer changes depending on the type of 397 /// wrapped data. See [`armor::Kind`] for the possible values. 398 /// 399 /// [`armor::Kind`]: ../../armor/enum.Kind.html 400 /// 401 /// # Examples 402 /// 403 /// ``` 404 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 405 /// use std::io::Write; 406 /// use sequoia_openpgp as openpgp; 407 /// use openpgp::armor; 408 /// use openpgp::serialize::stream::{Message, Armorer, Signer}; 409 /// # use sequoia_openpgp::policy::StandardPolicy; 410 /// # use openpgp::{Result, Cert}; 411 /// # use openpgp::packet::prelude::*; 412 /// # use openpgp::crypto::KeyPair; 413 /// # use openpgp::parse::Parse; 414 /// # use openpgp::parse::stream::*; 415 /// # let p = &StandardPolicy::new(); 416 /// # let cert = Cert::from_bytes(&include_bytes!( 417 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 418 /// # let signing_keypair 419 /// # = cert.keys().secret() 420 /// # .with_policy(p, None).alive().revoked(false).for_signing() 421 /// # .nth(0).unwrap() 422 /// # .key().clone().into_keypair()?; 423 /// 424 /// let mut sink = vec![]; 425 /// { 426 /// let message = Message::new(&mut sink); 427 /// let message = Armorer::new(message) 428 /// .kind(armor::Kind::Signature) 429 /// .build()?; 430 /// let mut signer = Signer::new(message, signing_keypair) 431 /// .detached() 432 /// .build()?; 433 /// 434 /// // Write the data directly to the `Signer`. 435 /// signer.write_all(b"Make it so, number one!")?; 436 /// // In reality, just io::copy() the file to be signed. 437 /// signer.finalize()?; 438 /// } 439 /// 440 /// assert!(std::str::from_utf8(&sink)? 441 /// .starts_with("-----BEGIN PGP SIGNATURE-----\n")); 442 /// # Ok(()) } kind(mut self, kind: armor::Kind) -> Self443 pub fn kind(mut self, kind: armor::Kind) -> Self { 444 self.kind = kind; 445 self 446 } 447 448 /// Adds a header to the armor block. 449 /// 450 /// There are a number of defined armor header keys (see [Section 451 /// 6 of RFC 4880]), but in practice, any key may be used, as 452 /// implementations should simply ignore unknown keys. 453 /// 454 /// [Section 6 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-6 455 /// 456 /// # Examples 457 /// 458 /// ``` 459 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 460 /// use std::io::Write; 461 /// use sequoia_openpgp as openpgp; 462 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter}; 463 /// 464 /// let mut sink = vec![]; 465 /// { 466 /// let message = Message::new(&mut sink); 467 /// let message = Armorer::new(message) 468 /// .add_header("Comment", "No comment.") 469 /// .build()?; 470 /// let mut message = LiteralWriter::new(message).build()?; 471 /// message.write_all(b"Hello world.")?; 472 /// message.finalize()?; 473 /// } 474 /// assert_eq!("-----BEGIN PGP MESSAGE-----\n\ 475 /// Comment: No comment.\n\ 476 /// \n\ 477 /// yxJiAAAAAABIZWxsbyB3b3JsZC4=\n\ 478 /// =6nHv\n\ 479 /// -----END PGP MESSAGE-----\n", 480 /// std::str::from_utf8(&sink)?); 481 /// # Ok(()) } add_header<K, V>(mut self, key: K, value: V) -> Self where K: AsRef<str>, V: AsRef<str>,482 pub fn add_header<K, V>(mut self, key: K, value: V) -> Self 483 where K: AsRef<str>, 484 V: AsRef<str>, 485 { 486 self.headers.push((key.as_ref().to_string(), 487 value.as_ref().to_string())); 488 self 489 } 490 491 /// Builds the armor writer, returning the writer stack. 492 /// 493 /// # Examples 494 /// 495 /// ``` 496 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 497 /// use sequoia_openpgp as openpgp; 498 /// use openpgp::serialize::stream::{Message, Armorer, LiteralWriter}; 499 /// 500 /// # let mut sink = vec![]; 501 /// let message = Message::new(&mut sink); 502 /// let message = Armorer::new(message) 503 /// // Customize the `Armorer` here. 504 /// .build()?; 505 /// # Ok(()) } build(self) -> Result<Message<'a>>506 pub fn build(self) -> Result<Message<'a>> { 507 let level = self.inner.as_ref().cookie_ref().level; 508 writer::Armorer::new( 509 self.inner, 510 Cookie::new(level + 1), 511 self.kind, 512 self.headers, 513 ) 514 } 515 } 516 517 impl<'a> fmt::Debug for Armorer<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result518 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 519 f.debug_struct("Armorer") 520 .field("inner", &self.inner) 521 .field("kind", &self.kind) 522 .field("headers", &self.headers) 523 .finish() 524 } 525 } 526 527 528 /// Writes an arbitrary packet. 529 /// 530 /// This writer can be used to construct arbitrary OpenPGP packets. 531 /// This is mainly useful for testing. The body will be written using 532 /// partial length encoding, or, if the body is short, using full 533 /// length encoding. 534 pub struct ArbitraryWriter<'a> { 535 inner: writer::BoxStack<'a, Cookie>, 536 } 537 538 impl<'a> ArbitraryWriter<'a> { 539 /// Creates a new writer with the given tag. 540 /// 541 /// # Example 542 /// 543 /// ``` 544 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 545 /// use std::io::Write; 546 /// use sequoia_openpgp as openpgp; 547 /// use openpgp::packet::Tag; 548 /// use openpgp::serialize::stream::{Message, ArbitraryWriter}; 549 /// 550 /// let mut sink = vec![]; 551 /// { 552 /// let message = Message::new(&mut sink); 553 /// let mut message = ArbitraryWriter::new(message, Tag::Literal)?; 554 /// message.write_all(b"t")?; // type 555 /// message.write_all(b"\x00")?; // filename length 556 /// message.write_all(b"\x00\x00\x00\x00")?; // date 557 /// message.write_all(b"Hello world.")?; // body 558 /// message.finalize()?; 559 /// } 560 /// assert_eq!(b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.", 561 /// sink.as_slice()); 562 /// # Ok(()) } new(mut inner: Message<'a>, tag: Tag) -> Result<Message<'a>>563 pub fn new(mut inner: Message<'a>, tag: Tag) 564 -> Result<Message<'a>> { 565 let level = inner.as_ref().cookie_ref().level + 1; 566 CTB::new(tag).serialize(&mut inner)?; 567 Ok(Message::from(Box::new(ArbitraryWriter { 568 inner: PartialBodyFilter::new(inner, Cookie::new(level)).into() 569 }))) 570 } 571 } 572 573 impl<'a> fmt::Debug for ArbitraryWriter<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result574 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 575 f.debug_struct("ArbitraryWriter") 576 .field("inner", &self.inner) 577 .finish() 578 } 579 } 580 581 impl<'a> Write for ArbitraryWriter<'a> { write(&mut self, buf: &[u8]) -> io::Result<usize>582 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 583 self.inner.write(buf) 584 } flush(&mut self) -> io::Result<()>585 fn flush(&mut self) -> io::Result<()> { 586 self.inner.flush() 587 } 588 } 589 590 impl<'a> writer::Stackable<'a, Cookie> for ArbitraryWriter<'a> { into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>>591 fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 592 Box::new(self.inner).into_inner() 593 } pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>>594 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 595 unreachable!("Only implemented by Signer") 596 } 597 /// Sets the inner stackable. mount(&mut self, _new: writer::BoxStack<'a, Cookie>)598 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) { 599 unreachable!("Only implemented by Signer") 600 } inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>>601 fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { 602 Some(self.inner.as_ref()) 603 } inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>>604 fn inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>> { 605 Some(self.inner.as_mut()) 606 } cookie_set(&mut self, cookie: Cookie) -> Cookie607 fn cookie_set(&mut self, cookie: Cookie) -> Cookie { 608 self.inner.cookie_set(cookie) 609 } cookie_ref(&self) -> &Cookie610 fn cookie_ref(&self) -> &Cookie { 611 self.inner.cookie_ref() 612 } cookie_mut(&mut self) -> &mut Cookie613 fn cookie_mut(&mut self) -> &mut Cookie { 614 self.inner.cookie_mut() 615 } position(&self) -> u64616 fn position(&self) -> u64 { 617 self.inner.position() 618 } 619 } 620 621 /// Signs a message. 622 /// 623 /// Signs a message with every [`crypto::Signer`] added to the 624 /// streaming signer. 625 /// 626 /// [`crypto::Signer`]: ../../crypto/trait.Signer.html 627 pub struct Signer<'a> { 628 // The underlying writer. 629 // 630 // Because this writer implements `Drop`, we cannot move the inner 631 // writer out of this writer. We therefore wrap it with `Option` 632 // so that we can `take()` it. 633 // 634 // Furthermore, the LiteralWriter will pop us off the stack, and 635 // take our inner reader. If that happens, we only update the 636 // digests. 637 inner: Option<writer::BoxStack<'a, Cookie>>, 638 signers: Vec<Box<dyn crypto::Signer + 'a>>, 639 intended_recipients: Vec<Fingerprint>, 640 detached: bool, 641 template: signature::SignatureBuilder, 642 creation_time: Option<SystemTime>, 643 hash: crypto::hash::Context, 644 cookie: Cookie, 645 position: u64, 646 } 647 648 impl<'a> Signer<'a> { 649 /// Creates a signer. 650 /// 651 /// Signs the message with the given [`crypto::Signer`]. To 652 /// create more than one signature, add more [`crypto::Signer`]s 653 /// using [`Signer::add_signer`]. Properties of the signatures 654 /// can be tweaked using the methods of this type. Notably, to 655 /// generate a detached signature (see [Section 11.4 of RFC 656 /// 4880]), use [`Signer::detached`]. For even more control over 657 /// the generated signatures, use [`Signer::with_template`]. 658 /// 659 /// [`crypto::Signer`]: ../../crypto/trait.Signer.html 660 /// [`Signer::add_signer`]: #method.add_signer 661 /// [Section 11.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.4 662 /// [`Signer::detached`]: #method.detached 663 /// [`Signer::with_template`]: #method.with_template 664 /// 665 /// # Example 666 /// 667 /// ``` 668 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 669 /// use std::io::{Read, Write}; 670 /// use sequoia_openpgp as openpgp; 671 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 672 /// use openpgp::policy::StandardPolicy; 673 /// # use openpgp::{Result, Cert}; 674 /// # use openpgp::packet::prelude::*; 675 /// # use openpgp::parse::Parse; 676 /// # use openpgp::parse::stream::*; 677 /// 678 /// let p = &StandardPolicy::new(); 679 /// let cert: Cert = // ... 680 /// # Cert::from_bytes(&include_bytes!( 681 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 682 /// let signing_keypair = cert.keys().secret() 683 /// .with_policy(p, None).alive().revoked(false).for_signing() 684 /// .nth(0).unwrap() 685 /// .key().clone().into_keypair()?; 686 /// 687 /// let mut sink = vec![]; 688 /// { 689 /// let message = Message::new(&mut sink); 690 /// let message = Signer::new(message, signing_keypair) 691 /// // Customize the `Signer` here. 692 /// .build()?; 693 /// let mut message = LiteralWriter::new(message).build()?; 694 /// message.write_all(b"Make it so, number one!")?; 695 /// message.finalize()?; 696 /// } 697 /// 698 /// // Now check the signature. 699 /// struct Helper<'a>(&'a openpgp::Cert); 700 /// impl<'a> VerificationHelper for Helper<'a> { 701 /// fn get_certs(&mut self, _: &[openpgp::KeyHandle]) 702 /// -> openpgp::Result<Vec<openpgp::Cert>> { 703 /// Ok(vec![self.0.clone()]) 704 /// } 705 /// 706 /// fn check(&mut self, structure: MessageStructure) 707 /// -> openpgp::Result<()> { 708 /// if let MessageLayer::SignatureGroup { ref results } = 709 /// structure.iter().nth(0).unwrap() 710 /// { 711 /// results.get(0).unwrap().as_ref().unwrap(); 712 /// Ok(()) 713 /// } else { panic!() } 714 /// } 715 /// } 716 /// 717 /// let mut verifier = VerifierBuilder::from_bytes(&sink)? 718 /// .with_policy(p, None, Helper(&cert))?; 719 /// 720 /// let mut message = String::new(); 721 /// verifier.read_to_string(&mut message)?; 722 /// assert_eq!(&message, "Make it so, number one!"); 723 /// # Ok(()) } 724 /// ``` new<S>(inner: Message<'a>, signer: S) -> Self where S: crypto::Signer + 'a725 pub fn new<S>(inner: Message<'a>, signer: S) -> Self 726 where S: crypto::Signer + 'a 727 { 728 Self::with_template(inner, signer, 729 signature::SignatureBuilder::new(SignatureType::Binary)) 730 } 731 732 /// Creates a signer with a given signature template. 733 /// 734 /// Signs the message with the given [`crypto::Signer`] like 735 /// [`Signer::new`], but allows more control over the generated 736 /// signatures. The given [`signature::SignatureBuilder`] is used to 737 /// create all the signatures. 738 /// 739 /// For every signature, the creation time is set to the current 740 /// time or the one specified using [`Signer::creation_time`], the 741 /// intended recipients are added (see 742 /// [`Signer::add_intended_recipient`]), the issuer and issuer 743 /// fingerprint subpackets are set according to the signing key, 744 /// and the hash algorithm set using [`Signer::hash_algo`] is used 745 /// to create the signature. 746 /// 747 /// [`crypto::Signer`]: ../../crypto/trait.Signer.html 748 /// [`Signer::new`]: #method.new 749 /// [`signature::SignatureBuilder`]: ../../packet/signature/struct.Builder.html 750 /// [`Signer::creation_time`]: #method.creation_time 751 /// [`Signer::hash_algo`]: #method.hash_algo 752 /// [`Signer::add_intended_recipient`]: #method.add_intended_recipient 753 /// 754 /// # Example 755 /// 756 /// ``` 757 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 758 /// use std::io::{Read, Write}; 759 /// use sequoia_openpgp as openpgp; 760 /// use openpgp::types::SignatureType; 761 /// use openpgp::packet::signature; 762 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 763 /// # use openpgp::policy::StandardPolicy; 764 /// # use openpgp::{Result, Cert}; 765 /// # use openpgp::packet::prelude::*; 766 /// # use openpgp::parse::Parse; 767 /// # use openpgp::parse::stream::*; 768 /// # 769 /// # let p = &StandardPolicy::new(); 770 /// # let cert: Cert = // ... 771 /// # Cert::from_bytes(&include_bytes!( 772 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 773 /// # let signing_keypair = cert.keys().secret() 774 /// # .with_policy(p, None).alive().revoked(false).for_signing() 775 /// # .nth(0).unwrap() 776 /// # .key().clone().into_keypair()?; 777 /// # let mut sink = vec![]; 778 /// 779 /// let message = Message::new(&mut sink); 780 /// let message = Signer::with_template( 781 /// message, signing_keypair, 782 /// signature::SignatureBuilder::new(SignatureType::Text) 783 /// .add_notation("issuer@starfleet.command", "Jean-Luc Picard", 784 /// None, true)?) 785 /// // Further customize the `Signer` here. 786 /// .build()?; 787 /// let mut message = LiteralWriter::new(message).build()?; 788 /// message.write_all(b"Make it so, number one!")?; 789 /// message.finalize()?; 790 /// # Ok(()) } 791 /// ``` with_template<S, T>(inner: Message<'a>, signer: S, template: T) -> Self where S: crypto::Signer + 'a, T: Into<signature::SignatureBuilder>,792 pub fn with_template<S, T>(inner: Message<'a>, signer: S, template: T) 793 -> Self 794 where S: crypto::Signer + 'a, 795 T: Into<signature::SignatureBuilder>, 796 { 797 let inner = writer::BoxStack::from(inner); 798 let level = inner.cookie_ref().level + 1; 799 Signer { 800 inner: Some(inner), 801 signers: vec![Box::new(signer)], 802 intended_recipients: Vec::new(), 803 detached: false, 804 template: template.into(), 805 creation_time: None, 806 hash: HashAlgorithm::default().context().unwrap(), 807 cookie: Cookie { 808 level, 809 private: Private::Signer, 810 }, 811 position: 0, 812 } 813 } 814 815 /// Creates a signer for a detached signature. 816 /// 817 /// Changes the `Signer` to create a detached signature (see 818 /// [Section 11.4 of RFC 4880]). Note that the literal data *must 819 /// not* be wrapped using the [`LiteralWriter`]. 820 /// 821 /// [Section 11.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.4 822 /// [`LiteralWriter`]: ../struct.LiteralWriter.html 823 /// 824 /// # Example 825 /// 826 /// ``` 827 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 828 /// use std::io::Write; 829 /// use sequoia_openpgp as openpgp; 830 /// use openpgp::serialize::stream::{Message, Signer}; 831 /// use sequoia_openpgp::policy::StandardPolicy; 832 /// # use openpgp::{Result, Cert}; 833 /// # use openpgp::packet::prelude::*; 834 /// # use openpgp::crypto::KeyPair; 835 /// # use openpgp::parse::Parse; 836 /// # use openpgp::parse::stream::*; 837 /// 838 /// let p = &StandardPolicy::new(); 839 /// # let cert = Cert::from_bytes(&include_bytes!( 840 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 841 /// # let signing_keypair 842 /// # = cert.keys().secret() 843 /// # .with_policy(p, None).alive().revoked(false).for_signing() 844 /// # .nth(0).unwrap() 845 /// # .key().clone().into_keypair()?; 846 /// 847 /// let mut sink = vec![]; 848 /// { 849 /// let message = Message::new(&mut sink); 850 /// let mut signer = Signer::new(message, signing_keypair) 851 /// .detached() 852 /// // Customize the `Signer` here. 853 /// .build()?; 854 /// 855 /// // Write the data directly to the `Signer`. 856 /// signer.write_all(b"Make it so, number one!")?; 857 /// // In reality, just io::copy() the file to be signed. 858 /// signer.finalize()?; 859 /// } 860 /// 861 /// // Now check the signature. 862 /// struct Helper<'a>(&'a openpgp::Cert); 863 /// impl<'a> VerificationHelper for Helper<'a> { 864 /// fn get_certs(&mut self, _: &[openpgp::KeyHandle]) 865 /// -> openpgp::Result<Vec<openpgp::Cert>> { 866 /// Ok(vec![self.0.clone()]) 867 /// } 868 /// 869 /// fn check(&mut self, structure: MessageStructure) 870 /// -> openpgp::Result<()> { 871 /// if let MessageLayer::SignatureGroup { ref results } = 872 /// structure.iter().nth(0).unwrap() 873 /// { 874 /// results.get(0).unwrap().as_ref().unwrap(); 875 /// Ok(()) 876 /// } else { panic!() } 877 /// } 878 /// } 879 /// 880 /// let mut verifier = DetachedVerifierBuilder::from_bytes(&sink)? 881 /// .with_policy(p, None, Helper(&cert))?; 882 /// 883 /// verifier.verify_bytes(b"Make it so, number one!")?; 884 /// # Ok(()) } 885 /// ``` detached(mut self) -> Self886 pub fn detached(mut self) -> Self { 887 self.detached = true; 888 self 889 } 890 891 /// Adds an additional signer. 892 /// 893 /// Can be used multiple times. 894 /// 895 /// # Example 896 /// 897 /// ``` 898 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 899 /// use std::io::Write; 900 /// use sequoia_openpgp as openpgp; 901 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 902 /// # use openpgp::policy::StandardPolicy; 903 /// # use openpgp::{Result, Cert}; 904 /// # use openpgp::packet::prelude::*; 905 /// # use openpgp::parse::Parse; 906 /// # use openpgp::parse::stream::*; 907 /// 908 /// # let p = &StandardPolicy::new(); 909 /// # let cert = Cert::from_bytes(&include_bytes!( 910 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 911 /// # let signing_keypair = cert.keys().secret() 912 /// # .with_policy(p, None).alive().revoked(false).for_signing() 913 /// # .nth(0).unwrap() 914 /// # .key().clone().into_keypair()?; 915 /// # let additional_signing_keypair = cert.keys().secret() 916 /// # .with_policy(p, None).alive().revoked(false).for_signing() 917 /// # .nth(0).unwrap() 918 /// # .key().clone().into_keypair()?; 919 /// 920 /// # let mut sink = vec![]; 921 /// let message = Message::new(&mut sink); 922 /// let message = Signer::new(message, signing_keypair) 923 /// .add_signer(additional_signing_keypair) 924 /// .build()?; 925 /// let mut message = LiteralWriter::new(message).build()?; 926 /// message.write_all(b"Make it so, number one!")?; 927 /// message.finalize()?; 928 /// # Ok(()) } 929 /// ``` add_signer<S>(mut self, signer: S) -> Self where S: crypto::Signer + 'a930 pub fn add_signer<S>(mut self, signer: S) -> Self 931 where S: crypto::Signer + 'a 932 { 933 self.signers.push(Box::new(signer)); 934 self 935 } 936 937 /// Adds an intended recipient. 938 /// 939 /// Indicates that the given certificate is an intended recipient 940 /// of this message. Can be used multiple times. This prevents 941 /// [*Surreptitious Forwarding*] of encrypted and signed messages, 942 /// i.e. forwarding a signed message using a different encryption 943 /// context. 944 /// 945 /// [*Surreptitious Forwarding*]: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html 946 /// 947 /// # Example 948 /// 949 /// ``` 950 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 951 /// use std::io::Write; 952 /// use sequoia_openpgp as openpgp; 953 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 954 /// # use openpgp::policy::StandardPolicy; 955 /// # use openpgp::{Result, Cert}; 956 /// # use openpgp::packet::prelude::*; 957 /// # use openpgp::crypto::KeyPair; 958 /// # use openpgp::parse::Parse; 959 /// # use openpgp::parse::stream::*; 960 /// 961 /// # let p = &StandardPolicy::new(); 962 /// # let cert = Cert::from_bytes(&include_bytes!( 963 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 964 /// # let signing_keypair = cert.keys().secret() 965 /// # .with_policy(p, None).alive().revoked(false).for_signing() 966 /// # .nth(0).unwrap() 967 /// # .key().clone().into_keypair()?; 968 /// let recipient: Cert = // ... 969 /// # Cert::from_bytes(&include_bytes!( 970 /// # "../../tests/data/keys/testy.pgp")[..])?; 971 /// 972 /// # let mut sink = vec![]; 973 /// let message = Message::new(&mut sink); 974 /// let message = Signer::new(message, signing_keypair) 975 /// .add_intended_recipient(&recipient) 976 /// .build()?; 977 /// let mut message = LiteralWriter::new(message).build()?; 978 /// message.write_all(b"Make it so, number one!")?; 979 /// message.finalize()?; 980 /// # Ok(()) } 981 /// ``` add_intended_recipient(mut self, recipient: &Cert) -> Self982 pub fn add_intended_recipient(mut self, recipient: &Cert) -> Self { 983 self.intended_recipients.push(recipient.fingerprint()); 984 self 985 } 986 987 /// Sets the hash algorithm to use for the signatures. 988 /// 989 /// # Example 990 /// 991 /// ``` 992 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 993 /// use std::io::Write; 994 /// use sequoia_openpgp as openpgp; 995 /// use openpgp::types::HashAlgorithm; 996 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 997 /// # use openpgp::policy::StandardPolicy; 998 /// # use openpgp::{Result, Cert}; 999 /// # use openpgp::packet::prelude::*; 1000 /// # use openpgp::parse::Parse; 1001 /// # use openpgp::parse::stream::*; 1002 /// 1003 /// # let p = &StandardPolicy::new(); 1004 /// # let cert = Cert::from_bytes(&include_bytes!( 1005 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 1006 /// # let signing_keypair = cert.keys().secret() 1007 /// # .with_policy(p, None).alive().revoked(false).for_signing() 1008 /// # .nth(0).unwrap() 1009 /// # .key().clone().into_keypair()?; 1010 /// 1011 /// # let mut sink = vec![]; 1012 /// let message = Message::new(&mut sink); 1013 /// let message = Signer::new(message, signing_keypair) 1014 /// .hash_algo(HashAlgorithm::SHA384)? 1015 /// .build()?; 1016 /// let mut message = LiteralWriter::new(message).build()?; 1017 /// message.write_all(b"Make it so, number one!")?; 1018 /// message.finalize()?; 1019 /// # Ok(()) } 1020 /// ``` hash_algo(mut self, algo: HashAlgorithm) -> Result<Self>1021 pub fn hash_algo(mut self, algo: HashAlgorithm) -> Result<Self> { 1022 self.hash = algo.context()?; 1023 Ok(self) 1024 } 1025 1026 /// Sets the signature's creation time to `time`. 1027 /// 1028 /// Note: it is up to the caller to make sure the signing keys are 1029 /// actually valid as of `time`. 1030 /// 1031 /// # Example 1032 /// 1033 /// ``` 1034 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1035 /// use std::io::Write; 1036 /// use sequoia_openpgp as openpgp; 1037 /// use openpgp::types::Timestamp; 1038 /// use openpgp::serialize::stream::{Message, Signer, LiteralWriter}; 1039 /// use openpgp::policy::StandardPolicy; 1040 /// # use openpgp::{Result, Cert}; 1041 /// # use openpgp::packet::prelude::*; 1042 /// # use openpgp::parse::Parse; 1043 /// # use openpgp::parse::stream::*; 1044 /// 1045 /// let p = &StandardPolicy::new(); 1046 /// let cert: Cert = // ... 1047 /// # Cert::from_bytes(&include_bytes!( 1048 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 1049 /// let signing_key = cert.keys().secret() 1050 /// .with_policy(p, None).alive().revoked(false).for_signing() 1051 /// .nth(0).unwrap() 1052 /// .key(); 1053 /// let signing_keypair = signing_key.clone().into_keypair()?; 1054 /// 1055 /// # let mut sink = vec![]; 1056 /// let message = Message::new(&mut sink); 1057 /// let message = Signer::new(message, signing_keypair) 1058 /// .creation_time(Timestamp::now() 1059 /// .round_down(None, signing_key.creation_time())?) 1060 /// .build()?; 1061 /// let mut message = LiteralWriter::new(message).build()?; 1062 /// message.write_all(b"Make it so, number one!")?; 1063 /// message.finalize()?; 1064 /// # Ok(()) } 1065 /// ``` creation_time<T: Into<SystemTime>>(mut self, creation_time: T) -> Self1066 pub fn creation_time<T: Into<SystemTime>>(mut self, creation_time: T) 1067 -> Self 1068 { 1069 self.creation_time = Some(creation_time.into()); 1070 self 1071 } 1072 1073 /// Builds the signer, returning the writer stack. 1074 /// 1075 /// The most useful filter to push to the writer stack next is the 1076 /// [`LiteralWriter`]. Note, if you are creating a signed OpenPGP 1077 /// message (see [Section 11.3 of RFC 4880]), literal data *must* 1078 /// be wrapped using the [`LiteralWriter`]. On the other hand, if 1079 /// you are creating a detached signature (see [Section 11.4 of 1080 /// RFC 4880]), the literal data *must not* be wrapped using the 1081 /// [`LiteralWriter`]. 1082 /// 1083 /// [`LiteralWriter`]: ../struct.LiteralWriter.html 1084 /// [Section 11.3 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.3 1085 /// [Section 11.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-11.4 1086 /// 1087 /// # Example 1088 /// 1089 /// ``` 1090 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1091 /// use std::io::Write; 1092 /// use sequoia_openpgp as openpgp; 1093 /// use openpgp::types::Timestamp; 1094 /// use openpgp::serialize::stream::{Message, Signer}; 1095 /// # use openpgp::policy::StandardPolicy; 1096 /// # use openpgp::{Result, Cert}; 1097 /// # use openpgp::packet::prelude::*; 1098 /// # use openpgp::parse::Parse; 1099 /// # use openpgp::parse::stream::*; 1100 /// 1101 /// # let p = &StandardPolicy::new(); 1102 /// # let cert: Cert = // ... 1103 /// # Cert::from_bytes(&include_bytes!( 1104 /// # "../../tests/data/keys/testy-new-private.pgp")[..])?; 1105 /// # let signing_keypair 1106 /// # = cert.keys().secret() 1107 /// # .with_policy(p, None).alive().revoked(false).for_signing() 1108 /// # .nth(0).unwrap() 1109 /// # .key().clone().into_keypair()?; 1110 /// # 1111 /// # let mut sink = vec![]; 1112 /// let message = Message::new(&mut sink); 1113 /// let message = Signer::new(message, signing_keypair) 1114 /// // Customize the `Signer` here. 1115 /// .build()?; 1116 /// # Ok(()) } 1117 /// ``` build(mut self) -> Result<Message<'a>>1118 pub fn build(mut self) -> Result<Message<'a>> 1119 { 1120 assert!(self.signers.len() > 0, "The constructor adds a signer."); 1121 assert!(self.inner.is_some(), "The constructor adds an inner writer."); 1122 1123 if ! self.detached { 1124 // For every key we collected, build and emit a one pass 1125 // signature packet. 1126 for (i, keypair) in self.signers.iter().enumerate() { 1127 let key = keypair.public(); 1128 let mut ops = OnePassSig3::new(self.template.typ()); 1129 ops.set_pk_algo(key.pk_algo()); 1130 ops.set_hash_algo(self.hash.algo()); 1131 ops.set_issuer(key.keyid()); 1132 ops.set_last(i == self.signers.len() - 1); 1133 Packet::OnePassSig(ops.into()) 1134 .serialize(self.inner.as_mut().unwrap())?; 1135 } 1136 } 1137 1138 Ok(Message::from(Box::new(self))) 1139 } 1140 emit_signatures(&mut self) -> Result<()>1141 fn emit_signatures(&mut self) -> Result<()> { 1142 if let Some(ref mut sink) = self.inner { 1143 // Emit the signatures in reverse, so that the 1144 // one-pass-signature and signature packets "bracket" the 1145 // message. 1146 for signer in self.signers.iter_mut() { 1147 // Part of the signature packet is hashed in, 1148 // therefore we need to clone the hash. 1149 let hash = self.hash.clone(); 1150 1151 // Make and hash a signature packet. 1152 let mut sig = self.template.clone() 1153 .set_signature_creation_time( 1154 self.creation_time 1155 .unwrap_or_else(SystemTime::now))?; 1156 1157 if ! self.intended_recipients.is_empty() { 1158 sig = sig.set_intended_recipients( 1159 self.intended_recipients.clone())?; 1160 } 1161 1162 // Compute the signature. 1163 let sig = sig.sign_hash(signer.as_mut(), hash)?; 1164 1165 // And emit the packet. 1166 Packet::Signature(sig).serialize(sink)?; 1167 } 1168 } 1169 Ok(()) 1170 } 1171 } 1172 1173 impl<'a> fmt::Debug for Signer<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1175 f.debug_struct("Signer") 1176 .field("inner", &self.inner) 1177 .field("cookie", &self.cookie) 1178 .finish() 1179 } 1180 } 1181 1182 impl<'a> Write for Signer<'a> { write(&mut self, buf: &[u8]) -> io::Result<usize>1183 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 1184 let written = match self.inner.as_mut() { 1185 // If we are creating a normal signature, pass data 1186 // through. 1187 Some(ref mut w) if ! self.detached => w.write(buf), 1188 // If we are creating a detached signature, just hash all 1189 // bytes. 1190 Some(_) => Ok(buf.len()), 1191 // When we are popped off the stack, we have no inner 1192 // writer. Just hash all bytes. 1193 None => Ok(buf.len()), 1194 }; 1195 1196 if let Ok(amount) = written { 1197 if self.template.typ() == SignatureType::Text { 1198 crate::parse::hash_update_text(&mut self.hash, &buf[..amount]); 1199 } else { 1200 self.hash.update(&buf[..amount]); 1201 } 1202 self.position += amount as u64; 1203 } 1204 1205 written 1206 } 1207 flush(&mut self) -> io::Result<()>1208 fn flush(&mut self) -> io::Result<()> { 1209 match self.inner.as_mut() { 1210 Some(ref mut w) => w.flush(), 1211 // When we are popped off the stack, we have no inner 1212 // writer. Just do nothing. 1213 None => Ok(()), 1214 } 1215 } 1216 } 1217 1218 impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> { pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>>1219 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1220 Ok(self.inner.take()) 1221 } mount(&mut self, new: writer::BoxStack<'a, Cookie>)1222 fn mount(&mut self, new: writer::BoxStack<'a, Cookie>) { 1223 self.inner = Some(new); 1224 } inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>>1225 fn inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>> { 1226 if let Some(ref mut i) = self.inner { 1227 Some(i) 1228 } else { 1229 None 1230 } 1231 } inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>>1232 fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { 1233 self.inner.as_ref().map(|r| r.as_ref()) 1234 } into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>>1235 fn into_inner(mut self: Box<Self>) 1236 -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1237 self.emit_signatures()?; 1238 Ok(self.inner.take()) 1239 } cookie_set(&mut self, cookie: Cookie) -> Cookie1240 fn cookie_set(&mut self, cookie: Cookie) -> Cookie { 1241 ::std::mem::replace(&mut self.cookie, cookie) 1242 } cookie_ref(&self) -> &Cookie1243 fn cookie_ref(&self) -> &Cookie { 1244 &self.cookie 1245 } cookie_mut(&mut self) -> &mut Cookie1246 fn cookie_mut(&mut self) -> &mut Cookie { 1247 &mut self.cookie 1248 } position(&self) -> u641249 fn position(&self) -> u64 { 1250 self.position 1251 } 1252 } 1253 1254 1255 /// Writes a literal data packet. 1256 /// 1257 /// Literal data, i.e. the payload or plaintext, must be wrapped in a 1258 /// literal data packet to be transported over OpenPGP (see [Section 1259 /// 5.9 of RFC 4880]). The body will be written using partial length 1260 /// encoding, or, if the body is short, using full length encoding. 1261 /// 1262 /// [Section 5.9 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.9 1263 /// 1264 /// # Note on metadata 1265 /// 1266 /// A literal data packet can communicate some metadata: a hint as to 1267 /// what kind of data is transported, the original file name, and a 1268 /// timestamp. Note that this metadata will not be authenticated by 1269 /// signatures (but will be authenticated by a SEIP/MDC container), 1270 /// and are therefore unreliable and should not be trusted. 1271 /// 1272 /// Therefore, it is good practice not to set this metadata when 1273 /// creating a literal data packet, and not to interpret it when 1274 /// consuming one. 1275 pub struct LiteralWriter<'a> { 1276 template: Literal, 1277 inner: writer::BoxStack<'a, Cookie>, 1278 signature_writer: Option<writer::BoxStack<'a, Cookie>>, 1279 } 1280 1281 impl<'a> LiteralWriter<'a> { 1282 /// Creates a new literal writer. 1283 /// 1284 /// # Example 1285 /// 1286 /// ``` 1287 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1288 /// use std::io::Write; 1289 /// use sequoia_openpgp as openpgp; 1290 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 1291 /// 1292 /// let mut sink = vec![]; 1293 /// { 1294 /// let message = Message::new(&mut sink); 1295 /// let mut message = LiteralWriter::new(message) 1296 /// // Customize the `LiteralWriter` here. 1297 /// .build()?; 1298 /// message.write_all(b"Hello world.")?; 1299 /// message.finalize()?; 1300 /// } 1301 /// assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", 1302 /// sink.as_slice()); 1303 /// # Ok(()) } 1304 /// ``` new(inner: Message<'a>) -> Self1305 pub fn new(inner: Message<'a>) -> Self { 1306 LiteralWriter { 1307 template: Literal::new(DataFormat::default()), 1308 inner: writer::BoxStack::from(inner), 1309 signature_writer: None, 1310 } 1311 } 1312 1313 /// Sets the data format. 1314 /// 1315 /// # Example 1316 /// 1317 /// ``` 1318 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1319 /// use std::io::Write; 1320 /// use sequoia_openpgp as openpgp; 1321 /// use openpgp::types::DataFormat; 1322 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 1323 /// 1324 /// let mut sink = vec![]; 1325 /// { 1326 /// let message = Message::new(&mut sink); 1327 /// let mut message = LiteralWriter::new(message) 1328 /// .format(DataFormat::Text) 1329 /// .build()?; 1330 /// message.write_all(b"Hello world.")?; 1331 /// message.finalize()?; 1332 /// } 1333 /// assert_eq!(b"\xcb\x12t\x00\x00\x00\x00\x00Hello world.", 1334 /// sink.as_slice()); 1335 /// # Ok(()) } 1336 /// ``` format(mut self, format: DataFormat) -> Self1337 pub fn format(mut self, format: DataFormat) -> Self { 1338 self.template.set_format(format); 1339 self 1340 } 1341 1342 /// Sets the filename. 1343 /// 1344 /// The standard does not specify the encoding. Filenames must 1345 /// not be longer than 255 bytes. Returns an error if the given 1346 /// name is longer than that. 1347 /// 1348 /// # Example 1349 /// 1350 /// ``` 1351 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1352 /// use std::io::Write; 1353 /// use sequoia_openpgp as openpgp; 1354 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 1355 /// 1356 /// let mut sink = vec![]; 1357 /// { 1358 /// let message = Message::new(&mut sink); 1359 /// let mut message = LiteralWriter::new(message) 1360 /// .filename("foobar")? 1361 /// .build()?; 1362 /// message.write_all(b"Hello world.")?; 1363 /// message.finalize()?; 1364 /// } 1365 /// assert_eq!(b"\xcb\x18b\x06foobar\x00\x00\x00\x00Hello world.", 1366 /// sink.as_slice()); 1367 /// # Ok(()) } 1368 /// ``` filename<B: AsRef<[u8]>>(mut self, filename: B) -> Result<Self>1369 pub fn filename<B: AsRef<[u8]>>(mut self, filename: B) -> Result<Self> { 1370 self.template.set_filename(filename.as_ref())?; 1371 Ok(self) 1372 } 1373 1374 /// Sets the date. 1375 /// 1376 /// This date may be the modification date or the creation date. 1377 /// Returns an error if the given date is not representable by 1378 /// OpenPGP. 1379 /// 1380 /// # Example 1381 /// 1382 /// ``` 1383 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1384 /// use std::io::Write; 1385 /// use sequoia_openpgp as openpgp; 1386 /// use openpgp::types::Timestamp; 1387 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 1388 /// 1389 /// let mut sink = vec![]; 1390 /// { 1391 /// let message = Message::new(&mut sink); 1392 /// let mut message = LiteralWriter::new(message) 1393 /// .date(Timestamp::from(1585925313))? 1394 /// .build()?; 1395 /// message.write_all(b"Hello world.")?; 1396 /// message.finalize()?; 1397 /// } 1398 /// assert_eq!(b"\xcb\x12b\x00\x5e\x87\x4c\xc1Hello world.", 1399 /// sink.as_slice()); 1400 /// # Ok(()) } 1401 /// ``` date<T: Into<SystemTime>>(mut self, timestamp: T) -> Result<Self>1402 pub fn date<T: Into<SystemTime>>(mut self, timestamp: T) -> Result<Self> 1403 { 1404 self.template.set_date(Some(timestamp.into()))?; 1405 Ok(self) 1406 } 1407 1408 /// Builds the literal writer, returning the writer stack. 1409 /// 1410 /// The next step is to write the payload to the writer stack. 1411 /// 1412 /// # Example 1413 /// 1414 /// ``` 1415 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1416 /// use std::io::Write; 1417 /// use sequoia_openpgp as openpgp; 1418 /// use openpgp::serialize::stream::{Message, LiteralWriter}; 1419 /// 1420 /// let mut sink = vec![]; 1421 /// { 1422 /// let message = Message::new(&mut sink); 1423 /// let mut message = LiteralWriter::new(message) 1424 /// // Customize the `LiteralWriter` here. 1425 /// .build()?; 1426 /// message.write_all(b"Hello world.")?; 1427 /// message.finalize()?; 1428 /// } 1429 /// assert_eq!(b"\xcb\x12b\x00\x00\x00\x00\x00Hello world.", 1430 /// sink.as_slice()); 1431 /// # Ok(()) } 1432 /// ``` build(mut self) -> Result<Message<'a>>1433 pub fn build(mut self) -> Result<Message<'a>> { 1434 let level = self.inner.cookie_ref().level + 1; 1435 1436 // For historical reasons, signatures over literal data 1437 // packets only include the body without metadata or framing. 1438 // Therefore, we check whether the writer is a 1439 // Signer, and if so, we pop it off the stack and 1440 // store it in 'self.signature_writer'. 1441 let signer_above = 1442 if let &Cookie { 1443 private: Private::Signer{..}, 1444 .. 1445 } = self.inner.cookie_ref() { 1446 true 1447 } else { 1448 false 1449 }; 1450 1451 if signer_above { 1452 let stack = self.inner.pop()?; 1453 // We know a signer has an inner stackable. 1454 let stack = stack.unwrap(); 1455 self.signature_writer = Some(self.inner); 1456 self.inner = stack; 1457 } 1458 1459 // Not hashed by the signature_writer (see above). 1460 CTB::new(Tag::Literal).serialize(&mut self.inner)?; 1461 1462 // Neither is any framing added by the PartialBodyFilter. 1463 self.inner 1464 = PartialBodyFilter::new(Message::from(self.inner), 1465 Cookie::new(level)).into(); 1466 1467 // Nor the headers. 1468 self.template.serialize_headers(&mut self.inner, false)?; 1469 1470 Ok(Message::from(Box::new(self))) 1471 } 1472 } 1473 1474 impl<'a> fmt::Debug for LiteralWriter<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1476 f.debug_struct("LiteralWriter") 1477 .field("inner", &self.inner) 1478 .finish() 1479 } 1480 } 1481 1482 impl<'a> Write for LiteralWriter<'a> { write(&mut self, buf: &[u8]) -> io::Result<usize>1483 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 1484 let written = self.inner.write(buf); 1485 1486 // Any successful written bytes needs to be hashed too. 1487 if let (&Ok(ref amount), &mut Some(ref mut sig)) 1488 = (&written, &mut self.signature_writer) { 1489 sig.write_all(&buf[..*amount])?; 1490 }; 1491 written 1492 } 1493 flush(&mut self) -> io::Result<()>1494 fn flush(&mut self) -> io::Result<()> { 1495 self.inner.flush() 1496 } 1497 } 1498 1499 impl<'a> writer::Stackable<'a, Cookie> for LiteralWriter<'a> { into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>>1500 fn into_inner(mut self: Box<Self>) 1501 -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1502 let signer = self.signature_writer.take(); 1503 let stack = self.inner 1504 .into_inner()?.unwrap(); // Peel off the PartialBodyFilter. 1505 1506 if let Some(mut signer) = signer { 1507 // We stashed away a Signer. Reattach it to the 1508 // stack and return it. 1509 signer.mount(stack); 1510 Ok(Some(signer)) 1511 } else { 1512 Ok(Some(stack)) 1513 } 1514 } 1515 pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>>1516 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1517 unreachable!("Only implemented by Signer") 1518 } 1519 /// Sets the inner stackable. mount(&mut self, _new: writer::BoxStack<'a, Cookie>)1520 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) { 1521 unreachable!("Only implemented by Signer") 1522 } inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>>1523 fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { 1524 Some(self.inner.as_ref()) 1525 } inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>>1526 fn inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>> { 1527 Some(self.inner.as_mut()) 1528 } cookie_set(&mut self, cookie: Cookie) -> Cookie1529 fn cookie_set(&mut self, cookie: Cookie) -> Cookie { 1530 self.inner.cookie_set(cookie) 1531 } cookie_ref(&self) -> &Cookie1532 fn cookie_ref(&self) -> &Cookie { 1533 self.inner.cookie_ref() 1534 } cookie_mut(&mut self) -> &mut Cookie1535 fn cookie_mut(&mut self) -> &mut Cookie { 1536 self.inner.cookie_mut() 1537 } position(&self) -> u641538 fn position(&self) -> u64 { 1539 self.inner.position() 1540 } 1541 } 1542 1543 /// Compresses a message. 1544 /// 1545 /// Writes a compressed data packet containing all packets written to 1546 /// this writer. 1547 pub struct Compressor<'a> { 1548 algo: CompressionAlgorithm, 1549 level: CompressionLevel, 1550 inner: writer::BoxStack<'a, Cookie>, 1551 } 1552 1553 impl<'a> Compressor<'a> { 1554 /// Creates a new compressor using the default algorithm and 1555 /// compression level. 1556 /// 1557 /// To change the compression algorithm use [`Compressor::algo`]. 1558 /// Use [`Compressor::level`] to change the compression level. 1559 /// 1560 /// [`Compressor::algo`]: #method.algo 1561 /// [`Compressor::level`]: #method.level 1562 /// 1563 /// # Example 1564 /// 1565 /// ``` 1566 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1567 /// use std::io::Write; 1568 /// use sequoia_openpgp as openpgp; 1569 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter}; 1570 /// use openpgp::types::CompressionAlgorithm; 1571 /// 1572 /// # let mut sink = vec![]; 1573 /// let message = Message::new(&mut sink); 1574 /// let message = Compressor::new(message) 1575 /// // Customize the `Compressor` here. 1576 /// # .algo(CompressionAlgorithm::Uncompressed) 1577 /// .build()?; 1578 /// let mut message = LiteralWriter::new(message).build()?; 1579 /// message.write_all(b"Hello world.")?; 1580 /// message.finalize()?; 1581 /// # Ok(()) } 1582 /// ``` new(inner: Message<'a>) -> Self1583 pub fn new(inner: Message<'a>) -> Self { 1584 Self { 1585 algo: Default::default(), 1586 level: Default::default(), 1587 inner: inner.into(), 1588 } 1589 } 1590 1591 /// Sets the compression algorithm. 1592 /// 1593 /// # Example 1594 /// 1595 /// ``` 1596 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1597 /// use std::io::Write; 1598 /// use sequoia_openpgp as openpgp; 1599 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter}; 1600 /// use openpgp::types::CompressionAlgorithm; 1601 /// 1602 /// let mut sink = vec![]; 1603 /// { 1604 /// let message = Message::new(&mut sink); 1605 /// let message = Compressor::new(message) 1606 /// .algo(CompressionAlgorithm::Uncompressed) 1607 /// .build()?; 1608 /// let mut message = LiteralWriter::new(message).build()?; 1609 /// message.write_all(b"Hello world.")?; 1610 /// message.finalize()?; 1611 /// } 1612 /// assert_eq!(b"\xc8\x15\x00\xcb\x12b\x00\x00\x00\x00\x00Hello world.", 1613 /// sink.as_slice()); 1614 /// # Ok(()) } 1615 /// ``` algo(mut self, algo: CompressionAlgorithm) -> Self1616 pub fn algo(mut self, algo: CompressionAlgorithm) -> Self { 1617 self.algo = algo; 1618 self 1619 } 1620 1621 /// Sets the compression level. 1622 /// 1623 /// # Example 1624 /// 1625 /// ``` 1626 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1627 /// use std::io::Write; 1628 /// use sequoia_openpgp as openpgp; 1629 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter}; 1630 /// use openpgp::types::{CompressionAlgorithm, CompressionLevel}; 1631 /// 1632 /// # let mut sink = vec![]; 1633 /// let message = Message::new(&mut sink); 1634 /// let message = Compressor::new(message) 1635 /// # .algo(CompressionAlgorithm::Uncompressed) 1636 /// .level(CompressionLevel::fastest()) 1637 /// .build()?; 1638 /// let mut message = LiteralWriter::new(message).build()?; 1639 /// message.write_all(b"Hello world.")?; 1640 /// message.finalize()?; 1641 /// # Ok(()) } 1642 /// ``` level(mut self, level: CompressionLevel) -> Self1643 pub fn level(mut self, level: CompressionLevel) -> Self { 1644 self.level = level; 1645 self 1646 } 1647 1648 /// Builds the compressor, returning the writer stack. 1649 /// 1650 /// The most useful filter to push to the writer stack next is the 1651 /// [`Signer`] or the [`LiteralWriter`]. Finally, literal data 1652 /// *must* be wrapped using the [`LiteralWriter`]. 1653 /// 1654 /// [`Signer`]: struct.Signer.html 1655 /// [`LiteralWriter`]: struct.LiteralWriter.html 1656 /// 1657 /// # Example 1658 /// 1659 /// ``` 1660 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1661 /// use std::io::Write; 1662 /// use sequoia_openpgp as openpgp; 1663 /// use openpgp::serialize::stream::{Message, Compressor, LiteralWriter}; 1664 /// use openpgp::types::CompressionAlgorithm; 1665 /// 1666 /// # let mut sink = vec![]; 1667 /// let message = Message::new(&mut sink); 1668 /// let message = Compressor::new(message) 1669 /// // Customize the `Compressor` here. 1670 /// # .algo(CompressionAlgorithm::Uncompressed) 1671 /// .build()?; 1672 /// let mut message = LiteralWriter::new(message).build()?; 1673 /// message.write_all(b"Hello world.")?; 1674 /// message.finalize()?; 1675 /// # Ok(()) } 1676 /// ``` build(mut self) -> Result<Message<'a>>1677 pub fn build(mut self) -> Result<Message<'a>> { 1678 let level = self.inner.cookie_ref().level + 1; 1679 1680 // Packet header. 1681 CTB::new(Tag::CompressedData).serialize(&mut self.inner)?; 1682 let inner: Message<'a> 1683 = PartialBodyFilter::new(Message::from(self.inner), 1684 Cookie::new(level)); 1685 1686 Self::new_naked(inner, self.algo, self.level, level) 1687 } 1688 1689 1690 /// Creates a new compressor using the given algorithm. 1691 pub(crate) // For CompressedData::serialize. new_naked(mut inner: Message<'a>, algo: CompressionAlgorithm, compression_level: CompressionLevel, level: usize) -> Result<Message<'a>>1692 fn new_naked(mut inner: Message<'a>, 1693 algo: CompressionAlgorithm, 1694 compression_level: CompressionLevel, 1695 level: usize) 1696 -> Result<Message<'a>> 1697 { 1698 // Compressed data header. 1699 inner.as_mut().write_u8(algo.into())?; 1700 1701 // Create an appropriate filter. 1702 let inner: Message<'a> = match algo { 1703 CompressionAlgorithm::Uncompressed => { 1704 // Avoid warning about unused value if compiled 1705 // without any compression support. 1706 let _ = compression_level; 1707 writer::Identity::new(inner, Cookie::new(level)) 1708 }, 1709 #[cfg(feature = "compression-deflate")] 1710 CompressionAlgorithm::Zip => 1711 writer::ZIP::new(inner, Cookie::new(level), compression_level), 1712 #[cfg(feature = "compression-deflate")] 1713 CompressionAlgorithm::Zlib => 1714 writer::ZLIB::new(inner, Cookie::new(level), compression_level), 1715 #[cfg(feature = "compression-bzip2")] 1716 CompressionAlgorithm::BZip2 => 1717 writer::BZ::new(inner, Cookie::new(level), compression_level), 1718 a => 1719 return Err(Error::UnsupportedCompressionAlgorithm(a).into()), 1720 }; 1721 1722 Ok(Message::from(Box::new(Self { 1723 algo, 1724 level: compression_level, 1725 inner: inner.into(), 1726 }))) 1727 } 1728 } 1729 1730 impl<'a> fmt::Debug for Compressor<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1731 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1732 f.debug_struct("Compressor") 1733 .field("inner", &self.inner) 1734 .finish() 1735 } 1736 } 1737 1738 impl<'a> io::Write for Compressor<'a> { write(&mut self, buf: &[u8]) -> io::Result<usize>1739 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 1740 self.inner.write(buf) 1741 } 1742 flush(&mut self) -> io::Result<()>1743 fn flush(&mut self) -> io::Result<()> { 1744 self.inner.flush() 1745 } 1746 } 1747 1748 impl<'a> writer::Stackable<'a, Cookie> for Compressor<'a> { into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>>1749 fn into_inner(self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1750 Box::new(self.inner).into_inner()?.unwrap().into_inner() 1751 } pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>>1752 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 1753 unreachable!("Only implemented by Signer") 1754 } 1755 /// Sets the inner stackable. mount(&mut self, _new: writer::BoxStack<'a, Cookie>)1756 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) { 1757 unreachable!("Only implemented by Signer") 1758 } inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>>1759 fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { 1760 Some(self.inner.as_ref()) 1761 } inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>>1762 fn inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>> { 1763 Some(self.inner.as_mut()) 1764 } cookie_set(&mut self, cookie: Cookie) -> Cookie1765 fn cookie_set(&mut self, cookie: Cookie) -> Cookie { 1766 self.inner.cookie_set(cookie) 1767 } cookie_ref(&self) -> &Cookie1768 fn cookie_ref(&self) -> &Cookie { 1769 self.inner.cookie_ref() 1770 } cookie_mut(&mut self) -> &mut Cookie1771 fn cookie_mut(&mut self) -> &mut Cookie { 1772 self.inner.cookie_mut() 1773 } position(&self) -> u641774 fn position(&self) -> u64 { 1775 self.inner.position() 1776 } 1777 } 1778 1779 /// A recipient of an encrypted message. 1780 /// 1781 /// OpenPGP messages are encrypted with the subkeys of recipients, 1782 /// identified by the keyid of said subkeys in the [`recipient`] field 1783 /// of [`PKESK`] packets (see [Section 5.1 of RFC 4880]). The keyid 1784 /// may be a wildcard (as returned by [`KeyID::wildcard()`]) to 1785 /// obscure the identity of the recipient. 1786 /// 1787 /// [`recipient`]: ../../packet/enum.PKESK.html#method.recipient 1788 /// [`PKESK`]: ../../packet/enum.PKESK.html 1789 /// [Section 5.1 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.1 1790 /// [`KeyID::wildcard()`]: ../../../struct.KeyID.html#method.wildcard 1791 /// 1792 /// Note that several subkeys in a certificate may be suitable 1793 /// encryption subkeys. OpenPGP does not specify what should happen 1794 /// in this case. Some implementations arbitrarily pick one 1795 /// encryption subkey, while others use all of them. This crate does 1796 /// not dictate a policy, but allows for arbitrary policies. We do, 1797 /// however, suggest to encrypt to all suitable subkeys. 1798 #[derive(Debug)] 1799 pub struct Recipient<'a> { 1800 keyid: KeyID, 1801 key: &'a Key<key::PublicParts, key::UnspecifiedRole>, 1802 } 1803 1804 impl<'a, P, R> From<&'a Key<P, R>> for Recipient<'a> 1805 where P: key::KeyParts, 1806 R: key::KeyRole, 1807 { from(key: &'a Key<P, R>) -> Self1808 fn from(key: &'a Key<P, R>) -> Self { 1809 Self::new(key.keyid(), key.parts_as_public().role_as_unspecified()) 1810 } 1811 } 1812 1813 impl<'a, P, R, R2> From<ValidKeyAmalgamation<'a, P, R, R2>> 1814 for Recipient<'a> 1815 where P: key::KeyParts, 1816 R: key::KeyRole, 1817 R2: Copy, 1818 { from(ka: ValidKeyAmalgamation<'a, P, R, R2>) -> Self1819 fn from(ka: ValidKeyAmalgamation<'a, P, R, R2>) -> Self { 1820 ka.key().into() 1821 } 1822 } 1823 1824 impl<'a> Recipient<'a> { 1825 /// Creates a new recipient with an explicit recipient keyid. 1826 /// 1827 /// Note: If you don't want to change the recipient keyid, 1828 /// `Recipient`s can be created from [`Key`] and 1829 /// [`ValidKeyAmalgamation`] using [`From`]. 1830 /// 1831 /// [`Key`]: ../../packet/enum.Key.html 1832 /// [`ValidKeyAmalgamation`]: ../../cert/amalgamation/key/struct.ValidKeyAmalgamation.html 1833 /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html 1834 /// 1835 /// # Example 1836 /// 1837 /// ``` 1838 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1839 /// use std::io::Write; 1840 /// use sequoia_openpgp as openpgp; 1841 /// use openpgp::cert::prelude::*; 1842 /// use openpgp::serialize::stream::{ 1843 /// Recipient, Message, Encryptor, 1844 /// }; 1845 /// use openpgp::policy::StandardPolicy; 1846 /// # use openpgp::parse::Parse; 1847 /// 1848 /// let p = &StandardPolicy::new(); 1849 /// 1850 /// let cert = Cert::from_bytes( 1851 /// # // We do some acrobatics here to abbreviate the Cert. 1852 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 1853 /// 1854 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 1855 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 1856 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 1857 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 1858 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 1859 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 1860 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 1861 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 1862 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 1863 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 1864 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 1865 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 1866 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 1867 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 1868 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 1869 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 1870 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 1871 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 1872 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 1873 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 1874 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 1875 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 1876 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 1877 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 1878 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 1879 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 1880 /// # =lAie 1881 /// # -----END PGP PUBLIC KEY BLOCK-----" 1882 /// # /* 1883 /// ... 1884 /// -----END PGP PUBLIC KEY BLOCK-----" 1885 /// # */ 1886 /// )?; 1887 /// 1888 /// let recipients = 1889 /// cert.keys().with_policy(p, None).alive().revoked(false) 1890 /// // Or `for_storage_encryption()`, for data at rest. 1891 /// .for_transport_encryption() 1892 /// .map(|ka| Recipient::new(ka.key().keyid(), ka.key())); 1893 /// 1894 /// # let mut sink = vec![]; 1895 /// let message = Message::new(&mut sink); 1896 /// let message = Encryptor::for_recipients(message, recipients).build()?; 1897 /// # let _ = message; 1898 /// # Ok(()) } 1899 /// ``` new<P, R>(keyid: KeyID, key: &'a Key<P, R>) -> Recipient<'a> where P: key::KeyParts, R: key::KeyRole,1900 pub fn new<P, R>(keyid: KeyID, key: &'a Key<P, R>) -> Recipient<'a> 1901 where P: key::KeyParts, 1902 R: key::KeyRole, 1903 { 1904 Recipient { 1905 keyid, 1906 key: key.parts_as_public().role_as_unspecified(), 1907 } 1908 } 1909 1910 /// Gets the recipient keyid. 1911 /// 1912 /// # Example 1913 /// 1914 /// ``` 1915 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1916 /// use std::io::Write; 1917 /// use sequoia_openpgp as openpgp; 1918 /// use openpgp::cert::prelude::*; 1919 /// use openpgp::serialize::stream::Recipient; 1920 /// use openpgp::policy::StandardPolicy; 1921 /// # use openpgp::parse::Parse; 1922 /// 1923 /// let p = &StandardPolicy::new(); 1924 /// 1925 /// let cert = Cert::from_bytes( 1926 /// # // We do some acrobatics here to abbreviate the Cert. 1927 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 1928 /// 1929 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 1930 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 1931 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 1932 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 1933 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 1934 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 1935 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 1936 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 1937 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 1938 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 1939 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 1940 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 1941 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 1942 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 1943 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 1944 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 1945 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 1946 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 1947 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 1948 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 1949 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 1950 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 1951 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 1952 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 1953 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 1954 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 1955 /// # =lAie 1956 /// # -----END PGP PUBLIC KEY BLOCK-----" 1957 /// # /* 1958 /// ... 1959 /// -----END PGP PUBLIC KEY BLOCK-----" 1960 /// # */ 1961 /// )?; 1962 /// 1963 /// let recipients = 1964 /// cert.keys().with_policy(p, None).alive().revoked(false) 1965 /// // Or `for_storage_encryption()`, for data at rest. 1966 /// .for_transport_encryption() 1967 /// .map(Into::into) 1968 /// .collect::<Vec<Recipient>>(); 1969 /// 1970 /// assert_eq!(recipients[0].keyid(), 1971 /// &"EA6E 3770 628A 713C".parse()?); 1972 /// # Ok(()) } 1973 /// ``` keyid(&self) -> &KeyID1974 pub fn keyid(&self) -> &KeyID { 1975 &self.keyid 1976 } 1977 1978 /// Sets the recipient keyid. 1979 /// 1980 /// # Example 1981 /// 1982 /// ``` 1983 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 1984 /// use std::io::Write; 1985 /// use sequoia_openpgp as openpgp; 1986 /// use openpgp::KeyID; 1987 /// use openpgp::cert::prelude::*; 1988 /// use openpgp::serialize::stream::{ 1989 /// Recipient, Message, Encryptor, 1990 /// }; 1991 /// use openpgp::policy::StandardPolicy; 1992 /// # use openpgp::parse::Parse; 1993 /// 1994 /// let p = &StandardPolicy::new(); 1995 /// 1996 /// let cert = Cert::from_bytes( 1997 /// # // We do some acrobatics here to abbreviate the Cert. 1998 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 1999 /// 2000 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 2001 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 2002 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 2003 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 2004 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 2005 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 2006 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 2007 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 2008 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 2009 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 2010 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 2011 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 2012 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 2013 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 2014 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 2015 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 2016 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 2017 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 2018 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 2019 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 2020 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 2021 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 2022 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 2023 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 2024 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 2025 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 2026 /// # =lAie 2027 /// # -----END PGP PUBLIC KEY BLOCK-----" 2028 /// # /* 2029 /// ... 2030 /// -----END PGP PUBLIC KEY BLOCK-----" 2031 /// # */ 2032 /// )?; 2033 /// 2034 /// let recipients = 2035 /// cert.keys().with_policy(p, None).alive().revoked(false) 2036 /// // Or `for_storage_encryption()`, for data at rest. 2037 /// .for_transport_encryption() 2038 /// .map(|ka| { 2039 /// let mut r: Recipient = ka.into(); 2040 /// // Set the recipient keyid to the wildcard id. 2041 /// r.set_keyid(KeyID::wildcard()); 2042 /// r 2043 /// }); 2044 /// 2045 /// # let mut sink = vec![]; 2046 /// let message = Message::new(&mut sink); 2047 /// let message = Encryptor::for_recipients(message, recipients).build()?; 2048 /// # let _ = message; 2049 /// # Ok(()) } 2050 /// ``` set_keyid(&mut self, keyid: KeyID) -> KeyID2051 pub fn set_keyid(&mut self, keyid: KeyID) -> KeyID { 2052 std::mem::replace(&mut self.keyid, keyid) 2053 } 2054 } 2055 2056 /// Encrypts a message. 2057 /// 2058 /// The stream will be encrypted using a generated session key, which 2059 /// will be encrypted using the given passwords, and for all given 2060 /// recipients. 2061 pub struct Encryptor<'a> { 2062 // XXX: Opportunity for optimization. Previously, this writer 2063 // implemented `Drop`, so we could not move the inner writer out 2064 // of this writer. We therefore wrapped it with `Option` so that 2065 // we can `take()` it. This writer no longer implements Drop, so 2066 // we could avoid the Option here. 2067 inner: Option<writer::BoxStack<'a, Cookie>>, 2068 recipients: Vec<Recipient<'a>>, 2069 passwords: Vec<Password>, 2070 sym_algo: SymmetricAlgorithm, 2071 aead_algo: Option<AEADAlgorithm>, 2072 hash: crypto::hash::Context, 2073 cookie: Cookie, 2074 } 2075 2076 impl<'a> Encryptor<'a> { 2077 /// Creates a new encryptor for the given recipients. 2078 /// 2079 /// To add more recipients, use [`Encryptor::add_recipient`]. To 2080 /// add a password, use [`Encryptor::add_password`]. To change 2081 /// the symmetric encryption algorithm, use 2082 /// [`Encryptor::sym_algo`]. To enable the experimental AEAD 2083 /// encryption, use [`Encryptor::aead_algo`]. 2084 /// 2085 /// [`Encryptor::add_recipient`]: #method.add_recipient 2086 /// [`Encryptor::add_password`]: #method.add_password 2087 /// [`Encryptor::sym_algo`]: #method.sym_algo 2088 /// [`Encryptor::aead_algo`]: #method.aead_algo 2089 /// 2090 /// # Example 2091 /// 2092 /// ``` 2093 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2094 /// use std::io::Write; 2095 /// use sequoia_openpgp as openpgp; 2096 /// use openpgp::cert::prelude::*; 2097 /// use openpgp::serialize::stream::{ 2098 /// Message, Encryptor, LiteralWriter, 2099 /// }; 2100 /// use openpgp::policy::StandardPolicy; 2101 /// # use openpgp::parse::Parse; 2102 /// let p = &StandardPolicy::new(); 2103 /// 2104 /// let cert = Cert::from_bytes( 2105 /// # // We do some acrobatics here to abbreviate the Cert. 2106 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 2107 /// 2108 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 2109 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 2110 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 2111 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 2112 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 2113 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 2114 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 2115 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 2116 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 2117 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 2118 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 2119 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 2120 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 2121 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 2122 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 2123 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 2124 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 2125 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 2126 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 2127 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 2128 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 2129 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 2130 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 2131 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 2132 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 2133 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 2134 /// # =lAie 2135 /// # -----END PGP PUBLIC KEY BLOCK-----" 2136 /// # /* 2137 /// ... 2138 /// -----END PGP PUBLIC KEY BLOCK-----" 2139 /// # */ 2140 /// )?; 2141 /// 2142 /// let recipients = 2143 /// cert.keys().with_policy(p, None).alive().revoked(false) 2144 /// // Or `for_storage_encryption()`, for data at rest. 2145 /// .for_transport_encryption(); 2146 /// 2147 /// # let mut sink = vec![]; 2148 /// let message = Message::new(&mut sink); 2149 /// let message = Encryptor::for_recipients(message, recipients).build()?; 2150 /// let mut w = LiteralWriter::new(message).build()?; 2151 /// w.write_all(b"Hello world.")?; 2152 /// w.finalize()?; 2153 /// # Ok(()) } 2154 /// ``` for_recipients<R>(inner: Message<'a>, recipients: R) -> Self where R: IntoIterator, R::Item: Into<Recipient<'a>>,2155 pub fn for_recipients<R>(inner: Message<'a>, recipients: R) -> Self 2156 where R: IntoIterator, 2157 R::Item: Into<Recipient<'a>>, 2158 { 2159 Self { 2160 inner: Some(inner.into()), 2161 recipients: recipients.into_iter().map(|r| r.into()).collect(), 2162 passwords: Vec::new(), 2163 sym_algo: Default::default(), 2164 aead_algo: Default::default(), 2165 hash: HashAlgorithm::SHA1.context().unwrap(), 2166 cookie: Default::default(), // Will be fixed in build. 2167 } 2168 } 2169 2170 /// Creates a new encryptor for the given passwords. 2171 /// 2172 /// To add more passwords, use [`Encryptor::add_password`]. To 2173 /// add an recipient, use [`Encryptor::add_recipient`]. To change 2174 /// the symmetric encryption algorithm, use 2175 /// [`Encryptor::sym_algo`]. To enable the experimental AEAD 2176 /// encryption, use [`Encryptor::aead_algo`]. 2177 /// 2178 /// [`Encryptor::add_recipient`]: #method.add_recipient 2179 /// [`Encryptor::add_password`]: #method.add_password 2180 /// [`Encryptor::sym_algo`]: #method.sym_algo 2181 /// [`Encryptor::aead_algo`]: #method.aead_algo 2182 /// 2183 /// # Example 2184 /// 2185 /// ``` 2186 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2187 /// use std::io::Write; 2188 /// use sequoia_openpgp as openpgp; 2189 /// use openpgp::serialize::stream::{ 2190 /// Message, Encryptor, LiteralWriter, 2191 /// }; 2192 /// 2193 /// # let mut sink = vec![]; 2194 /// let message = Message::new(&mut sink); 2195 /// let message = Encryptor::with_passwords( 2196 /// message, Some("совершенно секретно")).build()?; 2197 /// let mut w = LiteralWriter::new(message).build()?; 2198 /// w.write_all(b"Hello world.")?; 2199 /// w.finalize()?; 2200 /// # Ok(()) } 2201 /// ``` with_passwords<P>(inner: Message<'a>, passwords: P) -> Self where P: IntoIterator, P::Item: Into<Password>,2202 pub fn with_passwords<P>(inner: Message<'a>, passwords: P) -> Self 2203 where P: IntoIterator, 2204 P::Item: Into<Password>, 2205 { 2206 Self { 2207 inner: Some(inner.into()), 2208 recipients: Vec::new(), 2209 passwords: passwords.into_iter().map(|p| p.into()).collect(), 2210 sym_algo: Default::default(), 2211 aead_algo: Default::default(), 2212 hash: HashAlgorithm::SHA1.context().unwrap(), 2213 cookie: Default::default(), // Will be fixed in build. 2214 } 2215 } 2216 2217 /// Adds recipients. 2218 /// 2219 /// The resulting message can be encrypted by any recipient and 2220 /// with any password. 2221 /// 2222 /// # Example 2223 /// 2224 /// ``` 2225 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2226 /// use std::io::Write; 2227 /// use sequoia_openpgp as openpgp; 2228 /// use openpgp::cert::prelude::*; 2229 /// use openpgp::serialize::stream::{ 2230 /// Message, Encryptor, LiteralWriter, 2231 /// }; 2232 /// use openpgp::policy::StandardPolicy; 2233 /// # use openpgp::parse::Parse; 2234 /// let p = &StandardPolicy::new(); 2235 /// 2236 /// let cert = Cert::from_bytes( 2237 /// # // We do some acrobatics here to abbreviate the Cert. 2238 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 2239 /// 2240 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 2241 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 2242 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 2243 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 2244 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 2245 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 2246 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 2247 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 2248 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 2249 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 2250 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 2251 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 2252 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 2253 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 2254 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 2255 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 2256 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 2257 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 2258 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 2259 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 2260 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 2261 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 2262 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 2263 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 2264 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 2265 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 2266 /// # =lAie 2267 /// # -----END PGP PUBLIC KEY BLOCK-----" 2268 /// # /* 2269 /// ... 2270 /// -----END PGP PUBLIC KEY BLOCK-----" 2271 /// # */ 2272 /// )?; 2273 /// 2274 /// let recipients = 2275 /// cert.keys().with_policy(p, None).alive().revoked(false) 2276 /// // Or `for_storage_encryption()`, for data at rest. 2277 /// .for_transport_encryption(); 2278 /// 2279 /// # let mut sink = vec![]; 2280 /// let message = Message::new(&mut sink); 2281 /// let message = 2282 /// Encryptor::with_passwords(message, Some("совершенно секретно")) 2283 /// .add_recipients(recipients) 2284 /// .build()?; 2285 /// let mut message = LiteralWriter::new(message).build()?; 2286 /// message.write_all(b"Hello world.")?; 2287 /// message.finalize()?; 2288 /// # Ok(()) } 2289 /// ``` add_recipients<R>(mut self, recipients: R) -> Self where R: IntoIterator, R::Item: Into<Recipient<'a>>,2290 pub fn add_recipients<R>(mut self, recipients: R) -> Self 2291 where R: IntoIterator, 2292 R::Item: Into<Recipient<'a>>, 2293 { 2294 for r in recipients { 2295 self.recipients.push(r.into()); 2296 } 2297 self 2298 } 2299 2300 /// Adds passwords to encrypt with. 2301 /// 2302 /// The resulting message can be encrypted with any password and 2303 /// by any recipient. 2304 /// 2305 /// # Example 2306 /// 2307 /// ``` 2308 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2309 /// use std::io::Write; 2310 /// use sequoia_openpgp as openpgp; 2311 /// use openpgp::cert::prelude::*; 2312 /// use openpgp::serialize::stream::{ 2313 /// Message, Encryptor, LiteralWriter, 2314 /// }; 2315 /// use openpgp::policy::StandardPolicy; 2316 /// # use openpgp::parse::Parse; 2317 /// let p = &StandardPolicy::new(); 2318 /// 2319 /// let cert = Cert::from_bytes( 2320 /// # // We do some acrobatics here to abbreviate the Cert. 2321 /// "-----BEGIN PGP PUBLIC KEY BLOCK----- 2322 /// 2323 /// mQENBFpxtsABCADZcBa1Q3ZLZnju18o0+t8LoQuIIeyeUQ0H45y6xUqyrD5HSkVM 2324 /// # VGQs6IHLq70mAizBJ4VznUVqVOh/NhOlapXi6/TKpjHvttdg45o6Pgqa0Kx64luT 2325 /// # ZY+TEKyILcdBdhr3CzsEILnQst5jadgMvU9fnT/EkJIvxtWPlUzU5R7nnALO626x 2326 /// # 2M5Pj3k0h3ZNHMmYQQtReX/RP/xUh2SfOYG6i/MCclIlee8BXHB9k0bW2NAX2W7H 2327 /// # rLDGPm1LzmyqxFGDvDvfPlYZ5nN2cbGsv3w75LDzv75kMhVnkZsrUjnHjVRzFq7q 2328 /// # fSIpxlvJMEMKSIJ/TFztQoOBO5OlBb5qzYPpABEBAAG0F+G8iM+BzrnPg8+Ezr/P 2329 /// # hM6tzrvOt8+CiQFUBBMBCAA+FiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsAC 2330 /// # GwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQJH9tq8hJFP49hgf+ 2331 /// # IKvec0RkD9EHSLFc6AKDm/knaI4AIH0isZTz9jRCF8H/j3h8QVUE+/0jtCcyvR6F 2332 /// # TGVSfO3pelDPYGIjDFI3aA6H/UlhZWzYRXZ+QQRrV0zwvLna3XjiW8ib3Ky+5bpQ 2333 /// # 0uVeee30u+U3SnaCL9QB4+UvwVvAxRuk49Z0Q8TsRrQyQNYpeZDN7uNrvA134cf6 2334 /// # 6pLUvzPG4lMLIvSXFuHou704EhT7NS3wAzFtjMrsLLieVqtbEi/kBaJTQSZQwjVB 2335 /// # sE/Z8lp1heKw/33Br3cB63n4cTf0FdoFywDBhCAMU7fKboU5xBpm5bQJ4ck6j6w+ 2336 /// # BKG1FiQRR6PCUeb6GjxVOrkBDQRacbbAAQgAw538MMb/pRdpt7PTgBCedw+rU9fh 2337 /// # onZYKwmCO7wz5VrVf8zIVvWKxhX6fBTSAy8mxaYbeL/3woQ9Leuo8f0PQNs9zw1N 2338 /// # mdH+cnm2KQmL9l7/HQKMLgEAu/0C/q7ii/j8OMYitaMUyrwy+OzW3nCal/uJHIfj 2339 /// # bdKx29MbKgF/zaBs8mhTvf/Tu0rIVNDPEicwijDEolGSGebZxdGdHJA31uayMHDK 2340 /// # /mwySJViMZ8b+Lzc/dRgNbQoY6yjsjso7U9OZpQK1fooHOSQS6iLsSSsZLcGPD+7 2341 /// # m7j3jwq68SIJPMsu0O8hdjFWL4Cfj815CwptAxRGkp00CIusAabO7m8DzwARAQAB 2342 /// # iQE2BBgBCAAgFiEEfcpYtU6xQxad3uFfJH9tq8hJFP4FAlpxtsACGwwACgkQJH9t 2343 /// # q8hJFP5rmQgAoYOUXolTiQmWipJTdMG/VZ5X7mL8JiBWAQ11K1o01cZCMlziyHnJ 2344 /// # xJ6Mqjb6wAFpYBtqysJG/vfjc/XEoKgfFs7+zcuEnt41xJQ6tl/L0VTxs+tEwjZu 2345 /// # Rp/owB9GCkqN9+xNEnlH77TLW1UisW+l0F8CJ2WFOj4lk9rcXcLlEdGmXfWIlVCb 2346 /// # 2/o0DD+HDNsF8nWHpDEy0mcajkgIUTvXQaDXKbccX6Wgep8dyBP7YucGmRPd9Z6H 2347 /// # bGeT3KvlJlH5kthQ9shsmT14gYwGMR6rKpNUXmlpetkjqUK7pGVaHGgJWUZ9QPGU 2348 /// # awwPdWWvZSyXJAPZ9lC5sTKwMJDwIxILug== 2349 /// # =lAie 2350 /// # -----END PGP PUBLIC KEY BLOCK-----" 2351 /// # /* 2352 /// ... 2353 /// -----END PGP PUBLIC KEY BLOCK-----" 2354 /// # */ 2355 /// )?; 2356 /// 2357 /// let recipients = 2358 /// cert.keys().with_policy(p, None).alive().revoked(false) 2359 /// // Or `for_storage_encryption()`, for data at rest. 2360 /// .for_transport_encryption(); 2361 /// 2362 /// # let mut sink = vec![]; 2363 /// let message = Message::new(&mut sink); 2364 /// let message = 2365 /// Encryptor::for_recipients(message, recipients) 2366 /// .add_passwords(Some("совершенно секретно")) 2367 /// .build()?; 2368 /// let mut message = LiteralWriter::new(message).build()?; 2369 /// message.write_all(b"Hello world.")?; 2370 /// message.finalize()?; 2371 /// # Ok(()) } 2372 /// ``` add_passwords<P>(mut self, passwords: P) -> Self where P: IntoIterator, P::Item: Into<Password>,2373 pub fn add_passwords<P>(mut self, passwords: P) -> Self 2374 where P: IntoIterator, 2375 P::Item: Into<Password>, 2376 { 2377 for p in passwords { 2378 self.passwords.push(p.into()); 2379 } 2380 self 2381 } 2382 2383 /// Sets the symmetric algorithm to use. 2384 /// 2385 /// # Example 2386 /// 2387 /// ``` 2388 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2389 /// use std::io::Write; 2390 /// use sequoia_openpgp as openpgp; 2391 /// use openpgp::types::SymmetricAlgorithm; 2392 /// use openpgp::serialize::stream::{ 2393 /// Message, Encryptor, LiteralWriter, 2394 /// }; 2395 /// 2396 /// # let mut sink = vec![]; 2397 /// let message = Message::new(&mut sink); 2398 /// let message = 2399 /// Encryptor::with_passwords(message, Some("совершенно секретно")) 2400 /// .symmetric_algo(SymmetricAlgorithm::AES128) 2401 /// .build()?; 2402 /// let mut message = LiteralWriter::new(message).build()?; 2403 /// message.write_all(b"Hello world.")?; 2404 /// message.finalize()?; 2405 /// # Ok(()) } 2406 /// ``` symmetric_algo(mut self, algo: SymmetricAlgorithm) -> Self2407 pub fn symmetric_algo(mut self, algo: SymmetricAlgorithm) -> Self { 2408 self.sym_algo = algo; 2409 self 2410 } 2411 2412 /// Enables AEAD and sets the AEAD algorithm to use. 2413 /// 2414 /// This feature is [experimental](../../index.html#experimental-features). 2415 /// 2416 /// # Example 2417 /// 2418 /// ``` 2419 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2420 /// use std::io::Write; 2421 /// use sequoia_openpgp as openpgp; 2422 /// use openpgp::types::AEADAlgorithm; 2423 /// use openpgp::serialize::stream::{ 2424 /// Message, Encryptor, LiteralWriter, 2425 /// }; 2426 /// 2427 /// # let mut sink = vec![]; 2428 /// let message = Message::new(&mut sink); 2429 /// let message = 2430 /// Encryptor::with_passwords(message, Some("совершенно секретно")) 2431 /// .aead_algo(AEADAlgorithm::EAX) 2432 /// .build()?; 2433 /// let mut message = LiteralWriter::new(message).build()?; 2434 /// message.write_all(b"Hello world.")?; 2435 /// message.finalize()?; 2436 /// # Ok(()) } 2437 /// ``` aead_algo(mut self, algo: AEADAlgorithm) -> Self2438 pub fn aead_algo(mut self, algo: AEADAlgorithm) -> Self { 2439 self.aead_algo = Some(algo); 2440 self 2441 } 2442 2443 // The default chunk size. 2444 // 2445 // A page, 3 per mille overhead. 2446 const AEAD_CHUNK_SIZE : usize = 4096; 2447 2448 /// Builds the encryptor, returning the writer stack. 2449 /// 2450 /// The most useful filters to push to the writer stack next are 2451 /// the [`Padder`] or [`Compressor`], and after that the 2452 /// [`Signer`]. Finally, literal data *must* be wrapped using the 2453 /// [`LiteralWriter`]. 2454 /// 2455 /// [`Compressor`]: struct.Compressor.html 2456 /// [`Padder`]: padding/struct.Padder.html 2457 /// [`Signer`]: struct.Signer.html 2458 /// [`LiteralWriter`]: struct.LiteralWriter.html 2459 /// 2460 /// # Example 2461 /// 2462 /// ``` 2463 /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { 2464 /// use std::io::Write; 2465 /// use sequoia_openpgp as openpgp; 2466 /// use openpgp::serialize::stream::{ 2467 /// Message, Encryptor, LiteralWriter, 2468 /// }; 2469 /// 2470 /// # let mut sink = vec![]; 2471 /// let message = Message::new(&mut sink); 2472 /// let message = 2473 /// Encryptor::with_passwords(message, Some("совершенно секретно")) 2474 /// // Customize the `Encryptor` here. 2475 /// .build()?; 2476 /// 2477 /// // Optionally add a `Padder` or `Compressor` here. 2478 /// // Optionally add a `Signer` here. 2479 /// 2480 /// let mut message = LiteralWriter::new(message).build()?; 2481 /// message.write_all(b"Hello world.")?; 2482 /// message.finalize()?; 2483 /// # Ok(()) } 2484 /// ``` build(mut self) -> Result<Message<'a>>2485 pub fn build(mut self) -> Result<Message<'a>> { 2486 if self.recipients.len() + self.passwords.len() == 0 { 2487 return Err(Error::InvalidOperation( 2488 "Neither recipients nor passwords given".into()).into()); 2489 } 2490 2491 struct AEADParameters { 2492 algo: AEADAlgorithm, 2493 chunk_size: usize, 2494 nonce: Box<[u8]>, 2495 } 2496 2497 let aead = if let Some(algo) = self.aead_algo { 2498 let mut nonce = vec![0; algo.iv_size()?]; 2499 crypto::random(&mut nonce); 2500 Some(AEADParameters { 2501 algo, 2502 chunk_size: Self::AEAD_CHUNK_SIZE, 2503 nonce: nonce.into_boxed_slice(), 2504 }) 2505 } else { 2506 None 2507 }; 2508 2509 let mut inner = self.inner.take().expect("Added in constructors"); 2510 let level = inner.as_ref().cookie_ref().level + 1; 2511 2512 // Generate a session key. 2513 let sk = SessionKey::new(self.sym_algo.key_size()?); 2514 2515 // Write the PKESK packet(s). 2516 for recipient in self.recipients.iter() { 2517 let mut pkesk = 2518 PKESK3::for_recipient(self.sym_algo, &sk, recipient.key)?; 2519 pkesk.set_recipient(recipient.keyid.clone()); 2520 Packet::PKESK(pkesk.into()).serialize(&mut inner)?; 2521 } 2522 2523 // Write the SKESK packet(s). 2524 for password in self.passwords.iter() { 2525 if let Some(aead) = aead.as_ref() { 2526 let skesk = SKESK5::with_password(self.sym_algo, 2527 self.sym_algo, 2528 aead.algo, 2529 Default::default(), 2530 &sk, password).unwrap(); 2531 Packet::SKESK(skesk.into()).serialize(&mut inner)?; 2532 } else { 2533 let skesk = SKESK4::with_password(self.sym_algo, 2534 self.sym_algo, 2535 Default::default(), 2536 &sk, password).unwrap(); 2537 Packet::SKESK(skesk.into()).serialize(&mut inner)?; 2538 } 2539 } 2540 2541 if let Some(aead) = aead { 2542 // Write the AED packet. 2543 CTB::new(Tag::AED).serialize(&mut inner)?; 2544 let mut inner = PartialBodyFilter::new(Message::from(inner), 2545 Cookie::new(level)); 2546 let aed = AED1::new(self.sym_algo, aead.algo, 2547 aead.chunk_size as u64, aead.nonce)?; 2548 aed.serialize_headers(&mut inner)?; 2549 2550 writer::AEADEncryptor::new( 2551 inner.into(), 2552 Cookie::new(level), 2553 aed.symmetric_algo(), 2554 aed.aead(), 2555 aead.chunk_size, 2556 aed.iv(), 2557 &sk, 2558 ) 2559 } else { 2560 // Write the SEIP packet. 2561 CTB::new(Tag::SEIP).serialize(&mut inner)?; 2562 let mut inner = PartialBodyFilter::new(Message::from(inner), 2563 Cookie::new(level)); 2564 inner.write_all(&[1])?; // Version. 2565 2566 // Install encryptor. 2567 self.inner = Some(writer::Encryptor::new( 2568 inner.into(), 2569 Cookie::new(level), 2570 self.sym_algo, 2571 &sk, 2572 )?.into()); 2573 self.cookie = Cookie::new(level); 2574 2575 // Write the initialization vector, and the quick-check 2576 // bytes. The hash for the MDC must include the 2577 // initialization vector, hence we must write this to 2578 // self after installing the encryptor at self.inner. 2579 let mut iv = vec![0; self.sym_algo.block_size()?]; 2580 crypto::random(&mut iv); 2581 self.write_all(&iv)?; 2582 self.write_all(&iv[iv.len() - 2..])?; 2583 2584 Ok(Message::from(Box::new(self))) 2585 } 2586 } 2587 2588 /// Emits the MDC packet and recovers the original writer. emit_mdc(&mut self) -> Result<writer::BoxStack<'a, Cookie>>2589 fn emit_mdc(&mut self) -> Result<writer::BoxStack<'a, Cookie>> { 2590 if let Some(mut w) = self.inner.take() { 2591 // Write the MDC, which must be the last packet inside the 2592 // encrypted packet stream. The hash includes the MDC's 2593 // CTB and length octet. 2594 let mut header = Vec::new(); 2595 CTB::new(Tag::MDC).serialize(&mut header)?; 2596 BodyLength::Full(20).serialize(&mut header)?; 2597 2598 self.hash.update(&header); 2599 Packet::MDC(MDC::from(self.hash.clone())).serialize(&mut w)?; 2600 2601 // Now recover the original writer. First, strip the 2602 // Encryptor. 2603 let w = w.into_inner()?.unwrap(); 2604 // And the partial body filter. 2605 let w = w.into_inner()?.unwrap(); 2606 2607 Ok(w) 2608 } else { 2609 Err(Error::InvalidOperation( 2610 "Inner writer already taken".into()).into()) 2611 } 2612 } 2613 } 2614 2615 impl<'a> fmt::Debug for Encryptor<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result2616 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2617 f.debug_struct("Encryptor") 2618 .field("inner", &self.inner) 2619 .finish() 2620 } 2621 } 2622 2623 impl<'a> Write for Encryptor<'a> { write(&mut self, buf: &[u8]) -> io::Result<usize>2624 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 2625 let written = match self.inner.as_mut() { 2626 Some(ref mut w) => w.write(buf), 2627 None => Ok(buf.len()), 2628 }; 2629 if let Ok(amount) = written { 2630 self.hash.update(&buf[..amount]); 2631 } 2632 written 2633 } 2634 flush(&mut self) -> io::Result<()>2635 fn flush(&mut self) -> io::Result<()> { 2636 match self.inner.as_mut() { 2637 Some(ref mut w) => w.flush(), 2638 None => Ok(()), 2639 } 2640 } 2641 } 2642 2643 impl<'a> writer::Stackable<'a, Cookie> for Encryptor<'a> { pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>>2644 fn pop(&mut self) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 2645 unreachable!("Only implemented by Signer") 2646 } 2647 /// Sets the inner stackable. mount(&mut self, _new: writer::BoxStack<'a, Cookie>)2648 fn mount(&mut self, _new: writer::BoxStack<'a, Cookie>) { 2649 unreachable!("Only implemented by Signer") 2650 } inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>>2651 fn inner_ref(&self) -> Option<&dyn writer::Stackable<'a, Cookie>> { 2652 self.inner.as_ref().map(|r| r.as_ref()) 2653 } inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>>2654 fn inner_mut(&mut self) -> Option<&mut dyn writer::Stackable<'a, Cookie>> { 2655 if let Some(ref mut i) = self.inner { 2656 Some(i) 2657 } else { 2658 None 2659 } 2660 } into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>>2661 fn into_inner(mut self: Box<Self>) -> Result<Option<writer::BoxStack<'a, Cookie>>> { 2662 Ok(Some(self.emit_mdc()?)) 2663 } cookie_set(&mut self, cookie: Cookie) -> Cookie2664 fn cookie_set(&mut self, cookie: Cookie) -> Cookie { 2665 ::std::mem::replace(&mut self.cookie, cookie) 2666 } cookie_ref(&self) -> &Cookie2667 fn cookie_ref(&self) -> &Cookie { 2668 &self.cookie 2669 } cookie_mut(&mut self) -> &mut Cookie2670 fn cookie_mut(&mut self) -> &mut Cookie { 2671 &mut self.cookie 2672 } position(&self) -> u642673 fn position(&self) -> u64 { 2674 self.inner.as_ref().map(|i| i.position()).unwrap_or(0) 2675 } 2676 } 2677 2678 #[cfg(test)] 2679 mod test { 2680 use std::io::Read; 2681 use crate::{Packet, PacketPile, packet::CompressedData}; 2682 use crate::parse::{Parse, PacketParserResult, PacketParser}; 2683 use super::*; 2684 use crate::types::DataFormat::Text as T; 2685 use crate::policy::Policy; 2686 use crate::policy::StandardPolicy as P; 2687 2688 #[test] arbitrary()2689 fn arbitrary() { 2690 let mut o = vec![]; 2691 { 2692 let m = Message::new(&mut o); 2693 let mut ustr = ArbitraryWriter::new(m, Tag::Literal).unwrap(); 2694 ustr.write_all(b"t").unwrap(); // type 2695 ustr.write_all(b"\x00").unwrap(); // fn length 2696 ustr.write_all(b"\x00\x00\x00\x00").unwrap(); // date 2697 ustr.write_all(b"Hello world.").unwrap(); // body 2698 ustr.finalize().unwrap(); 2699 } 2700 2701 let mut pp = PacketParser::from_bytes(&o).unwrap().unwrap(); 2702 if let Packet::Literal(ref l) = pp.packet { 2703 assert_eq!(l.format(), DataFormat::Text); 2704 assert_eq!(l.filename(), None); 2705 assert_eq!(l.date(), None); 2706 } else { 2707 panic!("Unexpected packet type."); 2708 } 2709 2710 let mut body = vec![]; 2711 pp.read_to_end(&mut body).unwrap(); 2712 assert_eq!(&body, b"Hello world."); 2713 2714 // Make sure it is the only packet. 2715 let (_, ppr) = pp.recurse().unwrap(); 2716 assert!(ppr.is_eof()); 2717 } 2718 2719 // Create some crazy nesting structures, serialize the messages, 2720 // reparse them, and make sure we get the same result. 2721 #[test] stream_0()2722 fn stream_0() { 2723 // 1: CompressedData(CompressedData { algo: 0 }) 2724 // 1: Literal(Literal { body: "one (3 bytes)" }) 2725 // 2: Literal(Literal { body: "two (3 bytes)" }) 2726 // 2: Literal(Literal { body: "three (5 bytes)" }) 2727 let mut one = Literal::new(T); 2728 one.set_body(b"one".to_vec()); 2729 let mut two = Literal::new(T); 2730 two.set_body(b"two".to_vec()); 2731 let mut three = Literal::new(T); 2732 three.set_body(b"three".to_vec()); 2733 let mut reference = Vec::new(); 2734 reference.push( 2735 CompressedData::new(CompressionAlgorithm::Uncompressed) 2736 .push(one.into()) 2737 .push(two.into()) 2738 .into()); 2739 reference.push(three.into()); 2740 2741 let mut o = vec![]; 2742 { 2743 let m = Message::new(&mut o); 2744 let c = Compressor::new(m) 2745 .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); 2746 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2747 write!(ls, "one").unwrap(); 2748 let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter. 2749 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2750 write!(ls, "two").unwrap(); 2751 let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter. 2752 let c = c.finalize_one().unwrap().unwrap(); // Pop the Compressor. 2753 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2754 write!(ls, "three").unwrap(); 2755 ls.finalize().unwrap(); 2756 } 2757 2758 let pile = PacketPile::from(reference); 2759 let pile2 = PacketPile::from_bytes(&o).unwrap(); 2760 if pile != pile2 { 2761 eprintln!("REFERENCE..."); 2762 pile.pretty_print(); 2763 eprintln!("REPARSED..."); 2764 pile2.pretty_print(); 2765 panic!("Reparsed packet does not match reference packet!"); 2766 } 2767 } 2768 2769 // Create some crazy nesting structures, serialize the messages, 2770 // reparse them, and make sure we get the same result. 2771 #[test] stream_1()2772 fn stream_1() { 2773 // 1: CompressedData(CompressedData { algo: 0 }) 2774 // 1: CompressedData(CompressedData { algo: 0 }) 2775 // 1: Literal(Literal { body: "one (3 bytes)" }) 2776 // 2: Literal(Literal { body: "two (3 bytes)" }) 2777 // 2: CompressedData(CompressedData { algo: 0 }) 2778 // 1: Literal(Literal { body: "three (5 bytes)" }) 2779 // 2: Literal(Literal { body: "four (4 bytes)" }) 2780 let mut one = Literal::new(T); 2781 one.set_body(b"one".to_vec()); 2782 let mut two = Literal::new(T); 2783 two.set_body(b"two".to_vec()); 2784 let mut three = Literal::new(T); 2785 three.set_body(b"three".to_vec()); 2786 let mut four = Literal::new(T); 2787 four.set_body(b"four".to_vec()); 2788 let mut reference = Vec::new(); 2789 reference.push( 2790 CompressedData::new(CompressionAlgorithm::Uncompressed) 2791 .push(CompressedData::new(CompressionAlgorithm::Uncompressed) 2792 .push(one.into()) 2793 .push(two.into()) 2794 .into()) 2795 .push(CompressedData::new(CompressionAlgorithm::Uncompressed) 2796 .push(three.into()) 2797 .push(four.into()) 2798 .into()) 2799 .into()); 2800 2801 let mut o = vec![]; 2802 { 2803 let m = Message::new(&mut o); 2804 let c0 = Compressor::new(m) 2805 .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); 2806 let c = Compressor::new(c0) 2807 .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); 2808 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2809 write!(ls, "one").unwrap(); 2810 let c = ls.finalize_one().unwrap().unwrap(); 2811 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2812 write!(ls, "two").unwrap(); 2813 let c = ls.finalize_one().unwrap().unwrap(); 2814 let c0 = c.finalize_one().unwrap().unwrap(); 2815 let c = Compressor::new(c0) 2816 .algo(CompressionAlgorithm::Uncompressed).build().unwrap(); 2817 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2818 write!(ls, "three").unwrap(); 2819 let c = ls.finalize_one().unwrap().unwrap(); 2820 let mut ls = LiteralWriter::new(c).format(T).build().unwrap(); 2821 write!(ls, "four").unwrap(); 2822 ls.finalize().unwrap(); 2823 } 2824 2825 let pile = PacketPile::from(reference); 2826 let pile2 = PacketPile::from_bytes(&o).unwrap(); 2827 if pile != pile2 { 2828 eprintln!("REFERENCE..."); 2829 pile.pretty_print(); 2830 eprintln!("REPARSED..."); 2831 pile2.pretty_print(); 2832 panic!("Reparsed packet does not match reference packet!"); 2833 } 2834 } 2835 2836 #[cfg(feature = "compression-bzip2")] 2837 #[test] stream_big()2838 fn stream_big() { 2839 let zeros = vec![0; 1024 * 1024 * 4]; 2840 let mut o = vec![]; 2841 { 2842 let m = Message::new(&mut o); 2843 let c = Compressor::new(m) 2844 .algo(CompressionAlgorithm::BZip2).build().unwrap(); 2845 let mut ls = LiteralWriter::new(c).build().unwrap(); 2846 // Write 64 megabytes of zeroes. 2847 for _ in 0 .. 16 { 2848 ls.write_all(&zeros).unwrap(); 2849 } 2850 } 2851 assert!(o.len() < 1024); 2852 } 2853 2854 #[test] signature()2855 fn signature() { 2856 let p = &P::new(); 2857 use crate::crypto::KeyPair; 2858 use std::collections::HashMap; 2859 use crate::Fingerprint; 2860 2861 let mut keys: HashMap<Fingerprint, key::UnspecifiedPublic> = HashMap::new(); 2862 for tsk in &[ 2863 Cert::from_bytes(crate::tests::key("testy-private.pgp")).unwrap(), 2864 Cert::from_bytes(crate::tests::key("testy-new-private.pgp")).unwrap(), 2865 ] { 2866 for key in tsk.keys().with_policy(p, crate::frozen_time()) 2867 .for_signing().map(|ka| ka.key()) 2868 { 2869 keys.insert(key.fingerprint(), key.clone()); 2870 } 2871 } 2872 2873 let mut o = vec![]; 2874 { 2875 let mut signers = keys.iter().map(|(_, key)| { 2876 key.clone().parts_into_secret().unwrap().into_keypair() 2877 .expect("expected unencrypted secret key") 2878 }).collect::<Vec<KeyPair>>(); 2879 2880 let m = Message::new(&mut o); 2881 let mut signer = Signer::new(m, signers.pop().unwrap()); 2882 for s in signers.into_iter() { 2883 signer = signer.add_signer(s); 2884 } 2885 let signer = signer.build().unwrap(); 2886 let mut ls = LiteralWriter::new(signer).build().unwrap(); 2887 ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap(); 2888 let _ = ls.finalize().unwrap(); 2889 } 2890 2891 let mut ppr = PacketParser::from_bytes(&o).unwrap(); 2892 let mut good = 0; 2893 while let PacketParserResult::Some(pp) = ppr { 2894 if let Packet::Signature(ref sig) = pp.packet { 2895 let key = keys.get(&sig.issuer_fingerprints().nth(0).unwrap()) 2896 .unwrap(); 2897 sig.verify(key).unwrap(); 2898 good += 1; 2899 } 2900 2901 // Get the next packet. 2902 ppr = pp.recurse().unwrap().1; 2903 } 2904 assert_eq!(good, 2); 2905 } 2906 2907 #[test] encryptor()2908 fn encryptor() { 2909 let passwords = vec!["streng geheim".into(), 2910 "top secret".into()]; 2911 let message = b"Hello world."; 2912 2913 // Write a simple encrypted message... 2914 let mut o = vec![]; 2915 { 2916 let m = Message::new(&mut o); 2917 let encryptor = Encryptor::with_passwords(m, passwords.clone()) 2918 .build().unwrap(); 2919 let mut literal = LiteralWriter::new(encryptor).build() 2920 .unwrap(); 2921 literal.write_all(message).unwrap(); 2922 literal.finalize().unwrap(); 2923 } 2924 2925 // ... and recover it... 2926 #[derive(Debug, PartialEq)] 2927 enum State { 2928 Start, 2929 Decrypted(Vec<(SymmetricAlgorithm, SessionKey)>), 2930 Deciphered, 2931 MDC, 2932 Done, 2933 } 2934 2935 // ... with every password. 2936 for password in &passwords { 2937 let mut state = State::Start; 2938 let mut ppr = PacketParser::from_bytes(&o).unwrap(); 2939 while let PacketParserResult::Some(mut pp) = ppr { 2940 state = match state { 2941 // Look for the SKESK packet. 2942 State::Start => 2943 if let Packet::SKESK(ref skesk) = pp.packet { 2944 match skesk.decrypt(password) { 2945 Ok((algo, key)) 2946 => State::Decrypted( 2947 vec![(algo, key)]), 2948 Err(e) => 2949 panic!("Decryption failed: {}", e), 2950 } 2951 } else { 2952 panic!("Unexpected packet: {:?}", pp.packet) 2953 }, 2954 2955 // Look for the SEIP packet. 2956 State::Decrypted(mut keys) => 2957 match pp.packet { 2958 Packet::SEIP(_) => 2959 loop { 2960 if let Some((algo, key)) = keys.pop() { 2961 let r = pp.decrypt(algo, &key); 2962 if r.is_ok() { 2963 break State::Deciphered; 2964 } 2965 } else { 2966 panic!("seip decryption failed"); 2967 } 2968 }, 2969 Packet::SKESK(ref skesk) => 2970 match skesk.decrypt(password) { 2971 Ok((algo, key)) => { 2972 keys.push((algo, key)); 2973 State::Decrypted(keys) 2974 }, 2975 Err(e) => 2976 panic!("Decryption failed: {}", e), 2977 }, 2978 _ => 2979 panic!("Unexpected packet: {:?}", pp.packet), 2980 }, 2981 2982 // Look for the literal data packet. 2983 State::Deciphered => 2984 if let Packet::Literal(_) = pp.packet { 2985 let mut body = Vec::new(); 2986 pp.read_to_end(&mut body).unwrap(); 2987 assert_eq!(&body, message); 2988 State::MDC 2989 } else { 2990 panic!("Unexpected packet: {:?}", pp.packet) 2991 }, 2992 2993 // Look for the MDC packet. 2994 State::MDC => 2995 if let Packet::MDC(ref mdc) = pp.packet { 2996 assert_eq!(mdc.digest(), mdc.computed_digest()); 2997 State::Done 2998 } else { 2999 panic!("Unexpected packet: {:?}", pp.packet) 3000 }, 3001 3002 State::Done => 3003 panic!("Unexpected packet: {:?}", pp.packet), 3004 }; 3005 3006 // Next? 3007 ppr = pp.recurse().unwrap().1; 3008 } 3009 assert_eq!(state, State::Done); 3010 } 3011 } 3012 3013 #[test] aead_messages() -> Result<()>3014 fn aead_messages() -> Result<()> { 3015 // AEAD data is of the form: 3016 // 3017 // [ chunk1 ][ tag1 ] ... [ chunkN ][ tagN ][ tag ] 3018 // 3019 // All chunks are the same size except for the last chunk, which may 3020 // be shorter. 3021 // 3022 // In `Decryptor::read_helper`, we read a chunk and a tag worth of 3023 // data at a time. Because only the last chunk can be shorter, if 3024 // the amount read is less than `chunk_size + tag_size`, then we know 3025 // that we've read the last chunk. 3026 // 3027 // Unfortunately, this is not sufficient: if the last chunk is 3028 // `chunk_size - tag size` bytes large, then when we read it, we'll 3029 // read `chunk_size + tag_size` bytes, because we'll have also read 3030 // the final tag! 3031 // 3032 // Make sure we handle this situation correctly. 3033 3034 use std::cmp; 3035 3036 use crate::parse::{ 3037 stream::{ 3038 DecryptorBuilder, 3039 DecryptionHelper, 3040 VerificationHelper, 3041 MessageStructure, 3042 }, 3043 }; 3044 use crate::cert::prelude::*; 3045 use crate::serialize::stream::{LiteralWriter, Message}; 3046 3047 let (tsk, _) = CertBuilder::new() 3048 .set_cipher_suite(CipherSuite::Cv25519) 3049 .add_transport_encryption_subkey() 3050 .generate().unwrap(); 3051 3052 struct Helper<'a> { 3053 policy: &'a dyn Policy, 3054 tsk: &'a Cert, 3055 }; 3056 impl<'a> VerificationHelper for Helper<'a> { 3057 fn get_certs(&mut self, _ids: &[crate::KeyHandle]) 3058 -> Result<Vec<Cert>> { 3059 Ok(Vec::new()) 3060 } 3061 fn check(&mut self, _structure: MessageStructure) -> Result<()> { 3062 Ok(()) 3063 } 3064 } 3065 impl<'a> DecryptionHelper for Helper<'a> { 3066 fn decrypt<D>(&mut self, pkesks: &[PKESK], _skesks: &[SKESK], 3067 sym_algo: Option<SymmetricAlgorithm>, 3068 mut decrypt: D) -> Result<Option<crate::Fingerprint>> 3069 where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool 3070 { 3071 let mut keypair = self.tsk.keys().with_policy(self.policy, None) 3072 .for_transport_encryption() 3073 .map(|ka| ka.key()).next().unwrap() 3074 .clone().parts_into_secret().unwrap() 3075 .into_keypair().unwrap(); 3076 pkesks[0].decrypt(&mut keypair, sym_algo) 3077 .map(|(algo, session_key)| decrypt(algo, &session_key)); 3078 Ok(None) 3079 } 3080 } 3081 3082 let p = &P::new(); 3083 3084 for chunks in 0..3 { 3085 for msg_len in 3086 cmp::max(24, chunks * Encryptor::AEAD_CHUNK_SIZE) - 24 3087 ..chunks * Encryptor::AEAD_CHUNK_SIZE + 24 3088 { 3089 eprintln!("Encrypting message of size: {}", msg_len); 3090 3091 let mut content : Vec<u8> = Vec::new(); 3092 for i in 0..msg_len { 3093 content.push(b'0' + ((i % 10) as u8)); 3094 } 3095 3096 let mut msg = vec![]; 3097 { 3098 let m = Message::new(&mut msg); 3099 let recipients = tsk 3100 .keys().with_policy(p, None) 3101 .for_storage_encryption().for_transport_encryption(); 3102 let encryptor = Encryptor::for_recipients(m, recipients) 3103 .aead_algo(AEADAlgorithm::EAX) 3104 .build().unwrap(); 3105 let mut literal = LiteralWriter::new(encryptor).build() 3106 .unwrap(); 3107 literal.write_all(&content).unwrap(); 3108 literal.finalize().unwrap(); 3109 } 3110 3111 for &read_len in &[ 3112 37, 3113 Encryptor::AEAD_CHUNK_SIZE - 1, 3114 Encryptor::AEAD_CHUNK_SIZE, 3115 100 * Encryptor::AEAD_CHUNK_SIZE 3116 ] { 3117 for &do_err in &[ false, true ] { 3118 let mut msg = msg.clone(); 3119 if do_err { 3120 let l = msg.len() - 1; 3121 if msg[l] == 0 { 3122 msg[l] = 1; 3123 } else { 3124 msg[l] = 0; 3125 } 3126 } 3127 3128 let h = Helper { policy: p, tsk: &tsk }; 3129 // Note: a corrupted message is only guaranteed 3130 // to error out before it returns EOF. 3131 let mut v = match DecryptorBuilder::from_bytes(&msg)? 3132 .with_policy(p, None, h) 3133 { 3134 Ok(v) => v, 3135 Err(_) if do_err => continue, 3136 Err(err) => panic!("Decrypting message: {}", err), 3137 }; 3138 3139 let mut buffer = Vec::new(); 3140 buffer.resize(read_len, 0); 3141 3142 let mut decrypted_content = Vec::new(); 3143 loop { 3144 match v.read(&mut buffer[..read_len]) { 3145 Ok(0) if do_err => 3146 panic!("Expected an error, got EOF"), 3147 Ok(0) => break, 3148 Ok(len) => 3149 decrypted_content.extend_from_slice( 3150 &buffer[..len]), 3151 Err(_) if do_err => break, 3152 Err(err) => 3153 panic!("Decrypting data: {:?}", err), 3154 } 3155 } 3156 3157 if do_err { 3158 // If we get an error once, we should get 3159 // one again. 3160 for _ in 0..3 { 3161 assert!(v.read(&mut buffer[..read_len]).is_err()); 3162 } 3163 } 3164 3165 // We only corrupted the final tag, so we 3166 // should get all of the content. 3167 assert_eq!(msg_len, decrypted_content.len()); 3168 assert_eq!(content, decrypted_content); 3169 } 3170 } 3171 } 3172 } 3173 Ok(()) 3174 } 3175 3176 #[test] signature_at_time()3177 fn signature_at_time() { 3178 // Generates a signature with a specific Signature Creation 3179 // Time. 3180 use crate::cert::prelude::*; 3181 use crate::serialize::stream::{LiteralWriter, Message}; 3182 use crate::crypto::KeyPair; 3183 3184 let p = &P::new(); 3185 3186 let (cert, _) = CertBuilder::new() 3187 .add_signing_subkey() 3188 .set_cipher_suite(CipherSuite::Cv25519) 3189 .generate().unwrap(); 3190 3191 // What we're going to sign with. 3192 let ka = cert.keys().with_policy(p, None).for_signing().nth(0).unwrap(); 3193 3194 // A timestamp later than the key's creation. 3195 let timestamp = ka.key().creation_time() 3196 + std::time::Duration::from_secs(14 * 24 * 60 * 60); 3197 assert!(ka.key().creation_time() < timestamp); 3198 3199 let mut o = vec![]; 3200 { 3201 let signer_keypair : KeyPair = 3202 ka.key().clone().parts_into_secret().unwrap().into_keypair() 3203 .expect("expected unencrypted secret key"); 3204 3205 let m = Message::new(&mut o); 3206 let signer = Signer::new(m, signer_keypair); 3207 let signer = signer.creation_time(timestamp); 3208 let signer = signer.build().unwrap(); 3209 3210 let mut ls = LiteralWriter::new(signer).build().unwrap(); 3211 ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap(); 3212 let signer = ls.finalize_one().unwrap().unwrap(); 3213 let _ = signer.finalize_one().unwrap().unwrap(); 3214 } 3215 3216 let mut ppr = PacketParser::from_bytes(&o).unwrap(); 3217 let mut good = 0; 3218 while let PacketParserResult::Some(pp) = ppr { 3219 if let Packet::Signature(ref sig) = pp.packet { 3220 assert_eq!(sig.signature_creation_time(), Some(timestamp)); 3221 sig.verify(ka.key()).unwrap(); 3222 good += 1; 3223 } 3224 3225 // Get the next packet. 3226 ppr = pp.recurse().unwrap().1; 3227 } 3228 assert_eq!(good, 1); 3229 } 3230 3231 /// Checks that newlines are properly normalized when verifying 3232 /// text signatures. 3233 #[test] issue_530_signing() -> Result<()>3234 fn issue_530_signing() -> Result<()> { 3235 use std::io::Write; 3236 use crate::*; 3237 use crate::packet::signature; 3238 use crate::serialize::stream::{Message, Signer}; 3239 3240 use crate::policy::StandardPolicy; 3241 use crate::{Result, Cert}; 3242 use crate::parse::Parse; 3243 use crate::parse::stream::*; 3244 3245 let normalized_data = b"one\r\ntwo\r\nthree"; 3246 3247 let p = &StandardPolicy::new(); 3248 let cert: Cert = 3249 Cert::from_bytes(crate::tests::key("testy-new-private.pgp"))?; 3250 3251 for data in &[ 3252 &b"one\r\ntwo\r\nthree"[..], // dos 3253 b"one\ntwo\nthree", // unix 3254 b"one\ntwo\r\nthree", // mixed 3255 b"one\r\ntwo\nthree", 3256 b"one\rtwo\rthree", // classic mac 3257 ] { 3258 eprintln!("{:?}", String::from_utf8(data.to_vec())?); 3259 let signing_keypair = cert.keys().secret() 3260 .with_policy(p, None).alive().revoked(false).for_signing() 3261 .nth(0).unwrap() 3262 .key().clone().into_keypair()?; 3263 let mut signature = vec![]; 3264 { 3265 let message = Message::new(&mut signature); 3266 let mut message = Signer::with_template( 3267 message, signing_keypair, 3268 signature::SignatureBuilder::new(SignatureType::Text) 3269 ).detached().build()?; 3270 message.write_all(data)?; 3271 message.finalize()?; 3272 } 3273 3274 struct Helper {}; 3275 impl VerificationHelper for Helper { 3276 fn get_certs(&mut self, _ids: &[KeyHandle]) -> Result<Vec<Cert>> 3277 { 3278 Ok(vec![ 3279 Cert::from_bytes(crate::tests::key("testy-new.pgp"))?]) 3280 } 3281 fn check(&mut self, structure: MessageStructure) -> Result<()> { 3282 for (i, layer) in structure.iter().enumerate() { 3283 assert_eq!(i, 0); 3284 if let MessageLayer::SignatureGroup { results } = layer 3285 { 3286 assert_eq!(results.len(), 1); 3287 results[0].as_ref().unwrap(); 3288 assert!(results[0].is_ok()); 3289 return Ok(()); 3290 } else { 3291 unreachable!(); 3292 } 3293 } 3294 unreachable!() 3295 } 3296 } 3297 3298 let h = Helper {}; 3299 let mut v = DetachedVerifierBuilder::from_bytes(&signature)? 3300 .with_policy(p, None, h)?; 3301 3302 v.verify_bytes(data)?; 3303 v.verify_bytes(normalized_data)?; 3304 } 3305 3306 Ok(()) 3307 } 3308 } 3309