feat: update dependencies, optimize

This commit is contained in:
2023-10-28 16:41:07 +08:00
parent 373b3bcefc
commit 89ed3c26ed
12 changed files with 99 additions and 65 deletions

8
Cargo.lock generated
View File

@@ -611,9 +611,9 @@ dependencies = [
[[package]] [[package]]
name = "fiat-crypto" name = "fiat-crypto"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7"
[[package]] [[package]]
name = "flagset" name = "flagset"
@@ -1378,9 +1378,9 @@ dependencies = [
[[package]] [[package]]
name = "rust_util" name = "rust_util"
version = "0.6.45" version = "0.6.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45c3036388284b69995eb2864a943b0de55de76ad5b56fc2d3c60fecd7b9ad82" checksum = "cffc8cab4e18f1320f13ac0c357b4bef1c120723885a187799440440e563f7a4"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"libc", "libc",

View File

@@ -5,11 +5,7 @@ use std::time::{Instant, SystemTime};
use clap::Args; use clap::Args;
use openpgp_card::crypto_data::Cryptogram; use openpgp_card::crypto_data::Cryptogram;
use rust_util::{ use rust_util::{debugging, failure, iff, information, opt_result, println_ex, simple_error, success, util_msg, util_size, warning, XResult};
debugging, failure, iff, information, opt_result,
println_ex, simple_error, success, util_msg,
warning, XResult,
};
use rust_util::util_time::UnixEpochTime; use rust_util::util_time::UnixEpochTime;
use x509_parser::prelude::FromDer; use x509_parser::prelude::FromDer;
use x509_parser::x509::SubjectPublicKeyInfo; use x509_parser::x509::SubjectPublicKeyInfo;
@@ -85,10 +81,10 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
succeed_count += 1; succeed_count += 1;
total_len += len; total_len += len;
success!( success!(
"Decrypt {} succeed, cost {} ms, file size {} byte(s)", "Decrypt {} succeed, cost {} ms, file size {}",
path.to_str().unwrap_or("N/A"), path.to_str().unwrap_or("N/A"),
start_decrypt_single.elapsed().as_millis(), start_decrypt_single.elapsed().as_millis(),
len util_size::get_display_size(len as i64)
); );
} }
Err(e) => { Err(e) => {
@@ -99,9 +95,9 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
} }
if (succeed_count + failed_count) > 1 { if (succeed_count + failed_count) > 1 {
success!( success!(
"Decrypt succeed {} file(s) {} byte(s), failed {} file(s), total cost {} ms", "Decrypt succeed {} file(s) {}, failed {} file(s), total cost {} ms",
succeed_count, succeed_count,
total_len, util_size::get_display_size(total_len as i64),
failed_count, failed_count,
start.elapsed().as_millis(), start.elapsed().as_millis(),
); );
@@ -120,7 +116,9 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display); let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display);
let (_, meta) = opt_result!( let (_, meta) = opt_result!(
util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display); util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display);
util_msg::when_debug(|| {
debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap()); debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap());
});
let encryption_algorithm = meta.encryption_algorithm.as_deref() let encryption_algorithm = meta.encryption_algorithm.as_deref()
.unwrap_or(consts::TINY_ENC_AES_GCM); .unwrap_or(consts::TINY_ENC_AES_GCM);
@@ -143,12 +141,12 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let key_nonce = KeyNonce { k: &key.0, n: &nonce.0 }; let key_nonce = KeyNonce { k: &key.0, n: &nonce.0 };
// debugging!("Decrypt key: {}", hex::encode(&key.0)); // debugging!("Decrypt key: {}", hex::encode(&key.0));
debugging!("Decrypt nonce: {}", hex::encode(&nonce.0)); util_msg::when_debug(|| debugging!("Decrypt nonce: {}", hex::encode(&nonce.0)));
let enc_meta = parse_encrypted_meta(&meta, cryptor, &key_nonce)?; let enc_meta = parse_encrypted_meta(&meta, cryptor, &key_nonce)?;
parse_encrypted_comment(&meta, cryptor, &key_nonce)?; parse_encrypted_comment(&meta, cryptor, &key_nonce)?;
// Decrypt to output // Decrypt to output
if cmd_decrypt.direct_print { if cmd_decrypt.direct_print {
if meta.file_length > 10 * 1024 { if meta.file_length > 10 * 1024 {
warning!("File too large(more than 10K) cannot direct print on console."); warning!("File too large(more than 10K) cannot direct print on console.");
@@ -170,7 +168,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
return Ok(meta.file_length); return Ok(meta.file_length);
} }
// Digest file // Digest file
if cmd_decrypt.digest_file { if cmd_decrypt.digest_file {
let mut digest_write = DigestWrite::from_algo(digest_algorithm)?; let mut digest_write = DigestWrite::from_algo(digest_algorithm)?;
let _ = decrypt_file( let _ = decrypt_file(
@@ -186,7 +184,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
return Ok(0); return Ok(0);
} }
// Decrypt to file // Decrypt to file
let compressed_desc = iff!(meta.compress, " [compressed]", ""); let compressed_desc = iff!(meta.compress, " [compressed]", "");
let start = Instant::now(); let start = Instant::now();
@@ -195,12 +193,12 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
&mut file_in, meta.file_length, &mut file_out, cryptor, &key_nonce, meta.compress, &mut file_in, meta.file_length, &mut file_out, cryptor, &key_nonce, meta.compress,
)?; )?;
drop(file_out); drop(file_out);
util_file::update_out_file_time(enc_meta, path_out); util_file::update_file_time(enc_meta, path_out);
let encrypt_duration = start.elapsed(); let encrypt_duration = start.elapsed();
debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis()); debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis());
if do_skip_file_out && cmd_decrypt.remove_file { util::remove_file_with_msg(path); } if do_skip_file_out & &cmd_decrypt.remove_file { util::remove_file_with_msg(path); }
Ok(meta.file_length) Ok(meta.file_length)
} }
@@ -224,7 +222,7 @@ fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write,
last_block last_block
}; };
opt_result!(file_out.write_all(&last_block), "Write file failed: {}"); opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
debugging!("Decrypt finished, total bytes: {}", total_len); debugging!("Decrypt finished, total: {} byte(s)", total_len);
progress.finish(); progress.finish();
break; break;
} else { } else {
@@ -305,8 +303,7 @@ fn try_decrypt_key_ecdh(config: &Option<TinyEncryptConfig>,
ENC_CHACHA20_POLY1305_P384 => (Cryptor::ChaCha20Poly1305, AlgorithmId::EccP384), ENC_CHACHA20_POLY1305_P384 => (Cryptor::ChaCha20Poly1305, AlgorithmId::EccP384),
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc), _ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
}; };
let e_pub_key = &wrap_key.header.e_pub_key; let e_pub_key_bytes = wrap_key.header.get_e_pub_key_bytes()?;
let e_pub_key_bytes = opt_result!(util::decode_base64_url_no_pad(e_pub_key), "Invalid envelop: {}");
let (_, subject_public_key_info) = opt_result!( let (_, subject_public_key_info) = opt_result!(
SubjectPublicKeyInfo::from_der(&e_pub_key_bytes), "Invalid envelop: {}"); SubjectPublicKeyInfo::from_der(&e_pub_key_bytes), "Invalid envelop: {}");
@@ -341,15 +338,14 @@ fn try_decrypt_key_ecdh_pgp_x25519(envelop: &TinyEncryptEnvelop, pin: &Option<St
ENC_CHACHA20_POLY1305_X25519 => Cryptor::ChaCha20Poly1305, ENC_CHACHA20_POLY1305_X25519 => Cryptor::ChaCha20Poly1305,
_ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc), _ => return simple_error!("Unsupported header enc: {}", &wrap_key.header.enc),
}; };
let e_pub_key = &wrap_key.header.e_pub_key; let e_pub_key_bytes = wrap_key.header.get_e_pub_key_bytes()?;
let epk_bytes = opt_result!(util::decode_base64_url_no_pad(e_pub_key), "Invalid envelop: {}");
let mut pgp = util_pgp::get_openpgp()?; let mut pgp = util_pgp::get_openpgp()?;
let mut trans = opt_result!(pgp.transaction(), "Connect PIV card failed: {}"); let mut trans = opt_result!(pgp.transaction(), "Connect PIV card failed: {}");
util_pgp::read_and_verify_openpgp_pin(&mut trans, pin)?; util_pgp::read_and_verify_openpgp_pin(&mut trans, pin)?;
let shared_secret = trans.decipher(Cryptogram::ECDH(&epk_bytes))?; let shared_secret = trans.decipher(Cryptogram::ECDH(&e_pub_key_bytes))?;
let key = util::simple_kdf(shared_secret.as_slice()); let key = util::simple_kdf(shared_secret.as_slice());
let key_nonce = KeyNonce { k: &key, n: &wrap_key.nonce }; let key_nonce = KeyNonce { k: &key, n: &wrap_key.nonce };

