mirror of
https://github.com/Noratrieb/cluelessh.git
synced 2026-01-16 17:35:04 +01:00
ecdsa private key
This commit is contained in:
parent
dcba4931e5
commit
1a093aa536
8 changed files with 147 additions and 28 deletions
|
|
@ -5,7 +5,6 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use base64::Engine;
|
||||
use ed25519_dalek::VerifyingKey;
|
||||
use tracing::debug;
|
||||
|
||||
use cluelessh_format::{ParseError, Reader, Writer};
|
||||
|
|
@ -29,17 +28,27 @@ impl PublicKey {
|
|||
|
||||
let k = match alg {
|
||||
"ssh-ed25519" => {
|
||||
// <https://datatracker.ietf.org/doc/html/rfc8709#name-public-key-format>
|
||||
let len = p.u32()?;
|
||||
if len != 32 {
|
||||
return Err(ParseError(format!("incorrect ed25519 len: {len}")));
|
||||
}
|
||||
let public_key = p.array::<32>()?;
|
||||
let public_key = VerifyingKey::from_bytes(&public_key)
|
||||
let public_key = ed25519_dalek::VerifyingKey::from_bytes(&public_key)
|
||||
.map_err(|_| ParseError(format!("invalid ed25519 public key")))?;
|
||||
Self::Ed25519 { public_key }
|
||||
}
|
||||
"ecdsa-sha2-nistp256" => {
|
||||
todo!()
|
||||
// <https://datatracker.ietf.org/doc/html/rfc5656#section-3.1>
|
||||
let params = p.utf8_string()?;
|
||||
if params != "nistp256" {
|
||||
return Err(ParseError(format!("curve parameter mismatch: {params}")));
|
||||
}
|
||||
let q = p.string()?;
|
||||
let public_key = p256::ecdsa::VerifyingKey::from_sec1_bytes(q)
|
||||
.map_err(|_| ParseError("invalid public key format".to_owned()))?;
|
||||
|
||||
Self::EcdsaSha2NistP256 { public_key }
|
||||
}
|
||||
_ => return Err(ParseError(format!("unsupported key type: {alg}"))),
|
||||
};
|
||||
|
|
@ -51,6 +60,7 @@ impl PublicKey {
|
|||
p.string(self.algorithm_name());
|
||||
match self {
|
||||
Self::Ed25519 { public_key } => {
|
||||
// <https://datatracker.ietf.org/doc/html/rfc8709#name-public-key-format>
|
||||
p.string(public_key.as_bytes());
|
||||
}
|
||||
Self::EcdsaSha2NistP256 { public_key } => {
|
||||
|
|
@ -109,11 +119,47 @@ impl Display for PublicKey {
|
|||
Self::EcdsaSha2NistP256 { .. } => {
|
||||
let encoded_pubkey = b64encode(&self.to_wire_encoding());
|
||||
write!(f, "{} {encoded_pubkey}", self.algorithm_name())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn b64encode(bytes: &[u8]) -> String {
|
||||
base64::prelude::BASE64_STANDARD_NO_PAD.encode(bytes)
|
||||
base64::prelude::BASE64_STANDARD.encode(bytes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base64::Engine;
|
||||
|
||||
use super::PublicKey;
|
||||
|
||||
#[track_caller]
|
||||
fn test_roundtrip(keys: &[&str]) {
|
||||
for key_bytes in keys {
|
||||
eprintln!("{key_bytes}");
|
||||
let key_bytes: Vec<u8> = base64::prelude::BASE64_STANDARD.decode(key_bytes).unwrap();
|
||||
|
||||
let key = PublicKey::from_wire_encoding(&key_bytes).unwrap();
|
||||
|
||||
assert_eq!(key.to_wire_encoding(), key_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ed25519() {
|
||||
test_roundtrip(&[
|
||||
"AAAAC3NzaC1lZDI1NTE5AAAAIJJKT1n+xPwS4ECXXPVB5U5gWwMpqa+FMvVuyFwbfvEg",
|
||||
"AAAAC3NzaC1lZDI1NTE5AAAAINZ1yLdDhI2Vou/9qrPIUP8RU8Sg0WxLI2njtP5hkdL7",
|
||||
"AAAAC3NzaC1lZDI1NTE5AAAAIAIIWlDvWkMEX8XIu6lxvd4cFOxeFUpH4ZReKuyS3h9l",
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ecdsa_sha2_nistp256() {
|
||||
test_roundtrip(&[
|
||||
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZTdlJoLNb701EWnahywBv032Aby+Piza7TzKW1H6Z//Hni/rBcUgnMmG+Kc4XWp6zgny3FMFpviuL01eJbpY8=",
|
||||
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCv8bAwK5tZBEpOgFe6tmnog6GHKzeXnOK/qewbH4yiGb9fq4LkSY8oK3WhVZdIwtc1n8j9dNc4aGMURNlVBNKc=",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue