@@ -41,6 +41,8 @@ namespace {
4141
4242using ::location::nearby::proto::connections::Medium;
4343constexpr size_t kChunkSize = 64 * 1024 ;
44+ constexpr securegcm::UKey2Handshake::HandshakeCipher kCipher =
45+ securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
4446
4547class FakeEndpointChannel : public EndpointChannel {
4648 public:
@@ -193,6 +195,228 @@ TEST(EncryptionRunnerTest, ReadWrite) {
193195 EXPECT_EQ (response.client_status , Response::Status::kDone );
194196}
195197
198+ TEST (EncryptionRunnerTest, ClientWriteFails) {
199+ auto from_a_to_b = CreatePipe ();
200+ auto from_b_to_a = CreatePipe ();
201+ User user_a (/* reader=*/ from_b_to_a.first .get (),
202+ /* writer=*/ from_a_to_b.second .get ());
203+ User user_b (/* reader=*/ from_a_to_b.first .get (),
204+ /* writer=*/ from_b_to_a.second .get ());
205+ Response response;
206+ response.latch = CountDownLatch (1 );
207+
208+ // Close server's input stream, so client can't write to it.
209+ from_b_to_a.first ->Close ();
210+
211+ user_b.crypto .StartClient (
212+ &user_b.client , " endpoint_id" , &user_b.channel ,
213+ {
214+ .on_success_cb =
215+ [&response](const std::string& endpoint_id,
216+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
217+ const std::string& auth_token,
218+ const ByteArray& raw_auth_token) {
219+ response.client_status = Response::Status::kDone ;
220+ response.latch .CountDown ();
221+ },
222+ .on_failure_cb =
223+ [&response](const std::string& endpoint_id,
224+ EndpointChannel* channel) {
225+ response.client_status = Response::Status::kFailed ;
226+ response.latch .CountDown ();
227+ },
228+ });
229+ EXPECT_TRUE (response.latch .Await (absl::Milliseconds (5000 )).result ());
230+ EXPECT_EQ (response.client_status , Response::Status::kFailed );
231+ }
232+
233+ TEST (EncryptionRunnerTest, ServerWriteFails) {
234+ auto from_a_to_b = CreatePipe ();
235+ auto from_b_to_a = CreatePipe ();
236+ User user_a (/* reader=*/ from_b_to_a.first .get (),
237+ /* writer=*/ from_a_to_b.second .get ());
238+ User user_b (/* reader=*/ from_a_to_b.first .get (),
239+ /* writer=*/ from_b_to_a.second .get ());
240+ Response response;
241+ response.latch = CountDownLatch (1 );
242+
243+ // Close client's input stream, so server can't write to it.
244+ from_a_to_b.first ->Close ();
245+
246+ user_a.crypto .StartServer (
247+ &user_a.client , " endpoint_id" , &user_a.channel ,
248+ {
249+ .on_success_cb =
250+ [&response](const std::string& endpoint_id,
251+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
252+ const std::string& auth_token,
253+ const ByteArray& raw_auth_token) {
254+ response.server_status = Response::Status::kDone ;
255+ response.latch .CountDown ();
256+ },
257+ .on_failure_cb =
258+ [&response](const std::string& endpoint_id,
259+ EndpointChannel* channel) {
260+ response.server_status = Response::Status::kFailed ;
261+ response.latch .CountDown ();
262+ },
263+ });
264+ user_b.crypto .StartClient (
265+ &user_b.client , " endpoint_id" , &user_b.channel ,
266+ {
267+ .on_success_cb =
268+ [](const std::string& endpoint_id,
269+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
270+ const std::string& auth_token,
271+ const ByteArray& raw_auth_token) {},
272+ .on_failure_cb =
273+ [](const std::string& endpoint_id, EndpointChannel* channel) {},
274+ });
275+ EXPECT_TRUE (response.latch .Await (absl::Milliseconds (5000 )).result ());
276+ EXPECT_EQ (response.server_status , Response::Status::kFailed );
277+ }
278+
279+ TEST (EncryptionRunnerTest, ClientSendsGarbageMessage1) {
280+ auto from_server_to_client = CreatePipe ();
281+ auto from_client_to_server = CreatePipe ();
282+ User user_a (/* reader=*/ from_client_to_server.first .get (),
283+ /* writer=*/ from_server_to_client.second .get ());
284+ Response response;
285+ response.latch = CountDownLatch (1 );
286+
287+ user_a.crypto .StartServer (
288+ &user_a.client , " endpoint_id" , &user_a.channel ,
289+ {
290+ .on_success_cb =
291+ [&response](const std::string& endpoint_id,
292+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
293+ const std::string& auth_token,
294+ const ByteArray& raw_auth_token) {
295+ response.server_status = Response::Status::kDone ;
296+ response.latch .CountDown ();
297+ },
298+ .on_failure_cb =
299+ [&response](const std::string& endpoint_id,
300+ EndpointChannel* channel) {
301+ response.server_status = Response::Status::kFailed ;
302+ response.latch .CountDown ();
303+ },
304+ });
305+
306+ // Client writes garbage instead of message 1
307+ from_client_to_server.second ->Write (" Garbage" );
308+
309+ EXPECT_TRUE (response.latch .Await (absl::Milliseconds (5000 )).result ());
310+ EXPECT_EQ (response.server_status , Response::Status::kFailed );
311+
312+ // Check if server sent alert message.
313+ // The alert message should be readable from from_server_to_client.first.
314+ auto alert = from_server_to_client.first ->Read (kChunkSize );
315+ EXPECT_TRUE (alert.ok ());
316+ EXPECT_FALSE (alert.result ().Empty ());
317+ }
318+
319+ TEST (EncryptionRunnerTest, ServerSendsGarbageMessage2) {
320+ auto from_server_to_client = CreatePipe ();
321+ auto from_client_to_server = CreatePipe ();
322+ User user_b (/* reader=*/ from_server_to_client.first .get (),
323+ /* writer=*/ from_client_to_server.second .get ());
324+ Response response;
325+ response.latch = CountDownLatch (1 );
326+
327+ user_b.crypto .StartClient (
328+ &user_b.client , " endpoint_id" , &user_b.channel ,
329+ {
330+ .on_success_cb =
331+ [&response](const std::string& endpoint_id,
332+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
333+ const std::string& auth_token,
334+ const ByteArray& raw_auth_token) {
335+ response.client_status = Response::Status::kDone ;
336+ response.latch .CountDown ();
337+ },
338+ .on_failure_cb =
339+ [&response](const std::string& endpoint_id,
340+ EndpointChannel* channel) {
341+ response.client_status = Response::Status::kFailed ;
342+ response.latch .CountDown ();
343+ },
344+ });
345+
346+ // Client sends message 1.
347+ auto client_init = from_client_to_server.first ->Read (kChunkSize );
348+ EXPECT_TRUE (client_init.ok ());
349+
350+ // Server writes garbage instead of message 2.
351+ from_server_to_client.second ->Write (" Garbage" );
352+
353+ EXPECT_TRUE (response.latch .Await (absl::Milliseconds (5000 )).result ());
354+ EXPECT_EQ (response.client_status , Response::Status::kFailed );
355+
356+ // Check if client sent alert message.
357+ auto alert = from_client_to_server.first ->Read (kChunkSize );
358+ EXPECT_TRUE (alert.ok ());
359+ EXPECT_FALSE (alert.result ().Empty ());
360+ }
361+
362+ TEST (EncryptionRunnerTest, ClientSendsGarbageMessage3) {
363+ auto from_server_to_client = CreatePipe ();
364+ auto from_client_to_server = CreatePipe ();
365+ User user_a (/* reader=*/ from_client_to_server.first .get (),
366+ /* writer=*/ from_server_to_client.second .get ());
367+ User user_b (/* reader=*/ from_server_to_client.first .get (),
368+ /* writer=*/ from_client_to_server.second .get ());
369+ Response response;
370+ response.latch = CountDownLatch (1 );
371+
372+ user_a.crypto .StartServer (
373+ &user_a.client , " endpoint_id" , &user_a.channel ,
374+ {
375+ .on_success_cb =
376+ [&response](const std::string& endpoint_id,
377+ std::unique_ptr<securegcm::UKey2Handshake> ukey2,
378+ const std::string& auth_token,
379+ const ByteArray& raw_auth_token) {
380+ response.server_status = Response::Status::kDone ;
381+ response.latch .CountDown ();
382+ },
383+ .on_failure_cb =
384+ [&response](const std::string& endpoint_id,
385+ EndpointChannel* channel) {
386+ response.server_status = Response::Status::kFailed ;
387+ response.latch .CountDown ();
388+ },
389+ });
390+
391+ // Client starts, sends message 1
392+ std::unique_ptr<securegcm::UKey2Handshake> client_crypto =
393+ securegcm::UKey2Handshake::ForInitiator (kCipher );
394+ std::unique_ptr<std::string> client_init_str =
395+ client_crypto->GetNextHandshakeMessage ();
396+ from_client_to_server.second ->Write (
397+ ByteArray (*client_init_str).AsStringView ());
398+
399+ // Server reads message 1, sends message 2.
400+ // Read message 2 from server
401+ auto server_init = from_server_to_client.first ->Read (kChunkSize );
402+ EXPECT_TRUE (server_init.ok ());
403+
404+ // Client crypto parses message 2.
405+ client_crypto->ParseHandshakeMessage (std::string (server_init.result ()));
406+
407+ // Client sends garbage instead of message 3
408+ from_client_to_server.second ->Write (" Garbage" );
409+
410+ EXPECT_TRUE (response.latch .Await (absl::Milliseconds (5000 )).result ());
411+ EXPECT_EQ (response.server_status , Response::Status::kFailed );
412+
413+ // Check if server sent alert message.
414+ // Message 3 doesn't send alert in current UKEY2 implementation.
415+ auto alert = from_server_to_client.first ->Read (kChunkSize );
416+ EXPECT_TRUE (alert.ok ());
417+ EXPECT_TRUE (alert.result ().Empty ());
418+ }
419+
196420} // namespace
197421} // namespace connections
198422} // namespace nearby
0 commit comments