Skip to main content

mini_mail_auth/dkim/
headers.rs

1use super::{Algorithm, Canonicalization, Signature};
2use crate::common::headers::{HeaderWriter, Writer};
3use std::fmt::{Display, Formatter};
4
5impl Signature {
6    pub fn write(&self, writer: &mut impl Writer, as_header: bool) {
7        let (header, new_line) = match self.ch {
8            Canonicalization::Relaxed if !as_header => (&b"dkim-signature:"[..], &b" "[..]),
9            _ => (&b"DKIM-Signature: "[..], &b"\r\n\t"[..]),
10        };
11        writer.write(header);
12        writer.write(b"v=1; a=");
13        writer.write(match self.a {
14            Algorithm::RsaSha256 => b"rsa-sha256",
15        });
16        for (tag, value) in [(&b"; s="[..], &self.s), (&b"; d="[..], &self.d)] {
17            writer.write(tag);
18            writer.write(value.as_bytes());
19        }
20        writer.write(b"; c=");
21        self.ch.serialize_name(writer);
22        writer.write(b"/");
23        self.cb.serialize_name(writer);
24
25        writer.write(b";");
26        writer.write(new_line);
27
28        let mut bw = 1;
29        for (num, h) in self.h.iter().enumerate() {
30            if bw + h.len() + 1 >= 76 {
31                writer.write(new_line);
32                bw = 1;
33            }
34            if num > 0 {
35                writer.write_len(b":", &mut bw);
36            } else {
37                writer.write_len(b"h=", &mut bw);
38            }
39            writer.write_len(h.as_bytes(), &mut bw);
40        }
41
42        if self.t > 0 {
43            let value = self.t.to_string();
44            writer.write_len(b";", &mut bw);
45            if bw + 2 + value.len() >= 76 {
46                writer.write(new_line);
47                bw = 1;
48            } else {
49                writer.write_len(b" ", &mut bw);
50            }
51            writer.write_len(b"t=", &mut bw);
52            writer.write_len(value.as_bytes(), &mut bw);
53        }
54
55        for (tag, value) in [(&b"; bh="[..], &self.bh), (&b"; b="[..], &self.b)] {
56            writer.write_len(tag, &mut bw);
57            for &byte in value {
58                writer.write_len(&[byte], &mut bw);
59                if bw >= 76 {
60                    writer.write(new_line);
61                    bw = 1;
62                }
63            }
64        }
65
66        writer.write(b";");
67        if as_header {
68            writer.write(b"\r\n");
69        }
70    }
71}
72
73impl HeaderWriter for Signature {
74    fn write_header(&self, writer: &mut impl Writer) {
75        self.write(writer, true);
76    }
77}
78
79impl Display for Signature {
80    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81        let mut buf = Vec::new();
82        self.write(&mut buf, false);
83        f.write_str(&String::from_utf8_lossy(&buf))
84    }
85}