zipsign_api/unsign/
tar.rs

1#![cfg_attr(docsrs, doc(cfg(feature = "unsign-tar")))]
2
3use std::io::{Read, Seek, Write, copy};
4
5use crate::verify_unsign_tar::{
6    TarFindDataStartAndLenError, TarReadSignaturesError, tar_find_data_start_and_len,
7    tar_read_signatures,
8};
9
10crate::Error! {
11    /// An error returned by [`copy_and_unsign_tar()`]
12    pub struct UnsignTarError(Error) {
13        #[error("could not copy data")]
14        Copy(#[source] std::io::Error),
15        #[error("could not find read signatures in .tar.gz file")]
16        FindDataStartAndLen(#[source] TarFindDataStartAndLenError),
17        #[error("could not find read signatures in .tar.gz file")]
18        ReadSignatures(#[source] TarReadSignaturesError),
19        #[error("could not seek inside the input")]
20        Seek(#[source] std::io::Error),
21    }
22}
23
24/// Copy a signed `.tar.gz` file without the signatures
25pub fn copy_and_unsign_tar<I, O>(input: &mut I, output: &mut O) -> Result<(), UnsignTarError>
26where
27    I: ?Sized + Seek + Read,
28    O: ?Sized + Seek + Write,
29{
30    // seek to start of base64 encoded signatures
31    let (data_start, data_len) =
32        tar_find_data_start_and_len(input).map_err(Error::FindDataStartAndLen)?;
33
34    // read base64 encoded signatures
35    let _ = tar_read_signatures(data_start, data_len, input).map_err(Error::ReadSignatures)?;
36
37    // copy data
38    input.rewind().map_err(Error::Seek)?;
39    let _ = copy(&mut input.take(data_start), output).map_err(Error::Copy)?;
40
41    Ok(())
42}