View File

@@ -7,7 +7,7 @@ use std::time::Instant;
use clap::Args; use clap::Args;
use flate2::Compression; use flate2::Compression;
use rsa::Pkcs1v15Encrypt; use rsa::Pkcs1v15Encrypt;
use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, XResult}; use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, util_size, XResult};
use rust_util::util_time::UnixEpochTime; use rust_util::util_time::UnixEpochTime;
use crate::{crypto_cryptor, crypto_simple, util, util_enc_file, util_env, util_p256, util_p384, util_x25519}; use crate::{crypto_cryptor, crypto_simple, util, util_enc_file, util_env, util_p256, util_p384, util_x25519};
@@ -194,7 +194,7 @@ fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cr
None => GzStreamEncoder::new_default(), None => GzStreamEncoder::new_default(),
Some(compress_level) => { Some(compress_level) => {
if *compress_level > 9 { if *compress_level > 9 {
return simple_error!("Compress level must in range [0, 9]"); return simple_error!("Compress level must be in range [0, 9]");
} }
GzStreamEncoder::new(Compression::new(*compress_level)) GzStreamEncoder::new(Compression::new(*compress_level))
} }
@@ -221,10 +221,12 @@ fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut impl Write, cr
}; };
opt_result!(file_out.write_all(&last_block_and_tag), "Write file failed: {}"); opt_result!(file_out.write_all(&last_block_and_tag), "Write file failed: {}");
progress.finish(); progress.finish();
debugging!("Encrypt finished, total bytes: {}", total_len); debugging!("Encrypt finished, total bytes: {} byte(s)", total_len);
if compress { if compress {
information!("File is compressed: {} byte(s) -> {} byte(s), ratio: {}%", information!("File is compressed: {} -> {}, ratio: {}%",
total_len, write_len, util::ratio(write_len, total_len)); util_size::get_display_size(total_len as i64),
util_size::get_display_size(write_len as i64),
util::ratio(write_len, total_len));
} }
break; break;
} else { } else {
@@ -309,11 +311,7 @@ fn encrypt_envelop_shared_secret(cryptor: Cryptor,
cryptor, &key_nonce, key)?; cryptor, &key_nonce, key)?;
let wrap_key = WrapKey { let wrap_key = WrapKey {
header: WrapKeyHeader { header: WrapKeyHeader::from(enc_type, ephemeral_spki),
kid: None,
enc: enc_type.to_string(),
e_pub_key: util::encode_base64_url_no_pad(ephemeral_spki),
},
nonce: nonce.0.clone(), nonce: nonce.0.clone(),
encrypted_data: encrypted_key, encrypted_data: encrypted_key,
}; };

