| // Copyright 2014 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 "chromeos/dbus/fake_easy_unlock_client.h" |
| |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| // Callback for |GenerateEcP256KeyPair| method. Saves keys returned by the |
| // method in |private_key_target| and |public_key_target|. |
| void RecordKeyPair(std::string* private_key_target, |
| std::string* public_key_target, |
| const std::string& private_key_source, |
| const std::string& public_key_source) { |
| *private_key_target = private_key_source; |
| *public_key_target = public_key_source; |
| } |
| |
| // Callback for |EasyUnlockClient| methods that return a single piece of data. |
| // It saves the returned data in |data_target|. |
| void RecordData(std::string* data_target, |
| const std::string& data_source) { |
| *data_target = data_source; |
| } |
| |
| TEST(FakeEasyUnlockClientTest, GenerateEcP256KeyPair) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| std::string private_key_1; |
| std::string public_key_1; |
| client.GenerateEcP256KeyPair( |
| base::BindOnce(&RecordKeyPair, &private_key_1, &public_key_1)); |
| ASSERT_EQ("{\"ec_p256_private_key\": 1}", private_key_1); |
| ASSERT_EQ("{\"ec_p256_public_key\": 1}", public_key_1); |
| |
| std::string private_key_2; |
| std::string public_key_2; |
| client.GenerateEcP256KeyPair( |
| base::BindOnce(&RecordKeyPair, &private_key_2, &public_key_2)); |
| ASSERT_EQ("{\"ec_p256_private_key\": 2}", private_key_2); |
| ASSERT_EQ("{\"ec_p256_public_key\": 2}", public_key_2); |
| |
| EXPECT_NE(private_key_1, private_key_2); |
| EXPECT_NE(public_key_1, public_key_2); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair) { |
| ASSERT_TRUE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_private_key\": 12}", |
| "{\"ec_p256_public_key\": 12}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeysFromDiffrentPairs) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_private_key\": 12}", |
| "{\"ec_p256_public_key\": 34}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeyOrderSwitched) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_public_key\": 34}", |
| "{\"ec_p256_private_key\": 34}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidFormat) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "\"ec_p256_private_key\": 12", |
| "{\"ec_p256_public_key\": 12}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidFormat) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_private_key\": 12}", |
| "\"ec_p256_public_key\": 12")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidDictKey) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"invalid\": 12}", |
| "{\"ec_p256_public_key\": 12}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidDictKey) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_private_key\": 12}", |
| "{\"invalid\": 12}")); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_InvalidDictValues) { |
| ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( |
| "{\"ec_p256_private_key\": \"12\"}", |
| "{\"ec_p256_public_key\": \"12\"}")); |
| } |
| |
| // Verifies the fake |PerformECDHKeyAgreement| method is symetric in respect to |
| // key pairs from which private and public key used in the key agreement |
| // originate. |
| TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementSuccess) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| // (Fake) key pairs used in the test to generate fake shared keys. |
| const std::string private_key_1 = "{\"ec_p256_private_key\": 32}"; |
| const std::string public_key_1 = "{\"ec_p256_public_key\": 32}"; |
| |
| const std::string private_key_2 = "{\"ec_p256_private_key\": 352}"; |
| const std::string public_key_2 = "{\"ec_p256_public_key\": 352}"; |
| |
| const std::string private_key_3 = "{\"ec_p256_private_key\": 432}"; |
| const std::string public_key_3 = "{\"ec_p256_public_key\": 432}"; |
| |
| // Generate shared key for key pairs 1 and 2, using private key from the |
| // second key pair and public key from the first key pair. |
| std::string shared_key_1; |
| client.PerformECDHKeyAgreement(private_key_2, public_key_1, |
| base::BindOnce(&RecordData, &shared_key_1)); |
| EXPECT_FALSE(shared_key_1.empty()); |
| |
| // Generate shared key for key pairs 1 and 2, using private key from the |
| // first key pair and public key from the second key pair. |
| std::string shared_key_2; |
| client.PerformECDHKeyAgreement(private_key_1, public_key_2, |
| base::BindOnce(&RecordData, &shared_key_2)); |
| EXPECT_FALSE(shared_key_2.empty()); |
| |
| // The generated keys should be equal. They were generated using keys from |
| // the same key pairs, even though key pairs from which private and public key |
| // originate were switched. |
| EXPECT_EQ(shared_key_1, shared_key_2); |
| |
| // Generate a key using key pairs 1 and 3. |
| std::string shared_key_3; |
| client.PerformECDHKeyAgreement(private_key_1, public_key_3, |
| base::BindOnce(&RecordData, &shared_key_3)); |
| EXPECT_FALSE(shared_key_3.empty()); |
| |
| // The new key should be different from the previously generated ones, since |
| // the used key pairs are different. |
| EXPECT_NE(shared_key_3, shared_key_1); |
| EXPECT_NE(shared_key_3, shared_key_1); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyOrderSwitched) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| const std::string private_key = "{\"ec_p256_private_key\": 415}"; |
| const std::string public_key = "{\"ec_p256_public_key\": 345}"; |
| |
| std::string shared_key; |
| client.PerformECDHKeyAgreement(public_key, private_key, |
| base::BindOnce(&RecordData, &shared_key)); |
| EXPECT_TRUE(shared_key.empty()); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictKeyInvalid) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| const std::string private_key = "{\"ec_p256_private_key_invalid\": 415}"; |
| const std::string public_key = "{\"ec_p256_public_key_invalid\": 345}"; |
| |
| std::string shared_key; |
| client.PerformECDHKeyAgreement(private_key, public_key, |
| base::BindOnce(&RecordData, &shared_key)); |
| EXPECT_TRUE(shared_key.empty()); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictValueInvalid) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| const std::string private_key = "{\"ec_p256_private_key\": 415}"; |
| const std::string public_key = "{\"ec_p256_public_key\": \"345__\"}"; |
| |
| std::string shared_key; |
| client.PerformECDHKeyAgreement(private_key, public_key, |
| base::BindOnce(&RecordData, &shared_key)); |
| EXPECT_TRUE(shared_key.empty()); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyFormatInvalid) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| const std::string private_key = "invalid"; |
| const std::string public_key = "{\"ec_p256_public_key\": 345}"; |
| |
| std::string shared_key; |
| client.PerformECDHKeyAgreement(private_key, public_key, |
| base::BindOnce(&RecordData, &shared_key)); |
| EXPECT_TRUE(shared_key.empty()); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, CreateSecureMessage) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| std::string message; |
| |
| chromeos::EasyUnlockClient::CreateSecureMessageOptions options; |
| options.key = "KEY"; |
| options.associated_data = "ASSOCIATED_DATA"; |
| options.public_metadata = "PUBLIC_METADATA"; |
| options.verification_key_id = "VERIFICATION_KEY_ID"; |
| options.decryption_key_id = "DECRYPTION_KEY_ID"; |
| options.encryption_type = "ENCRYPTION_TYPE"; |
| options.signature_type = "SIGNATURE_TYPE"; |
| |
| client.CreateSecureMessage("PAYLOAD", options, |
| base::BindOnce(&RecordData, &message)); |
| |
| const std::string expected_message( |
| "{\"securemessage\": {" |
| "\"payload\": \"PAYLOAD\"," |
| "\"key\": \"KEY\"," |
| "\"associated_data\": \"ASSOCIATED_DATA\"," |
| "\"public_metadata\": \"PUBLIC_METADATA\"," |
| "\"verification_key_id\": \"VERIFICATION_KEY_ID\"," |
| "\"decryption_key_id\": \"DECRYPTION_KEY_ID\"," |
| "\"encryption_type\": \"ENCRYPTION_TYPE\"," |
| "\"signature_type\": \"SIGNATURE_TYPE\"}" |
| "}"); |
| ASSERT_EQ(expected_message, message); |
| } |
| |
| TEST(FakeEasyUnlockClientTest, UnwrapSecureMessage) { |
| chromeos::FakeEasyUnlockClient client; |
| |
| std::string message; |
| |
| chromeos::EasyUnlockClient::UnwrapSecureMessageOptions options; |
| options.key = "KEY"; |
| options.associated_data = "ASSOCIATED_DATA"; |
| options.encryption_type = "ENCRYPTION_TYPE"; |
| options.signature_type = "SIGNATURE_TYPE"; |
| |
| client.UnwrapSecureMessage("MESSAGE", options, |
| base::BindOnce(&RecordData, &message)); |
| |
| const std::string expected_message( |
| "{\"unwrapped_securemessage\": {" |
| "\"message\": \"MESSAGE\"," |
| "\"key\": \"KEY\"," |
| "\"associated_data\": \"ASSOCIATED_DATA\"," |
| "\"encryption_type\": \"ENCRYPTION_TYPE\"," |
| "\"signature_type\": \"SIGNATURE_TYPE\"}" |
| "}"); |
| ASSERT_EQ(expected_message, message); |
| } |
| |
| } // namespace |