From 4871555a31cc2bf4a878d84300f63bbca55738a3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Mar 2022 16:07:27 -0700 Subject: [PATCH] ssh-key: add `PrivateKey::public_key` and `From` conversions Support for getting the `PublicKey` associated with a `PrivateKey`, along with `From` conversions between them and the various intermediate types. --- ssh-key/src/private.rs | 37 +++++++++++++++++++++++++++++++++- ssh-key/src/private/dsa.rs | 12 +++++++++++ ssh-key/src/private/ed25519.rs | 12 +++++++++++ ssh-key/src/private/rsa.rs | 12 +++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/ssh-key/src/private.rs b/ssh-key/src/private.rs index b6d60af4c..e4598fc11 100644 --- a/ssh-key/src/private.rs +++ b/ssh-key/src/private.rs @@ -23,7 +23,7 @@ pub use self::{ use crate::{ base64::{Decode, DecoderExt}, - public, Algorithm, CipherAlg, Error, KdfAlg, KdfOptions, Result, + public, Algorithm, CipherAlg, Error, KdfAlg, KdfOptions, PublicKey, Result, }; use core::str::FromStr; use pem_rfc7468::{self as pem, PemLabel}; @@ -128,6 +128,27 @@ impl PrivateKey { pub fn algorithm(&self) -> Algorithm { self.key_data.algorithm() } + + /// Get the [`PublicKey`] which corresponds to this private key. + pub fn public_key(&self) -> PublicKey { + PublicKey { + key_data: public::KeyData::from(&self.key_data), + #[cfg(feature = "alloc")] + comment: self.comment.clone(), + } + } +} + +impl From for PublicKey { + fn from(private_key: PrivateKey) -> PublicKey { + private_key.public_key() + } +} + +impl From<&PrivateKey> for PublicKey { + fn from(private_key: &PrivateKey) -> PublicKey { + private_key.public_key() + } } impl FromStr for PrivateKey { @@ -263,3 +284,17 @@ impl Decode for KeypairData { } } } + +impl From<&KeypairData> for public::KeyData { + fn from(keypair_data: &KeypairData) -> public::KeyData { + match keypair_data { + #[cfg(feature = "alloc")] + KeypairData::Dsa(dsa) => public::KeyData::Dsa(dsa.into()), + #[cfg(feature = "ecdsa")] + KeypairData::Ecdsa(ecdsa) => public::KeyData::Ecdsa(ecdsa.into()), + KeypairData::Ed25519(ed25519) => public::KeyData::Ed25519(ed25519.into()), + #[cfg(feature = "alloc")] + KeypairData::Rsa(rsa) => public::KeyData::Rsa(rsa.into()), + } + } +} diff --git a/ssh-key/src/private/dsa.rs b/ssh-key/src/private/dsa.rs index e30b3727f..fd3229850 100644 --- a/ssh-key/src/private/dsa.rs +++ b/ssh-key/src/private/dsa.rs @@ -71,6 +71,18 @@ impl Decode for DsaKeypair { } } +impl From for DsaPublicKey { + fn from(keypair: DsaKeypair) -> DsaPublicKey { + keypair.public + } +} + +impl From<&DsaKeypair> for DsaPublicKey { + fn from(keypair: &DsaKeypair) -> DsaPublicKey { + keypair.public.clone() + } +} + impl fmt::Debug for DsaKeypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("DsaKeypair") diff --git a/ssh-key/src/private/ed25519.rs b/ssh-key/src/private/ed25519.rs index 4dca7c6a5..c28257264 100644 --- a/ssh-key/src/private/ed25519.rs +++ b/ssh-key/src/private/ed25519.rs @@ -109,6 +109,18 @@ impl Decode for Ed25519Keypair { } } +impl From for Ed25519PublicKey { + fn from(keypair: Ed25519Keypair) -> Ed25519PublicKey { + keypair.public + } +} + +impl From<&Ed25519Keypair> for Ed25519PublicKey { + fn from(keypair: &Ed25519Keypair) -> Ed25519PublicKey { + keypair.public + } +} + impl fmt::Debug for Ed25519Keypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Ed25519Keypair") diff --git a/ssh-key/src/private/rsa.rs b/ssh-key/src/private/rsa.rs index cf01f9fd6..292707dd7 100644 --- a/ssh-key/src/private/rsa.rs +++ b/ssh-key/src/private/rsa.rs @@ -64,6 +64,18 @@ impl Decode for RsaKeypair { } } +impl From for RsaPublicKey { + fn from(keypair: RsaKeypair) -> RsaPublicKey { + keypair.public + } +} + +impl From<&RsaKeypair> for RsaPublicKey { + fn from(keypair: &RsaKeypair) -> RsaPublicKey { + keypair.public.clone() + } +} + impl fmt::Debug for RsaKeypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RsaKeypair")