feat: v1.9.11, piv meta outputs ssh public key
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -406,7 +406,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "card-cli"
|
name = "card-cli"
|
||||||
version = "1.9.9"
|
version = "1.9.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"authenticator",
|
"authenticator",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "card-cli"
|
name = "card-cli"
|
||||||
version = "1.9.9"
|
version = "1.9.11"
|
||||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ use yubikey::piv::{AlgorithmId, metadata};
|
|||||||
use crate::pivutil;
|
use crate::pivutil;
|
||||||
use crate::pivutil::{get_algorithm_id_by_certificate, slot_equals, ToStr};
|
use crate::pivutil::{get_algorithm_id_by_certificate, slot_equals, ToStr};
|
||||||
use crate::pkiutil::bytes_to_pem;
|
use crate::pkiutil::bytes_to_pem;
|
||||||
|
use crate::sshutil::SshVecWriter;
|
||||||
|
use crate::util::base64_encode;
|
||||||
|
|
||||||
pub struct CommandImpl;
|
pub struct CommandImpl;
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ impl Command for CommandImpl {
|
|||||||
let public_key_bit_string = &cert.subject_public_key_info.subject_public_key;
|
let public_key_bit_string = &cert.subject_public_key_info.subject_public_key;
|
||||||
match algorithm_id {
|
match algorithm_id {
|
||||||
AlgorithmId::EccP256 | AlgorithmId::EccP384 => {
|
AlgorithmId::EccP256 | AlgorithmId::EccP384 => {
|
||||||
|
let ec_bit_len = iff!(matches!(algorithm_id, AlgorithmId::EccP256), 256, 384);
|
||||||
let pk_point_hex = public_key_bit_string.raw_bytes();
|
let pk_point_hex = public_key_bit_string.raw_bytes();
|
||||||
json.insert("pk_point_hex", hex::encode(pk_point_hex));
|
json.insert("pk_point_hex", hex::encode(pk_point_hex));
|
||||||
if pk_point_hex[0] == 0x04 {
|
if pk_point_hex[0] == 0x04 {
|
||||||
@@ -88,6 +91,14 @@ impl Command for CommandImpl {
|
|||||||
format!("02{}", hex::encode(&pk_point_hex[1..(pk_point_hex.len() / 2) + 1])),
|
format!("02{}", hex::encode(&pk_point_hex[1..(pk_point_hex.len() / 2) + 1])),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut ssh_public_key = vec![];
|
||||||
|
ssh_public_key.write_string(format!("ecdsa-sha2-nistp{}", ec_bit_len).as_bytes());
|
||||||
|
ssh_public_key.write_string(format!("nistp{}", ec_bit_len).as_bytes());
|
||||||
|
ssh_public_key.write_string(pk_point_hex);
|
||||||
|
let ssh_public_key_str = format!(
|
||||||
|
"ecdsa-sha2-nistp{} {} PIV:{}", ec_bit_len, base64_encode(ssh_public_key), slot_id);
|
||||||
|
json.insert("ssh_public_key", ssh_public_key_str.to_string());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -100,6 +111,7 @@ impl Command for CommandImpl {
|
|||||||
|
|
||||||
let x509_certificate = parse_x509_certificate(cert_der.as_slice()).unwrap().1;
|
let x509_certificate = parse_x509_certificate(cert_der.as_slice()).unwrap().1;
|
||||||
let public_key_bytes = x509_certificate.public_key().raw;
|
let public_key_bytes = x509_certificate.public_key().raw;
|
||||||
|
|
||||||
json.insert("subject", x509_certificate.subject.to_string());
|
json.insert("subject", x509_certificate.subject.to_string());
|
||||||
json.insert("issuer", x509_certificate.issuer.to_string());
|
json.insert("issuer", x509_certificate.issuer.to_string());
|
||||||
json.insert("public_key_hex", hex::encode(public_key_bytes));
|
json.insert("public_key_hex", hex::encode(public_key_bytes));
|
||||||
|
|||||||
@@ -7,27 +7,7 @@ use yubikey::piv::{AlgorithmId, sign_data};
|
|||||||
|
|
||||||
use crate::{pinutil, pivutil, util};
|
use crate::{pinutil, pivutil, util};
|
||||||
use crate::pivutil::{get_algorithm_id_by_certificate, slot_equals, ToStr};
|
use crate::pivutil::{get_algorithm_id_by_certificate, slot_equals, ToStr};
|
||||||
|
use crate::sshutil::SshVecWriter;
|
||||||
trait VecWriter {
|
|
||||||
fn write_bytes(&mut self, bytes: &[u8]) -> ();
|
|
||||||
fn write_u32(&mut self, num: u32) -> ();
|
|
||||||
fn write_string(&mut self, bytes: &[u8]) -> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VecWriter for Vec<u8> {
|
|
||||||
fn write_bytes(&mut self, bytes: &[u8]) -> () {
|
|
||||||
self.extend_from_slice(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_u32(&mut self, num: u32) -> () {
|
|
||||||
self.write_bytes(&num.to_be_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_string(&mut self, bytes: &[u8]) -> () {
|
|
||||||
self.write_u32(bytes.len() as u32);
|
|
||||||
self.write_bytes(bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CommandImpl;
|
pub struct CommandImpl;
|
||||||
|
|
||||||
|
|||||||
@@ -18,4 +18,25 @@ pub fn generate_ssh_string(e: &[u8], n: &[u8], comment: &str) -> String {
|
|||||||
pub fn append_slice_with_len(v: &mut Vec<u8>, s: &[u8]) {
|
pub fn append_slice_with_len(v: &mut Vec<u8>, s: &[u8]) {
|
||||||
v.extend_from_slice(&(s.len() as u32).to_be_bytes()[..]);
|
v.extend_from_slice(&(s.len() as u32).to_be_bytes()[..]);
|
||||||
v.extend_from_slice(s);
|
v.extend_from_slice(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait SshVecWriter {
|
||||||
|
fn write_bytes(&mut self, bytes: &[u8]) -> ();
|
||||||
|
fn write_u32(&mut self, num: u32) -> ();
|
||||||
|
fn write_string(&mut self, bytes: &[u8]) -> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SshVecWriter for Vec<u8> {
|
||||||
|
fn write_bytes(&mut self, bytes: &[u8]) -> () {
|
||||||
|
self.extend_from_slice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_u32(&mut self, num: u32) -> () {
|
||||||
|
self.write_bytes(&num.to_be_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string(&mut self, bytes: &[u8]) -> () {
|
||||||
|
self.write_u32(bytes.len() as u32);
|
||||||
|
self.write_bytes(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user