feat: v1.9.6
This commit is contained in:
@@ -6,7 +6,7 @@ use rust_util::{util_msg, XResult};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
|
||||
use crate::pgpcardutil;
|
||||
use crate::util::{base64_encode, try_decode};
|
||||
use crate::util::{base64_encode, read_stdin, try_decode};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum EncryptAlgo {
|
||||
@@ -34,6 +34,7 @@ impl Command for CommandImpl {
|
||||
.arg(Arg::with_name("pin").short("p").long("pin").takes_value(true).default_value("123456").help("OpenPGP card user pin"))
|
||||
.arg(Arg::with_name("pass").long("pass").takes_value(true).help("[deprecated] now OpenPGP card user pin"))
|
||||
.arg(Arg::with_name("ciphertext").short("c").long("ciphertext").takes_value(true).help("Cipher text (HEX or Base64)"))
|
||||
.arg(Arg::with_name("stdin").long("stdin").help("Standard input (Ciphertext)"))
|
||||
.arg(Arg::with_name("algo").long("algo").takes_value(true).help("Algo: RSA, X25519/ECDH"))
|
||||
.arg(Arg::with_name("json").long("json").help("JSON output"))
|
||||
}
|
||||
@@ -53,6 +54,8 @@ impl Command for CommandImpl {
|
||||
|
||||
let ciphertext_bytes = if let Some(ciphertext) = ciphertext {
|
||||
opt_result!(try_decode(ciphertext), "Decode cipher failed: {}")
|
||||
} else if sub_arg_matches.is_present("stdin") {
|
||||
read_stdin()?
|
||||
} else {
|
||||
return simple_error!("--ciphertext must be assigned");
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ use yubikey::piv::AlgorithmId;
|
||||
use yubikey::YubiKey;
|
||||
|
||||
use crate::pivutil;
|
||||
use crate::util::try_decode;
|
||||
use crate::util::{read_stdin, try_decode};
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -19,6 +19,7 @@ impl Command for CommandImpl {
|
||||
.arg(Arg::with_name("slot").short("s").long("slot").takes_value(true).help("PIV slot, e.g. 82, 83 ... 95, 9a, 9c, 9d, 9e"))
|
||||
.arg(Arg::with_name("pin").short("p").long("pin").takes_value(true).default_value("123456").help("OpenPGP card user pin"))
|
||||
.arg(Arg::with_name("ciphertext").long("ciphertext").short("c").takes_value(true).help("Encrypted data (HEX or Base64)"))
|
||||
.arg(Arg::with_name("stdin").long("stdin").help("Standard input (Ciphertext)"))
|
||||
.arg(Arg::with_name("json").long("json").help("JSON output"))
|
||||
}
|
||||
|
||||
@@ -33,6 +34,8 @@ impl Command for CommandImpl {
|
||||
|
||||
let encrypted_data = if let Some(ciphertext) = sub_arg_matches.value_of("ciphertext") {
|
||||
opt_result!(try_decode(ciphertext), "Decode --ciphertext failed: {}")
|
||||
} else if sub_arg_matches.is_present("stdin") {
|
||||
read_stdin()?
|
||||
} else {
|
||||
return simple_error!("Argument --ciphertext must be assigned");
|
||||
};
|
||||
|
||||
@@ -9,6 +9,8 @@ use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::util_msg;
|
||||
use rust_util::util_msg::MessageType;
|
||||
|
||||
use crate::util::{read_stdin, try_decode};
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
// https://docs.rs/openssl/0.10.36/openssl/encrypt/index.html
|
||||
@@ -19,6 +21,8 @@ impl Command for CommandImpl {
|
||||
SubCommand::with_name(self.name()).about("RSA decrypt subcommand")
|
||||
.arg(Arg::with_name("pri-key-in").long("pri-key-in").takes_value(true).help("Private key in"))
|
||||
.arg(Arg::with_name("encrypted").long("encrypted").takes_value(true).help("Encrypted data"))
|
||||
.arg(Arg::with_name("ciphertext").long("ciphertext").takes_value(true).help("Encrypted data"))
|
||||
.arg(Arg::with_name("stdin").long("stdin").help("Standard input (Ciphertext)"))
|
||||
.arg(Arg::with_name("padding").long("padding").takes_value(true)
|
||||
.possible_values(&["pkcs1", "oaep", "pss", "none"]).help("Padding"))
|
||||
.arg(Arg::with_name("json").long("json").help("JSON output"))
|
||||
@@ -40,17 +44,21 @@ impl Command for CommandImpl {
|
||||
let keypair = opt_result!(Rsa::private_key_from_pem(&pri_key_bytes), "Parse RSA failed: {}");
|
||||
let keypair = opt_result!(PKey::from_rsa(keypair), "RSA to PKey failed: {}");
|
||||
|
||||
let encrypted = if let Some(encrypted) = sub_arg_matches.value_of("encrypted") {
|
||||
opt_result!(hex::decode(encrypted), "Decode encrypted HEX failed: {}")
|
||||
let ciphertext_opt = sub_arg_matches.value_of("encrypted")
|
||||
.or_else(|| sub_arg_matches.value_of("ciphertext"));
|
||||
let ciphertext = if let Some(ciphertext) = ciphertext_opt {
|
||||
opt_result!(try_decode(ciphertext), "Decode ciphertext HEX or Base64 failed: {}")
|
||||
} else if sub_arg_matches.is_present("stdin") {
|
||||
read_stdin()?
|
||||
} else {
|
||||
return simple_error!("Data is required, --data-hex or --data argument!");
|
||||
return simple_error!("Data is required, --ciphertext or --encrypted argument!");
|
||||
};
|
||||
|
||||
util_msg::when(MessageType::DEBUG, || {
|
||||
let rsa = keypair.rsa().unwrap();
|
||||
let n = rsa.n();
|
||||
let d = rsa.d();
|
||||
let m = BigNum::from_slice(&encrypted).unwrap();
|
||||
let m = BigNum::from_slice(&ciphertext).unwrap();
|
||||
let mut r = BigNum::new().unwrap();
|
||||
r.mod_exp(&m, d, n, &mut BigNumContext::new().unwrap()).unwrap();
|
||||
let v = r.to_vec();
|
||||
@@ -63,12 +71,12 @@ impl Command for CommandImpl {
|
||||
|
||||
let mut decrypter = opt_result!(Decrypter::new(&keypair), "Decrypter new failed: {}");
|
||||
opt_result!(decrypter.set_rsa_padding(padding), "Set RSA padding failed: {}");
|
||||
let buffer_len = opt_result!(decrypter.decrypt_len(&encrypted), "Decrypt len failed: {}");
|
||||
let buffer_len = opt_result!(decrypter.decrypt_len(&ciphertext), "Decrypt len failed: {}");
|
||||
let mut data = vec![0; buffer_len];
|
||||
let decrypted_len = opt_result!(decrypter.decrypt(&encrypted, &mut data), "Decrypt failed: {}");
|
||||
let decrypted_len = opt_result!(decrypter.decrypt(&ciphertext, &mut data), "Decrypt failed: {}");
|
||||
data.truncate(decrypted_len);
|
||||
|
||||
let encrypted_hex = hex::encode(&encrypted);
|
||||
let encrypted_hex = hex::encode(&ciphertext);
|
||||
information!("Padding: {}", padding_str);
|
||||
success!("Message HEX: {}", hex::encode(&data));
|
||||
success!("Message: {}", String::from_utf8_lossy(&data));
|
||||
|
||||
13
src/util.rs
13
src/util.rs
@@ -1,3 +1,5 @@
|
||||
use std::io::Read;
|
||||
|
||||
use base64::{DecodeError, Engine};
|
||||
use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD};
|
||||
use rust_util::XResult;
|
||||
@@ -15,11 +17,18 @@ pub fn base64_decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError> {
|
||||
}
|
||||
|
||||
pub fn try_decode(input: &str) -> XResult<Vec<u8>> {
|
||||
return match hex::decode(input) {
|
||||
match hex::decode(input) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => match base64_decode(input) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => simple_error!("decode hex or base64 error: {}", e),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_stdin() -> XResult<Vec<u8>> {
|
||||
let mut buffer = vec![];
|
||||
let mut stdin = std::io::stdin();
|
||||
opt_result!(stdin.read_to_end(&mut buffer), "Read stdin failed: {}");
|
||||
Ok(buffer)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user