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