From 3ebc10f19534670f52fdd61399d6fced29cd52f0 Mon Sep 17 00:00:00 2001 From: Warren Date: Sat, 20 Jun 2026 15:59:17 +0800 Subject: [PATCH] Remove dead code: compute_exchange_hash + write_ssh_mpint_to_hash in kex_complete.rs (replaced by kex_exchange.rs version) --- markbase-core/src/ssh_server/kex_complete.rs | 115 +------------------ 1 file changed, 2 insertions(+), 113 deletions(-) diff --git a/markbase-core/src/ssh_server/kex_complete.rs b/markbase-core/src/ssh_server/kex_complete.rs index fd00dee..649b754 100644 --- a/markbase-core/src/ssh_server/kex_complete.rs +++ b/markbase-core/src/ssh_server/kex_complete.rs @@ -2,12 +2,11 @@ // 参考OpenSSH kex.c: complete implementation use crate::ssh_server::crypto::SessionKeys; -use crate::ssh_server::kex::{KexProposal, KexResult}; +use crate::ssh_server::kex::KexResult; use crate::ssh_server::kex_exchange::KexExchangeHandler; use crate::ssh_server::packet::{PacketType, SshPacket}; use anyhow::{anyhow, Result}; use log::info; -use sha2::{Digest, Sha256}; /// SSH密钥交换完整状态管理(参考OpenSSH struct kex) pub struct KexState { @@ -74,54 +73,6 @@ impl KexState { ); } - /// 计算Exchange Hash(参考OpenSSH kex.c: kex_hash()) - /// H = SHA256(V_C || V_S || I_C || I_S || K_S || K_C || K_S || shared_secret) - pub fn compute_exchange_hash( - &self, - shared_secret: &[u8], - server_host_key_blob: &[u8], - client_public_key: &[u8], - server_public_key: &[u8], - ) -> Result> { - // 参考OpenSSH kex.c: kex_hash() - let mut hasher = Sha256::new(); - - // V_C: 客户端版本字符串(SSH string格式) - write_ssh_string_to_hash(&mut hasher, &self.client_version)?; - - // V_S: 服务器版本字符串(SSH string格式) - write_ssh_string_to_hash(&mut hasher, &self.server_version)?; - - // OpenSSH kexgex.c: "kexinit messages: fake header: len+SSH2_MSG_KEXINIT" - // Remove SSH_MSG_KEXINIT type byte from payloads and prepend it in exchange hash - - let client_kexinit_without_type = &self.client_kexinit_payload[1..]; - let server_kexinit_without_type = &self.server_kexinit_payload[1..]; - - hasher.update(((client_kexinit_without_type.len() + 1) as u32).to_be_bytes()); - hasher.update([20]); // SSH_MSG_KEXINIT type byte - hasher.update(client_kexinit_without_type); - - hasher.update(((server_kexinit_without_type.len() + 1) as u32).to_be_bytes()); - hasher.update([20]); // SSH_MSG_KEXINIT type byte - hasher.update(server_kexinit_without_type); - - // K_S: 服务器主机密钥blob(SSH string格式) - hasher.update(server_host_key_blob); - - // K_C: 客户端Curve25519公钥(SSH string格式) - write_ssh_bytes_to_hash(&mut hasher, client_public_key)?; - - // K_S: 服务器Curve25519公钥(SSH string格式) - write_ssh_bytes_to_hash(&mut hasher, server_public_key)?; - - // K: 共享密钥(SSH mpint格式) - // OpenSSH要求:去掉前导零 - write_ssh_mpint_to_hash(&mut hasher, shared_secret)?; - - Ok(hasher.finalize().to_vec()) - } - /// 处理SSH_MSG_NEWKEYS(参考OpenSSH kex.c: kex_input_newkeys()) pub fn handle_newkeys(&mut self, packet: &SshPacket) -> Result<()> { info!("Processing SSH_MSG_NEWKEYS"); @@ -159,72 +110,10 @@ impl KexState { } } -/// SSH string写入到hash(辅助函数) -fn write_ssh_string_to_hash(hasher: &mut Sha256, s: &str) -> Result<()> { - hasher.update((s.len() as u32).to_be_bytes()); - hasher.update(s.as_bytes()); - Ok(()) -} - -/// SSH bytes写入到hash(辅助函数) -fn write_ssh_bytes_to_hash(hasher: &mut Sha256, bytes: &[u8]) -> Result<()> { - hasher.update((bytes.len() as u32).to_be_bytes()); - hasher.update(bytes); - Ok(()) -} - -/// SSH mpint写入到hash(参考OpenSSH sshbuf_put_mpint()) -fn write_ssh_mpint_to_hash(hasher: &mut Sha256, bytes: &[u8]) -> Result<()> { - // OpenSSH要求:去掉前导零(如果最高位为1) - let mpint_bytes = if !bytes.is_empty() && bytes[0] >= 0x80 { - // 需要添加前导零(避免负数) - let mut mpint = vec![0u8]; - mpint.extend_from_slice(bytes); - mpint - } else { - bytes.to_vec() - }; - - hasher.update((mpint_bytes.len() as u32).to_be_bytes()); - hasher.update(&mpint_bytes); - - Ok(()) -} - #[cfg(test)] mod tests { use super::*; - - #[test] - fn test_exchange_hash_computation() { - let kex_result = KexResult::choose_algorithms( - &KexProposal::server_default(), - &KexProposal::client_default(), - ) - .unwrap(); - - let mut state = KexState::new( - "SSH-2.0-OpenSSH_10.2".to_string(), - "SSH-2.0-MarkBaseSSH_1.0".to_string(), - kex_result, - ) - .unwrap(); - - // Set minimal KEXINIT payloads (need at least 1 byte for packet type) - state.client_kexinit_payload = vec![20u8]; // SSH_MSG_KEXINIT type byte - state.server_kexinit_payload = vec![20u8]; // SSH_MSG_KEXINIT type byte - - let shared_secret = vec![0u8; 32]; - let host_key = vec![0u8; 32]; - let client_pub = vec![0u8; 32]; - let server_pub = vec![0u8; 32]; - - let hash = state - .compute_exchange_hash(&shared_secret, &host_key, &client_pub, &server_pub) - .unwrap(); - - assert_eq!(hash.len(), 32); // SHA256输出32字节 - } + use crate::ssh_server::kex::{KexProposal, KexResult}; #[test] fn test_newkeys_handling() {