View File

@@ -8,7 +8,6 @@ use rust_util::{
debugging, failure, iff, opt_result, simple_error, success, debugging, failure, iff, opt_result, simple_error, success,
util_msg, util_size, util_time, XResult, util_msg, util_size, util_time, XResult,
}; };
use rust_util::util_msg::MessageType;
use rust_util::util_time::UnixEpochTime; use rust_util::util_time::UnixEpochTime;
use simpledateformat::format_human2; use simpledateformat::format_human2;
@@ -97,7 +96,7 @@ pub fn info_single(path: &PathBuf, cmd_info: &CmdInfo) -> XResult<()> {
header(&format!("Envelop #{}", i + 1)), header(&format!("Envelop #{}", i + 1)),
util_envelop::format_envelop(envelop, &config) util_envelop::format_envelop(envelop, &config)
)); ));
util_msg::when(MessageType::DEBUG, || { util_msg::when_debug(|| {
if let Ok(wrap_key) = WrapKey::parse(&envelop.encrypted_key) { if let Ok(wrap_key) = WrapKey::parse(&envelop.encrypted_key) {
debugging!("Wrap key: {}", serde_json::to_string(&wrap_key).expect("SHOULD NOT HAPPEN")); debugging!("Wrap key: {}", serde_json::to_string(&wrap_key).expect("SHOULD NOT HAPPEN"));
} }

View File

@@ -74,14 +74,16 @@ fn get_encryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Encry
match crypto { match crypto {
Cryptor::Aes256Gcm => { Cryptor::Aes256Gcm => {
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}"); let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
let aes256_gcm_stream_encryptor = Aes256GcmStreamEncryptor::new(key, key_nonce.n); let aes256_gcm_stream_encryptor = Aes256GcmStreamEncryptor::new(
key, key_nonce.n);
key.zeroize(); key.zeroize();
Ok(Box::new(Aes256GcmEncryptor { Ok(Box::new(Aes256GcmEncryptor {
aes256_gcm_stream_encryptor, aes256_gcm_stream_encryptor,
})) }))
} }
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Encryptor { Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Encryptor {
chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(key_nonce.k, key_nonce.n)?, chacha20_poly1305_stream_encryptor: ChaCha20Poly1305StreamEncryptor::new(
key_nonce.k, key_nonce.n)?,
})) }))
} }
} }
@@ -90,14 +92,16 @@ fn get_decryptor(crypto: Cryptor, key_nonce: &KeyNonce) -> XResult<Box<dyn Decry
match crypto { match crypto {
Cryptor::Aes256Gcm => { Cryptor::Aes256Gcm => {
let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}"); let mut key: [u8; 32] = opt_result!(key_nonce.k.try_into(), "Bad AES 256 key: {}");
let aes256_gcm_stream_decryptor = Aes256GcmStreamDecryptor::new(key, key_nonce.n); let aes256_gcm_stream_decryptor = Aes256GcmStreamDecryptor::new(
key, key_nonce.n);
key.zeroize(); key.zeroize();
Ok(Box::new(Aes256GcmDecryptor { Ok(Box::new(Aes256GcmDecryptor {
aes256_gcm_stream_decryptor, aes256_gcm_stream_decryptor,
})) }))
} }
Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Decryptor { Cryptor::ChaCha20Poly1305 => Ok(Box::new(ChaCha20Poly1305Decryptor {
chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(key_nonce.k, key_nonce.n)?, chacha20_poly1305_stream_decryptor: ChaCha20Poly1305StreamDecryptor::new(
key_nonce.k, key_nonce.n)?,
})) }))
} }
} }

