]> git.proxmox.com Git - proxmox-backup.git/blame - src/backup/checksum_reader.rs
verify: introduce & use new Datastore.Verify privilege
[proxmox-backup.git] / src / backup / checksum_reader.rs
CommitLineData
f7d4e4b5 1use anyhow::{Error};
9025312a 2use std::sync::Arc;
018d11bb
DM
3use std::io::Read;
4
9025312a
WB
5use super::CryptConfig;
6use crate::tools::borrow::Tied;
7
8pub 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 14impl <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 44impl <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}