1pub mod builder;
8pub mod headers;
9pub mod parse;
10pub mod seal;
11pub mod verify;
12
13use crate::{
14 common::{
15 crypto::{Algorithm, Sha256, SigningKey},
16 headers::Header,
17 verify::VerifySignature,
18 },
19 dkim::{Canonicalization, NeedDomain},
20 ArcOutput, AuthenticationResults, DkimResult,
21};
22
23#[derive(Debug, PartialEq, Eq, Clone, Default)]
24pub struct ArcSealer<T: SigningKey<Hasher = Sha256>, State = NeedDomain> {
25 _state: std::marker::PhantomData<State>,
26 pub(crate) key: T,
27 pub(crate) signature: Signature,
28 pub(crate) seal: Seal,
29}
30
31#[derive(Debug, PartialEq, Eq, Clone, Default)]
32pub struct Signature {
33 pub i: u32,
34 pub a: Algorithm,
35 pub d: String,
36 pub s: String,
37 pub b: Vec<u8>,
38 pub bh: Vec<u8>,
39 pub h: Vec<String>,
40 pub z: Vec<String>,
41 pub l: u64,
42 pub x: u64,
43 pub t: u64,
44 pub ch: Canonicalization,
45 pub cb: Canonicalization,
46}
47
48#[derive(Debug, PartialEq, Eq, Clone, Default)]
49pub struct Seal {
50 pub i: u32,
51 pub a: Algorithm,
52 pub b: Vec<u8>,
53 pub d: String,
54 pub s: String,
55 pub t: u64,
56 pub cv: ChainValidation,
57}
58
59#[derive(Debug, PartialEq, Eq, Clone)]
60pub struct Results {
61 pub i: u32,
62}
63
64#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct ArcSet<'x> {
66 pub signature: Signature,
67 pub seal: Seal,
68 pub results: &'x AuthenticationResults<'x>,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct Set<'x> {
73 pub signature: Header<'x, &'x Signature>,
74 pub seal: Header<'x, &'x Seal>,
75 pub results: Header<'x, &'x Results>,
76}
77
78#[derive(Debug, PartialEq, Eq, Clone, Default)]
79pub enum ChainValidation {
80 #[default]
81 None,
82 Fail,
83 Pass,
84}
85
86impl VerifySignature for Signature {
87 fn signature(&self) -> &[u8] {
88 &self.b
89 }
90
91 fn algorithm(&self) -> Algorithm {
92 self.a
93 }
94
95 fn selector(&self) -> &str {
96 &self.s
97 }
98
99 fn domain(&self) -> &str {
100 &self.d
101 }
102}
103
104impl VerifySignature for Seal {
105 fn signature(&self) -> &[u8] {
106 &self.b
107 }
108
109 fn algorithm(&self) -> Algorithm {
110 self.a
111 }
112
113 fn selector(&self) -> &str {
114 &self.s
115 }
116
117 fn domain(&self) -> &str {
118 &self.d
119 }
120}
121
122impl<'x> ArcOutput<'x> {
123 pub fn with_result(mut self, result: DkimResult) -> Self {
124 self.result = result;
125 self
126 }
127
128 pub fn with_set(mut self, set: Set<'x>) -> Self {
129 self.set.push(set);
130 self
131 }
132
133 pub fn can_be_sealed(&self) -> bool {
134 self.set.is_empty() || self.set.last().unwrap().seal.header.cv != ChainValidation::Fail
135 }
136}
137
138impl Default for ArcOutput<'_> {
139 fn default() -> Self {
140 Self {
141 result: DkimResult::None,
142 set: Vec::new(),
143 }
144 }
145}