diff --git a/Cargo.toml b/Cargo.toml index 60bb104..f27ceb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,11 @@ futures = "0.3.30" hex = "0.4.3" md-5 = "0.10.6" procfs = "0.16.0" -sha-1 = "0.10.1" thiserror = "1.0.60" rayon = "1.10.0" deb-version = "0.1.1" +sha1 = "0.10.6" +sha2 = "0.10.9" [dependencies.tokio] version = "1.37.0" diff --git a/src/hash.rs b/src/hash.rs index f2ab5a7..0d51312 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -4,6 +4,7 @@ use hex::FromHex; use md5::{digest::generic_array::GenericArray, Digest, Md5}; use sha1::Sha1; +use sha2::{Sha256, Sha512}; use std::{io, path::Path}; use thiserror::Error; @@ -49,6 +50,30 @@ pub fn compare_hash( } match expected_hash { + RequestChecksum::Md5(sum) => { + let expected = <[u8; 16]>::from_hex(sum) + .map(GenericArray::from) + .map_err(|_| ChecksumError::InvalidInput(format!("MD5 {}", sum)))?; + + let mut buffer = vec![0u8; 8 * 1024]; + let mut hasher = Md5::new(); + + loop { + match file.read(&mut buffer) { + Ok(0) => break, + Ok(bytes) => hasher.update(&buffer[..bytes]), + Err(why) => return Err(ChecksumError::FileRead(why)), + } + } + + let hash = &*hasher.finalize(); + + if &*expected == hash { + Ok(()) + } else { + Err(ChecksumError::Mismatch) + } + } RequestChecksum::Sha1(sum) => { let expected = <[u8; 20]>::from_hex(sum) .map(GenericArray::from) @@ -73,13 +98,37 @@ pub fn compare_hash( Err(ChecksumError::Mismatch) } } - RequestChecksum::Md5(sum) => { - let expected = <[u8; 16]>::from_hex(sum) + RequestChecksum::Sha256(sum) => { + let expected = <[u8; 32]>::from_hex(sum) .map(GenericArray::from) - .map_err(|_| ChecksumError::InvalidInput(format!("MD5 {}", sum)))?; + .map_err(|_| ChecksumError::InvalidInput(format!("SHA256 {}", sum)))?; let mut buffer = vec![0u8; 8 * 1024]; - let mut hasher = Md5::new(); + let mut hasher = Sha256::new(); + + loop { + match file.read(&mut buffer) { + Ok(0) => break, + Ok(bytes) => hasher.update(&buffer[..bytes]), + Err(why) => return Err(ChecksumError::FileRead(why)), + } + } + + let hash = &*hasher.finalize(); + + if &*expected == hash { + Ok(()) + } else { + Err(ChecksumError::Mismatch) + } + } + RequestChecksum::Sha512(sum) => { + let expected = <[u8; 64]>::from_hex(sum) + .map(GenericArray::from) + .map_err(|_| ChecksumError::InvalidInput(format!("SHA512 {}", sum)))?; + + let mut buffer = vec![0u8; 8 * 1024]; + let mut hasher = Sha512::new(); loop { match file.read(&mut buffer) { diff --git a/src/request.rs b/src/request.rs index 38b32e0..2f0ae87 100644 --- a/src/request.rs +++ b/src/request.rs @@ -32,6 +32,8 @@ pub enum RequestError { pub enum RequestChecksum { Md5(String), Sha1(String), + Sha256(String), + Sha512(String), } #[derive(Debug, Clone, Eq)] @@ -89,6 +91,10 @@ impl FromStr for Request { RequestChecksum::Md5(value.to_owned()) } else if let Some(value) = checksum_string.strip_prefix("SHA1:") { RequestChecksum::Sha1(value.to_owned()) + } else if let Some(value) = checksum_string.strip_prefix("SHA256:") { + RequestChecksum::Sha256(value.to_owned()) + } else if let Some(value) = checksum_string.strip_prefix("SHA512:") { + RequestChecksum::Sha512(value.to_owned()) } else { return Err(RequestError::UnknownChecksum(checksum_string.into())); };