Skip to main content

Crate ceal

Crate ceal 

Source
Expand description

Opportunistic Encryption for E-Mail

This library can query the S/MIME and OpenPGP keys from the recipient’s DNS record and use it to encrypt messages. The keys are stored in the SMIMEA or OPENPGPKEY records respectively. All recipients must have at least one of the same record. Unfortunately, E-Mail programs are not very good when presented with a choice between two different encryption methods within the same message. If encryption is not possible due to lack of keys (of the same type), the message is sent unencrypted.

You can use this as a stand-alone library or as an extension to [lettre].

§Example Usage: Stand-Alone library

You can use this library by providing raw messages to it, like this:

use email_address::EmailAddress;
let message = b"From: John Doe <john.doe@example.org>\r
To: Max Mustermann <max.mustermann@example.org>\r
Subject: Hello\r
Content-Type: text/plain; charset=\"utf-8\"\r
Content-Transfer-Encoding: 7bit\r
\r
Hello, how are you?\r
";

let recipients = ["max.mustermann@example.org".parse::<EmailAddress>().unwrap()];
let message = ceal::encrypt(message, &recipients).await;

If an encryption key was found, the result will look something like this:

From: John Doe <john.doe@example.org>
To: Max Mustermann <max.mustermann@example.org>
Subject: Hello
Content-Type: multipart/encrypted; protocol="application/pgp-encrypted";
 boundary="=-fRbE3wtPT1u0rEVI"

--=-fRbE3wtPT1u0rEVI
Content-Type: application/pgp-encrypted
Content-Transfer-Encoding: 7bit

Version: 1

--=-fRbE3wtPT1u0rEVI
Content-Type: application/octet-stream; name="encrypted.asc"
Content-Description: OpenPGP Encrypted Message
Content-Transfer-Encoding: 7bit

-----BEGIN PGP MESSAGE-----

wWwGFQQAaKICkqGFdPWZFLNGsneBbdOVVBIBB0DS2mtKK0qe7UPwhrxFKUFzywC6
yaXOKdNnIb1fHPM7eDBttgL9Injkz237nD98dwvdF4RD3dLbLGoQtw9nufbgyihf
mRr7zUVHdZf8hjpkRVfSrwIJAgaO3vLYxhj3lMiOCgDda12W0bJJl9clRwXEOnlh
m1duZv2Wxlx+ig1WRJuSYbKIUKg9MrX1mqsVdlF5DdNkEH2ywCmI1UTXBYzSKQEv
1h/+77iozcYqiJfV74TuWM9AT3YrNPA0SZnFFkttXV0vhsuvi72DbTTq9sieqH13
IH9FiCin5kefw5y4/MeIFqJXbfKzgP+8z4tXYwAQmrqskT662PndfvzbJSJ+4LQ=
-----END PGP MESSAGE-----

--=-fRbE3wtPT1u0rEVI--

§Example Usage: [lettre] transport

First, you need to enable the lettre feature of this crate. Then you may use it to create a [lettre] transport that applies opportunistic encryption just before sending the message:

use lettre::{
	AsyncTransport, Message, SmtpTransport, Tokio1Executor,
	message::SinglePart,
	transport::smtp::{AsyncSmtpTransport, client::{Tls, TlsParameters}}
};
use ceal::lettre::AsyncTransportExt as _;

let email = Message::builder()
	.from("John Doe <john.doe@example.org>".parse().unwrap())
	.to("Max Mustermann <max.mustermann@example.org>".parse().unwrap())
	.subject("Hello")
	.singlepart(SinglePart::plain(String::from("Hello, how are you?")))
	.unwrap();

let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("mail.example.org")
	.unwrap()
	.tls(Tls::Required(TlsParameters::new("mail.example.org".into()).unwrap()))
	.build()
	.with_opportunistic_encryption();

mailer.send(email).await.expect("Could not send E-Mail");

Modules§

address
This mod contains the Address trait.
dns
openpgp
smime

Functions§

encrypt
Apply opportunistic encryption to this message.
encrypt_openpgp
Encrypt the message using the provided OpenPGP certificates.
encrypt_smime
Encrypt the message using the provided S/MIME certificates.