Commit
Author: Dirkjan Ochtman [dirkjan@ochtman.nl]
Hash: 0cb42d2b4aaaa4798170ff1f2d8a720f22403519
Timestamp: Wed, 14 Dec 2022 14:27:05 +0000 (1 year ago)

+32 -17 +/-4 browse
Make RustCrypto dependencies optional
1diff --git a/Cargo.toml b/Cargo.toml
2index dfbe172..28914eb 100644
3--- a/Cargo.toml
4+++ b/Cargo.toml
5 @@ -15,25 +15,27 @@ resolver = "2"
6 [lib]
7 doctest = false
8
9+ [features]
10+ default = ["rust-crypto"]
11+ rust-crypto = ["ed25519-dalek", "rsa", "sha1", "sha2"]
12+ test = []
13+
14 [dependencies]
15 ahash = "0.8.0"
16- ed25519-dalek = "1.0.1"
17+ ed25519-dalek = { version = "1.0.1", optional = true }
18 flate2 = "1.0.25"
19 lru-cache = "0.1.2"
20 mail-parser = { version = "0.8", git = "https://github.com/stalwartlabs/mail-parser", features = ["ludicrous_mode", "full_encoding"] }
21 mail-builder = { version = "0.2.5", git = "https://github.com/stalwartlabs/mail-builder", features = ["ludicrous_mode"] }
22 parking_lot = "0.12.0"
23 quick-xml = "0.27.1"
24- rsa = "0.7.0"
25+ rsa = { version = "0.7.0", optional = true }
26 serde = { version = "1.0", features = ["derive"] }
27 serde_json = "1.0"
28- sha1 = { version = "0.10", features = ["oid"] }
29- sha2 = { version = "0.10.6", features = ["oid"] }
30+ sha1 = { version = "0.10", features = ["oid"], optional = true }
31+ sha2 = { version = "0.10.6", features = ["oid"], optional = true }
32 trust-dns-resolver = { version = "0.22.0", features = ["dns-over-rustls", "dnssec-ring"] }
33 zip = "0.6.3"
34
35 [dev-dependencies]
36 tokio = { version = "1.16", features = ["net", "io-util", "time", "rt-multi-thread", "macros"] }
37-
38- [features]
39- test = []
40 diff --git a/src/common/crypto/mod.rs b/src/common/crypto/mod.rs
41index 1ee3b41..ad25c26 100644
42--- a/src/common/crypto/mod.rs
43+++ b/src/common/crypto/mod.rs
44 @@ -1,11 +1,15 @@
45+ #[cfg(feature = "sha1")]
46 use sha1::{digest::Output, Digest};
47
48 use crate::{dkim::Canonicalization, Result};
49
50 use super::headers::{Writable, Writer};
51
52+ #[cfg(feature = "rust-crypto")]
53 mod rust_crypto;
54+ #[cfg(feature = "rust-crypto")]
55 pub use rust_crypto::{Ed25519Key, RsaKey};
56+ #[cfg(feature = "rust-crypto")]
57 pub(crate) use rust_crypto::{Ed25519PublicKey, RsaPublicKey};
58
59 pub trait SigningKey {
60 @@ -43,7 +47,9 @@ impl VerifyingKeyType {
61 bytes: &[u8],
62 ) -> Result<Box<dyn VerifyingKey + Send + Sync>> {
63 match self {
64+ #[cfg(feature = "rust-crypto")]
65 Self::Rsa => RsaPublicKey::verifying_key_from_bytes(bytes),
66+ #[cfg(feature = "rust-crypto")]
67 Self::Ed25519 => Ed25519PublicKey::verifying_key_from_bytes(bytes),
68 }
69 }
70 @@ -75,30 +81,37 @@ pub enum HashAlgorithm {
71 impl HashAlgorithm {
72 pub fn hash(&self, data: impl Writable) -> HashOutput {
73 match self {
74+ #[cfg(feature = "sha1")]
75 Self::Sha1 => {
76 let mut hasher = sha1::Sha1::new();
77 data.write(&mut hasher);
78- HashOutput::Sha1(hasher.finalize())
79+ HashOutput::RustCryptoSha1(hasher.finalize())
80 }
81+ #[cfg(feature = "sha2")]
82 Self::Sha256 => {
83 let mut hasher = sha2::Sha256::new();
84 data.write(&mut hasher);
85- HashOutput::Sha256(hasher.finalize())
86+ HashOutput::RustCryptoSha256(hasher.finalize())
87 }
88 }
89 }
90 }
91
92+ #[non_exhaustive]
93 pub enum HashOutput {
94- Sha1(Output<sha1::Sha1>),
95- Sha256(Output<sha2::Sha256>),
96+ #[cfg(feature = "sha1")]
97+ RustCryptoSha1(Output<sha1::Sha1>),
98+ #[cfg(feature = "sha2")]
99+ RustCryptoSha256(Output<sha2::Sha256>),
100 }
101
102 impl AsRef<[u8]> for HashOutput {
103 fn as_ref(&self) -> &[u8] {
104 match self {
105- Self::Sha1(output) => output.as_ref(),
106- Self::Sha256(output) => output.as_ref(),
107+ #[cfg(feature = "sha1")]
108+ Self::RustCryptoSha1(output) => output.as_ref(),
109+ #[cfg(feature = "sha2")]
110+ Self::RustCryptoSha256(output) => output.as_ref(),
111 }
112 }
113 }
114 diff --git a/src/common/crypto/rust_crypto.rs b/src/common/crypto/rust_crypto.rs
115index a1af70d..c5b16fc 100644
116--- a/src/common/crypto/rust_crypto.rs
117+++ b/src/common/crypto/rust_crypto.rs
118 @@ -236,12 +236,12 @@ impl HashImpl for Sha256 {
119
120 impl HashContext for sha1::Sha1 {
121 fn complete(self) -> HashOutput {
122- HashOutput::Sha1(self.finalize())
123+ HashOutput::RustCryptoSha1(self.finalize())
124 }
125 }
126
127 impl HashContext for sha2::Sha256 {
128 fn complete(self) -> HashOutput {
129- HashOutput::Sha256(self.finalize())
130+ HashOutput::RustCryptoSha256(self.finalize())
131 }
132 }
133 diff --git a/src/lib.rs b/src/lib.rs
134index ccfde5f..cc5bf7f 100644
135--- a/src/lib.rs
136+++ b/src/lib.rs
137 @@ -283,8 +283,6 @@ pub mod report;
138 pub mod spf;
139
140 pub use flate2;
141- pub use sha1;
142- pub use sha2;
143 pub use trust_dns_resolver;
144 pub use zip;
145
146 @@ -572,12 +570,14 @@ impl From<io::Error> for Error {
147 }
148 }
149
150+ #[cfg(feature = "rsa")]
151 impl From<rsa::errors::Error> for Error {
152 fn from(err: rsa::errors::Error) -> Self {
153 Error::CryptoError(err.to_string())
154 }
155 }
156
157+ #[cfg(feature = "ed25519-dalek")]
158 impl From<ed25519_dalek::ed25519::Error> for Error {
159 fn from(err: ed25519_dalek::ed25519::Error) -> Self {
160 Error::CryptoError(err.to_string())