View File

@@ -96,7 +96,7 @@ pub fn make_key256_and_nonce() -> (SecVec, SecVec) {
pub fn simple_kdf(input: &[u8]) -> Vec<u8> { pub fn simple_kdf(input: &[u8]) -> Vec<u8> {
let mut input = input.to_vec(); let mut input = input.to_vec();
for _ in 0..8 { for _ in 0..8 {
let mut sha256 = DigestWrite::sha256().expect("SHOULD NOT HAPPEN"); let mut sha256 = DigestWrite::sha256();
sha256.write_all(&input).expect("SHOULD NOT HAPPEN"); sha256.write_all(&input).expect("SHOULD NOT HAPPEN");
input = sha256.digest(); input = sha256.digest();
} }

View File

@@ -33,8 +33,8 @@ impl DigestWrite {
} }
} }
pub fn sha256() -> XResult<Self> { pub fn sha256() -> Self {
Ok(Self { digest: Box::new(Sha256::new()) }) Self { digest: Box::new(Sha256::new()) }
} }
pub fn digest(self) -> Vec<u8> { pub fn digest(self) -> Vec<u8> {

View File

@@ -46,7 +46,7 @@ pub fn read_tiny_encrypt_meta(r: &mut impl Read) -> XResult<(u32, TinyEncryptMet
return simple_error!("Meta too large: {}", length); return simple_error!("Meta too large: {}", length);
} }
debugging!("Encrypted meta len: {}", length); debugging!("Encrypted meta length: {}", length);
let mut meta_buff = vec![0; length as usize]; let mut meta_buff = vec![0; length as usize];
opt_result!(r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}"); opt_result!(r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}");

