Add encryption

- actually encrypt the body of a mail
This commit is contained in:
Malte Meiboom
2025-12-17 11:11:28 +01:00
parent 64312da01d
commit eeda63f5ab
4 changed files with 55 additions and 7 deletions
+39
View File
@@ -4,12 +4,14 @@
// cryptographic functions
//
use std::io::Write;
use std::sync::Arc;
use anyhow;
use bytes::Bytes;
use sequoia_openpgp::parse::{PacketParser, PacketParserResult, Parse};
use sequoia_openpgp::policy::StandardPolicy;
use sequoia_openpgp::serialize::stream::{Message, Armorer, Encryptor, LiteralWriter};
use sequoia_openpgp::{Fingerprint, Cert, Packet};
use sequoia_openpgp::cert::raw::RawCertParser;
use sequoia_cert_store::{Store, CertStore, LazyCert};
@@ -20,6 +22,7 @@ use wot::{Depth, Path};
use crate::types::errors::HuskError;
use crate::types::husk_context::HuskContext;
use crate::types::introducer::Introducer;
use crate::types::recipient::Recipient;
pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result<Cert> {
@@ -155,6 +158,42 @@ pub fn is_encrypted(body: &Bytes) -> bool {
false
}
pub fn encrypt(context: &HuskContext<'_>, body: &Bytes, recipients: &Vec<Recipient>)
-> anyhow::Result<Bytes> {
let mut keys = Vec::new();
// XXX: handle the case where a certificate misses an encryption subkey
for rcpt in recipients {
if rcpt.can_encrypt() {
for cert in &rcpt.certs {
cert.with_policy(&context.policy, None)?
.keys()
.supported()
.alive()
.revoked(false)
.for_transport_encryption()
.for_each(|k| {
keys.push(k);
});
}
}
}
if keys.len() > 0 {
let mut sink = Vec::new();
let message = Message::new(&mut sink);
let message = Armorer::new(message).build()?;
let message = Encryptor::for_recipients(message, keys).build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(&body[..])?;
message.finalize()?;
Ok(Bytes::from(sink))
} else {
Err(HuskError::NoEncryptionKeys.into())
}
}
#[cfg(test)]
pub mod tests {
use bytes::Bytes;