| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quic/core/crypto/curve25519_key_exchange.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "absl/strings/string_view.h" |
| #include "quic/core/crypto/quic_random.h" |
| #include "quic/platform/api/quic_test.h" |
| |
| namespace quic { |
| namespace test { |
| |
| class Curve25519KeyExchangeTest : public QuicTest { |
| public: |
| // Holds the result of a key exchange callback. |
| class TestCallbackResult { |
| public: |
| void set_ok(bool ok) { ok_ = ok; } |
| bool ok() { return ok_; } |
| |
| private: |
| bool ok_ = false; |
| }; |
| |
| // Key exchange callback which sets the result into the specified |
| // TestCallbackResult. |
| class TestCallback : public AsynchronousKeyExchange::Callback { |
| public: |
| TestCallback(TestCallbackResult* result) : result_(result) {} |
| virtual ~TestCallback() = default; |
| |
| void Run(bool ok) { result_->set_ok(ok); } |
| |
| private: |
| TestCallbackResult* result_; |
| }; |
| }; |
| |
| // SharedKey just tests that the basic key exchange identity holds: that both |
| // parties end up with the same key. |
| TEST_F(Curve25519KeyExchangeTest, SharedKey) { |
| QuicRandom* const rand = QuicRandom::GetInstance(); |
| |
| for (int i = 0; i < 5; i++) { |
| const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand)); |
| const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand)); |
| |
| std::unique_ptr<Curve25519KeyExchange> alice( |
| Curve25519KeyExchange::New(alice_key)); |
| std::unique_ptr<Curve25519KeyExchange> bob( |
| Curve25519KeyExchange::New(bob_key)); |
| |
| const absl::string_view alice_public(alice->public_value()); |
| const absl::string_view bob_public(bob->public_value()); |
| |
| std::string alice_shared, bob_shared; |
| ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared)); |
| ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared)); |
| ASSERT_EQ(alice_shared, bob_shared); |
| } |
| } |
| |
| // SharedKeyAsync just tests that the basic asynchronous key exchange identity |
| // holds: that both parties end up with the same key. |
| TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) { |
| QuicRandom* const rand = QuicRandom::GetInstance(); |
| |
| for (int i = 0; i < 5; i++) { |
| const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand)); |
| const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand)); |
| |
| std::unique_ptr<Curve25519KeyExchange> alice( |
| Curve25519KeyExchange::New(alice_key)); |
| std::unique_ptr<Curve25519KeyExchange> bob( |
| Curve25519KeyExchange::New(bob_key)); |
| |
| const absl::string_view alice_public(alice->public_value()); |
| const absl::string_view bob_public(bob->public_value()); |
| |
| std::string alice_shared, bob_shared; |
| TestCallbackResult alice_result; |
| ASSERT_FALSE(alice_result.ok()); |
| alice->CalculateSharedKeyAsync( |
| bob_public, &alice_shared, |
| std::make_unique<TestCallback>(&alice_result)); |
| ASSERT_TRUE(alice_result.ok()); |
| TestCallbackResult bob_result; |
| ASSERT_FALSE(bob_result.ok()); |
| bob->CalculateSharedKeyAsync(alice_public, &bob_shared, |
| std::make_unique<TestCallback>(&bob_result)); |
| ASSERT_TRUE(bob_result.ok()); |
| ASSERT_EQ(alice_shared, bob_shared); |
| ASSERT_NE(0u, alice_shared.length()); |
| ASSERT_NE(0u, bob_shared.length()); |
| } |
| } |
| |
| } // namespace test |
| } // namespace quic |