zipsign_api/verify/
zip.rs

1#![cfg_attr(docsrs, doc(cfg(feature = "verify-zip")))]
2
3use std::io::{Read, Seek};
4
5use super::{NoMatch, ReadSignaturesError, VerifyingKey, find_match, read_signatures};
6use crate::{Prehash, Signature};
7
8crate::Error! {
9    /// An error returned by [`verify_zip()`]
10    pub struct VerifyZipError(Error) {
11        #[error("could not read input")]
12        InputRead(#[source] std::io::Error),
13        #[error("no matching key/signature pair found")]
14        NoMatch(NoMatch),
15        #[error("could not read signatures from input")]
16        ReadSignaturesError(#[source] ReadSignaturesError),
17    }
18}
19
20/// Find the index of the first [`VerifyingKey`] that matches the a signature in a signed `.zip`
21/// file
22pub fn verify_zip<R>(
23    signed_file: &mut R,
24    keys: &[VerifyingKey],
25    context: Option<&[u8]>,
26) -> Result<usize, VerifyZipError>
27where
28    R: ?Sized + Read + Seek,
29{
30    let (prehashed_message, signatures) = read_zip(signed_file)?;
31    let (key_idx, _) =
32        find_match(keys, &signatures, &prehashed_message, context).map_err(Error::NoMatch)?;
33    Ok(key_idx)
34}
35
36fn read_zip<R>(signed_file: &mut R) -> Result<(Prehash, Vec<Signature>), VerifyZipError>
37where
38    R: ?Sized + Read + Seek,
39{
40    let signatures = read_signatures(signed_file).map_err(Error::ReadSignaturesError)?;
41    let prehashed_message = Prehash::calculate(signed_file).map_err(Error::InputRead)?;
42    Ok((prehashed_message, signatures))
43}