diff --git a/Cargo.toml b/Cargo.toml index 70f21ca128ddb3116c0865aee1bde60c892b69d1..1e920fcb1c277e58fe127d7e1c8e318d9d93b7be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,10 +55,8 @@ num_cpus = "1.15.0" walkdir = "2.3.2" async-channel = "1.8.0" uuid = { version = "1.3.0", features = ["v4"]} -rpm-infra ="0.0.3" +rpm-infra ="0.12.1" dns-lookup = {version="1.0.8"} -#sha1 is used in openpgp signature generation -sha1 = "0.10.5" sha2 = "0.10.6" bincode = "2.0.0-rc.3" secstr = "0.5.1" diff --git a/src/client/file_handler/mod.rs b/src/client/file_handler/mod.rs index 5aa2121f6548264b76085a1e3ead4779e2df0061..6b2a569766cdf154b6ef6ca43781cf8bdac41139 100644 --- a/src/client/file_handler/mod.rs +++ b/src/client/file_handler/mod.rs @@ -3,5 +3,4 @@ pub mod efi; pub mod traits; pub mod factory; pub mod generic; -pub mod kernel_module; -pub mod sequential_cursor; \ No newline at end of file +pub mod kernel_module; \ No newline at end of file diff --git a/src/client/file_handler/rpm.rs b/src/client/file_handler/rpm.rs index ee34b519e7899ad489895418e54f72914c2412c5..b6a4bacdbe41dcd94f76dcafa4be85a42f773721 100644 --- a/src/client/file_handler/rpm.rs +++ b/src/client/file_handler/rpm.rs @@ -21,11 +21,9 @@ use async_trait::async_trait; use crate::util::error::Result; use std::fs::File; use std::io::{BufReader, Read}; -use rpm::{Header, IndexSignatureTag, RPMPackage}; +use rpm::{Header, IndexSignatureTag, Package, Digests}; -use super::sequential_cursor::SeqCursor; use uuid::Uuid; -use sha1; use crate::util::options; use crate::util::sign::KeyType; use crate::util::error::Error; @@ -67,7 +65,7 @@ impl FileHandler for RpmFileHandler { //2. header and content async fn split_data(&self, path: &PathBuf, _sign_options: &mut HashMap) -> Result>> { let file = File::open(path)?; - let package = RPMPackage::parse(&mut BufReader::new(file))?; + let package = Package::parse(&mut BufReader::new(file))?; let mut header_bytes = Vec::::with_capacity(1024); //collect head and head&payload arrays package.metadata.header.write(&mut header_bytes)?; @@ -86,46 +84,25 @@ impl FileHandler for RpmFileHandler { ) -> Result<(String, String)> { let temp_rpm = temp_dir.join(Uuid::new_v4().to_string()); let file = File::open(path)?; - let mut package = RPMPackage::parse(&mut BufReader::new(file))?; + let mut package = Package::parse(&mut BufReader::new(file))?; let mut header_bytes = Vec::::with_capacity(1024); package.metadata.header.write(&mut header_bytes)?; - //calculate md5 and sha1 digest - let mut header_and_content_cursor = - SeqCursor::new(&[header_bytes.as_slice(), package.content.as_slice()]); - let digest_md5 = { - use md5::Digest; - let mut hasher = md5::Md5::default(); - { - // avoid loading it into memory all at once - // since the content could be multiple 100s of MBs - let mut buf = [0u8; 256]; - while let Ok(n) = header_and_content_cursor.read(&mut buf[..]) { - if n == 0 { - break; - } - hasher.update(&buf[0..n]); - } - } - let hash_result = hasher.finalize(); - hash_result.to_vec() - }; - let digest_sha1 = { - use sha1::Digest; - let mut hasher = sha1::Sha1::default(); - hasher.update(&header_bytes); - let digest = hasher.finalize(); - hex::encode(digest) - }; - package.metadata.signature = Header::::new_signature_header( - header_and_content_cursor - .len() - .try_into() - .expect("headers + payload can't be larger than 4gb"), - &digest_md5, - digest_sha1, + let Digests { + header_digest_sha256, + header_digest_sha1, + header_and_content_digest, + } = Package::create_sig_header_digests(header_bytes.as_slice(), &package.content.as_slice())?; + + //Only RSA Signature is supported currently. + let builder = Header::::builder().add_digest( + &header_digest_sha1, + &header_digest_sha256, + &header_and_content_digest, + ).add_rsa_signature( data[0].as_slice(), data[1].as_slice(), ); + package.metadata.signature = builder.build(header_bytes.as_slice().len() + package.content.len()); //save data into temp file let mut output = File::create(temp_rpm.clone())?; package.write(&mut output)?; diff --git a/src/client/file_handler/sequential_cursor.rs b/src/client/file_handler/sequential_cursor.rs deleted file mode 100644 index 6e3f2cacd8ac0b06574aedb29692967a1f18ae25..0000000000000000000000000000000000000000 --- a/src/client/file_handler/sequential_cursor.rs +++ /dev/null @@ -1,163 +0,0 @@ -//NOTE: this file is copied from (rpm-rs)[https://github.com/rpm-rs/rpm] which is under MIT License -//! Cursor implementation over multiple slices -use std::io::{Seek, SeekFrom}; - -pub struct SeqCursor<'s> { - cursors: Vec>, - position: u64, - len: usize, -} - -impl<'s> SeqCursor<'s> { - /// Add an additional slice to the end of the cursor - /// - /// Does not modify the current cursors position. - #[allow(unused)] - pub fn add<'b>(&mut self, another: &'b [u8]) - where - 'b: 's, - { - let cursor = std::io::Cursor::<&'s [u8]>::new(another); - self.cursors.push(cursor); - self.len += another.len(); - } - - /// Crate a new cursor based on a slice of bytes slices. - pub fn new<'b>(slices: &[&'b [u8]]) -> Self - where - 'b: 's, - { - let len = slices.iter().fold(0usize, |acc, slice| slice.len() + acc); - Self { - cursors: slices - .iter() - .map(|slice| std::io::Cursor::new(*slice)) - .collect::>(), - position: 0u64, - len, - } - } - - /// Total length of all slices summed up. - pub(crate) fn len(&self) -> usize { - self.len - } -} - -impl<'s> std::io::Read for SeqCursor<'s> { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - let mut total_read = 0usize; - let mut acc_offset = 0usize; - for cursor in self.cursors.iter_mut() { - let chunk_len = cursor.get_ref().len(); - acc_offset += chunk_len; - if self.position <= acc_offset as u64 { - // remaining unread bytes - let rem_unread_in_chunk = (acc_offset as u64 - self.position) as usize; - // seek to the beginning of the currently first unread byte in the - // iterations cursor - cursor.seek(SeekFrom::Start( - chunk_len as u64 - rem_unread_in_chunk as u64, - ))?; - let fin = std::cmp::min(total_read + rem_unread_in_chunk, buf.len()); - let read = cursor.read(&mut buf[total_read..fin])?; - self.position += read as u64; - total_read += read; - if total_read >= buf.len() { - debug_assert_eq!(total_read, buf.len(), "Always equal. qed"); - break; - } - } - } - Ok(total_read) - } -} - -impl<'s> std::io::Seek for SeqCursor<'s> { - fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { - self.position = match pos { - std::io::SeekFrom::Start(rel) => rel, - std::io::SeekFrom::End(rel) => (self.len as i64 + rel) as u64, - std::io::SeekFrom::Current(rel) => (self.position as i64 + rel) as u64, - }; - Ok(self.position) - } -} - -#[cfg(test)] -mod test { - use super::*; - use std::io::Read; - use std::io::Seek; - - #[test] - fn sequential_cursor() { - let c1 = vec![1u8; 17]; - let c2 = vec![2u8; 17]; - let c3 = vec![3u8; 17]; - - let mut buf = Vec::::with_capacity(17 * 3); - unsafe { - buf.set_len(17 * 3); - } - let mut sq = SeqCursor::new(&[c1.as_slice(), c2.as_slice(), c3.as_slice()]); - - sq.seek(std::io::SeekFrom::Current(16)).unwrap(); - sq.read(&mut buf[0..4]).unwrap(); - assert_eq!(buf[0..4].to_vec(), vec![1u8, 2u8, 2u8, 2u8]); - - sq.seek(std::io::SeekFrom::Current(12)).unwrap(); - sq.read(&mut buf[4..8]).unwrap(); - assert_eq!(buf[4..8].to_vec(), vec![2u8, 2u8, 3u8, 3u8]); - } - - #[test] - fn sequential_cursor_with_short_buffer() { - let c1 = vec![1u8, 2u8]; - let c2 = vec![3u8, 4u8]; - let mut sq = SeqCursor::new(&[c1.as_slice(), c2.as_slice()]); - - //read with a short buffer - let mut buf = vec![0u8; 1]; - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![1u8]); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![2u8]); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![3u8]); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![4u8]); - } - - #[test] - fn sequential_cursor_with_seek() { - let c1 = vec![1u8; 2]; - let c2 = vec![2u8; 2]; - let c3 = vec![3u8; 2]; - - let mut buf = vec![0u8; 6]; - // without seek - let mut sq = SeqCursor::new(&[c1.as_slice(), c2.as_slice(), c3.as_slice()]); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![1u8, 1u8, 2u8, 2u8, 3u8, 3u8]); - - // seek with start - let mut buf = vec![0u8; 5]; - sq.seek(SeekFrom::Start(1)).unwrap(); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![1u8, 2u8, 2u8, 3u8, 3u8]); - - //seek with current - let mut buf = vec![0u8; 5]; - sq.seek(SeekFrom::Start(0)).unwrap(); - sq.seek(SeekFrom::Current(1)).unwrap(); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![1u8, 2u8, 2u8, 3u8, 3u8]); - - //seek with end - let mut buf = vec![0u8; 3]; - sq.seek(SeekFrom::End(-3)).unwrap(); - sq.read(&mut buf).unwrap(); - assert_eq!(buf.to_vec(), vec![2u8, 3u8, 3u8]); - } -} diff --git a/src/util/error.rs b/src/util/error.rs index e680140ffa77d783cef87f78e318b04bd2552862..3e4492cb13190422fa821e4d43f7c3263fa9be49 100644 --- a/src/util/error.rs +++ b/src/util/error.rs @@ -28,7 +28,7 @@ use std::net::AddrParseError; use std::num::ParseIntError; use std::string::FromUtf8Error; use std::sync::PoisonError; -use rpm::RPMError; +use rpm::Error as RPMError; use thiserror::Error as ThisError; use tonic::transport::Error as TonicError; use bincode::error::{EncodeError, DecodeError};