1use md5::{Digest, Md5};
2use sha1::Sha1;
3
4use crate::EwfError;
5use crate::{Image, Result, VerifyResult};
6
7impl Image {
8 pub fn verify(&self) -> Result<VerifyResult> {
20 let mut md5 = Md5::new();
21 let mut sha1 = Sha1::new();
22 let mut offset = 0_u64;
23 let logical_size = self.info().logical_size;
24 let mut buf = vec![0; 1024 * 1024];
25
26 while offset < logical_size {
27 let remaining = logical_size - offset;
28 let request = usize::try_from(remaining.min(buf.len() as u64))
29 .map_err(|_| EwfError::Malformed("verify read size does not fit usize".into()))?;
30 let read = self.read_at(&mut buf[..request], offset)?;
31 if read == 0 {
32 return Err(EwfError::Malformed(
33 "verify reached EOF before logical image end".into(),
34 ));
35 }
36
37 md5.update(&buf[..read]);
38 sha1.update(&buf[..read]);
39 offset += u64::try_from(read).expect("usize fits u64");
40 }
41
42 let computed_md5: [u8; 16] = md5.finalize().into();
43 let computed_sha1: [u8; 20] = sha1.finalize().into();
44 let stored = &self.info().stored_hashes;
45
46 Ok(VerifyResult {
47 computed_md5: Some(computed_md5),
48 computed_sha1: Some(computed_sha1),
49 md5_match: stored.md5.map(|expected| expected == computed_md5),
50 sha1_match: stored.sha1.map(|expected| expected == computed_sha1),
51 })
52 }
53}