View File

@@ -7,6 +7,7 @@ use crate::consts;
pub const TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM: &str = "TINY_ENCRYPT_DEFAULT_ALGORITHM"; pub const TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM: &str = "TINY_ENCRYPT_DEFAULT_ALGORITHM";
pub const TINY_ENCRYPT_ENV_DEFAULT_COMPRESS: &str = "TINY_ENCRYPT_DEFAULT_COMPRESS"; pub const TINY_ENCRYPT_ENV_DEFAULT_COMPRESS: &str = "TINY_ENCRYPT_DEFAULT_COMPRESS";
pub const TINY_ENCRYPT_ENV_NO_PROGRESS: &str = "TINY_ENCRYPT_NO_PROGRESS";
pub fn get_default_encryption_algorithm() -> Option<&'static str> { pub fn get_default_encryption_algorithm() -> Option<&'static str> {
let env_default_algorithm = env::var(TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok(); let env_default_algorithm = env::var(TINY_ENCRYPT_ENV_DEFAULT_ALGORITHM).ok();
@@ -25,3 +26,7 @@ pub fn get_default_encryption_algorithm() -> Option<&'static str> {
pub fn get_default_compress() -> Option<bool> { pub fn get_default_compress() -> Option<bool> {
iff!(rust_util_env::is_env_off(TINY_ENCRYPT_ENV_DEFAULT_COMPRESS), Some(true), None) iff!(rust_util_env::is_env_off(TINY_ENCRYPT_ENV_DEFAULT_COMPRESS), Some(true), None)
} }
pub fn get_no_progress() -> bool {
rust_util_env::is_env_on(TINY_ENCRYPT_ENV_NO_PROGRESS)
}

View File

@@ -6,13 +6,13 @@ use rust_util::util_time::UnixEpochTime;
use crate::spec::EncEncryptedMeta; use crate::spec::EncEncryptedMeta;
pub fn update_out_file_time(enc_meta: Option<EncEncryptedMeta>, path_out: &str) { pub fn update_file_time(enc_meta: Option<EncEncryptedMeta>, path: &str) {
if let Some(enc_meta) = &enc_meta { if let Some(enc_meta) = &enc_meta {
let create_time = enc_meta.c_time.map(SystemTime::from_millis); let create_time = enc_meta.c_time.map(SystemTime::from_millis);
let modify_time = enc_meta.m_time.map(SystemTime::from_millis); let modify_time = enc_meta.m_time.map(SystemTime::from_millis);
if create_time.is_some() || modify_time.is_some() { if create_time.is_some() || modify_time.is_some() {
let set_times_result = fs_set_times::set_times( let set_times_result = fs_set_times::set_times(
path_out, path,
create_time.map(SystemTimeSpec::Absolute), create_time.map(SystemTimeSpec::Absolute),
modify_time.map(SystemTimeSpec::Absolute), modify_time.map(SystemTimeSpec::Absolute),
); );

View File

@@ -1,28 +1,46 @@
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use rust_util::{debugging, util_msg};
use crate::util_env;
const PB_PROGRESS: &str = "#-"; const PB_PROGRESS: &str = "#-";
const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} {bytes_per_sec} ({eta})"; const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} {bytes_per_sec} ({eta})";
pub struct Progress { pub enum Progress {
progress_bar: ProgressBar, NoProgress,
Progress(ProgressBar),
} }
impl Progress { impl Progress {
pub fn new(total: u64) -> Self { pub fn new(total: u64) -> Self {
let no_progress = util_env::get_no_progress();
let is_atty = util_msg::is_atty();
if no_progress || !is_atty {
debugging!("No progress: [{}, {}]", no_progress, is_atty);
Self::NoProgress
} else {
let progress_bar = ProgressBar::new(total); let progress_bar = ProgressBar::new(total);
progress_bar.set_style(ProgressStyle::default_bar() progress_bar.set_style(ProgressStyle::default_bar()
.template(PB_TEMPLATE).expect("SHOULD NOT FAIL") .template(PB_TEMPLATE).expect("SHOULD NOT FAIL")
.progress_chars(PB_PROGRESS) .progress_chars(PB_PROGRESS)
); );
Self { progress_bar } Self::Progress(progress_bar)
}
} }
pub fn position(&self, position: u64) { pub fn position(&self, position: u64) {
self.progress_bar.set_position(position) match self {
Progress::NoProgress => {}
Progress::Progress(progress_bar) => progress_bar.set_position(position),
}
} }
pub fn finish(&self) { pub fn finish(&self) {
self.progress_bar.finish_and_clear() match self {
Progress::NoProgress => {}
Progress::Progress(progress_bar) => progress_bar.finish_and_clear(),
}
} }
} }

View File

@@ -1,7 +1,7 @@
use rust_util::{opt_result, simple_error, XResult}; use rust_util::{opt_result, simple_error, XResult};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::util::{decode_base64_url_no_pad, encode_base64_url_no_pad}; use crate::util;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@@ -20,17 +20,31 @@ pub struct WrapKeyHeader {
pub e_pub_key: String, pub e_pub_key: String,
} }
impl WrapKeyHeader {
pub fn from(enc_type: &str, ephemeral_spki: &[u8]) -> Self {
WrapKeyHeader {
kid: None,
enc: enc_type.to_string(),
e_pub_key: util::encode_base64_url_no_pad(ephemeral_spki),
}
}
pub fn get_e_pub_key_bytes(self) -> XResult<Vec<u8>> {
Ok(opt_result!(util::decode_base64_url_no_pad(&self.e_pub_key), "Invalid envelop e_pub_key: {}"))
}
}
impl WrapKey { impl WrapKey {
pub fn encode(&self) -> XResult<String> { pub fn encode(&self) -> XResult<String> {
let mut buf = String::with_capacity(512); let mut buf = String::with_capacity(512);
buf.push_str("WK:"); buf.push_str("WK:");
let header = serde_json::to_string(&self.header)?; let header = serde_json::to_string(&self.header)?;
let header_str = encode_base64_url_no_pad(header.as_bytes()); let header_str = util::encode_base64_url_no_pad(header.as_bytes());
buf.push_str(&header_str); buf.push_str(&header_str);
buf.push('.'); buf.push('.');
buf.push_str(&encode_base64_url_no_pad(&self.nonce)); buf.push_str(&util::encode_base64_url_no_pad(&self.nonce));
buf.push('.'); buf.push('.');
buf.push_str(&encode_base64_url_no_pad(&self.encrypted_data)); buf.push_str(&util::encode_base64_url_no_pad(&self.encrypted_data));
Ok(buf) Ok(buf)
} }
@@ -43,13 +57,13 @@ impl WrapKey {
return simple_error!("Invalid wrap key."); return simple_error!("Invalid wrap key.");
} }
let header = wks[0].chars().skip(3).collect::<String>(); let header = wks[0].chars().skip(3).collect::<String>();
let header_bytes = opt_result!(decode_base64_url_no_pad(&header), "Invalid wrap key header: {}"); let header_bytes = opt_result!(util::decode_base64_url_no_pad(&header), "Invalid wrap key header: {}");
let nonce = wks[1]; let nonce = wks[1];
let encrypted_data = wks[2]; let encrypted_data = wks[2];
let header_str = opt_result!(String::from_utf8(header_bytes), "Invalid wrap key header: {}"); let header_str = opt_result!(String::from_utf8(header_bytes), "Invalid wrap key header: {}");
let header: WrapKeyHeader = opt_result!(serde_json::from_str(&header_str), "Invalid wrap key header: {}"); let header: WrapKeyHeader = opt_result!(serde_json::from_str(&header_str), "Invalid wrap key header: {}");
let nonce = opt_result!(decode_base64_url_no_pad(nonce), "Invalid wrap key: {}"); let nonce = opt_result!(util::decode_base64_url_no_pad(nonce), "Invalid wrap key: {}");
let encrypted_data = opt_result!(decode_base64_url_no_pad(encrypted_data), "Invalid wrap key: {}"); let encrypted_data = opt_result!(util::decode_base64_url_no_pad(encrypted_data), "Invalid wrap key: {}");
Ok(WrapKey { Ok(WrapKey {
header, header,
nonce, nonce,