Skip to content

Commit

Permalink
Implement public key fingerprint
Browse files Browse the repository at this point in the history
  • Loading branch information
honzasp committed Jul 17, 2022
1 parent d92ab78 commit 472aeea
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ path = "tests/keys/main.rs"
[dependencies]
aes = "0.8"
aes-gcm = "^0.10.0-pre"
base64 = "^0.13"
bcrypt-pbkdf = "0.9"
bytes = "1.1"
cbc = "0.1"
Expand Down
3 changes: 2 additions & 1 deletion examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ async fn verify_pubkey(
accept_tx: makiko::AcceptPubkeySender,
) -> Result<()> {
log::info!("verifying server pubkey: {}", pubkey);
let prompt = format!("ssh: server pubkey: {}\nssh: do you want to connect?", pubkey);
let prompt = format!("ssh: server pubkey fingerprint {}\nssh: do you want to connect?",
pubkey.fingerprint());
if ask_yes_no(&prompt).await? {
accept_tx.accept();
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ pub use self::mac::MacAlgo;
pub use self::pubkey::{PubkeyAlgo, Pubkey, Privkey};

pub use bytes;
pub use ecdsa;
pub use ecdsa::elliptic_curve;
pub use ed25519_dalek;
pub use rsa;
pub use p256;
pub use p384;
pub use ecdsa;
pub use ecdsa::elliptic_curve;
pub use rsa;

pub mod cipher;
mod client;
Expand Down
27 changes: 25 additions & 2 deletions src/pubkey/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,36 @@ impl Pubkey {
}
}

pub(crate) fn decode(blob: Bytes) -> Result<Self> {
/// Decode a public key from SSH wire encoding.
///
/// This is the encoding initially defined by RFC 4253. For keys other than RSA, the encoding
/// is defined in the RFC that introduces the key type.
pub fn decode(blob: Bytes) -> Result<Self> {
decode_pubkey(blob)
}

pub(crate) fn encode(&self) -> Bytes {
/// Encode a public key into SSH encoding.
///
/// This is the encoding initially defined by RFC 4253. For keys other than RSA, the encoding
/// is defined in the RFC that introduces the key type.
///
/// You can use this method to calculate a digest of the public key.
pub fn encode(&self) -> Bytes {
encode_pubkey(self)
}

/// Compute a fingerprint of the public key.
///
/// The fingerprint is in the SHA-256 digest of the public key encoded with base64 (not padded
/// with `=` characters) and prefixed with `SHA256:` (e.g.
/// `"SHA256:eaBPG/rqx+IPa0Lc9KHypkG3UxjmUwerwq9CZ/xpPWM"`). If you need another format, use
/// [`encode()`][Self::encode()] to encode the key into bytes and apply a digest of your
/// choice.
pub fn fingerprint(&self) -> String {
use sha2::Digest;
let digest = sha2::Sha256::digest(self.encode());
format!("SHA256:{}", base64::encode_config(digest, base64::STANDARD_NO_PAD))
}
}

impl fmt::Display for Pubkey {
Expand Down
25 changes: 24 additions & 1 deletion tests/keys/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn check_decode_privkey(expected_privkey: makiko::Privkey, pem_data: &str, passw
}

#[test]
#[should_panic] // this is not implemented
#[should_panic] // this functionality is not implemented
fn test_decode_encrypted_rsa_aes128_gcm() {
// the `cryptography` library in Python does not support keys encrypted using aes128-gcm, so
// the keys.rs file does not contain `encrypted_rsa_aes128_gcm()`
Expand All @@ -85,3 +85,26 @@ fn test_decode_encrypted_rsa_aes128_gcm() {
assert_eq!(decoded.pubkey, decoded.privkey.pubkey());
}

fn check_fingerprint(privkey: makiko::Privkey, expected: &str) {
let fingerprint = privkey.pubkey().fingerprint();
assert_eq!(fingerprint, expected);
}

#[test] fn test_fingerprint_alice_ed25519() {
check_fingerprint(keys::alice_ed25519(), "SHA256:sBkOpFO1h8D6+8mvKFvAgaHSFLjrG3LMeXDhST/qXwY");
}
#[test] fn test_fingerprint_ruth_rsa_1024() {
check_fingerprint(keys::ruth_rsa_1024(), "SHA256:JKKfprhKd9n4BaqMcwQmdrtaMxxvaYAi3LEwfsl/j10");
}
#[test] fn test_fingerprint_ruth_rsa_2048() {
check_fingerprint(keys::ruth_rsa_2048(), "SHA256:f7yXzeoej4cteCs7EipdN2+GPWRLgtleYTpDDQzNybk");
}
#[test] fn test_fingerprint_ruth_rsa_4096() {
check_fingerprint(keys::ruth_rsa_4096(), "SHA256:eaBPG/rqx+IPa0Lc9KHypkG3UxjmUwerwq9CZ/xpPWM");
}
#[test] fn test_fingerprint_eda_ecdsa_p256() {
check_fingerprint(keys::eda_ecdsa_p256(), "SHA256:c8EWc8omrSNzIK2ipOLWju6F9Do4ypK+mf3RRbgOCXw");
}
#[test] fn test_fingerprint_eda_ecdsa_p384() {
check_fingerprint(keys::eda_ecdsa_p384(), "SHA256:8vBuizZHVX0885H8gCJQTzpf73/S9y3vT3VAHtuBikY");
}

0 comments on commit 472aeea

Please sign in to comment.