feat: add pgp card
This commit is contained in:
13
src/card.rs
Normal file
13
src/card.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use openpgp_card_pcsc::PcscBackend;
|
||||
use rust_util::{opt_result, opt_value_result, simple_error, warning, XResult};
|
||||
|
||||
pub fn get_card() -> XResult<PcscBackend> {
|
||||
let card_list = opt_result!(PcscBackend::cards(None), "Read OpenPGP card list failed: {}");
|
||||
if card_list.is_empty() {
|
||||
return simple_error!("Cannot find any card");
|
||||
}
|
||||
if card_list.len() > 1 {
|
||||
warning!("Find {} OpenPGP cards, will use first card", card_list.len());
|
||||
}
|
||||
Ok(opt_value_result!(card_list.into_iter().next(), "SHOULD NOT HAPPEN, CANNOT FIND ANY CARD"))
|
||||
}
|
||||
43
src/cmd_decrypt.rs
Normal file
43
src/cmd_decrypt.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use std::path::PathBuf;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose;
|
||||
use openpgp_card::crypto_data::Cryptogram;
|
||||
use openpgp_card::OpenPgp;
|
||||
use rust_util::{debugging, failure, opt_result, simple_error, success, XResult};
|
||||
use crate::card::get_card;
|
||||
use crate::file;
|
||||
|
||||
pub fn decrypt(path: PathBuf, pin: &Option<String>) -> XResult<()> {
|
||||
let path_display = format!("{}", path.display());
|
||||
let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display);
|
||||
let meta = opt_result!(file::read_tiny_encrypt_meta(&mut file_in), "Read file: {}, failed: {}", &path_display);
|
||||
|
||||
let mut card = match get_card() {
|
||||
Err(e) => {
|
||||
failure!("Get PGP card failed: {}", e);
|
||||
return simple_error!("Get card failed: {}", e);
|
||||
}
|
||||
Ok(card) => card
|
||||
};
|
||||
let mut pgp = OpenPgp::new(card);
|
||||
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
|
||||
|
||||
let pin = pin.as_ref().map(|s| s.as_str()).unwrap_or_else(|| "123456");
|
||||
if let Err(e) = trans.verify_pw1_user(pin.as_ref()) {
|
||||
failure!("Verify user pin failed: {}", e);
|
||||
return simple_error!("User pin verify failed: {}", e);
|
||||
}
|
||||
success!("User pin verify success!");
|
||||
|
||||
let pgp_envelop = meta.pgp_envelop.unwrap();
|
||||
debugging!("PGP envelop: {}", &pgp_envelop);
|
||||
let pgp_envelop_bytes = opt_result!(general_purpose::STANDARD.decode(&pgp_envelop), "Decode PGP envelop failed: {}");
|
||||
|
||||
let key = trans.decipher(Cryptogram::RSA(&pgp_envelop_bytes))?;
|
||||
|
||||
success!("{}", hex::encode(&key));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -7,7 +7,6 @@ pub fn info(path: PathBuf) -> XResult<()> {
|
||||
let path_display = format!("{}", path.display());
|
||||
let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display);
|
||||
let meta = opt_result!(file::read_tiny_encrypt_meta(&mut file_in), "Read file: {}, failed: {}", &path_display);
|
||||
// println!("{}", serde_json::to_string_pretty(&meta).expect("SHOULD NOT HAPPEN"));
|
||||
|
||||
let mut infos = vec![];
|
||||
infos.push("Tiny Encrypt File Info".to_string());
|
||||
|
||||
@@ -9,7 +9,9 @@ use rust_util::{information, XResult};
|
||||
mod spec;
|
||||
mod crypto;
|
||||
mod file;
|
||||
mod card;
|
||||
mod cmd_info;
|
||||
mod cmd_decrypt;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "tiny-encrypt-rs")]
|
||||
@@ -47,7 +49,10 @@ fn main() -> XResult<()> {
|
||||
paths.iter().for_each(|f| information!("{:?}", f));
|
||||
Ok(())
|
||||
}
|
||||
Commands::Decrypt { .. } => {
|
||||
Commands::Decrypt { mut paths } => {
|
||||
for path in paths {
|
||||
cmd_decrypt::decrypt(path, &Some("123456".to_string())).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Commands::Info { path } => {
|
||||
|
||||
Reference in New Issue
Block a user