1// Copyright 2014 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 "chromeos/dbus/fake_easy_unlock_client.h" 6 7#include <string> 8 9#include "base/bind.h" 10#include "testing/gtest/include/gtest/gtest.h" 11 12namespace { 13 14// Callback for |GenerateEcP256KeyPair| method. Saves keys returned by the 15// method in |private_key_target| and |public_key_target|. 16void RecordKeyPair(std::string* private_key_target, 17 std::string* public_key_target, 18 const std::string& private_key_source, 19 const std::string& public_key_source) { 20 *private_key_target = private_key_source; 21 *public_key_target = public_key_source; 22} 23 24// Callback for |EasyUnlockClient| methods that return a single piece of data. 25// It saves the returned data in |data_target|. 26void RecordData(std::string* data_target, 27 const std::string& data_source) { 28 *data_target = data_source; 29} 30 31TEST(FakeEasyUnlockClientTest, GenerateEcP256KeyPair) { 32 chromeos::FakeEasyUnlockClient client; 33 34 std::string private_key_1; 35 std::string public_key_1; 36 client.GenerateEcP256KeyPair( 37 base::Bind(&RecordKeyPair, &private_key_1, &public_key_1)); 38 ASSERT_EQ("{\"ec_p256_private_key\": 1}", private_key_1); 39 ASSERT_EQ("{\"ec_p256_public_key\": 1}", public_key_1); 40 41 std::string private_key_2; 42 std::string public_key_2; 43 client.GenerateEcP256KeyPair( 44 base::Bind(&RecordKeyPair, &private_key_2, &public_key_2)); 45 ASSERT_EQ("{\"ec_p256_private_key\": 2}", private_key_2); 46 ASSERT_EQ("{\"ec_p256_public_key\": 2}", public_key_2); 47 48 EXPECT_NE(private_key_1, private_key_2); 49 EXPECT_NE(public_key_1, public_key_2); 50} 51 52TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair) { 53 ASSERT_TRUE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 54 "{\"ec_p256_private_key\": 12}", 55 "{\"ec_p256_public_key\": 12}")); 56} 57 58TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeysFromDiffrentPairs) { 59 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 60 "{\"ec_p256_private_key\": 12}", 61 "{\"ec_p256_public_key\": 34}")); 62} 63 64TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeyOrderSwitched) { 65 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 66 "{\"ec_p256_public_key\": 34}", 67 "{\"ec_p256_private_key\": 34}")); 68} 69 70TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidFormat) { 71 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 72 "\"ec_p256_private_key\": 12", 73 "{\"ec_p256_public_key\": 12}")); 74} 75 76TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidFormat) { 77 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 78 "{\"ec_p256_private_key\": 12}", 79 "\"ec_p256_public_key\": 12")); 80} 81 82TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidDictKey) { 83 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 84 "{\"invalid\": 12}", 85 "{\"ec_p256_public_key\": 12}")); 86} 87 88TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidDictKey) { 89 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 90 "{\"ec_p256_private_key\": 12}", 91 "{\"invalid\": 12}")); 92} 93 94TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_InvalidDictValues) { 95 ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( 96 "{\"ec_p256_private_key\": \"12\"}", 97 "{\"ec_p256_public_key\": \"12\"}")); 98} 99 100// Verifies the fake |PerformECDHKeyAgreement| method is symetric in respect to 101// key pairs from which private and public key used in the key agreement 102// originate. 103TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementSuccess) { 104 chromeos::FakeEasyUnlockClient client; 105 106 // (Fake) key pairs used in the test to generate fake shared keys. 107 const std::string private_key_1 = "{\"ec_p256_private_key\": 32}"; 108 const std::string public_key_1 = "{\"ec_p256_public_key\": 32}"; 109 110 const std::string private_key_2 = "{\"ec_p256_private_key\": 352}"; 111 const std::string public_key_2 = "{\"ec_p256_public_key\": 352}"; 112 113 const std::string private_key_3 = "{\"ec_p256_private_key\": 432}"; 114 const std::string public_key_3 = "{\"ec_p256_public_key\": 432}"; 115 116 // Generate shared key for key pairs 1 and 2, using private key from the 117 // second key pair and public key from the first key pair. 118 std::string shared_key_1; 119 client.PerformECDHKeyAgreement(private_key_2, 120 public_key_1, 121 base::Bind(&RecordData, &shared_key_1)); 122 EXPECT_FALSE(shared_key_1.empty()); 123 124 // Generate shared key for key pairs 1 and 2, using private key from the 125 // first key pair and public key from the second key pair. 126 std::string shared_key_2; 127 client.PerformECDHKeyAgreement(private_key_1, 128 public_key_2, 129 base::Bind(&RecordData, &shared_key_2)); 130 EXPECT_FALSE(shared_key_2.empty()); 131 132 // The generated keys should be equal. They were generated using keys from 133 // the same key pairs, even though key pairs from which private and public key 134 // originate were switched. 135 EXPECT_EQ(shared_key_1, shared_key_2); 136 137 // Generate a key using key pairs 1 and 3. 138 std::string shared_key_3; 139 client.PerformECDHKeyAgreement(private_key_1, 140 public_key_3, 141 base::Bind(&RecordData, &shared_key_3)); 142 EXPECT_FALSE(shared_key_3.empty()); 143 144 // The new key should be different from the previously generated ones, since 145 // the used key pairs are different. 146 EXPECT_NE(shared_key_3, shared_key_1); 147 EXPECT_NE(shared_key_3, shared_key_1); 148} 149 150TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyOrderSwitched) { 151 chromeos::FakeEasyUnlockClient client; 152 153 const std::string private_key = "{\"ec_p256_private_key\": 415}"; 154 const std::string public_key = "{\"ec_p256_public_key\": 345}"; 155 156 std::string shared_key; 157 client.PerformECDHKeyAgreement(public_key, 158 private_key, 159 base::Bind(&RecordData, &shared_key)); 160 EXPECT_TRUE(shared_key.empty()); 161} 162 163TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictKeyInvalid) { 164 chromeos::FakeEasyUnlockClient client; 165 166 const std::string private_key = "{\"ec_p256_private_key_invalid\": 415}"; 167 const std::string public_key = "{\"ec_p256_public_key_invalid\": 345}"; 168 169 std::string shared_key; 170 client.PerformECDHKeyAgreement(private_key, 171 public_key, 172 base::Bind(&RecordData, &shared_key)); 173 EXPECT_TRUE(shared_key.empty()); 174} 175 176TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictValueInvalid) { 177 chromeos::FakeEasyUnlockClient client; 178 179 const std::string private_key = "{\"ec_p256_private_key\": 415}"; 180 const std::string public_key = "{\"ec_p256_public_key\": \"345__\"}"; 181 182 std::string shared_key; 183 client.PerformECDHKeyAgreement(private_key, 184 public_key, 185 base::Bind(&RecordData, &shared_key)); 186 EXPECT_TRUE(shared_key.empty()); 187} 188 189TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyFormatInvalid) { 190 chromeos::FakeEasyUnlockClient client; 191 192 const std::string private_key = "invalid"; 193 const std::string public_key = "{\"ec_p256_public_key\": 345}"; 194 195 std::string shared_key; 196 client.PerformECDHKeyAgreement(private_key, 197 public_key, 198 base::Bind(&RecordData, &shared_key)); 199 EXPECT_TRUE(shared_key.empty()); 200} 201 202TEST(FakeEasyUnlockClientTest, CreateSecureMessage) { 203 chromeos::FakeEasyUnlockClient client; 204 205 std::string message; 206 207 chromeos::EasyUnlockClient::CreateSecureMessageOptions options; 208 options.key = "KEY"; 209 options.associated_data = "ASSOCIATED_DATA"; 210 options.public_metadata = "PUBLIC_METADATA"; 211 options.verification_key_id = "VERIFICATION_KEY_ID"; 212 options.decryption_key_id = "DECRYPTION_KEY_ID"; 213 options.encryption_type = "ENCRYPTION_TYPE"; 214 options.signature_type = "SIGNATURE_TYPE"; 215 216 client.CreateSecureMessage( 217 "PAYLOAD", 218 options, 219 base::Bind(&RecordData, &message)); 220 221 const std::string expected_message( 222 "{\"securemessage\": {" 223 "\"payload\": \"PAYLOAD\"," 224 "\"key\": \"KEY\"," 225 "\"associated_data\": \"ASSOCIATED_DATA\"," 226 "\"public_metadata\": \"PUBLIC_METADATA\"," 227 "\"verification_key_id\": \"VERIFICATION_KEY_ID\"," 228 "\"decryption_key_id\": \"DECRYPTION_KEY_ID\"," 229 "\"encryption_type\": \"ENCRYPTION_TYPE\"," 230 "\"signature_type\": \"SIGNATURE_TYPE\"}" 231 "}"); 232 ASSERT_EQ(expected_message, message); 233} 234 235TEST(FakeEasyUnlockClientTest, UnwrapSecureMessage) { 236 chromeos::FakeEasyUnlockClient client; 237 238 std::string message; 239 240 chromeos::EasyUnlockClient::UnwrapSecureMessageOptions options; 241 options.key = "KEY"; 242 options.associated_data = "ASSOCIATED_DATA"; 243 options.encryption_type = "ENCRYPTION_TYPE"; 244 options.signature_type = "SIGNATURE_TYPE"; 245 246 client.UnwrapSecureMessage( 247 "MESSAGE", 248 options, 249 base::Bind(&RecordData, &message)); 250 251 const std::string expected_message( 252 "{\"unwrapped_securemessage\": {" 253 "\"message\": \"MESSAGE\"," 254 "\"key\": \"KEY\"," 255 "\"associated_data\": \"ASSOCIATED_DATA\"," 256 "\"encryption_type\": \"ENCRYPTION_TYPE\"," 257 "\"signature_type\": \"SIGNATURE_TYPE\"}" 258 "}"); 259 ASSERT_EQ(expected_message, message); 260} 261 262} // namespace 263 264