use OpenPGPTool encrypt file
This commit is contained in:
@@ -2,7 +2,10 @@ extern crate sequoia_openpgp as openpgp;
|
||||
use crate::openpgp::armor;
|
||||
use std::{
|
||||
fs::File,
|
||||
path::Path,
|
||||
io::{
|
||||
ErrorKind,
|
||||
Read,
|
||||
Write,
|
||||
BufWriter,
|
||||
},
|
||||
@@ -22,25 +25,37 @@ use openpgp::{
|
||||
LiteralWriter,
|
||||
},
|
||||
};
|
||||
use indicatif::{
|
||||
ProgressBar,
|
||||
ProgressStyle
|
||||
};
|
||||
|
||||
pub struct OpenPGPClient {
|
||||
const BUFF_SIZE: usize = 512 * 1024;
|
||||
const PB_PROGRESS: &str = "#-";
|
||||
const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})";
|
||||
|
||||
pub struct OpenPGPTool {
|
||||
pub tpk: TPK,
|
||||
}
|
||||
|
||||
impl OpenPGPClient {
|
||||
pub fn from_file(file: &str) -> XResult<OpenPGPClient> {
|
||||
Ok(OpenPGPClient{
|
||||
impl OpenPGPTool {
|
||||
pub fn from_file(file: &str) -> XResult<OpenPGPTool> {
|
||||
Ok(OpenPGPTool{
|
||||
tpk: TPK::from_file(std::path::Path::new(file))?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_bytes(bs: &[u8]) -> XResult<OpenPGPClient> {
|
||||
Ok(OpenPGPClient{
|
||||
pub fn from_bytes(bs: &[u8]) -> XResult<OpenPGPTool> {
|
||||
Ok(OpenPGPTool{
|
||||
tpk: TPK::from_bytes(&bs)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encrypt_file(&self, from_file: &str, to_file: &str, armor: bool) -> XResult<()> {
|
||||
if Path::new(to_file).exists() {
|
||||
return Err(new_box_error(&format!("To file exists: {}", to_file)));
|
||||
}
|
||||
|
||||
let recipient: Recipient = match self.tpk.keys_valid()
|
||||
.key_flags(KeyFlags::default().set_encrypt_at_rest(true).set_encrypt_for_transport(true))
|
||||
.map(|(_, _, key)| key.into())
|
||||
@@ -51,15 +66,36 @@ impl OpenPGPClient {
|
||||
let message = if armor {
|
||||
Message::new(armor::Writer::new(std::io::stdout(), armor::Kind::Message, &[])?)
|
||||
} else {
|
||||
Message::new(BufWriter::new(File::open(to_file)?))
|
||||
Message::new(BufWriter::new(File::create(to_file)?))
|
||||
};
|
||||
let encryptor = Encryptor::for_recipient(message, recipient).build()?;
|
||||
let mut pgp_encrypt_writer = LiteralWriter::new(encryptor).build()?;
|
||||
// TODO read from from_file
|
||||
pgp_encrypt_writer.write_all(b"Hello world.")?;
|
||||
let mut from = File::open(from_file)?;
|
||||
encrypt_read_write(&mut from, &mut pgp_encrypt_writer)?;
|
||||
pgp_encrypt_writer.finalize()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt_read_write(file: &mut File, write: &mut dyn Write) -> XResult<()> {
|
||||
let mut buf: [u8; BUFF_SIZE] = [0u8; BUFF_SIZE];
|
||||
let file_len = file.metadata()?.len();
|
||||
let mut read = 0_u64;
|
||||
|
||||
let pb = ProgressBar::new(file_len);
|
||||
pb.set_style(ProgressStyle::default_bar().template(PB_TEMPLATE).progress_chars(PB_PROGRESS));
|
||||
|
||||
loop {
|
||||
let len = match file.read(&mut buf) {
|
||||
Ok(0) => { pb.finish_and_clear(); return Ok(()); },
|
||||
Ok(len) => len,
|
||||
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
|
||||
Err(e) => return Err(Box::new(e)),
|
||||
};
|
||||
write.write(&buf[..len])?;
|
||||
read += len as u64;
|
||||
pb.set_position(read);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user