1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
use std::sync::OnceLock;
use sequoia_openpgp as openpgp;
use openpgp::cert::Cert;
use openpgp::parse::Parse;
use openpgp::policy::StandardPolicy;
use openpgp::serialize::stream::{
Armorer, Encryptor, LiteralWriter, Message, Signer,
};
use std::io::Write;
/// Encrypt with password, using a minimal writer stack.
pub fn encrypt_with_password(
bytes: &[u8],
password: &str,
) -> openpgp::Result<Vec<u8>> {
let mut sink = vec![];
let message =
Encryptor::with_passwords(Message::new(&mut sink), Some(password))
.build()?;
let mut w = LiteralWriter::new(message).build()?;
w.write_all(bytes)?;
w.finalize()?;
Ok(sink)
}
/// Encrypt ignoring revocation or expiration.
/// Uses a minimal writer stack.
pub fn encrypt_to_cert(
bytes: &[u8],
cert: &Cert,
) -> openpgp::Result<Vec<u8>> {
let mut sink = vec![];
let p = &StandardPolicy::new();
let recipients = cert
.keys()
.with_policy(p, None)
.supported()
.for_transport_encryption()
.for_storage_encryption();
let message =
Encryptor::for_recipients(Message::new(&mut sink), recipients)
.build()?;
let mut w = LiteralWriter::new(message).build()?;
w.write_all(bytes)?;
w.finalize()?;
Ok(sink)
}
/// Sign ignoring revocation or expiration.
pub fn sign(bytes: &[u8], sender: &Cert) -> openpgp::Result<Vec<u8>> {
let mut sink = vec![];
let p = &StandardPolicy::new();
let signing_keypair = sender
.keys()
.with_policy(p, None)
.secret()
.for_signing()
.next()
.unwrap()
.key()
.clone()
.into_keypair()?;
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)?.build()?;
let mut w = LiteralWriter::new(message).build()?;
w.write_all(bytes)?;
w.finalize()?;
Ok(sink)
}
/// Encrypt and sign, ignoring revocation or expiration.
/// Uses a realistic writer stack with padding and armor.
pub fn encrypt_to_cert_and_sign(
bytes: &[u8],
sender: &Cert,
recipient: &Cert,
) -> openpgp::Result<Vec<u8>> {
let mut sink = vec![];
let p = &StandardPolicy::new();
let signing_keypair = sender
.keys()
.with_policy(p, None)
.secret()
.for_signing()
.next()
.unwrap()
.key()
.clone()
.into_keypair()?;
let recipients = recipient
.keys()
.with_policy(p, None)
.supported()
.for_transport_encryption()
.for_storage_encryption();
let message = Message::new(&mut sink);
let message = Armorer::new(message).build()?;
let message = Encryptor::for_recipients(message, recipients).build()?;
let message = Signer::new(message, signing_keypair)?
//.add_intended_recipient(&recipient)
.build()?;
let mut w = LiteralWriter::new(message).build()?;
w.write_all(bytes)?;
w.finalize()?;
Ok(sink)
}
fn zeros_1_mb() -> &'static [u8] {
static ZEROS_1_MB: OnceLock<Vec<u8>> = OnceLock::new();
ZEROS_1_MB.get_or_init(|| vec![0; 1024 * 1024])
}
fn zeros_10_mb() -> &'static [u8] {
static ZEROS_10_MB: OnceLock<Vec<u8>> = OnceLock::new();
ZEROS_10_MB.get_or_init(|| vec![0; 10 * 1024 * 1024])
}
/// Encrypt a very short, medium and very long message.
pub fn messages() -> impl Iterator<Item = &'static [u8]> {
[b"Hello world.", zeros_1_mb(), zeros_10_mb()]
.into_iter()
}
/// Returns the sender key.
pub fn sender() -> &'static Cert {
static CERT: OnceLock<Cert> = OnceLock::new();
CERT.get_or_init(|| {
Cert::from_bytes(
&include_bytes!("../../tests/data/keys/sender.pgp")[..])
.unwrap()
})
}
/// Returns the recipient key.
pub fn recipient() -> &'static Cert {
static CERT: OnceLock<Cert> = OnceLock::new();
CERT.get_or_init(|| {
Cert::from_bytes(
&include_bytes!("../../tests/data/keys/recipient.pgp")[..])
.unwrap()
})
}
|