]> git.proxmox.com Git - proxmox-backup.git/blob - src/backup/checksum_reader.rs
da8cf70292f8098a7b7cdff7a60ffd246c6ea1fb
[proxmox-backup.git] / src / backup / checksum_reader.rs
1 use failure::*;
2 use std::io::Read;
3
4 pub struct ChecksumReader<'a, R> {
5 reader: R,
6 hasher: crc32fast::Hasher,
7 signer: Option<openssl::sign::Signer<'a>>,
8 }
9
10 impl <'a, R: Read> ChecksumReader<'a, R> {
11
12 pub fn new(reader: R, signer: Option<openssl::sign::Signer<'a>>) -> Self {
13 let hasher = crc32fast::Hasher::new();
14 Self { reader, hasher, signer }
15 }
16
17 pub fn finish(mut self) -> Result<(R, u32, Option<[u8; 32]>), Error> {
18 let crc = self.hasher.finalize();
19
20 if let Some(ref mut signer) = self.signer {
21 let mut tag = [0u8; 32];
22 signer.sign(&mut tag)?;
23 Ok((self.reader, crc, Some(tag)))
24 } else {
25 Ok((self.reader, crc, None))
26 }
27 }
28 }
29
30 impl <'a, R: Read> Read for ChecksumReader<'a, R> {
31
32 fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
33 let count = self.reader.read(buf)?;
34 if count > 0 {
35 self.hasher.update(&buf[..count]);
36 if let Some(ref mut signer) = self.signer {
37 signer.update(&buf[..count])
38 .map_err(|err| {
39 std::io::Error::new(
40 std::io::ErrorKind::Other,
41 format!("hmac update failed - {}", err))
42 })?;
43 }
44 }
45 Ok(count)
46 }
47 }