Commit
+55 -19 +/-3 browse
1 | diff --git a/src/arc/seal.rs b/src/arc/seal.rs |
2 | index 88561f3..6835c16 100644 |
3 | --- a/src/arc/seal.rs |
4 | +++ b/src/arc/seal.rs |
5 | @@ -8,13 +8,16 @@ |
6 | * except according to those terms. |
7 | */ |
8 | |
9 | - use std::{io::Write, time::SystemTime}; |
10 | + use std::time::SystemTime; |
11 | |
12 | use mail_builder::encoders::base64::base64_encode; |
13 | - use sha2::{Digest, Sha256}; |
14 | + use sha2::Sha256; |
15 | |
16 | use crate::{ |
17 | - common::{crypto::SigningKey, headers::Writer}, |
18 | + common::{ |
19 | + crypto::{HashContext, SigningKey}, |
20 | + headers::Writer, |
21 | + }, |
22 | dkim::{Canonicalization, Done}, |
23 | ArcOutput, AuthenticatedMessage, AuthenticationResults, DkimResult, Error, |
24 | }; |
25 | @@ -72,7 +75,7 @@ impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, Done> { |
26 | .duration_since(SystemTime::UNIX_EPOCH) |
27 | .map(|d| d.as_secs()) |
28 | .unwrap_or(0); |
29 | - set.signature.bh = base64_encode(&body_hasher.finalize())?; |
30 | + set.signature.bh = base64_encode(body_hasher.finish().as_ref())?; |
31 | set.signature.t = now; |
32 | set.signature.x = if set.signature.x > 0 { |
33 | now + set.signature.x |
34 | @@ -88,11 +91,11 @@ impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, Done> { |
35 | set.signature.write(&mut header_hasher, false); |
36 | |
37 | // Sign |
38 | - let b = self.key.sign(&header_hasher.finalize())?; |
39 | + let b = self.key.sign(header_hasher.finish())?; |
40 | set.signature.b = base64_encode(&b)?; |
41 | |
42 | // Hash ARC chain |
43 | - let mut header_hasher = Sha256::new(); |
44 | + let mut header_hasher = self.key.hasher(); |
45 | if !arc_output.set.is_empty() { |
46 | Canonicalization::Relaxed.canonicalize_headers( |
47 | &mut arc_output.set.iter().flat_map(|set| { |
48 | @@ -109,11 +112,11 @@ impl<T: SigningKey<Hasher = Sha256>> ArcSealer<T, Done> { |
49 | // Hash ARC headers for the current instance |
50 | set.results.write(&mut header_hasher, set.seal.i, false); |
51 | set.signature.write(&mut header_hasher, false); |
52 | - header_hasher.write_all(b"\r\n")?; |
53 | + header_hasher.write(b"\r\n"); |
54 | set.seal.write(&mut header_hasher, false); |
55 | |
56 | // Seal |
57 | - let b = self.key.sign(&header_hasher.finalize())?; |
58 | + let b = self.key.sign(header_hasher.finish())?; |
59 | set.seal.b = base64_encode(&b)?; |
60 | |
61 | Ok(set) |
62 | diff --git a/src/common/crypto.rs b/src/common/crypto.rs |
63 | index 5e206d2..a897c9b 100644 |
64 | --- a/src/common/crypto.rs |
65 | +++ b/src/common/crypto.rs |
66 | @@ -14,9 +14,9 @@ use crate::{dkim::Canonicalization, Error, Result}; |
67 | use super::headers::Writer; |
68 | |
69 | pub trait SigningKey { |
70 | - type Hasher: Digest + Writer; |
71 | + type Hasher: HashContext; |
72 | |
73 | - fn sign(&self, data: &Output<Self::Hasher>) -> Result<Vec<u8>>; |
74 | + fn sign(&self, data: HashOutput) -> Result<Vec<u8>>; |
75 | |
76 | fn hasher(&self) -> Self::Hasher { |
77 | Self::Hasher::new() |
78 | @@ -58,9 +58,12 @@ impl<T: Digest + AssociatedOid + io::Write> RsaKey<T> { |
79 | impl SigningKey for RsaKey<Sha1> { |
80 | type Hasher = Sha1; |
81 | |
82 | - fn sign(&self, data: &Output<Self::Hasher>) -> Result<Vec<u8>> { |
83 | + fn sign(&self, data: HashOutput) -> Result<Vec<u8>> { |
84 | self.inner |
85 | - .sign(PaddingScheme::new_pkcs1v15_sign::<Self::Hasher>(), data) |
86 | + .sign( |
87 | + PaddingScheme::new_pkcs1v15_sign::<Self::Hasher>(), |
88 | + data.as_ref(), |
89 | + ) |
90 | .map_err(|err| Error::CryptoError(err.to_string())) |
91 | } |
92 | |
93 | @@ -72,9 +75,12 @@ impl SigningKey for RsaKey<Sha1> { |
94 | impl SigningKey for RsaKey<Sha256> { |
95 | type Hasher = Sha256; |
96 | |
97 | - fn sign(&self, data: &Output<Self::Hasher>) -> Result<Vec<u8>> { |
98 | + fn sign(&self, data: HashOutput) -> Result<Vec<u8>> { |
99 | self.inner |
100 | - .sign(PaddingScheme::new_pkcs1v15_sign::<Self::Hasher>(), data) |
101 | + .sign( |
102 | + PaddingScheme::new_pkcs1v15_sign::<Self::Hasher>(), |
103 | + data.as_ref(), |
104 | + ) |
105 | .map_err(|err| Error::CryptoError(err.to_string())) |
106 | } |
107 | |
108 | @@ -104,7 +110,7 @@ impl Ed25519Key { |
109 | impl SigningKey for Ed25519Key { |
110 | type Hasher = Sha256; |
111 | |
112 | - fn sign(&self, data: &Output<Self::Hasher>) -> Result<Vec<u8>> { |
113 | + fn sign(&self, data: HashOutput) -> Result<Vec<u8>> { |
114 | Ok(self.inner.sign(data.as_ref()).to_bytes().to_vec()) |
115 | } |
116 | |
117 | @@ -227,6 +233,31 @@ impl Writer for Sha256 { |
118 | } |
119 | } |
120 | |
121 | + pub trait HashContext: Writer + Sized { |
122 | + fn new() -> Self; |
123 | + fn finish(self) -> HashOutput; |
124 | + } |
125 | + |
126 | + impl HashContext for Sha1 { |
127 | + fn new() -> Self { |
128 | + <Self as Digest>::new() |
129 | + } |
130 | + |
131 | + fn finish(self) -> HashOutput { |
132 | + HashOutput::Sha1(self.finalize()) |
133 | + } |
134 | + } |
135 | + |
136 | + impl HashContext for Sha256 { |
137 | + fn new() -> Self { |
138 | + <Self as Digest>::new() |
139 | + } |
140 | + |
141 | + fn finish(self) -> HashOutput { |
142 | + HashOutput::Sha256(self.finalize()) |
143 | + } |
144 | + } |
145 | + |
146 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
147 | #[repr(u64)] |
148 | pub enum HashAlgorithm { |
149 | diff --git a/src/dkim/sign.rs b/src/dkim/sign.rs |
150 | index d264b1a..9203449 100644 |
151 | --- a/src/dkim/sign.rs |
152 | +++ b/src/dkim/sign.rs |
153 | @@ -11,10 +11,12 @@ |
154 | use std::time::SystemTime; |
155 | |
156 | use mail_builder::encoders::base64::base64_encode; |
157 | - use sha1::Digest; |
158 | |
159 | use super::{DkimSigner, Done, Signature}; |
160 | - use crate::{common::crypto::SigningKey, Error}; |
161 | + use crate::{ |
162 | + common::crypto::{HashContext, SigningKey}, |
163 | + Error, |
164 | + }; |
165 | |
166 | impl<T: SigningKey> DkimSigner<T, Done> { |
167 | /// Signs a message. |
168 | @@ -44,7 +46,7 @@ impl<T: SigningKey> DkimSigner<T, Done> { |
169 | |
170 | // Create Signature |
171 | let mut signature = self.template.clone(); |
172 | - signature.bh = base64_encode(&body_hasher.finalize())?; |
173 | + signature.bh = base64_encode(&body_hasher.finish().as_ref())?; |
174 | signature.t = now; |
175 | signature.x = if signature.x > 0 { |
176 | now + signature.x |
177 | @@ -60,7 +62,7 @@ impl<T: SigningKey> DkimSigner<T, Done> { |
178 | signature.write(&mut header_hasher, false); |
179 | |
180 | // Sign |
181 | - let b = self.key.sign(&header_hasher.finalize())?; |
182 | + let b = self.key.sign(header_hasher.finish())?; |
183 | |
184 | // Encode |
185 | signature.b = base64_encode(&b)?; |