feat: add pgp card
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
*.tinyenc
|
||||
# ---> Rust
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
|
||||
1362
Cargo.lock
generated
1362
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@@ -9,8 +9,18 @@ description = "A simple and tiny file encrypt tool"
|
||||
|
||||
[dependencies]
|
||||
aes-gcm = { version = "0.10.1", features = ["zeroize"] }
|
||||
base64 = "0.21.0"
|
||||
clap = { version = "4.1.4", features = ["derive"] }
|
||||
hex = "0.4.3"
|
||||
openpgp-card = "0.3.3"
|
||||
openpgp-card-pcsc = "0.3.0"
|
||||
reqwest = { version = "0.11.14", features = ["blocking", "rustls", "rustls-tls"] }
|
||||
rust_util = "0.6.41"
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = "1.0.93"
|
||||
yubico_manager = "0.9.0"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
|
||||
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