]>
Commit | Line | Data |
---|---|---|
f7d4e4b5 | 1 | use anyhow::{Error}; |
9025312a | 2 | use std::sync::Arc; |
018d11bb DM |
3 | use std::io::Read; |
4 | ||
9025312a WB |
5 | use super::CryptConfig; |
6 | use crate::tools::borrow::Tied; | |
7 | ||
8 | pub struct ChecksumReader<R> { | |
018d11bb DM |
9 | reader: R, |
10 | hasher: crc32fast::Hasher, | |
9025312a | 11 | signer: Option<Tied<Arc<CryptConfig>, openssl::sign::Signer<'static>>>, |
018d11bb DM |
12 | } |
13 | ||
9025312a | 14 | impl <R: Read> ChecksumReader<R> { |
018d11bb | 15 | |
9025312a | 16 | pub fn new(reader: R, config: Option<Arc<CryptConfig>>) -> Self { |
018d11bb | 17 | let hasher = crc32fast::Hasher::new(); |
9025312a WB |
18 | let signer = match config { |
19 | Some(config) => { | |
20 | let tied_signer = Tied::new(config, |config| { | |
21 | Box::new(unsafe { (*config).data_signer() }) | |
22 | }); | |
23 | Some(tied_signer) | |
24 | } | |
25 | None => None, | |
26 | }; | |
27 | ||
018d11bb DM |
28 | Self { reader, hasher, signer } |
29 | } | |
30 | ||
31 | pub fn finish(mut self) -> Result<(R, u32, Option<[u8; 32]>), Error> { | |
32 | let crc = self.hasher.finalize(); | |
33 | ||
34 | if let Some(ref mut signer) = self.signer { | |
35 | let mut tag = [0u8; 32]; | |
36 | signer.sign(&mut tag)?; | |
37 | Ok((self.reader, crc, Some(tag))) | |
38 | } else { | |
39 | Ok((self.reader, crc, None)) | |
40 | } | |
41 | } | |
42 | } | |
43 | ||
9025312a | 44 | impl <R: Read> Read for ChecksumReader<R> { |
018d11bb DM |
45 | |
46 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> { | |
47 | let count = self.reader.read(buf)?; | |
48 | if count > 0 { | |
49 | self.hasher.update(&buf[..count]); | |
50 | if let Some(ref mut signer) = self.signer { | |
51 | signer.update(&buf[..count]) | |
52 | .map_err(|err| { | |
53 | std::io::Error::new( | |
54 | std::io::ErrorKind::Other, | |
55 | format!("hmac update failed - {}", err)) | |
56 | })?; | |
57 | } | |
58 | } | |
59 | Ok(count) | |
60 | } | |
61 | } |