diff --git a/Cargo.lock b/Cargo.lock index 2509ffb..382e067 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -320,7 +320,7 @@ dependencies = [ [[package]] name = "card-cli" -version = "1.7.4" +version = "1.7.5" dependencies = [ "authenticator", "base64 0.21.4", diff --git a/Cargo.toml b/Cargo.toml index d094f84..9081ae7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.7.4" +version = "1.7.5" authors = ["Hatter Jiang "] edition = "2018" diff --git a/src/cmd_pgpcarddecrypt.rs b/src/cmd_pgpcarddecrypt.rs index 3e8c6ca..c046d9c 100644 --- a/src/cmd_pgpcarddecrypt.rs +++ b/src/cmd_pgpcarddecrypt.rs @@ -3,11 +3,27 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; use openpgp_card::crypto_data::Cryptogram; use openpgp_card::OpenPgp; +use rust_util::{util_msg, XResult}; use rust_util::util_clap::{Command, CommandError}; -use rust_util::util_msg; use crate::util::{base64_decode, base64_encode}; +#[derive(Debug, Clone, Copy)] +enum EncryptAlgo { + RSA, + ECDH, +} + +impl EncryptAlgo { + fn from_str(algo: &str) -> XResult { + match algo { + "rsa" => Ok(Self::RSA), + "x25519" | "ecdh" => Ok(Self::ECDH), + _ => return simple_error!("Unknown algo: {}", algo), + } + } +} + pub struct CommandImpl; impl Command for CommandImpl { @@ -35,6 +51,7 @@ impl Command for CommandImpl { let cipher_base64 = sub_arg_matches.value_of("cipher-base64"); let algo = sub_arg_matches.value_of("algo").unwrap_or("rsa").to_lowercase(); + let algo = EncryptAlgo::from_str(&algo)?; let cipher_bytes = if let Some(cipher) = cipher { opt_result!(hex::decode(cipher), "Decode cipher failed: {}") @@ -51,10 +68,9 @@ impl Command for CommandImpl { opt_result!(trans.verify_pw1_user(pin.as_ref()), "User pin verify failed: {}"); success!("User pin verify success!"); - let text = match algo.as_str() { - "rsa" => trans.decipher(Cryptogram::RSA(&cipher_bytes))?, - "x25519" | "ecdh" => trans.decipher(Cryptogram::ECDH(&cipher_bytes))?, - _ => return simple_error!("Unknown algo: {}", &algo), + let text = match algo { + EncryptAlgo::RSA => trans.decipher(Cryptogram::RSA(&cipher_bytes))?, + EncryptAlgo::ECDH => trans.decipher(Cryptogram::ECDH(&cipher_bytes))?, }; // let text = trans.decipher(Cryptogram::RSA(&cipher_bytes))?; success!("Clear text HEX: {}", hex::encode(&text)); diff --git a/src/cmd_pgpcardsign.rs b/src/cmd_pgpcardsign.rs index 87c9bcb..c896677 100644 --- a/src/cmd_pgpcardsign.rs +++ b/src/cmd_pgpcardsign.rs @@ -13,6 +13,24 @@ use crate::util::base64_encode; const BUFF_SIZE: usize = 512 * 1024; +#[derive(Debug, Clone, Copy)] +enum SignAlgo { + RSA, + ECDSA, + EdDSA, +} + +impl SignAlgo { + fn from_str(algo: &str) -> XResult { + match algo { + "rsa" => Ok(Self::RSA), + "ecdsa" => Ok(Self::ECDSA), + "eddsa" => Ok(Self::EdDSA), + _ => return simple_error!("Unknown algo: {}", algo), + } + } +} + pub struct CommandImpl; impl Command for CommandImpl { @@ -29,6 +47,7 @@ impl Command for CommandImpl { .arg(Arg::with_name("use-sha256").long("use-sha256").help("Use SHA256 for file in")) .arg(Arg::with_name("use-sha384").long("use-sha384").help("Use SHA384 for file in")) .arg(Arg::with_name("use-sha512").long("use-sha512").help("Use SHA512 for file in")) + .arg(Arg::with_name("algo").long("algo").help("Algorithm, rsa, ecdsa, eddsa")) .arg(Arg::with_name("json").long("json").help("JSON output")) } @@ -45,6 +64,9 @@ impl Command for CommandImpl { let mut sha512 = sub_arg_matches.value_of("sha512").map(|s| s.to_string()); let file_in_opt = sub_arg_matches.value_of("in"); + let algo = sub_arg_matches.value_of("algo").unwrap_or("rsa").to_lowercase(); + let algo = SignAlgo::from_str(&algo)?; + let mut json = BTreeMap::new(); if let Some(file_in) = file_in_opt { if sha256.is_some() || sha384.is_some() || sha512.is_some() { return simple_error!("Conflict --in vs --sha256, --sha384, --sha512 args"); } @@ -88,7 +110,11 @@ impl Command for CommandImpl { let sha256_hex = crate::digest::copy_sha256(&sha256_hex)?; opt_result!(trans.verify_pw1_sign(pin.as_ref()), "User sign pin verify failed: {}"); success!("User sign pin verify success!"); - let sig = trans.signature_for_hash(Hash::SHA256(sha256_hex))?; + let sig = match algo { + SignAlgo::RSA => trans.signature_for_hash(Hash::SHA256(sha256_hex))?, + SignAlgo::ECDSA => trans.signature_for_hash(Hash::ECDSA(&sha256_hex))?, + SignAlgo::EdDSA => trans.signature_for_hash(Hash::EdDSA(&sha256_hex))?, + }; success!("SHA256 signature HEX: {}", hex::encode(&sig)); success!("SHA256 signature base64: {}", base64_encode(&sig)); if json_output { @@ -103,7 +129,11 @@ impl Command for CommandImpl { let sha384_hex = crate::digest::copy_sha384(&sha384_hex)?; opt_result!(trans.verify_pw1_sign(pin.as_ref()), "User sign pin verify failed: {}"); success!("User sign pin verify success!"); - let sig = trans.signature_for_hash(Hash::SHA384(sha384_hex))?; + let sig = match algo { + SignAlgo::RSA => trans.signature_for_hash(Hash::SHA384(sha384_hex))?, + SignAlgo::ECDSA => trans.signature_for_hash(Hash::ECDSA(&sha384_hex))?, + SignAlgo::EdDSA => trans.signature_for_hash(Hash::EdDSA(&sha384_hex))?, + }; success!("SHA384 signature HEX: {}", hex::encode(&sig)); success!("SHA384 signature base64: {}", base64_encode(&sig)); if json_output { @@ -118,7 +148,11 @@ impl Command for CommandImpl { let sha512_hex = crate::digest::copy_sha512(&sha512_hex)?; opt_result!(trans.verify_pw1_sign(pin.as_ref()), "User sign pin verify failed: {}"); success!("User sign pin verify success!"); - let sig = trans.signature_for_hash(Hash::SHA512(sha512_hex))?; + let sig = match algo { + SignAlgo::RSA => trans.signature_for_hash(Hash::SHA512(sha512_hex))?, + SignAlgo::ECDSA => trans.signature_for_hash(Hash::ECDSA(&sha512_hex))?, + SignAlgo::EdDSA => trans.signature_for_hash(Hash::EdDSA(&sha512_hex))?, + }; success!("SHA512 signature HEX: {}", hex::encode(&sig)); success!("SHA512 signature base64: {}", base64_encode(&sig)); if json_output {