feat: update ssh agent

This commit is contained in:
2025-05-27 00:04:26 +08:00
parent febdf659cd
commit a698a852fd
4 changed files with 63 additions and 9 deletions

View File

@@ -63,7 +63,7 @@ which = "7.0.3"
percent-encoding = "2.3.1" percent-encoding = "2.3.1"
external-command-rs = "0.1.1" external-command-rs = "0.1.1"
ssh-agent-lib = { version = "0.5.1" } ssh-agent-lib = { version = "0.5.1" }
ssh-key = { version = "0.6", features = ["ecdsa"] } ssh-key = { version = "0.6", features = ["ecdsa", "alloc"] }
tokio = "1.45.1" tokio = "1.45.1"
ssh-encoding = { version = "0.2.0", features = ["alloc"] } ssh-encoding = { version = "0.2.0", features = ["alloc"] }
#lazy_static = "1.4.0" #lazy_static = "1.4.0"

View File

@@ -1,19 +1,24 @@
use std::fs::remove_file; use std::fs::remove_file;
use std::path::PathBuf; use std::path::PathBuf;
use clap::{App, Arg, ArgMatches, SubCommand}; use crate::ecdsautil::{
generate_ecdsa_keypair, parse_ec_public_key_to_point, parse_ecdsa_r_and_s, EcdsaAlgorithm,
use crate::ecdsautil::{generate_ecdsa_keypair, parse_ecdsa_r_and_s, EcdsaAlgorithm}; };
use crate::util::base64_encode; use crate::util::base64_encode;
use clap::{App, Arg, ArgMatches, SubCommand};
use rsa::RsaPublicKey;
use rust_util::util_clap::{Command, CommandError}; use rust_util::util_clap::{Command, CommandError};
use rust_util::XResult; use rust_util::XResult;
use spki::DecodePublicKey;
use ssh_agent_lib::agent::{listen, Session}; use ssh_agent_lib::agent::{listen, Session};
use ssh_agent_lib::error::AgentError; use ssh_agent_lib::error::AgentError;
use ssh_agent_lib::proto::{Extension, Identity, SignRequest}; use ssh_agent_lib::proto::{Extension, Identity, SignRequest};
use ssh_agent_lib::ssh_encoding::Encode; use ssh_agent_lib::ssh_encoding::Encode;
use ssh_agent_lib::ssh_key::public::KeyData; use ssh_agent_lib::ssh_key::public::KeyData;
use ssh_agent_lib::ssh_key::{Algorithm, Signature}; use ssh_agent_lib::ssh_key::{Algorithm, Signature};
use ssh_key::public::EcdsaPublicKey;
use ssh_key::{EcdsaCurve, Mpint}; use ssh_key::{EcdsaCurve, Mpint};
use std::convert::TryFrom;
use tokio::net::UnixListener as Listener; use tokio::net::UnixListener as Listener;
#[derive(Default, Clone)] #[derive(Default, Clone)]
@@ -44,9 +49,7 @@ f17326c188b9d0cffeddd8ff935f24f2074bbef128ac5b04b9cac05de967df5dbfd065698dce3b8c
) )
.unwrap(); .unwrap();
let identity = Identity { let identity = Identity {
pubkey: KeyData::Ecdsa( pubkey: KeyData::Ecdsa(EcdsaPublicKey::from_sec1_bytes(&public_key_point).unwrap()),
ssh_key::public::EcdsaPublicKey::from_sec1_bytes(&public_key_point).unwrap(),
),
comment: "test".to_string(), comment: "test".to_string(),
}; };
let mut writer = vec![]; let mut writer = vec![];
@@ -61,8 +64,11 @@ f17326c188b9d0cffeddd8ff935f24f2074bbef128ac5b04b9cac05de967df5dbfd065698dce3b8c
let algorithm = &request.pubkey.algorithm(); let algorithm = &request.pubkey.algorithm();
match algorithm { match algorithm {
Algorithm::Ecdsa { curve: _ } => {} Algorithm::Ecdsa { curve: _ } => {}
Algorithm::Ed25519 => {}
Algorithm::Rsa { hash: _ } => {} Algorithm::Rsa { hash: _ } => {}
Algorithm::Ed25519 => {
debugging!("Algorithm::Ed25519 not supported");
return Err(AgentError::Failure);
}
Algorithm::Dsa => { Algorithm::Dsa => {
debugging!("Algorithm::Dsa not supported"); debugging!("Algorithm::Dsa not supported");
return Err(AgentError::Failure); return Err(AgentError::Failure);
@@ -117,6 +123,24 @@ f17326c188b9d0cffeddd8ff935f24f2074bbef128ac5b04b9cac05de967df5dbfd065698dce3b8c
} }
} }
fn get_identity(uri: &str) -> XResult<Identity> {
let public_key_bytes = external_command_rs::external_public_key("card-cli", uri)?;
let ec_point = parse_ec_public_key_to_point(&public_key_bytes).unwrap(); // TODO ...
let identity = Identity {
pubkey: KeyData::Ecdsa(EcdsaPublicKey::from_sec1_bytes(&ec_point).unwrap()),
comment: "test".to_string(),
};
let rsa_public_key = RsaPublicKey::from_public_key_der(&public_key_bytes).unwrap();
let identity = Identity {
pubkey: KeyData::Rsa(ssh_key::public::RsaPublicKey::try_from(&rsa_public_key).unwrap()),
comment: "test".to_string(),
};
simple_error!("Unknown uri algorithm: {}", uri)
}
pub struct CommandImpl; pub struct CommandImpl;
impl Command for CommandImpl { impl Command for CommandImpl {

View File

@@ -94,6 +94,36 @@ pub fn generate_ecdsa_keypair(algo: EcdsaAlgorithm) -> XResult<(String, String,
} }
} }
pub fn parse_ec_public_key_to_point(public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
match parse_p521_public_key_to_point(public_key_bytes) {
Ok(point) => Ok(point),
Err(_) => match parse_p384_public_key_to_point(public_key_bytes) {
Ok(point) => Ok(point),
Err(_) => parse_p256_public_key_to_point(public_key_bytes),
}
}
}
pub fn parse_p256_public_key_to_point(public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
use p256::{PublicKey, elliptic_curve::sec1::ToEncodedPoint};
use spki::DecodePublicKey;
let public_key = PublicKey::from_public_key_der(public_key_bytes)?;
Ok(public_key.to_encoded_point(false).as_bytes().to_vec())
}
pub fn parse_p384_public_key_to_point(public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
use p384::{PublicKey, elliptic_curve::sec1::ToEncodedPoint};
use spki::DecodePublicKey;
let public_key = PublicKey::from_public_key_der(public_key_bytes)?;
Ok(public_key.to_encoded_point(false).as_bytes().to_vec())
}
pub fn parse_p521_public_key_to_point(public_key_bytes: &[u8]) -> XResult<Vec<u8>> {
use p521::{PublicKey, elliptic_curve::sec1::ToEncodedPoint};
use spki::DecodePublicKey;
let public_key = PublicKey::from_public_key_der(public_key_bytes)?;
Ok(public_key.to_encoded_point(false).as_bytes().to_vec())
}
macro_rules! parse_ecdsa_private_key_to_public_key { macro_rules! parse_ecdsa_private_key_to_public_key {
($algo: tt, $parse_ecdsa_private_key: tt) => ({ ($algo: tt, $parse_ecdsa_private_key: tt) => ({

View File

@@ -226,7 +226,7 @@ pub fn rsa_public_key_to_jwk(rsa_public_key: &RsaPublicKey) -> XResult<String> {
Ok(serde_json::to_string(&jwk).unwrap()) Ok(serde_json::to_string(&jwk).unwrap())
} }
fn try_parse_rsa(public_key: &str) -> XResult<RsaPublicKey> { pub fn try_parse_rsa(public_key: &str) -> XResult<RsaPublicKey> {
debugging!("Try parse RSA public key PEM."); debugging!("Try parse RSA public key PEM.");
// parse RSA public key PEM not works? why? // parse RSA public key PEM not works? why?
if let Ok(rsa_public_key) = RsaPublicKey::from_public_key_pem(public_key) { if let Ok(rsa_public_key) = RsaPublicKey::from_public_key_pem(public_key) {