]> git.proxmox.com Git - proxmox-backup.git/blame - src/backup/checksum_writer.rs
switch from failure to anyhow
[proxmox-backup.git] / src / backup / checksum_writer.rs
CommitLineData
9025312a 1use std::sync::Arc;
018d11bb
DM
2use std::io::Write;
3
f7d4e4b5 4use anyhow::{Error};
9025312a
WB
5
6use super::CryptConfig;
7use crate::tools::borrow::Tied;
8
9pub struct ChecksumWriter<W> {
018d11bb
DM
10 writer: W,
11 hasher: crc32fast::Hasher,
9025312a 12 signer: Option<Tied<Arc<CryptConfig>, openssl::sign::Signer<'static>>>,
018d11bb
DM
13}
14
9025312a 15impl <W: Write> ChecksumWriter<W> {
018d11bb 16
9025312a 17 pub fn new(writer: W, 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.clone(), |config| {
22 Box::new(unsafe { (*config).data_signer() })
23 });
24 Some(tied_signer)
25 }
26 None => None,
27 };
018d11bb
DM
28 Self { writer, hasher, signer }
29 }
30
31 pub fn finish(mut self) -> Result<(W, 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.writer, crc, Some(tag)))
38 } else {
39 Ok((self.writer, crc, None))
40 }
41 }
42}
43
9025312a 44impl <W: Write> Write for ChecksumWriter<W> {
018d11bb
DM
45
46 fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
47 self.hasher.update(buf);
48 if let Some(ref mut signer) = self.signer {
49 signer.update(buf)
50 .map_err(|err| {
51 std::io::Error::new(
52 std::io::ErrorKind::Other,
53 format!("hmac update failed - {}", err))
54 })?;
55 }
56 self.writer.write(buf)
57 }
58
59 fn flush(&mut self) -> Result<(), std::io::Error> {
60 self.writer.flush()
61 }
62}