feat: v1.1.12, piv sign works
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -384,7 +384,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "card-cli"
|
||||
version = "1.1.11"
|
||||
version = "1.1.12"
|
||||
dependencies = [
|
||||
"authenticator",
|
||||
"base64 0.13.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "card-cli"
|
||||
version = "1.1.11"
|
||||
version = "1.1.12"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -15,42 +15,51 @@ impl Command for CommandImpl {
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("PIV Sign subcommand")
|
||||
.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("sha256").short("2").long("sha256").takes_value(true).help("Digest SHA256 HEX"))
|
||||
.arg(Arg::with_name("json").long("json").help("JSON output"))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let json_output = sub_arg_matches.is_present("json");
|
||||
if json_output {
|
||||
rust_util::util_msg::set_logger_std_out(false);
|
||||
}
|
||||
warning!("This feature is not complete");
|
||||
let pin_opt = sub_arg_matches.value_of("pass").or_else(|| sub_arg_matches.value_of("pin"));
|
||||
if json_output { rust_util::util_msg::set_logger_std_out(false); }
|
||||
|
||||
let pin_opt = sub_arg_matches.value_of("pin");
|
||||
let pin = opt_value_result!(pin_opt, "User pin must be assigned");
|
||||
|
||||
let sha256_hex_opt = sub_arg_matches.value_of("sha256").map(|s| s.to_string());
|
||||
|
||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||
opt_result!(yk.verify_pin(pin.as_bytes()), "YubiKey verify pin failed: {}");
|
||||
|
||||
let hash = hex::decode(
|
||||
"3031300d060960864801650304020105000420".to_string() +
|
||||
"66d8dff9cbf819183700ff6d08349d9472af54031e8e297f8ab341e307f5387c").unwrap();
|
||||
rust_util::util_msg::when(MessageType::DEBUG, || debugging!("Hash: {}", hex::encode(&hash)));
|
||||
let hash_padding = pkcs1_padding_for_sign(&hash, 2048).unwrap();
|
||||
rust_util::util_msg::when(MessageType::DEBUG, || debugging!("PKCS1 padding: {}", hex::encode(&hash_padding)));
|
||||
let raw_in = crate::digest::copy_rsa2048(&hash_padding).unwrap();
|
||||
let sign_result = yubikey::piv::sign_data(&mut yk, &raw_in, AlgorithmId::Rsa2048, SlotId::Signature);
|
||||
let sign = opt_result!(sign_result, "Sign data failed: {}");
|
||||
let sign_bytes = sign.as_slice();
|
||||
let sha256_prefix = hex::decode("3031300d060960864801650304020105000420").unwrap();
|
||||
|
||||
if json_output {
|
||||
let mut json = BTreeMap::<&'_ str, String>::new();
|
||||
json.insert("hash_hex", hex::encode(&hash));
|
||||
json.insert("sign_hex", hex::encode(&sign_bytes));
|
||||
json.insert("sign_base64", base64::encode(&sign_bytes));
|
||||
println!("{}", serde_json::to_string_pretty(&json).unwrap());
|
||||
} else {
|
||||
success!("Signature HEX: {}", hex::encode(sign_bytes));
|
||||
success!("Signature base64: {}", base64::encode(sign_bytes));
|
||||
if let Some(sha256_hex) = sha256_hex_opt {
|
||||
let hash = opt_result!(hex::decode(sha256_hex), "Decode sha256 failed: {}");
|
||||
|
||||
let mut hash_with_oid = Vec::with_capacity(128);
|
||||
hash_with_oid.extend_from_slice(&sha256_prefix);
|
||||
hash_with_oid.extend_from_slice(&hash);
|
||||
let hash_padding = pkcs1_padding_for_sign(&hash_with_oid, 2048).unwrap();
|
||||
rust_util::util_msg::when(MessageType::DEBUG, || {
|
||||
debugging!("Hash: {}", hex::encode(&hash));
|
||||
debugging!("Hash with OID: {}", hex::encode(&hash_with_oid));
|
||||
debugging!("PKCS1 padding: {}", hex::encode(&hash_padding));
|
||||
});
|
||||
let raw_in = crate::digest::copy_rsa2048(&hash_padding).unwrap();
|
||||
let sign_result = yubikey::piv::sign_data(&mut yk, &raw_in, AlgorithmId::Rsa2048, SlotId::Signature);
|
||||
let sign = opt_result!(sign_result, "Sign data failed: {}");
|
||||
let sign_bytes = sign.as_slice();
|
||||
|
||||
if json_output {
|
||||
let mut json = BTreeMap::<&'_ str, String>::new();
|
||||
json.insert("hash_hex", hex::encode(&hash));
|
||||
json.insert("sign_hex", hex::encode(&sign_bytes));
|
||||
json.insert("sign_base64", base64::encode(&sign_bytes));
|
||||
println!("{}", serde_json::to_string_pretty(&json).unwrap());
|
||||
} else {
|
||||
success!("Signature HEX: {}", hex::encode(sign_bytes));
|
||||
success!("Signature base64: {}", base64::encode(sign_bytes));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user