1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/crypto/curve25519_key_exchange.h"
6 
7 #include <memory>
8 #include <string>
9 #include <utility>
10 
11 #include "absl/strings/string_view.h"
12 #include "quiche/quic/core/crypto/quic_random.h"
13 #include "quiche/quic/platform/api/quic_test.h"
14 
15 namespace quic {
16 namespace test {
17 
18 class Curve25519KeyExchangeTest : public QuicTest {
19  public:
20   // Holds the result of a key exchange callback.
21   class TestCallbackResult {
22    public:
set_ok(bool ok)23     void set_ok(bool ok) { ok_ = ok; }
ok()24     bool ok() { return ok_; }
25 
26    private:
27     bool ok_ = false;
28   };
29 
30   // Key exchange callback which sets the result into the specified
31   // TestCallbackResult.
32   class TestCallback : public AsynchronousKeyExchange::Callback {
33    public:
TestCallback(TestCallbackResult * result)34     TestCallback(TestCallbackResult* result) : result_(result) {}
35     virtual ~TestCallback() = default;
36 
Run(bool ok)37     void Run(bool ok) { result_->set_ok(ok); }
38 
39    private:
40     TestCallbackResult* result_;
41   };
42 };
43 
44 // SharedKey just tests that the basic key exchange identity holds: that both
45 // parties end up with the same key.
TEST_F(Curve25519KeyExchangeTest,SharedKey)46 TEST_F(Curve25519KeyExchangeTest, SharedKey) {
47   QuicRandom* const rand = QuicRandom::GetInstance();
48 
49   for (int i = 0; i < 5; i++) {
50     const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
51     const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
52 
53     std::unique_ptr<Curve25519KeyExchange> alice(
54         Curve25519KeyExchange::New(alice_key));
55     std::unique_ptr<Curve25519KeyExchange> bob(
56         Curve25519KeyExchange::New(bob_key));
57 
58     const absl::string_view alice_public(alice->public_value());
59     const absl::string_view bob_public(bob->public_value());
60 
61     std::string alice_shared, bob_shared;
62     ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
63     ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
64     ASSERT_EQ(alice_shared, bob_shared);
65   }
66 }
67 
68 // SharedKeyAsync just tests that the basic asynchronous key exchange identity
69 // holds: that both parties end up with the same key.
TEST_F(Curve25519KeyExchangeTest,SharedKeyAsync)70 TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
71   QuicRandom* const rand = QuicRandom::GetInstance();
72 
73   for (int i = 0; i < 5; i++) {
74     const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
75     const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
76 
77     std::unique_ptr<Curve25519KeyExchange> alice(
78         Curve25519KeyExchange::New(alice_key));
79     std::unique_ptr<Curve25519KeyExchange> bob(
80         Curve25519KeyExchange::New(bob_key));
81 
82     const absl::string_view alice_public(alice->public_value());
83     const absl::string_view bob_public(bob->public_value());
84 
85     std::string alice_shared, bob_shared;
86     TestCallbackResult alice_result;
87     ASSERT_FALSE(alice_result.ok());
88     alice->CalculateSharedKeyAsync(
89         bob_public, &alice_shared,
90         std::make_unique<TestCallback>(&alice_result));
91     ASSERT_TRUE(alice_result.ok());
92     TestCallbackResult bob_result;
93     ASSERT_FALSE(bob_result.ok());
94     bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
95                                  std::make_unique<TestCallback>(&bob_result));
96     ASSERT_TRUE(bob_result.ok());
97     ASSERT_EQ(alice_shared, bob_shared);
98     ASSERT_NE(0u, alice_shared.length());
99     ASSERT_NE(0u, bob_shared.length());
100   }
101 }
102 
103 }  // namespace test
104 }  // namespace quic
105