steel_crypto/
signature.rs1use rsa::pkcs1v15::SigningKey;
6use rsa::sha2::Sha256;
7use rsa::signature::{SignatureEncoding, Signer as RsaSigner, Verifier};
8use rsa::{RsaPrivateKey, RsaPublicKey};
9
10use crate::rsa_utils::CryptError;
11
12pub trait SignatureUpdater {
16 fn update(&self, output: &mut dyn SignatureOutput) -> Result<(), CryptError>;
18}
19
20pub trait SignatureOutput {
24 fn update(&mut self, data: &[u8]) -> Result<(), CryptError>;
26}
27
28impl SignatureUpdater for &[u8] {
30 fn update(&self, output: &mut dyn SignatureOutput) -> Result<(), CryptError> {
31 output.update(self)
32 }
33}
34
35pub trait Signer {
39 fn sign(&self, updater: &dyn SignatureUpdater) -> Result<Vec<u8>, CryptError>;
41}
42
43pub trait SignatureValidator {
47 fn validate(
49 &self,
50 updater: &dyn SignatureUpdater,
51 signature: &[u8],
52 ) -> Result<bool, CryptError>;
53}
54
55pub struct RsaPrivateKeySigner {
59 signing_key: SigningKey<Sha256>,
60}
61
62impl RsaPrivateKeySigner {
63 #[must_use]
64 pub fn new(private_key: RsaPrivateKey) -> Self {
65 Self {
66 signing_key: SigningKey::new(private_key),
67 }
68 }
69}
70
71impl Signer for RsaPrivateKeySigner {
72 fn sign(&self, updater: &dyn SignatureUpdater) -> Result<Vec<u8>, CryptError> {
73 let mut collector = ByteCollector::new();
75 updater.update(&mut collector)?;
76
77 let signature = self.signing_key.sign(&collector.bytes);
79 Ok(signature.to_bytes().as_ref().to_vec())
80 }
81}
82
83pub struct RsaPublicKeyValidator {
87 verifying_key: rsa::pkcs1v15::VerifyingKey<Sha256>,
88}
89
90impl RsaPublicKeyValidator {
91 #[must_use]
92 pub fn new(public_key: RsaPublicKey) -> Self {
93 Self {
94 verifying_key: rsa::pkcs1v15::VerifyingKey::new(public_key),
95 }
96 }
97}
98
99impl SignatureValidator for RsaPublicKeyValidator {
100 fn validate(
101 &self,
102 updater: &dyn SignatureUpdater,
103 signature_bytes: &[u8],
104 ) -> Result<bool, CryptError> {
105 let mut collector = ByteCollector::new();
107 updater.update(&mut collector)?;
108
109 let signature = match rsa::pkcs1v15::Signature::try_from(signature_bytes) {
111 Ok(sig) => sig,
112 Err(_) => return Ok(false),
113 };
114
115 Ok(self
117 .verifying_key
118 .verify(&collector.bytes, &signature)
119 .is_ok())
120 }
121}
122
123pub struct MultiKeyValidator {
127 validators: Vec<RsaPublicKeyValidator>,
128}
129
130impl MultiKeyValidator {
131 pub fn new(public_keys: Vec<RsaPublicKey>) -> Self {
132 Self {
133 validators: public_keys
134 .into_iter()
135 .map(RsaPublicKeyValidator::new)
136 .collect(),
137 }
138 }
139}
140
141impl SignatureValidator for MultiKeyValidator {
142 fn validate(
143 &self,
144 updater: &dyn SignatureUpdater,
145 signature: &[u8],
146 ) -> Result<bool, CryptError> {
147 for validator in &self.validators {
149 if validator.validate(updater, signature)? {
150 return Ok(true);
151 }
152 }
153 Ok(false)
155 }
156}
157
158pub struct NoValidation;
162
163impl SignatureValidator for NoValidation {
164 fn validate(
165 &self,
166 _updater: &dyn SignatureUpdater,
167 _signature: &[u8],
168 ) -> Result<bool, CryptError> {
169 Ok(true)
170 }
171}
172
173struct ByteCollector {
175 bytes: Vec<u8>,
176}
177
178impl ByteCollector {
179 const fn new() -> Self {
180 Self { bytes: Vec::new() }
181 }
182}
183
184impl SignatureOutput for ByteCollector {
185 fn update(&mut self, data: &[u8]) -> Result<(), CryptError> {
186 self.bytes.extend_from_slice(data);
187 Ok(())
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194 use crate::rsa_utils::generate_key_pair;
195
196 struct TestUpdater {
197 data: Vec<u8>,
198 }
199
200 impl SignatureUpdater for TestUpdater {
201 fn update(&self, output: &mut dyn SignatureOutput) -> Result<(), CryptError> {
202 output.update(&self.data)
203 }
204 }
205
206 #[test]
207 fn test_sign_and_verify() {
208 let (private_key, public_key) = generate_key_pair().unwrap();
209
210 let signer = RsaPrivateKeySigner::new(private_key);
211 let validator = RsaPublicKeyValidator::new(public_key);
212
213 let data = b"Hello, signed chat!";
214 let updater = TestUpdater {
215 data: data.to_vec(),
216 };
217
218 let signature = signer.sign(&updater).unwrap();
219 assert_eq!(signature.len(), 128);
222
223 let is_valid = validator.validate(&updater, &signature).unwrap();
224 assert!(is_valid);
225 }
226
227 #[test]
228 fn test_invalid_signature() {
229 let (_, public_key) = generate_key_pair().unwrap();
230 let validator = RsaPublicKeyValidator::new(public_key);
231
232 let data = b"Hello, signed chat!";
233 let updater = TestUpdater {
234 data: data.to_vec(),
235 };
236
237 let bad_signature = vec![0u8; crate::SIGNATURE_BYTES];
238 let is_valid = validator.validate(&updater, &bad_signature).unwrap();
239 assert!(!is_valid);
240 }
241
242 #[test]
243 fn test_no_validation() {
244 let validator = NoValidation;
245 let data = b"Any data";
246 let updater = TestUpdater {
247 data: data.to_vec(),
248 };
249 let signature = vec![0u8; 10];
250
251 let is_valid = validator.validate(&updater, &signature).unwrap();
252 assert!(is_valid);
253 }
254}