From 3638341aa4cff5b830dd8c8a93247b6f5ed15483 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 8 Jul 2020 14:06:50 +0200 Subject: [PATCH] src/backup/file_formats.rs: remove signed chunks We can include signature in the manifest instead (patch will follow). --- src/backup/data_blob.rs | 106 ++----------------------------- src/backup/data_blob_reader.rs | 49 -------------- src/backup/data_blob_writer.rs | 74 +-------------------- src/backup/file_formats.rs | 21 ------ src/bin/proxmox-backup-client.rs | 53 +++++++--------- src/client/backup_writer.rs | 38 +++++------ 6 files changed, 50 insertions(+), 291 deletions(-) diff --git a/src/backup/data_blob.rs b/src/backup/data_blob.rs index a397727b..07e7ca6a 100644 --- a/src/backup/data_blob.rs +++ b/src/backup/data_blob.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, format_err, Error}; +use anyhow::{bail, Error}; use std::convert::TryInto; use proxmox::tools::io::{ReadExt, WriteExt}; @@ -174,8 +174,6 @@ impl DataBlob { CryptMode::None } else if magic == &ENCR_COMPR_BLOB_MAGIC_1_0 || magic == &ENCRYPTED_BLOB_MAGIC_1_0 { CryptMode::Encrypt - } else if magic == &AUTH_COMPR_BLOB_MAGIC_1_0 || magic == &AUTHENTICATED_BLOB_MAGIC_1_0 { - CryptMode::SignOnly } else { bail!("Invalid blob magic number."); }) @@ -209,75 +207,11 @@ impl DataBlob { } else { bail!("unable to decrypt blob - missing CryptConfig"); } - } else if magic == &AUTH_COMPR_BLOB_MAGIC_1_0 || magic == &AUTHENTICATED_BLOB_MAGIC_1_0 { - let header_len = std::mem::size_of::(); - let head = unsafe { - (&self.raw_data[..header_len]).read_le_value::()? - }; - - let data_start = std::mem::size_of::(); - - // Note: only verify if we have a crypt config - if let Some(config) = config { - let signature = config.compute_auth_tag(&self.raw_data[data_start..]); - if signature != head.tag { - bail!("verifying blob signature failed"); - } - } - - if magic == &AUTH_COMPR_BLOB_MAGIC_1_0 { - let data = zstd::block::decompress(&self.raw_data[data_start..], 16*1024*1024)?; - Ok(data) - } else { - Ok(self.raw_data[data_start..].to_vec()) - } } else { bail!("Invalid blob magic number."); } } - /// Create a signed DataBlob, optionally compressed - pub fn create_signed( - data: &[u8], - config: &CryptConfig, - compress: bool, - ) -> Result { - - if data.len() > MAX_BLOB_SIZE { - bail!("data blob too large ({} bytes).", data.len()); - } - - let compr_data; - let (_compress, data, magic) = if compress { - compr_data = zstd::block::compress(data, 1)?; - // Note: We only use compression if result is shorter - if compr_data.len() < data.len() { - (true, &compr_data[..], AUTH_COMPR_BLOB_MAGIC_1_0) - } else { - (false, data, AUTHENTICATED_BLOB_MAGIC_1_0) - } - } else { - (false, data, AUTHENTICATED_BLOB_MAGIC_1_0) - }; - - let header_len = std::mem::size_of::(); - let mut raw_data = Vec::with_capacity(data.len() + header_len); - - let head = AuthenticatedDataBlobHeader { - head: DataBlobHeader { magic, crc: [0; 4] }, - tag: config.compute_auth_tag(data), - }; - unsafe { - raw_data.write_le_value(head)?; - } - raw_data.extend_from_slice(data); - - let mut blob = DataBlob { raw_data }; - blob.set_crc(blob.compute_crc()); - - Ok(blob) - } - /// Load blob from ``reader`` pub fn load(reader: &mut dyn std::io::Read) -> Result { @@ -309,14 +243,6 @@ impl DataBlob { let blob = DataBlob { raw_data: data }; - Ok(blob) - } else if magic == AUTH_COMPR_BLOB_MAGIC_1_0 || magic == AUTHENTICATED_BLOB_MAGIC_1_0 { - if data.len() < std::mem::size_of::() { - bail!("authenticated blob too small ({} bytes).", data.len()); - } - - let blob = DataBlob { raw_data: data }; - Ok(blob) } else { bail!("unable to parse raw blob - wrong magic"); @@ -362,7 +288,6 @@ impl DataBlob { /// we always compute the correct one. pub struct DataChunkBuilder<'a, 'b> { config: Option<&'b CryptConfig>, - crypt_mode: CryptMode, orig_data: &'a [u8], digest_computed: bool, digest: [u8; 32], @@ -376,7 +301,6 @@ impl <'a, 'b> DataChunkBuilder<'a, 'b> { Self { orig_data, config: None, - crypt_mode: CryptMode::None, digest_computed: false, digest: [0u8; 32], compress: true, @@ -393,18 +317,12 @@ impl <'a, 'b> DataChunkBuilder<'a, 'b> { /// Set encryption Configuration /// - /// If set, chunks are encrypted or signed - pub fn crypt_config(mut self, value: &'b CryptConfig, crypt_mode: CryptMode) -> Self { + /// If set, chunks are encrypted + pub fn crypt_config(mut self, value: &'b CryptConfig) -> Self { if self.digest_computed { panic!("unable to set crypt_config after compute_digest()."); } - if crypt_mode == CryptMode::None { - self.config = None; - } else { - self.config = Some(value); - } - - self.crypt_mode = crypt_mode; + self.config = Some(value); self } @@ -438,25 +356,13 @@ impl <'a, 'b> DataChunkBuilder<'a, 'b> { self.compute_digest(); } - let chunk = match self.crypt_mode { - CryptMode::None | CryptMode::Encrypt => { - DataBlob::encode(self.orig_data, self.config, self.compress)? - } - CryptMode::SignOnly => DataBlob::create_signed( - self.orig_data, - self.config - .ok_or_else(|| format_err!("cannot sign without crypt config"))?, - self.compress, - )?, - }; - + let chunk = DataBlob::encode(self.orig_data, self.config, self.compress)?; Ok((chunk, self.digest)) } /// Create a chunk filled with zeroes pub fn build_zero_chunk( crypt_config: Option<&CryptConfig>, - crypt_mode: CryptMode, chunk_size: usize, compress: bool, ) -> Result<(DataBlob, [u8; 32]), Error> { @@ -465,7 +371,7 @@ impl <'a, 'b> DataChunkBuilder<'a, 'b> { zero_bytes.resize(chunk_size, 0u8); let mut chunk_builder = DataChunkBuilder::new(&zero_bytes).compress(compress); if let Some(ref crypt_config) = crypt_config { - chunk_builder = chunk_builder.crypt_config(crypt_config, crypt_mode); + chunk_builder = chunk_builder.crypt_config(crypt_config); } chunk_builder.build() diff --git a/src/backup/data_blob_reader.rs b/src/backup/data_blob_reader.rs index d6fc7865..b941d9ef 100644 --- a/src/backup/data_blob_reader.rs +++ b/src/backup/data_blob_reader.rs @@ -8,8 +8,6 @@ use super::*; enum BlobReaderState { Uncompressed { expected_crc: u32, csum_reader: ChecksumReader }, Compressed { expected_crc: u32, decompr: zstd::stream::read::Decoder>> }, - Signed { expected_crc: u32, expected_hmac: [u8; 32], csum_reader: ChecksumReader }, - SignedCompressed { expected_crc: u32, expected_hmac: [u8; 32], decompr: zstd::stream::read::Decoder>> }, Encrypted { expected_crc: u32, decrypt_reader: CryptReader>> }, EncryptedCompressed { expected_crc: u32, decompr: zstd::stream::read::Decoder>>>> }, } @@ -41,22 +39,6 @@ impl DataBlobReader { let decompr = zstd::stream::read::Decoder::new(csum_reader)?; Ok(Self { state: BlobReaderState::Compressed { expected_crc, decompr }}) } - AUTHENTICATED_BLOB_MAGIC_1_0 => { - let expected_crc = u32::from_le_bytes(head.crc); - let mut expected_hmac = [0u8; 32]; - reader.read_exact(&mut expected_hmac)?; - let csum_reader = ChecksumReader::new(reader, config); - Ok(Self { state: BlobReaderState::Signed { expected_crc, expected_hmac, csum_reader }}) - } - AUTH_COMPR_BLOB_MAGIC_1_0 => { - let expected_crc = u32::from_le_bytes(head.crc); - let mut expected_hmac = [0u8; 32]; - reader.read_exact(&mut expected_hmac)?; - let csum_reader = ChecksumReader::new(reader, config); - - let decompr = zstd::stream::read::Decoder::new(csum_reader)?; - Ok(Self { state: BlobReaderState::SignedCompressed { expected_crc, expected_hmac, decompr }}) - } ENCRYPTED_BLOB_MAGIC_1_0 => { let expected_crc = u32::from_le_bytes(head.crc); let mut iv = [0u8; 16]; @@ -99,31 +81,6 @@ impl DataBlobReader { } Ok(reader) } - BlobReaderState::Signed { csum_reader, expected_crc, expected_hmac } => { - let (reader, crc, hmac) = csum_reader.finish()?; - if crc != expected_crc { - bail!("blob crc check failed"); - } - if let Some(hmac) = hmac { - if hmac != expected_hmac { - bail!("blob signature check failed"); - } - } - Ok(reader) - } - BlobReaderState::SignedCompressed { expected_crc, expected_hmac, decompr } => { - let csum_reader = decompr.finish().into_inner(); - let (reader, crc, hmac) = csum_reader.finish()?; - if crc != expected_crc { - bail!("blob crc check failed"); - } - if let Some(hmac) = hmac { - if hmac != expected_hmac { - bail!("blob signature check failed"); - } - } - Ok(reader) - } BlobReaderState::Encrypted { expected_crc, decrypt_reader } => { let csum_reader = decrypt_reader.finish()?.into_inner(); let (reader, crc, _) = csum_reader.finish()?; @@ -155,12 +112,6 @@ impl Read for DataBlobReader { BlobReaderState::Compressed { decompr, .. } => { decompr.read(buf) } - BlobReaderState::Signed { csum_reader, .. } => { - csum_reader.read(buf) - } - BlobReaderState::SignedCompressed { decompr, .. } => { - decompr.read(buf) - } BlobReaderState::Encrypted { decrypt_reader, .. } => { decrypt_reader.read(buf) } diff --git a/src/backup/data_blob_writer.rs b/src/backup/data_blob_writer.rs index 4ff01957..10b2813a 100644 --- a/src/backup/data_blob_writer.rs +++ b/src/backup/data_blob_writer.rs @@ -8,8 +8,6 @@ use super::*; enum BlobWriterState { Uncompressed { csum_writer: ChecksumWriter }, Compressed { compr: zstd::stream::write::Encoder> }, - Signed { csum_writer: ChecksumWriter }, - SignedCompressed { compr: zstd::stream::write::Encoder> }, Encrypted { crypt_writer: CryptWriter> }, EncryptedCompressed { compr: zstd::stream::write::Encoder>> }, } @@ -42,33 +40,6 @@ impl DataBlobWriter { Ok(Self { state: BlobWriterState::Compressed { compr }}) } - pub fn new_signed(mut writer: W, config: Arc) -> Result { - writer.seek(SeekFrom::Start(0))?; - let head = AuthenticatedDataBlobHeader { - head: DataBlobHeader { magic: AUTHENTICATED_BLOB_MAGIC_1_0, crc: [0; 4] }, - tag: [0u8; 32], - }; - unsafe { - writer.write_le_value(head)?; - } - let csum_writer = ChecksumWriter::new(writer, Some(config)); - Ok(Self { state: BlobWriterState::Signed { csum_writer }}) - } - - pub fn new_signed_compressed(mut writer: W, config: Arc) -> Result { - writer.seek(SeekFrom::Start(0))?; - let head = AuthenticatedDataBlobHeader { - head: DataBlobHeader { magic: AUTH_COMPR_BLOB_MAGIC_1_0, crc: [0; 4] }, - tag: [0u8; 32], - }; - unsafe { - writer.write_le_value(head)?; - } - let csum_writer = ChecksumWriter::new(writer, Some(config)); - let compr = zstd::stream::write::Encoder::new(csum_writer, 1)?; - Ok(Self { state: BlobWriterState::SignedCompressed { compr }}) - } - pub fn new_encrypted(mut writer: W, config: Arc) -> Result { writer.seek(SeekFrom::Start(0))?; let head = EncryptedDataBlobHeader { @@ -129,37 +100,6 @@ impl DataBlobWriter { Ok(writer) } - BlobWriterState::Signed { csum_writer } => { - let (mut writer, crc, tag) = csum_writer.finish()?; - - let head = AuthenticatedDataBlobHeader { - head: DataBlobHeader { magic: AUTHENTICATED_BLOB_MAGIC_1_0, crc: crc.to_le_bytes() }, - tag: tag.unwrap(), - }; - - writer.seek(SeekFrom::Start(0))?; - unsafe { - writer.write_le_value(head)?; - } - - Ok(writer) - } - BlobWriterState::SignedCompressed { compr } => { - let csum_writer = compr.finish()?; - let (mut writer, crc, tag) = csum_writer.finish()?; - - let head = AuthenticatedDataBlobHeader { - head: DataBlobHeader { magic: AUTH_COMPR_BLOB_MAGIC_1_0, crc: crc.to_le_bytes() }, - tag: tag.unwrap(), - }; - - writer.seek(SeekFrom::Start(0))?; - unsafe { - writer.write_le_value(head)?; - } - - Ok(writer) - } BlobWriterState::Encrypted { crypt_writer } => { let (csum_writer, iv, tag) = crypt_writer.finish()?; let (mut writer, crc, _) = csum_writer.finish()?; @@ -203,12 +143,6 @@ impl Write for DataBlobWriter { BlobWriterState::Compressed { ref mut compr } => { compr.write(buf) } - BlobWriterState::Signed { ref mut csum_writer } => { - csum_writer.write(buf) - } - BlobWriterState::SignedCompressed { ref mut compr } => { - compr.write(buf) - } BlobWriterState::Encrypted { ref mut crypt_writer } => { crypt_writer.write(buf) } @@ -226,13 +160,7 @@ impl Write for DataBlobWriter { BlobWriterState::Compressed { ref mut compr } => { compr.flush() } - BlobWriterState::Signed { ref mut csum_writer } => { - csum_writer.flush() - } - BlobWriterState::SignedCompressed { ref mut compr } => { - compr.flush() - } - BlobWriterState::Encrypted { ref mut crypt_writer } => { + BlobWriterState::Encrypted { ref mut crypt_writer } => { crypt_writer.flush() } BlobWriterState::EncryptedCompressed { ref mut compr } => { diff --git a/src/backup/file_formats.rs b/src/backup/file_formats.rs index efc62f47..f0caa430 100644 --- a/src/backup/file_formats.rs +++ b/src/backup/file_formats.rs @@ -17,12 +17,6 @@ pub const ENCRYPTED_BLOB_MAGIC_1_0: [u8; 8] = [123, 103, 133, 190, 34, 45, 76, 2 // openssl::sha::sha256(b"Proxmox Backup zstd compressed encrypted blob v1.0")[0..8] pub const ENCR_COMPR_BLOB_MAGIC_1_0: [u8; 8] = [230, 89, 27, 191, 11, 191, 216, 11]; -//openssl::sha::sha256(b"Proxmox Backup authenticated blob v1.0")[0..8] -pub const AUTHENTICATED_BLOB_MAGIC_1_0: [u8; 8] = [31, 135, 238, 226, 145, 206, 5, 2]; - -//openssl::sha::sha256(b"Proxmox Backup zstd compressed authenticated blob v1.0")[0..8] -pub const AUTH_COMPR_BLOB_MAGIC_1_0: [u8; 8] = [126, 166, 15, 190, 145, 31, 169, 96]; - // openssl::sha::sha256(b"Proxmox Backup fixed sized chunk index v1.0")[0..8] pub const FIXED_SIZED_CHUNK_INDEX_1_0: [u8; 8] = [47, 127, 65, 237, 145, 253, 15, 205]; @@ -50,19 +44,6 @@ pub struct DataBlobHeader { pub crc: [u8; 4], } -/// Authenticated data blob binary storage format -/// -/// The ``DataBlobHeader`` for authenticated blobs additionally contains -/// a 16 byte HMAC tag, followed by the data: -/// -/// (MAGIC || CRC32 || TAG || Data). -#[derive(Endian)] -#[repr(C,packed)] -pub struct AuthenticatedDataBlobHeader { - pub head: DataBlobHeader, - pub tag: [u8; 32], -} - /// Encrypted data blob binary storage format /// /// The ``DataBlobHeader`` for encrypted blobs additionally contains @@ -87,8 +68,6 @@ pub fn header_size(magic: &[u8; 8]) -> usize { &COMPRESSED_BLOB_MAGIC_1_0 => std::mem::size_of::(), &ENCRYPTED_BLOB_MAGIC_1_0 => std::mem::size_of::(), &ENCR_COMPR_BLOB_MAGIC_1_0 => std::mem::size_of::(), - &AUTHENTICATED_BLOB_MAGIC_1_0 => std::mem::size_of::(), - &AUTH_COMPR_BLOB_MAGIC_1_0 => std::mem::size_of::(), _ => panic!("unknown blob magic"), } } diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 7d4f28fa..a5dd2146 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -263,7 +263,6 @@ pub async fn api_datastore_latest_snapshot( async fn backup_directory>( client: &BackupWriter, - crypt_mode: CryptMode, previous_manifest: Option>, dir_path: P, archive_name: &str, @@ -274,6 +273,8 @@ async fn backup_directory>( catalog: Arc>>, exclude_pattern: Vec, entries_max: usize, + compress: bool, + encrypt: bool, ) -> Result { let pxar_stream = PxarBackupStream::open( @@ -300,7 +301,7 @@ async fn backup_directory>( }); let stats = client - .upload_stream(crypt_mode, previous_manifest, archive_name, stream, "dynamic", None) + .upload_stream(previous_manifest, archive_name, stream, "dynamic", None, compress, encrypt) .await?; Ok(stats) @@ -308,12 +309,13 @@ async fn backup_directory>( async fn backup_image>( client: &BackupWriter, - crypt_mode: CryptMode, previous_manifest: Option>, image_path: P, archive_name: &str, image_size: u64, chunk_size: Option, + compress: bool, + encrypt: bool, _verbose: bool, ) -> Result { @@ -327,7 +329,7 @@ async fn backup_image>( let stream = FixedChunkStream::new(stream, chunk_size.unwrap_or(4*1024*1024)); let stats = client - .upload_stream(crypt_mode, previous_manifest, archive_name, stream, "fixed", Some(image_size)) + .upload_stream(previous_manifest, archive_name, stream, "fixed", Some(image_size), compress, encrypt) .await?; Ok(stats) @@ -638,7 +640,7 @@ async fn start_garbage_collection(param: Value) -> Result { fn spawn_catalog_upload( client: Arc, - crypt_mode: CryptMode, + encrypt: bool, ) -> Result< ( Arc>>, @@ -656,7 +658,7 @@ fn spawn_catalog_upload( tokio::spawn(async move { let catalog_upload_result = client - .upload_stream(crypt_mode, None, CATALOG_NAME, catalog_chunk_stream, "dynamic", None) + .upload_stream(None, CATALOG_NAME, catalog_chunk_stream, "dynamic", None, true, encrypt) .await; if let Err(ref err) = catalog_upload_result { @@ -986,21 +988,21 @@ async fn create_backup( BackupSpecificationType::CONFIG => { println!("Upload config file '{}' to '{:?}' as {}", filename, repo, target); let stats = client - .upload_blob_from_file(&filename, &target, true, crypt_mode) + .upload_blob_from_file(&filename, &target, true, crypt_mode == CryptMode::Encrypt) .await?; manifest.add_file(target, stats.size, stats.csum, crypt_mode)?; } BackupSpecificationType::LOGFILE => { // fixme: remove - not needed anymore ? println!("Upload log file '{}' to '{:?}' as {}", filename, repo, target); let stats = client - .upload_blob_from_file(&filename, &target, true, crypt_mode) + .upload_blob_from_file(&filename, &target, true, crypt_mode == CryptMode::Encrypt) .await?; manifest.add_file(target, stats.size, stats.csum, crypt_mode)?; } BackupSpecificationType::PXAR => { // start catalog upload on first use if catalog.is_none() { - let (cat, res) = spawn_catalog_upload(client.clone(), crypt_mode)?; + let (cat, res) = spawn_catalog_upload(client.clone(), crypt_mode == CryptMode::Encrypt)?; catalog = Some(cat); catalog_result_tx = Some(res); } @@ -1010,7 +1012,6 @@ async fn create_backup( catalog.lock().unwrap().start_directory(std::ffi::CString::new(target.as_str())?.as_c_str())?; let stats = backup_directory( &client, - crypt_mode, previous_manifest.clone(), &filename, &target, @@ -1021,6 +1022,8 @@ async fn create_backup( catalog.clone(), pattern_list.clone(), entries_max as usize, + true, + crypt_mode == CryptMode::Encrypt, ).await?; manifest.add_file(target, stats.size, stats.csum, crypt_mode)?; catalog.lock().unwrap().end_directory()?; @@ -1029,12 +1032,13 @@ async fn create_backup( println!("Upload image '{}' to '{:?}' as {}", filename, repo, target); let stats = backup_image( &client, - crypt_mode, previous_manifest.clone(), &filename, &target, size, chunk_size_opt, + true, + crypt_mode == CryptMode::Encrypt, verbose, ).await?; manifest.add_file(target, stats.size, stats.csum, crypt_mode)?; @@ -1062,7 +1066,7 @@ async fn create_backup( let target = "rsa-encrypted.key"; println!("Upload RSA encoded key to '{:?}' as {}", repo, target); let stats = client - .upload_blob_from_data(rsa_encrypted_key, target, false, CryptMode::None) + .upload_blob_from_data(rsa_encrypted_key, target, false, false) .await?; manifest.add_file(format!("{}.blob", target), stats.size, stats.csum, crypt_mode)?; @@ -1081,13 +1085,12 @@ async fn create_backup( println!("Upload index.json to '{:?}'", repo); let manifest = serde_json::to_string_pretty(&manifest)?.into(); - // manifests are never encrypted - let manifest_crypt_mode = match crypt_mode { - CryptMode::None => CryptMode::None, - _ => CryptMode::SignOnly, - }; + + // manifests are never encrypted, but include a signature + // fixme: sign manifest + client - .upload_blob_from_data(manifest, MANIFEST_BLOB_NAME, true, manifest_crypt_mode) + .upload_blob_from_data(manifest, MANIFEST_BLOB_NAME, true, false) .await?; client.finish().await?; @@ -1414,18 +1417,10 @@ async fn upload_log(param: Value) -> Result { let data = file_get_contents(logfile)?; + // fixme: howto sign log? let blob = match crypt_mode { - CryptMode::None => DataBlob::encode(&data, None, true)?, - CryptMode::Encrypt => { - DataBlob::encode(&data, crypt_config.as_ref().map(Arc::as_ref), true)? - } - CryptMode::SignOnly => DataBlob::create_signed( - &data, - crypt_config - .ok_or_else(|| format_err!("cannot sign without crypt config"))? - .as_ref(), - true, - )?, + CryptMode::None | CryptMode::SignOnly => DataBlob::encode(&data, None, true)?, + CryptMode::Encrypt => DataBlob::encode(&data, crypt_config.as_ref().map(Arc::as_ref), true)?, }; let raw_data = blob.into_inner(); diff --git a/src/client/backup_writer.rs b/src/client/backup_writer.rs index 4bfb6e6d..8cad52bb 100644 --- a/src/client/backup_writer.rs +++ b/src/client/backup_writer.rs @@ -163,17 +163,12 @@ impl BackupWriter { data: Vec, file_name: &str, compress: bool, - crypt_mode: CryptMode, + encrypt: bool, ) -> Result { - let blob = match (crypt_mode, &self.crypt_config) { - (CryptMode::None, _) => DataBlob::encode(&data, None, compress)?, - (_, None) => bail!("requested encryption/signing without a crypt config"), - (CryptMode::Encrypt, Some(crypt_config)) => { - DataBlob::encode(&data, Some(crypt_config), compress)? - } - (CryptMode::SignOnly, Some(crypt_config)) => { - DataBlob::create_signed(&data, crypt_config, compress)? - } + let blob = match (encrypt, &self.crypt_config) { + (false, _) => DataBlob::encode(&data, None, compress)?, + (true, None) => bail!("requested encryption without a crypt config"), + (true, Some(crypt_config)) => DataBlob::encode(&data, Some(crypt_config), compress)?, }; let raw_data = blob.into_inner(); @@ -190,8 +185,8 @@ impl BackupWriter { src_path: P, file_name: &str, compress: bool, - crypt_mode: CryptMode, - ) -> Result { + encrypt: bool, + ) -> Result { let src_path = src_path.as_ref(); @@ -205,17 +200,18 @@ impl BackupWriter { .await .map_err(|err| format_err!("unable to read file {:?} - {}", src_path, err))?; - self.upload_blob_from_data(contents, file_name, compress, crypt_mode).await + self.upload_blob_from_data(contents, file_name, compress, encrypt).await } pub async fn upload_stream( &self, - crypt_mode: CryptMode, previous_manifest: Option>, archive_name: &str, stream: impl Stream>, prefix: &str, fixed_size: Option, + compress: bool, + encrypt: bool, ) -> Result { let known_chunks = Arc::new(Mutex::new(HashSet::new())); @@ -224,6 +220,10 @@ impl BackupWriter { param["size"] = size.into(); } + if encrypt && self.crypt_config.is_none() { + bail!("requested encryption without a crypt config"); + } + let index_path = format!("{}_index", prefix); let close_path = format!("{}_close", prefix); @@ -249,8 +249,8 @@ impl BackupWriter { stream, &prefix, known_chunks.clone(), - self.crypt_config.clone(), - crypt_mode, + if encrypt { self.crypt_config.clone() } else { None }, + compress, self.verbose, ) .await?; @@ -476,7 +476,7 @@ impl BackupWriter { prefix: &str, known_chunks: Arc>>, crypt_config: Option>, - crypt_mode: CryptMode, + compress: bool, verbose: bool, ) -> impl Future> { @@ -507,10 +507,10 @@ impl BackupWriter { let offset = stream_len.fetch_add(chunk_len, Ordering::SeqCst) as u64; let mut chunk_builder = DataChunkBuilder::new(data.as_ref()) - .compress(true); + .compress(compress); if let Some(ref crypt_config) = crypt_config { - chunk_builder = chunk_builder.crypt_config(crypt_config, crypt_mode); + chunk_builder = chunk_builder.crypt_config(crypt_config); } let mut known_chunks = known_chunks.lock().unwrap();