@@ -2,9 +2,9 @@ mod groups;
22use std:: marker:: PhantomData ;
33
44use byteorder:: { BigEndian , ByteOrder } ;
5- use log:: debug;
65use digest:: Digest ;
76use groups:: DH ;
7+ use log:: debug;
88use num_bigint:: BigUint ;
99use russh_cryptovec:: CryptoVec ;
1010use russh_keys:: encoding:: Encoding ;
@@ -105,16 +105,27 @@ impl<D: Digest> KexAlgorithm for DhGroupKex<D> {
105105
106106 debug ! ( "client_pubkey: {:?}" , client_pubkey) ;
107107
108- self . dh . generate_private_key ( ) ;
109- 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) ;
110115
111116 // fill exchange.
112117 exchange. server_ephemeral . clear ( ) ;
113- exchange. server_ephemeral . extend ( & server_pubkey ) ;
118+ exchange. server_ephemeral . extend ( & encoded_server_pubkey ) ;
114119
115- let shared = self
116- . dh
117- . compute_shared_secret ( DH :: decode_public_key ( client_pubkey) ) ;
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+ }
124+
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+ }
118129 self . shared_secret = Some ( biguint_to_mpint ( & shared) ) ;
119130 Ok ( ( ) )
120131 }
@@ -125,22 +136,35 @@ impl<D: Digest> KexAlgorithm for DhGroupKex<D> {
125136 client_ephemeral : & mut CryptoVec ,
126137 buf : & mut CryptoVec ,
127138 ) -> Result < ( ) , crate :: Error > {
128- self . dh . generate_private_key ( ) ;
129- 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+ }
130145
131146 // fill exchange.
147+ let encoded_pubkey = biguint_to_mpint ( client_pubkey) ;
132148 client_ephemeral. clear ( ) ;
133- client_ephemeral. extend ( & client_pubkey ) ;
149+ client_ephemeral. extend ( & encoded_pubkey ) ;
134150
135151 buf. push ( msg:: KEX_ECDH_INIT ) ;
136- buf. extend_ssh_string ( & client_pubkey ) ;
152+ buf. extend_ssh_string ( & encoded_pubkey ) ;
137153
138154 Ok ( ( ) )
139155 }
140156
141157 fn compute_shared_secret ( & mut self , remote_pubkey_ : & [ u8 ] ) -> Result < ( ) , crate :: Error > {
142158 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+
143164 let shared = self . dh . compute_shared_secret ( remote_pubkey) ;
165+ if !self . dh . validate_shared_secret ( & shared) {
166+ return Err ( crate :: Error :: Inconsistent ) ;
167+ }
144168 self . shared_secret = Some ( biguint_to_mpint ( & shared) ) ;
145169 Ok ( ( ) )
146170 }
0 commit comments