@@ -4,6 +4,7 @@ use std::marker::PhantomData;
44use byteorder:: { BigEndian , ByteOrder } ;
55use digest:: Digest ;
66use groups:: DH ;
7+ use log:: debug;
78use num_bigint:: BigUint ;
89use russh_cryptovec:: CryptoVec ;
910use russh_keys:: encoding:: Encoding ;
@@ -104,16 +105,27 @@ impl<D: Digest> KexAlgorithm for DhGroupKex<D> {
104105
105106 debug ! ( "client_pubkey: {:?}" , client_pubkey) ;
106107
107- self . dh . generate_private_key ( ) ;
108- let server_pubkey = biguint_to_mpint ( & self . dh . generate_public_key ( ) ) ;
108+ self . dh . generate_private_key ( true ) ;
109+ let server_pubkey = & self . dh . generate_public_key ( ) ;
110+ if !self . dh . validate_public_key ( server_pubkey) {
111+ return Err ( crate :: Error :: Inconsistent ) ;
112+ }
113+
114+ let encoded_server_pubkey = biguint_to_mpint ( server_pubkey) ;
109115
110116 // fill exchange.
111117 exchange. server_ephemeral . clear ( ) ;
112- exchange. server_ephemeral . extend ( & server_pubkey) ;
118+ exchange. server_ephemeral . extend ( & encoded_server_pubkey) ;
119+
120+ let decoded_client_pubkey = DH :: decode_public_key ( client_pubkey) ;
121+ if !self . dh . validate_public_key ( & decoded_client_pubkey) {
122+ return Err ( crate :: Error :: Inconsistent ) ;
123+ }
113124
114- let shared = self
115- . dh
116- . compute_shared_secret ( DH :: decode_public_key ( client_pubkey) ) ;
125+ let shared = self . dh . compute_shared_secret ( decoded_client_pubkey) ;
126+ if !self . dh . validate_shared_secret ( & shared) {
127+ return Err ( crate :: Error :: Inconsistent ) ;
128+ }
117129 self . shared_secret = Some ( biguint_to_mpint ( & shared) ) ;
118130 Ok ( ( ) )
119131 }
@@ -124,22 +136,35 @@ impl<D: Digest> KexAlgorithm for DhGroupKex<D> {
124136 client_ephemeral : & mut CryptoVec ,
125137 buf : & mut CryptoVec ,
126138 ) -> Result < ( ) , crate :: Error > {
127- self . dh . generate_private_key ( ) ;
128- let client_pubkey = biguint_to_mpint ( & self . dh . generate_public_key ( ) ) ;
139+ self . dh . generate_private_key ( false ) ;
140+ let client_pubkey = & self . dh . generate_public_key ( ) ;
141+
142+ if !self . dh . validate_public_key ( client_pubkey) {
143+ return Err ( crate :: Error :: Inconsistent ) ;
144+ }
129145
130146 // fill exchange.
147+ let encoded_pubkey = biguint_to_mpint ( client_pubkey) ;
131148 client_ephemeral. clear ( ) ;
132- client_ephemeral. extend ( & client_pubkey ) ;
149+ client_ephemeral. extend ( & encoded_pubkey ) ;
133150
134151 buf. push ( msg:: KEX_ECDH_INIT ) ;
135- buf. extend_ssh_string ( & client_pubkey ) ;
152+ buf. extend_ssh_string ( & encoded_pubkey ) ;
136153
137154 Ok ( ( ) )
138155 }
139156
140157 fn compute_shared_secret ( & mut self , remote_pubkey_ : & [ u8 ] ) -> Result < ( ) , crate :: Error > {
141158 let remote_pubkey = DH :: decode_public_key ( remote_pubkey_) ;
159+
160+ if !self . dh . validate_public_key ( & remote_pubkey) {
161+ return Err ( crate :: Error :: Inconsistent ) ;
162+ }
163+
142164 let shared = self . dh . compute_shared_secret ( remote_pubkey) ;
165+ if !self . dh . validate_shared_secret ( & shared) {
166+ return Err ( crate :: Error :: Inconsistent ) ;
167+ }
143168 self . shared_secret = Some ( biguint_to_mpint ( & shared) ) ;
144169 Ok ( ( ) )
145170 }
0 commit comments