1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ use crypto_channel:: * ;
1516use matrix_sdk_base:: crypto:: types:: qr_login:: { QrCodeData , QrCodeMode , QrCodeModeData } ;
1617use serde:: { Serialize , de:: DeserializeOwned } ;
1718use tracing:: { instrument, trace} ;
1819use url:: Url ;
1920use vodozemac:: ecies:: {
20- CheckCode , Ecies , EstablishedEcies , InboundCreationResult , InitialMessage , Message ,
21- OutboundCreationResult ,
21+ CheckCode , Ecies , EstablishedEcies , InboundCreationResult , OutboundCreationResult ,
2222} ;
2323
2424use super :: {
2525 SecureChannelError as Error ,
2626 rendezvous_channel:: { InboundChannelCreationResult , RendezvousChannel } ,
2727} ;
2828use crate :: { config:: RequestConfig , http_client:: HttpClient } ;
29+ mod crypto_channel;
2930
3031const LOGIN_INITIATE_MESSAGE : & str = "MATRIX_QR_CODE_LOGIN_INITIATE" ;
3132const LOGIN_OK_MESSAGE : & str = "MATRIX_QR_CODE_LOGIN_OK" ;
3233
3334pub ( super ) struct SecureChannel {
3435 channel : RendezvousChannel ,
3536 qr_code_data : QrCodeData ,
36- ecies : Ecies ,
37+ crypto_channel : CryptoChannel ,
3738}
3839
3940impl SecureChannel {
@@ -46,12 +47,12 @@ impl SecureChannel {
4647 let rendezvous_url = channel. rendezvous_url ( ) . to_owned ( ) ;
4748 let mode_data = QrCodeModeData :: Login ;
4849
49- let ecies = Ecies :: new ( ) ;
50- let public_key = ecies . public_key ( ) ;
50+ let crypto_channel = CryptoChannel :: new_ecies ( ) ;
51+ let public_key = crypto_channel . public_key ( ) ;
5152
5253 let qr_code_data = QrCodeData { public_key, rendezvous_url, mode_data } ;
5354
54- Ok ( Self { channel, qr_code_data, ecies } )
55+ Ok ( Self { channel, qr_code_data, crypto_channel } )
5556 }
5657
5758 /// Create a new secure channel to reciprocate an existing login with.
@@ -74,21 +75,26 @@ impl SecureChannel {
7475 trace ! ( "Trying to connect the secure channel." ) ;
7576
7677 let message = self . channel . receive ( ) . await ?;
77- let message = std:: str:: from_utf8 ( & message) ?;
78- let message = InitialMessage :: decode ( message) ?;
78+ let result = self . crypto_channel . establish_inbound_channel ( & message) ?;
7979
80- let InboundCreationResult { ecies, message } =
81- self . ecies . establish_inbound_channel ( & message) ?;
82- let message = std:: str:: from_utf8 ( & message) ?;
80+ let message = std:: str:: from_utf8 ( result. plaintext ( ) ) ?;
8381
8482 trace ! ( "Received the initial secure channel message" ) ;
8583
8684 if message == LOGIN_INITIATE_MESSAGE {
87- let mut secure_channel = EstablishedSecureChannel { channel : self . channel , ecies } ;
85+ let secure_channel = match result {
86+ CryptoChannelCreationResult :: Ecies ( InboundCreationResult { ecies, .. } ) => {
87+ let crypto_channel = EstablishedCryptoChannel :: Ecies ( ecies) ;
8888
89- trace ! ( "Sending the LOGIN OK message" ) ;
89+ let mut secure_channel =
90+ EstablishedSecureChannel { channel : self . channel , crypto_channel } ;
9091
91- secure_channel. send ( LOGIN_OK_MESSAGE ) . await ?;
92+ trace ! ( "Sending the LOGIN OK message" ) ;
93+
94+ secure_channel. send ( LOGIN_OK_MESSAGE ) . await ?;
95+ secure_channel
96+ }
97+ } ;
9298
9399 Ok ( AlmostEstablishedSecureChannel { secure_channel } )
94100 } else {
@@ -122,7 +128,7 @@ impl AlmostEstablishedSecureChannel {
122128
123129pub ( super ) struct EstablishedSecureChannel {
124130 channel : RendezvousChannel ,
125- ecies : EstablishedEcies ,
131+ crypto_channel : EstablishedCryptoChannel ,
126132}
127133
128134impl EstablishedSecureChannel {
@@ -133,22 +139,30 @@ impl EstablishedSecureChannel {
133139 qr_code_data : & QrCodeData ,
134140 expected_mode : QrCodeMode ,
135141 ) -> Result < Self , Error > {
142+ enum ChannelType {
143+ Ecies ( EstablishedEcies ) ,
144+ }
145+
136146 if qr_code_data. mode ( ) == expected_mode {
137147 Err ( Error :: InvalidIntent )
138148 } else {
139149 trace ! ( "Attempting to create a new inbound secure channel from a QR code." ) ;
140150
141151 let client = HttpClient :: new ( client, RequestConfig :: short_retry ( ) ) ;
142- let ecies = Ecies :: new ( ) ;
143152
144153 // Let's establish an outbound ECIES channel, the other side won't know that
145154 // it's talking to us, the device that scanned the QR code, until it
146155 // receives and successfully decrypts the initial message. We're here encrypting
147156 // the `LOGIN_INITIATE_MESSAGE`.
148- let OutboundCreationResult { ecies, message } = ecies. establish_outbound_channel (
149- qr_code_data. public_key ,
150- LOGIN_INITIATE_MESSAGE . as_bytes ( ) ,
151- ) ?;
157+ let ( crypto_channel, encoded_message) = {
158+ let ecies = Ecies :: new ( ) ;
159+
160+ let OutboundCreationResult { ecies, message } = ecies. establish_outbound_channel (
161+ qr_code_data. public_key ,
162+ LOGIN_INITIATE_MESSAGE . as_bytes ( ) ,
163+ ) ?;
164+ ( ChannelType :: Ecies ( ecies) , message. encode ( ) . as_bytes ( ) . to_vec ( ) )
165+ } ;
152166
153167 // The other side has crated a rendezvous channel, we're going to connect to it
154168 // and send this initial encrypted message through it. The initial message on
@@ -159,25 +173,31 @@ impl EstablishedSecureChannel {
159173
160174 trace ! (
161175 "Received the initial message from the rendezvous channel, sending the LOGIN \
162- INITIATE message"
176+ INITIATE message"
163177 ) ;
164178
165179 // Now we're sending the encrypted message through the rendezvous channel to the
166180 // other side.
167- let encoded_message = message. encode ( ) . as_bytes ( ) . to_vec ( ) ;
168181 channel. send ( encoded_message) . await ?;
169182
170183 trace ! ( "Waiting for the LOGIN OK message" ) ;
171184
172- // We can create our EstablishedSecureChannel struct now and use the
173- // convenient helpers which transparently decrypt on receival.
174- let mut ret = Self { channel, ecies } ;
175- let response = ret. receive ( ) . await ?;
185+ let ( response, channel) = match crypto_channel {
186+ ChannelType :: Ecies ( ecies) => {
187+ // We can create our EstablishedSecureChannel struct now and use the
188+ // convenient helpers which transparently decrypt on receival.
189+ let crypto_channel = EstablishedCryptoChannel :: Ecies ( ecies) ;
190+ let mut channel = Self { channel, crypto_channel } ;
191+
192+ let response = channel. receive ( ) . await ?;
193+ ( response, channel)
194+ }
195+ } ;
176196
177197 trace ! ( "Received the LOGIN OK message, maybe." ) ;
178198
179199 if response == LOGIN_OK_MESSAGE {
180- Ok ( ret )
200+ Ok ( channel )
181201 } else {
182202 Err ( Error :: SecureChannelMessage { expected : LOGIN_OK_MESSAGE , received : response } )
183203 }
@@ -188,7 +208,7 @@ impl EstablishedSecureChannel {
188208 /// both sides of the channel are indeed communicating with each other and
189209 /// not with a 3rd party.
190210 pub ( super ) fn check_code ( & self ) -> & CheckCode {
191- self . ecies . check_code ( )
211+ self . crypto_channel . check_code ( )
192212 }
193213
194214 /// Send the given message over to the other side.
@@ -210,18 +230,14 @@ impl EstablishedSecureChannel {
210230 }
211231
212232 async fn send ( & mut self , message : & str ) -> Result < ( ) , Error > {
213- let message = self . ecies . encrypt ( message. as_bytes ( ) ) ;
214- let message = message. encode ( ) ;
233+ let message = self . crypto_channel . seal ( message. as_bytes ( ) ) ;
215234
216- Ok ( self . channel . send ( message. as_bytes ( ) . to_vec ( ) ) . await ?)
235+ Ok ( self . channel . send ( message) . await ?)
217236 }
218237
219238 async fn receive ( & mut self ) -> Result < String , Error > {
220239 let message = self . channel . receive ( ) . await ?;
221- let ciphertext = std:: str:: from_utf8 ( & message) ?;
222- let message = Message :: decode ( ciphertext) ?;
223-
224- let decrypted = self . ecies . decrypt ( & message) ?;
240+ let decrypted = self . crypto_channel . open ( & message) ?;
225241
226242 Ok ( String :: from_utf8 ( decrypted) . map_err ( |e| e. utf8_error ( ) ) ?)
227243 }
0 commit comments