From 9f46c7de4b20f3467bb8a101a365432f080bca34 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 24 Jun 2019 13:56:37 +0200 Subject: [PATCH] src/bin/proxmox-backup-client.rs: upload rsa encoded key after backup --- src/backup/crypt_config.rs | 13 +++++++++++ src/bin/proxmox-backup-client.rs | 37 +++++++++++++++++++++++++++----- src/client/http_client.rs | 31 +++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/backup/crypt_config.rs b/src/backup/crypt_config.rs index d49335a6..e22ffbce 100644 --- a/src/backup/crypt_config.rs +++ b/src/backup/crypt_config.rs @@ -167,4 +167,17 @@ impl CryptConfig { Ok(decr_data) } + + pub fn generate_rsa_encoded_key( + &self, + rsa: openssl::rsa::Rsa, + ) -> Result, Error> { + + let mut buffer = vec![0u8; rsa.size() as usize]; + let len = rsa.public_encrypt(&self.enc_key, &mut buffer, openssl::rsa::Padding::PKCS1)?; + if len != buffer.len() { + bail!("got unexpected length from rsa.public_encrypt()."); + } + Ok(buffer) + } } diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index f4386e6f..da76c20d 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -482,7 +482,7 @@ fn create_backup( match backup_type { BackupType::CONFIG => { println!("Upload config file '{}' to '{:?}' as {}", filename, repo, target); - client.upload_blob(&filename, &target, crypt_config.clone(), true).wait()?; + client.upload_blob_from_file(&filename, &target, crypt_config.clone(), true).wait()?; } BackupType::PXAR => { println!("Upload directory '{}' to '{:?}' as {}", filename, repo, target); @@ -511,6 +511,27 @@ fn create_backup( } } + if let Some(crypt_config) = crypt_config { + let path = master_pubkey_path()?; + if path.exists() { + let pem_data = proxmox_backup::tools::file_get_contents(&path)?; + let rsa = openssl::rsa::Rsa::public_key_from_pem(&pem_data)?; + let enc_key = crypt_config.generate_rsa_encoded_key(rsa)?; + let target = "rsa-encoded.key"; + println!("Upload RSA encoded key to '{:?}' as {}", repo, target); + client.upload_blob_from_data(enc_key, target, None, false).wait()?; + + // openssl rsautl -decrypt -inkey master-private.pem -in mtest.enckey -out t + /* + let mut buffer2 = vec![0u8; rsa.size() as usize]; + let pem_data = proxmox_backup::tools::file_get_contents("master-private.pem")?; + let rsa = openssl::rsa::Rsa::private_key_from_pem(&pem_data)?; + let len = rsa.private_decrypt(&buffer, &mut buffer2, openssl::rsa::Padding::PKCS1)?; + println!("TEST {} {:?}", len, buffer2); + */ + } + } + client.finish().wait()?; let end_time = Local.timestamp(Local::now().timestamp(), 0); @@ -853,6 +874,15 @@ fn key_create( } } +fn master_pubkey_path() -> Result { + let base = BaseDirectories::with_prefix("proxmox-backup")?; + + // usually $HOME/.config/proxmox-backup/master-public.pem + let path = base.place_config_file("master-public.pem")?; + + Ok(path) +} + fn key_import_master_pubkey( param: Value, _info: &ApiMethod, @@ -868,10 +898,7 @@ fn key_import_master_pubkey( bail!("Unable to decode PEM data - {}", err); } - let base = BaseDirectories::with_prefix("proxmox-backup")?; - - // usually $HOME/.config/proxmox-backup/master-public.pem - let target_path = base.place_config_file("master-public.pem")?; + let target_path = master_pubkey_path()?; proxmox_backup::tools::file_set_contents(&target_path, &pem_data, None)?; diff --git a/src/client/http_client.rs b/src/client/http_client.rs index c3006d74..61d98ca7 100644 --- a/src/client/http_client.rs +++ b/src/client/http_client.rs @@ -452,7 +452,36 @@ impl BackupClient { self.canceller.take().unwrap().cancel(); } - pub fn upload_blob>( + pub fn upload_blob_from_data( + &self, + data: Vec, + file_name: &str, + crypt_config: Option>, + compress: bool, + ) -> impl Future { + + let h2 = self.h2.clone(); + let file_name = file_name.to_owned(); + + futures::future::ok(()) + .and_then(move |_| { + let blob = if let Some(ref crypt_config) = crypt_config { + DataBlob::encode(&data, Some(crypt_config), compress)? + } else { + DataBlob::encode(&data, None, compress)? + }; + + let raw_data = blob.into_inner(); + Ok(raw_data) + }) + .and_then(move |raw_data| { + let param = json!({"encoded-size": raw_data.len(), "file-name": file_name }); + h2.upload("blob", Some(param), raw_data) + .map(|_| {}) + }) + } + + pub fn upload_blob_from_file>( &self, src_path: P, file_name: &str,