Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sk constructors #201

Merged
merged 5 commits into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ssh-key/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ pub enum Error {
/// Version number.
number: u32,
},

/// Byte array is longer than allowed.
TooLong {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably just be Error::FormatEncoding or encoding::Error::Length

/// Bad length that did not pass validation check.
bad_len: usize,
},
}

impl fmt::Display for Error {
Expand Down Expand Up @@ -111,6 +117,7 @@ impl fmt::Display for Error {
"unexpected trailing data at end of message ({remaining} bytes)",
),
Error::Version { number: version } => write!(f, "version unsupported: {version}"),
Error::TooLong { bad_len } => write!(f, "too long byte array: {bad_len}"),
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions ssh-key/src/private/sk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ pub struct SkEcdsaSha2NistP256 {

#[cfg(feature = "ecdsa")]
impl SkEcdsaSha2NistP256 {
/// Construct new instance of SkEcdsaSha2NistP256.
#[cfg(feature = "alloc")]
pub fn new(
public: public::SkEcdsaSha2NistP256,
flags: u8,
key_handle: impl Into<Vec<u8>>,
) -> Result<Self> {
let key_handle = key_handle.into();

if key_handle.len() <= 255 {
Ok(SkEcdsaSha2NistP256 {
public,
flags,
key_handle,
reserved: Vec::<u8>::new(),
})
} else {
Err(Error::TooLong {
bad_len: key_handle.len(),
})
}
}

/// Get the ECDSA/NIST P-256 public key.
pub fn public(&self) -> &public::SkEcdsaSha2NistP256 {
&self.public
Expand Down Expand Up @@ -96,6 +119,29 @@ pub struct SkEd25519 {
}

impl SkEd25519 {
/// Construct new instance of SkEd25519.
#[cfg(feature = "alloc")]
pub fn new(
public: public::SkEd25519,
flags: u8,
key_handle: impl Into<Vec<u8>>,
) -> Result<Self> {
let key_handle = key_handle.into();

if key_handle.len() <= 255 {
Ok(SkEd25519 {
public,
flags,
key_handle,
reserved: Vec::<u8>::new(),
})
} else {
Err(Error::TooLong {
bad_len: key_handle.len(),
})
}
}

/// Get the Ed25519 public key.
pub fn public(&self) -> &public::SkEd25519 {
&self.public
Expand Down
18 changes: 18 additions & 0 deletions ssh-key/src/public/sk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ pub struct SkEcdsaSha2NistP256 {

#[cfg(feature = "ecdsa")]
impl SkEcdsaSha2NistP256 {
/// Construct new instance of SkEcdsaSha2NistP256.
#[cfg(feature = "alloc")]
pub fn new(ec_point: EcdsaNistP256PublicKey, application: impl Into<String>) -> Self {
SkEcdsaSha2NistP256 {
ec_point,
application: application.into(),
}
}

/// Get the elliptic curve point for this Security Key.
pub fn ec_point(&self) -> &EcdsaNistP256PublicKey {
&self.ec_point
Expand Down Expand Up @@ -123,6 +132,15 @@ pub struct SkEd25519 {
}

impl SkEd25519 {
/// Construct new instance of SkEd25519.
#[cfg(feature = "alloc")]
pub fn new(public_key: Ed25519PublicKey, application: impl Into<String>) -> Self {
SkEd25519 {
public_key,
application: application.into(),
}
}

/// Get the Ed25519 private key for this security key.
pub fn public_key(&self) -> &Ed25519PublicKey {
&self.public_key
Expand Down
41 changes: 41 additions & 0 deletions ssh-key/tests/public_key.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//! SSH public key tests.

use hex_literal::hex;
#[cfg(feature = "alloc")]
use ssh_key::public::{Ed25519PublicKey, SkEd25519};
use ssh_key::{Algorithm, PublicKey};
use std::collections::HashSet;
#[cfg(all(feature = "ecdsa", feature = "alloc"))]
use {sec1::consts::U32, ssh_key::public::SkEcdsaSha2NistP256};

#[cfg(feature = "ecdsa")]
use ssh_key::EcdsaCurve;
Expand Down Expand Up @@ -296,6 +300,25 @@ fn decode_sk_ecdsa_p256_openssh() {
);
}

#[cfg(all(feature = "ecdsa", feature = "alloc"))]
#[test]
fn new_sk_ecdsa_p256() {
const EXAMPLE_EC_POINT: [u8; 65] = [
0x04, 0x81, 0x0b, 0x40, 0x9d, 0x83, 0x82, 0xf6, 0x97, 0xd7, 0x24, 0x25, 0x28, 0x5a, 0x24,
0x7d, 0x63, 0x36, 0xb2, 0xeb, 0x9a, 0x08, 0x52, 0x36, 0xaa, 0x9d, 0x1e, 0x26, 0x87, 0x47,
0xca, 0x0e, 0x8e, 0xe2, 0x27, 0xf1, 0x73, 0x75, 0xe9, 0x44, 0xa7, 0x75, 0x39, 0x2f, 0x1d,
0x35, 0x84, 0x2d, 0x13, 0xf6, 0x23, 0x75, 0x74, 0xab, 0x03, 0xe0, 0x0e, 0x9c, 0xc1, 0x79,
0x9e, 0xcd, 0x8d, 0x93, 0x1e,
];

let ec_point = sec1::EncodedPoint::<U32>::from_bytes(&EXAMPLE_EC_POINT).unwrap();
let sk_key = SkEcdsaSha2NistP256::new(ec_point, "ssh:".to_string());
let key = PublicKey::from_openssh(OPENSSH_SK_ECDSA_P256_EXAMPLE).unwrap();

let ecdsa_key = key.key_data().sk_ecdsa_p256().unwrap();
assert_eq!(&sk_key, ecdsa_key);
}

#[test]
fn decode_sk_ed25519_openssh() {
let key = PublicKey::from_openssh(OPENSSH_SK_ED25519_EXAMPLE).unwrap();
Expand All @@ -318,6 +341,24 @@ fn decode_sk_ed25519_openssh() {
);
}

#[cfg(feature = "alloc")]
#[test]
fn new_sk_ed25519_openssh() {
const EXAMPLE_PUBKEY: Ed25519PublicKey = Ed25519PublicKey {
0: [
0x21, 0x68, 0xfe, 0x4e, 0x4b, 0x53, 0xcf, 0x3a, 0xde, 0xee, 0xba, 0x60, 0x2f, 0x5e,
0x50, 0xed, 0xb5, 0xef, 0x44, 0x1d, 0xba, 0x88, 0x4f, 0x51, 0x19, 0x10, 0x9d, 0xb2,
0xda, 0xfd, 0xd7, 0x33,
],
};

let sk_key = SkEd25519::new(EXAMPLE_PUBKEY, "ssh:".to_string());
let key = PublicKey::from_openssh(OPENSSH_SK_ED25519_EXAMPLE).unwrap();

let ed25519_key = key.key_data().sk_ed25519().unwrap();
assert_eq!(&sk_key, ed25519_key);
}

#[cfg(all(feature = "alloc"))]
#[test]
fn decode_custom_algorithm_openssh() {
Expand Down
Loading