diff --git a/Cargo.toml b/Cargo.toml index ffef7cb801a232da512f9bc8db16c09ec5687b43..e9a518af1bbb00402d1d4d1f412373b2a61fb713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ [profile.release] opt-level = 's' -# lto = "fat" +lto = "fat" debug = 1 [patch."https://github.com/mkj/ed25519-dalek"] diff --git a/sshproto/src/cliauth.rs b/sshproto/src/cliauth.rs index fbdb977249b9bacf8069f68714c3fd49af5ebf61..421105216f179faff89936ac12221c4a61684c86 100644 --- a/sshproto/src/cliauth.rs +++ b/sshproto/src/cliauth.rs @@ -14,7 +14,7 @@ use crate::{packets::UserauthPkOk, *}; use behaviour::CliBehaviour; use client::*; use conn::RespPackets; -use packets::{AuthMethod, MethodPubKey, ParseContext, UserauthRequest}; +use packets::{MessageNumber, AuthMethod, MethodPubKey, ParseContext, UserauthRequest}; use packets::{Packet, Signature, Userauth60}; use sign::{SignKey, OwnedSig}; use sshnames::*; @@ -169,11 +169,12 @@ impl CliAuth { sig: None, signing_now: true, }), - }.into(); + }; let msg = auth::AuthSigMsg { sess_id: BinString(sess_id.as_ref()), - p: sig_packet, + msg_num: MessageNumber::SSH_MSG_USERAUTH_REQUEST as u8, + u: sig_packet, }; key.sign_serialize(&msg) } else { diff --git a/sshproto/src/kex.rs b/sshproto/src/kex.rs index 24d4c2cad68a4170052f2bff60ae2e6006809b36..a5f17e334ae7a0fbc5a24c6d154cdf6387c275f6 100644 --- a/sshproto/src/kex.rs +++ b/sshproto/src/kex.rs @@ -20,7 +20,8 @@ use namelist::LocalNames; use packets::{Packet, PubKey, Signature}; use sign::SigType; use sshnames::*; -use wireformat::{hash_mpint, hash_ser, hash_ser_length, BinString, Blob}; +use wireformat::{hash_mpint, BinString, Blob}; +use sshwire::{hash_ser, hash_ser_length}; use behaviour::{CliBehaviour, Behaviour, ServBehaviour}; // at present we only have curve25519 with sha256 diff --git a/sshproto/src/sign.rs b/sshproto/src/sign.rs index 9e9acc466311c494d9f415aa6a4e58b73ab4cc8a..e6e2288ee1eda82180de4195fe07efbc8367476b 100644 --- a/sshproto/src/sign.rs +++ b/sshproto/src/sign.rs @@ -9,10 +9,11 @@ use rand::rngs::OsRng; use ed25519_dalek as dalek; use ed25519_dalek::{Verifier, Signer}; -use crate::*; +use crate::{*, packets::ParseContext}; use sshnames::*; use packets::{PubKey, Signature, Ed25519PubKey}; use wireformat::BinString; +use sshwire::SSHEncode; use pretty_hex::PrettyHex; @@ -123,12 +124,15 @@ impl SignKey { k.try_into() } - pub(crate) fn sign_serialize<'s>(&self, msg: &'s impl serde::Serialize) -> Result<OwnedSig> { + // pub(crate) fn sign_serialize<'s>(&self, msg: &'s impl serde::Serialize) -> Result<OwnedSig> { + pub(crate) fn sign_serialize<'s>(&self, msg: &'s impl SSHEncode) -> Result<OwnedSig> { match self { SignKey::Ed25519(k) => { let exk: dalek::ExpandedSecretKey = (&k.secret).into(); exk.sign_parts(|h| { - wireformat::hash_ser(h, msg).map_err(|_| dalek::SignatureError::new()) + let mut ctx = ParseContext::default(); + ctx.method_pubkey_force_sig_bool = true; + sshwire::hash_ser(h, Some(&ctx), msg).map_err(|_| dalek::SignatureError::new()) }, &k.public) .trap() .map(|s| s.into()) diff --git a/sshproto/src/sshwire.rs b/sshproto/src/sshwire.rs index bfa5e0b7c60a34aa4d7bc75f875bf3788d8f8c29..8c30c7fb5c43f814a7a4a5f20835a5ca6b47db9c 100644 --- a/sshproto/src/sshwire.rs +++ b/sshproto/src/sshwire.rs @@ -71,6 +71,27 @@ where Ok(s.pos) } +pub fn hash_ser_length<T>(hash_ctx: &mut impl digest::DynDigest, + value: &T) -> Result<()> +where + T: SSHEncode, +{ + let len = length_enc(value)? as u32; + hash_ctx.update(&len.to_be_bytes()); + hash_ser(hash_ctx, None, value) +} + +pub fn hash_ser<T>(hash_ctx: &mut impl digest::DynDigest, + parse_ctx: Option<&ParseContext>, + value: &T) -> Result<()> +where + T: SSHEncode, +{ + let mut s = EncodeHash { hash_ctx, parse_ctx: parse_ctx.cloned() }; + value.enc(&mut s)?; + Ok(()) +} + pub fn length_enc<T>(value: &T) -> Result<usize> where T: SSHEncode, @@ -214,7 +235,7 @@ impl<'de> SSHDecode<'de> for bool { // TODO: inline seemed to help code size in wireformat? impl<'de> SSHDecode<'de> for u8 { - #[inline] + // #[inline] fn dec<S>(s: &mut S) -> Result<Self> where S: SSHSource<'de> { let t = s.take(core::mem::size_of::<u8>())?; @@ -223,7 +244,7 @@ impl<'de> SSHDecode<'de> for u8 { } impl<'de> SSHDecode<'de> for u32 { - #[inline] + // #[inline] fn dec<S>(s: &mut S) -> Result<Self> where S: SSHSource<'de> { let t = s.take(core::mem::size_of::<u32>())?; @@ -232,7 +253,7 @@ impl<'de> SSHDecode<'de> for u32 { } impl<'de: 'a, 'a> SSHDecode<'de> for &'a str { - #[inline] + // #[inline] fn dec<S>(s: &mut S) -> Result<Self> where S: SSHSource<'de> { let len = u32::dec(s)?; diff --git a/sshproto/src/traffic.rs b/sshproto/src/traffic.rs index 0ac6679411d88d0778a1a97cace7ca3229314273..31136728a98e16c78acc53ec3d3b761a55d4982b 100644 --- a/sshproto/src/traffic.rs +++ b/sshproto/src/traffic.rs @@ -180,10 +180,6 @@ impl<'a> Traffic<'a> { _ => Err(Error::bug())?, }; - let mut z = [0u8; 1000]; - let qlen = wireformat::write_ssh(&mut z, &p)?; - trace!("old {qlen} {:?}", (&z[..qlen]).hex_dump()); - // Use the remainder of our buffer to write the packet. Payload starts // after the length and padding bytes which get filled by encrypt() let wbuf = &mut self.buf[len..]; @@ -194,8 +190,6 @@ impl<'a> Traffic<'a> { trace!("Sending {p:?}"); trace!("new {plen} {:?}", (&wbuf[SSH_PAYLOAD_START..SSH_PAYLOAD_START+plen]).hex_dump()); - assert_eq!(z[..qlen], wbuf[SSH_PAYLOAD_START..SSH_PAYLOAD_START+plen]); - // Encrypt in place let elen = keys.encrypt(plen, wbuf)?; self.state = TrafState::Write { idx, len: len+elen }; diff --git a/sshproto/src/wireformat.rs b/sshproto/src/wireformat.rs index 3996647969de456cbca05d2779c33740932e061d..55169736e84dec7d66a3f8ea0bd60f094ec5e016 100644 --- a/sshproto/src/wireformat.rs +++ b/sshproto/src/wireformat.rs @@ -162,10 +162,12 @@ impl<B: Clone> Clone for Blob<B> { } } -impl<B: Serialize + Debug> Debug for Blob<B> { +impl<B: SSHEncode + Serialize + Debug> Debug for Blob<B> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let len = SeSSHBytes::get_length(&self.0) + let len = sshwire::length_enc(&self.0) .map_err(|_| ser::Error::custom(Error::bug()))?; + // let len = SeSSHBytes::get_length(&self.0) + // .map_err(|_| ser::Error::custom(Error::bug()))?; write!(f, "Blob(len={len}, {:?})", self.0) } } @@ -279,6 +281,7 @@ impl SeSSHBytes<'_> { /// Appends serialized data fn push(&mut self, v: &[u8]) -> Res { + panic!("push"); match self { SeSSHBytes::WriteBytes { target, ref mut pos } => { if *pos + v.len() > target.len() { @@ -532,6 +535,7 @@ impl<'de> DeSSHBytes<'de> { } fn take(&mut self, len: usize) -> Result<&'de [u8]> { + panic!("take"); if len > self.input.len() { return Err(Error::RanOut); }