feat: v1.3.1, add --pgp-auth
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -384,7 +384,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "card-cli"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
dependencies = [
|
||||
"authenticator",
|
||||
"base64 0.13.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "card-cli"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -23,13 +23,15 @@ lazy_static! {
|
||||
}
|
||||
|
||||
struct SshAgent {
|
||||
use_sign: bool,
|
||||
pin: String,
|
||||
public_key: PublicKey,
|
||||
comment: String,
|
||||
ssh_string: String,
|
||||
}
|
||||
|
||||
impl SshAgent {
|
||||
fn new() -> XResult<Self> {
|
||||
fn new(pin: String, use_sign: bool) -> XResult<Self> {
|
||||
let mut card = crate::pgpcardutil::get_card()?;
|
||||
let (public_key, comment, ssh_string) = {
|
||||
let mut pgp = OpenPgp::new(&mut card);
|
||||
@@ -38,7 +40,7 @@ impl SshAgent {
|
||||
.map(|d| d.application_id().map(|i| i.serial()))
|
||||
.unwrap_or_else(|_| Ok(0)).unwrap_or_else(|_| 0);
|
||||
let serial = hex::encode(serial.to_be_bytes());
|
||||
let public_key = opt_result!(trans.public_key(KeyType::Signing), "Cannot find signing key: {}");
|
||||
let public_key = opt_result!(trans.public_key(iff!(use_sign, KeyType::Signing, KeyType::Authentication)), "Cannot find signing key: {}");
|
||||
let rsa_public_key = match public_key {
|
||||
PublicKeyMaterial::E(_) => return simple_error!("Not supports ec key"),
|
||||
PublicKeyMaterial::R(rsa_public_key) => rsa_public_key,
|
||||
@@ -51,7 +53,7 @@ impl SshAgent {
|
||||
e: with_sign(e.to_vec()),
|
||||
n: with_sign(n.to_vec()),
|
||||
});
|
||||
let comment = format!("pgp-card:{}", serial);
|
||||
let comment = format!("pgp-card:{}:{}", iff!(use_sign, "sign", "auth"), serial);
|
||||
(public_key, comment.clone(), crate::sshutil::generate_ssh_string(e, n, &comment))
|
||||
};
|
||||
{
|
||||
@@ -59,6 +61,8 @@ impl SshAgent {
|
||||
*card_mutex = Some(card);
|
||||
}
|
||||
Ok(Self {
|
||||
use_sign,
|
||||
pin,
|
||||
public_key,
|
||||
comment,
|
||||
ssh_string,
|
||||
@@ -107,8 +111,15 @@ impl SshAgent {
|
||||
};
|
||||
let mut pgp = OpenPgp::new(card_mut);
|
||||
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
|
||||
opt_result!(trans.verify_pw1_sign("123456".as_bytes()), "User sign pin verify failed: {}");
|
||||
let sig = opt_result!(trans.signature_for_hash(hash), "Sign OpenPGP card failed: {}");
|
||||
let sig = if self.use_sign {
|
||||
debugging!("User pin verify for pw1 sign, use sign: {}", self.use_sign);
|
||||
opt_result!(trans.verify_pw1_sign(self.pin.as_bytes()), "User sign pin verify failed: {}");
|
||||
opt_result!(trans.signature_for_hash(hash), "Sign OpenPGP card failed: {}")
|
||||
} else {
|
||||
debugging!("User pin verify for pw1 user, use sign: {}", self.use_sign);
|
||||
opt_result!(trans.verify_pw1_user(self.pin.as_bytes()), "User user pin verify failed: {}");
|
||||
opt_result!(trans.authenticate_for_hash(hash), "Auth OpenPGP card failed: {}")
|
||||
};
|
||||
|
||||
debugging!("Signature: {:?}", sig);
|
||||
success!("SSH request sign success");
|
||||
@@ -144,6 +155,8 @@ impl Command for CommandImpl {
|
||||
SubCommand::with_name(self.name()).about("SSH-Agent subcommand")
|
||||
.arg(Arg::with_name("pin").short("p").long("pin").default_value("123456").help("OpenPGP card user pin"))
|
||||
.arg(Arg::with_name("pgp").long("pgp").help("Use PGP"))
|
||||
.arg(Arg::with_name("pgp-sign").long("pgp-sign").help("Use PGP sign"))
|
||||
.arg(Arg::with_name("pgp-auth").long("pgp-auth").help("Use PGP auth"))
|
||||
.arg(Arg::with_name("piv").long("piv").help("Use PIV"))
|
||||
.arg(Arg::with_name("sock-file").long("sock-file").default_value("connect.ssh").help("Sock file, usage SSH_AUTH_SOCK=sock-file ssh ..."))
|
||||
}
|
||||
@@ -154,18 +167,25 @@ impl Command for CommandImpl {
|
||||
if !(use_pgp ^ use_piv) {
|
||||
return simple_error!("Args --pgp or --piv must have one selection");
|
||||
}
|
||||
let use_pgp_sign = sub_arg_matches.is_present("pgp-sign");
|
||||
let use_pgp_auth = sub_arg_matches.is_present("pgp-auth");
|
||||
if use_pgp && !(use_pgp_sign ^ use_pgp_auth) {
|
||||
return simple_error!("Args --pgp-sign or --pgp-auth must have one selection when use --pgp");
|
||||
}
|
||||
let pin = sub_arg_matches.value_of("pin").unwrap();
|
||||
|
||||
let sock_file = sub_arg_matches.value_of("sock-file").unwrap();
|
||||
information!("Sock file: {}", sock_file);
|
||||
|
||||
let sock_file_path = PathBuf::from(sock_file);
|
||||
let sock_file_path = PathBuf::from(".");
|
||||
match std::fs::canonicalize(sock_file_path) {
|
||||
Ok(canonicalized_sock_file_path) => information!("SSH_AUTH_SOCK={}", canonicalized_sock_file_path.to_str().unwrap_or_else(|| "-")),
|
||||
Ok(canonicalized_sock_file_path) => information!("SSH_AUTH_SOCK={}/{}",
|
||||
canonicalized_sock_file_path.to_str().unwrap_or_else(|| "-"), sock_file),
|
||||
Err(e) => warning!("Get canonicalized sock file path failed: {}", e),
|
||||
}
|
||||
|
||||
if use_pgp {
|
||||
let ssh_agent = SshAgent::new()?;
|
||||
let ssh_agent = SshAgent::new(pin.to_string(), use_pgp_sign)?;
|
||||
information!("{}", &ssh_agent.ssh_string);
|
||||
|
||||
let _ = remove_file(sock_file);
|
||||
|
||||
Reference in New Issue
Block a user