From 843dd3bfed23dd7c5f4a79e35b41ffd46ee750c1 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:59:10 +0200 Subject: [PATCH] better logs and stuff --- ssh-transport/src/crypto.rs | 2 -- ssh-transport/src/lib.rs | 30 +++++++++++++++++------------- ssh-transport/src/packet.rs | 24 +++++------------------- ssh-transport/src/packet/ctors.rs | 6 ++++++ ssh-transport/src/parse.rs | 4 ++++ 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/ssh-transport/src/crypto.rs b/ssh-transport/src/crypto.rs index b7ebebb..70326e9 100644 --- a/ssh-transport/src/crypto.rs +++ b/ssh-transport/src/crypto.rs @@ -231,10 +231,8 @@ impl Session { algorithm: alg_c2s, state: { let mut state = derive_key(k, h, "C", session_id, alg_c2s.key_size); - eprintln!("k={state:x?}"); let iv = derive_key(k, h, "A", session_id, alg_c2s.iv_size); state.extend_from_slice(&iv); - eprintln!("n={iv:x?}"); state }, }, diff --git a/ssh-transport/src/lib.rs b/ssh-transport/src/lib.rs index fa9cda8..0cb5217 100644 --- a/ssh-transport/src/lib.rs +++ b/ssh-transport/src/lib.rs @@ -9,8 +9,8 @@ use std::{collections::VecDeque, mem::take}; use crypto::{AlgorithmName, AlgorithmNegotiation, EncryptionAlgorithm}; use ed25519_dalek::ed25519::signature::Signer; use packet::{ - DhKeyExchangeInitReplyPacket, KeyExchangeEcDhInitPacket, KeyExchangeInitPacket, Packet, - PacketTransport, SshPublicKey, SshSignature, + KeyExchangeEcDhInitPacket, KeyExchangeInitPacket, Packet, PacketTransport, SshPublicKey, + SshSignature, }; use parse::{NameList, Parser, Writer}; use rand::RngCore; @@ -193,6 +193,7 @@ impl ServerConnection { ], }; let kex_algorithm = kex_algorithms.find(kex.kex_algorithms.0)?; + debug!(name = %kex_algorithm.name(), "Using KEX algorithm"); let server_host_key_algorithm = require_algorithm("ssh-ed25519", kex.server_host_key_algorithms)?; @@ -206,8 +207,12 @@ impl ServerConnection { let encryption_client_to_server = encryption_algorithms_client_to_server .find(kex.encryption_algorithms_client_to_server.0)?; + debug!(name = %encryption_client_to_server.name(), "Using encryption algorithm C->S"); + let encryption_server_to_client = encryption_algorithms_server_to_client .find(kex.encryption_algorithms_server_to_client.0)?; + debug!(name = %encryption_server_to_client.name(), "Using encryption algorithm S->C"); + let mac_algorithm_client_to_server = require_algorithm("hmac-sha2-256", kex.mac_algorithms_client_to_server)?; let mac_algorithm_server_to_client = @@ -275,7 +280,6 @@ impl ServerConnection { encryption_client_to_server, encryption_server_to_client, } => { - // TODO: move to keys.rs let dh = KeyExchangeEcDhInitPacket::parse(&packet.payload)?; let client_public_key = dh.qc; @@ -312,7 +316,7 @@ impl ServerConnection { ); // V_S hash_string(&mut hash, client_kexinit); // I_C hash_string(&mut hash, server_kexinit); // I_S - add_hash(&mut hash, &pub_hostkey.to_bytes()); // K_S + hash_string(&mut hash, &pub_hostkey.to_bytes()); // K_S // For normal DH as in RFC4253, e and f are mpints. // But for ECDH as defined in RFC5656, Q_C and Q_S are strings. @@ -333,17 +337,17 @@ impl ServerConnection { // eprintln!("shared_secret: {:x?}", shared_secret.as_bytes()); // eprintln!("hash: {:x?}", hash); - let packet = DhKeyExchangeInitReplyPacket { - public_host_key: pub_hostkey, - ephemeral_public_key: &server_public_key, - signature: SshSignature { + let packet = Packet::new_msg_kex_ecdh_reply( + &pub_hostkey.to_bytes(), + &server_public_key, + &SshSignature { format: b"ssh-ed25519", data: &signature.to_bytes(), - }, - }; - self.packet_transport.queue_packet(Packet { - payload: packet.to_bytes(), - }); + } + .to_bytes(), + ); + + self.packet_transport.queue_packet(packet); self.state = ServerState::NewKeys { h: hash.into(), k: shared_secret, diff --git a/ssh-transport/src/packet.rs b/ssh-transport/src/packet.rs index dbf9202..6ad49f0 100644 --- a/ssh-transport/src/packet.rs +++ b/ssh-transport/src/packet.rs @@ -159,6 +159,7 @@ impl Packet { let payload = &bytes[1..][..payload_len]; // TODO: handle the annoying decryption special case differnt where its +0 instead of +4 + // also TODO: this depends on the cipher! //if (bytes.len() + 4) % 8 != 0 { // return Err(client_error!("full packet length must be multiple of 8: {}", bytes.len())); //} @@ -280,7 +281,7 @@ impl<'a> KeyExchangeInitPacket<'a> { let mut data = Writer::new(); data.u8(numbers::SSH_MSG_KEXINIT); - data.write(&self.cookie); + data.array(self.cookie); data.name_list(self.kex_algorithms); data.name_list(self.server_host_key_algorithms); data.name_list(self.encryption_algorithms_client_to_server); @@ -325,7 +326,6 @@ pub(crate) struct SshPublicKey<'a> { impl SshPublicKey<'_> { pub(crate) fn to_bytes(&self) -> Vec { let mut data = Writer::new(); - data.u32((4 + self.format.len() + 4 + self.data.len()) as u32); // ed25519-specific! // data.string(self.format); @@ -339,26 +339,12 @@ pub(crate) struct SshSignature<'a> { pub(crate) data: &'a [u8], } -#[derive(Debug)] -pub(crate) struct DhKeyExchangeInitReplyPacket<'a> { - /// K_S - pub(crate) public_host_key: SshPublicKey<'a>, - /// Q_S - pub(crate) ephemeral_public_key: &'a [u8], - pub(crate) signature: SshSignature<'a>, -} -impl<'a> DhKeyExchangeInitReplyPacket<'a> { +impl SshSignature<'_> { pub(crate) fn to_bytes(&self) -> Vec { let mut data = Writer::new(); - - data.u8(numbers::SSH_MSG_KEX_ECDH_REPLY); - data.write(&self.public_host_key.to_bytes()); - data.string(self.ephemeral_public_key); - - data.u32((4 + self.signature.format.len() + 4 + self.signature.data.len()) as u32); // - data.string(self.signature.format); - data.string(self.signature.data); + data.string(self.format); + data.string(self.data); data.finish() } } diff --git a/ssh-transport/src/packet/ctors.rs b/ssh-transport/src/packet/ctors.rs index e7cb8ca..3d0bb55 100644 --- a/ssh-transport/src/packet/ctors.rs +++ b/ssh-transport/src/packet/ctors.rs @@ -51,6 +51,12 @@ ctors! { // 1 to 19 Transport layer generic (e.g., disconnect, ignore, debug, etc.) // 20 to 29 Algorithm negotiation // 30 to 49 Key exchange method specific (numbers can be reused for different authentication methods) + fn new_msg_kex_ecdh_init(SSH_MSG_KEX_ECDH_INIT; client_ephemeral_public_key_qc: string); + fn new_msg_kex_ecdh_reply(SSH_MSG_KEX_ECDH_REPLY; + server_public_host_key_ks: string, + server_ephemeral_public_key_qs: string, + signature: string, + ); // ----- // User authentication protocol: diff --git a/ssh-transport/src/parse.rs b/ssh-transport/src/parse.rs index 047e308..44dae6e 100644 --- a/ssh-transport/src/parse.rs +++ b/ssh-transport/src/parse.rs @@ -96,6 +96,10 @@ impl Writer { self.0.extend_from_slice(v); } + pub fn array(&mut self, arr: [u8; N]) { + self.write(&arr); + } + pub fn name_list(&mut self, list: NameList<'_>) { self.string(list.0.as_bytes()); }