Skip to main content

mail_auth/arc/
builder.rs

1/*
2 * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
3 *
4 * SPDX-License-Identifier: Apache-2.0 OR MIT
5 */
6
7use super::{ArcSealer, Seal, Signature};
8use crate::{
9    common::crypto::{Sha256, SigningKey},
10    dkim::{Canonicalization, Done, NeedDomain, NeedHeaders, NeedSelector},
11};
12
13impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T> {
14    pub fn from_key(key: T) -> ArcSealer<T, NeedDomain> {
15        ArcSealer {
16            _state: Default::default(),
17            signature: Signature {
18                a: key.algorithm(),
19                ..Default::default()
20            },
21            seal: Seal {
22                a: key.algorithm(),
23                ..Default::default()
24            },
25            key,
26        }
27    }
28}
29
30impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, NeedDomain> {
31    /// Sets the domain to use for signing.
32    pub fn domain(mut self, domain: impl Into<String> + Clone) -> ArcSealer<T, NeedSelector> {
33        self.signature.d = domain.clone().into();
34        self.seal.d = domain.into();
35        ArcSealer {
36            _state: Default::default(),
37            key: self.key,
38            signature: self.signature,
39            seal: self.seal,
40        }
41    }
42}
43
44impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, NeedSelector> {
45    /// Sets the selector to use for signing.
46    pub fn selector(mut self, selector: impl Into<String> + Clone) -> ArcSealer<T, NeedHeaders> {
47        self.signature.s = selector.clone().into();
48        self.seal.s = selector.into();
49        ArcSealer {
50            _state: Default::default(),
51            key: self.key,
52            signature: self.signature,
53            seal: self.seal,
54        }
55    }
56}
57
58impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, NeedHeaders> {
59    /// Sets the headers to sign.
60    pub fn headers(
61        mut self,
62        headers: impl IntoIterator<Item = impl Into<String>>,
63    ) -> ArcSealer<T, Done> {
64        self.signature.h = headers.into_iter().map(|h| h.into()).collect();
65        ArcSealer {
66            _state: Default::default(),
67            key: self.key,
68            signature: self.signature,
69            seal: self.seal,
70        }
71    }
72}
73
74impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, Done> {
75    /// Sets the number of seconds from now to use for the signature expiration.
76    pub fn expiration(mut self, expiration: u64) -> Self {
77        self.signature.x = expiration;
78        self
79    }
80
81    /// Include the body length in the signature.
82    pub fn body_length(mut self, body_length: bool) -> Self {
83        self.signature.l = u64::from(body_length);
84        self
85    }
86
87    /// Sets header canonicalization algorithm.
88    pub fn header_canonicalization(mut self, ch: Canonicalization) -> Self {
89        self.signature.ch = ch;
90        self
91    }
92
93    /// Sets header canonicalization algorithm.
94    pub fn body_canonicalization(mut self, cb: Canonicalization) -> Self {
95        self.signature.cb = cb;
96        self
97    }
98}