rustexamples/arc_seal.rs -rw-r--r-- 2.9 KiB
1/*
2 * Copyright (c) 2020-2023, Stalwart Labs Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7 * option. This file may not be copied, modified, or distributed
8 * except according to those terms.
9 */
10
11use mail_auth::{
12 arc::ArcSealer,
13 common::{
14 crypto::{RsaKey, Sha256},
15 headers::HeaderWriter,
16 },
17 AuthenticatedMessage, AuthenticationResults, Resolver,
18};
19
20const TEST_MESSAGE: &str = include_str!("../resources/arc/001.txt");
21
22const RSA_PRIVATE_KEY: &str = r#"-----BEGIN RSA PRIVATE KEY-----
23MIICXwIBAAKBgQDwIRP/UC3SBsEmGqZ9ZJW3/DkMoGeLnQg1fWn7/zYtIxN2SnFC
24jxOCKG9v3b4jYfcTNh5ijSsq631uBItLa7od+v/RtdC2UzJ1lWT947qR+Rcac2gb
25to/NMqJ0fzfVjH4OuKhitdY9tf6mcwGjaNBcWToIMmPSPDdQPNUYckcQ2QIDAQAB
26AoGBALmn+XwWk7akvkUlqb+dOxyLB9i5VBVfje89Teolwc9YJT36BGN/l4e0l6QX
27/1//6DWUTB3KI6wFcm7TWJcxbS0tcKZX7FsJvUz1SbQnkS54DJck1EZO/BLa5ckJ
28gAYIaqlA9C0ZwM6i58lLlPadX/rtHb7pWzeNcZHjKrjM461ZAkEA+itss2nRlmyO
29n1/5yDyCluST4dQfO8kAB3toSEVc7DeFeDhnC1mZdjASZNvdHS4gbLIA1hUGEF9m
303hKsGUMMPwJBAPW5v/U+AWTADFCS22t72NUurgzeAbzb1HWMqO4y4+9Hpjk5wvL/
31eVYizyuce3/fGke7aRYw/ADKygMJdW8H/OcCQQDz5OQb4j2QDpPZc0Nc4QlbvMsj
327p7otWRO5xRa6SzXqqV3+F0VpqvDmshEBkoCydaYwc2o6WQ5EBmExeV8124XAkEA
33qZzGsIxVP+sEVRWZmW6KNFSdVUpk3qzK0Tz/WjQMe5z0UunY9Ax9/4PVhp/j61bf
34eAYXunajbBSOLlx4D+TunwJBANkPI5S9iylsbLs6NkaMHV6k5ioHBBmgCak95JGX
35GMot/L2x0IYyMLAz6oLWh2hm7zwtb0CgOrPo1ke44hFYnfc=
36-----END RSA PRIVATE KEY-----"#;
37
38#[tokio::main]
39async fn main() {
40 // Create a resolver using Cloudflare DNS
41 let resolver = Resolver::new_cloudflare_tls().unwrap();
42
43 // Parse message to be sealed
44 let authenticated_message = AuthenticatedMessage::parse(TEST_MESSAGE.as_bytes()).unwrap();
45
46 // Verify ARC and DKIM signatures
47 let arc_result = resolver.verify_arc(&authenticated_message).await;
48 let dkim_result = resolver.verify_dkim(&authenticated_message).await;
49
50 // Build Authenticated-Results header
51 let auth_results = AuthenticationResults::new("mx.mydomain.org")
52 .with_dkim_results(&dkim_result, "sender@example.org")
53 .with_arc_result(&arc_result, "127.0.0.1".parse().unwrap());
54
55 // Seal message
56 if arc_result.can_be_sealed() {
57 // Seal the e-mail message using RSA-SHA256
58 let pk_rsa = RsaKey::<Sha256>::from_pkcs1_pem(RSA_PRIVATE_KEY).unwrap();
59 let arc_set = ArcSealer::from_key(pk_rsa)
60 .domain("example.org")
61 .selector("default")
62 .headers(["From", "To", "Subject", "DKIM-Signature"])
63 .seal(&authenticated_message, &auth_results, &arc_result)
64 .unwrap();
65
66 // Print the sealed message to stdout
67 println!("{}{}", arc_set.to_header(), TEST_MESSAGE)
68 } else {
69 eprintln!("The message could not be sealed, probably an ARC chain with cv=fail was found.")
70 }
71}