feat: add ssh agnet(not yet work)
This commit is contained in:
50
src/cmd_sshagent.rs
Normal file
50
src/cmd_sshagent.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use openpgp_card::{KeyType, OpenPgp};
|
||||
use openpgp_card::crypto_data::PublicKeyMaterial;
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
impl Command for CommandImpl {
|
||||
fn name(&self) -> &str { "ssh-agent" }
|
||||
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("SSH-Agent 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("in").short("i").long("in").takes_value(true).help("File in"))
|
||||
.arg(Arg::with_name("pgp").long("pgp").help("Use PGP"))
|
||||
.arg(Arg::with_name("sock-file").long("sock-file").default_value("connect.ssh").help("Sock file, usage SSH_AUTH_SOCK=sock-file ssh ..."))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let use_pgp = sub_arg_matches.is_present("pgp");
|
||||
let sock_file = sub_arg_matches.value_of("sock-file").unwrap();
|
||||
information!("Sock file: {}", sock_file);
|
||||
|
||||
if use_pgp {
|
||||
let mut card = crate::pgpcardutil::get_card()?;
|
||||
let mut pgp = OpenPgp::new(&mut card);
|
||||
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
|
||||
let serial = trans.application_related_data()
|
||||
.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 rsa_public_key = match public_key {
|
||||
PublicKeyMaterial::E(_) => return simple_error!("Not supports ec key"),
|
||||
PublicKeyMaterial::R(rsa_public_key) => rsa_public_key,
|
||||
_ => return simple_error!("Unknown key type"),
|
||||
};
|
||||
let e = rsa_public_key.v();
|
||||
let n = rsa_public_key.n();
|
||||
|
||||
let comment = format!("pgp-card:{}", serial);
|
||||
let ssh_string = crate::sshutil::generate_ssh_string(e, n, &comment);
|
||||
information!("{}", ssh_string);
|
||||
}
|
||||
|
||||
information!("card-cli ssh-agent...");
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ extern crate rust_util;
|
||||
use clap::{App, AppSettings, ArgMatches};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
|
||||
mod sshutil;
|
||||
mod fido;
|
||||
mod digest;
|
||||
mod rsautil;
|
||||
@@ -26,6 +27,7 @@ mod cmd_pivdecrypt;
|
||||
mod cmd_pivgenerate;
|
||||
mod cmd_chall;
|
||||
mod cmd_challconfig;
|
||||
mod cmd_sshagent;
|
||||
|
||||
pub struct DefaultCommandImpl;
|
||||
|
||||
@@ -64,6 +66,7 @@ fn inner_main() -> CommandError {
|
||||
Box::new(cmd_pivgenerate::CommandImpl),
|
||||
Box::new(cmd_u2fregister::CommandImpl),
|
||||
Box::new(cmd_u2fsign::CommandImpl),
|
||||
Box::new(cmd_sshagent::CommandImpl),
|
||||
];
|
||||
let mut app = App::new(env!("CARGO_PKG_NAME"))
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
|
||||
20
src/sshutil.rs
Normal file
20
src/sshutil.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
pub fn with_sign(mut vec: Vec<u8>) -> Vec<u8> {
|
||||
if vec.len() > 0 && vec[0] >= 128 {
|
||||
vec.insert(0, 0x00);
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
pub fn generate_ssh_string(e: &[u8], n: &[u8], comment: &str) -> String {
|
||||
let mut ssh_key = vec![];
|
||||
let ssh_rsa_bytes = "ssh-rsa".as_bytes();
|
||||
ssh_key.extend_from_slice(&(ssh_rsa_bytes.len() as u32).to_be_bytes()[..]);
|
||||
ssh_key.extend_from_slice(ssh_rsa_bytes);
|
||||
let e = with_sign(e.to_vec());
|
||||
ssh_key.extend_from_slice(&(e.len() as u32).to_be_bytes()[..]);
|
||||
ssh_key.extend_from_slice(&e);
|
||||
let n = with_sign(n.to_vec());
|
||||
ssh_key.extend_from_slice(&(n.len() as u32).to_be_bytes()[..]);
|
||||
ssh_key.extend_from_slice(&n);
|
||||
format!("ssh-rsa {} {}", base64::encode(&ssh_key), comment)
|
||||
}
|
||||
Reference in New Issue
Block a user