blob: bc96d5eddb3c73703b53054cff956ffd36a17f6d [file] [log] [blame]
tengs0b8ae152015-07-23 21:23:311// Copyright 2015 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
Gyuyoung Kim6afb5082018-01-19 13:35:575#include <memory>
6
petere0807cf2015-11-20 14:46:247#include "base/base64url.h"
tengs0b8ae152015-07-23 21:23:318#include "base/bind.h"
avif57136c12015-12-25 23:27:459#include "base/macros.h"
Kyle Horimoto2693aa82017-07-27 17:08:0110#include "components/cryptauth/device_to_device_initiator_helper.h"
khorimotocec3fb22017-01-20 02:06:4811#include "components/cryptauth/device_to_device_responder_operations.h"
khorimoto999e934c2016-11-18 20:10:4212#include "components/cryptauth/fake_secure_message_delegate.h"
sacomoto005557782017-05-23 12:04:2713#include "components/cryptauth/session_keys.h"
tengs0b8ae152015-07-23 21:23:3114#include "testing/gtest/include/gtest/gtest.h"
15
khorimotocec3fb22017-01-20 02:06:4816namespace cryptauth {
tengs0b8ae152015-07-23 21:23:3117
18namespace {
19
20// The initiator's session public key in base64url form. Note that this is
21// actually a serialized proto.
22const char kInitiatorSessionPublicKeyBase64[] =
23 "CAESRQogOlH8DgPMQu7eAt-b6yoTXcazG8mAl6SPC5Ds-LTULIcSIQDZDMqsoYRO4tNMej1FB"
24 "El1sTiTiVDqrcGq-CkYCzDThw==";
25
26// The responder's session public key in base64url form. Note that this is
27// actually a serialized proto.
28const char kResponderSessionPublicKeyBase64[] =
29 "CAESRgohAN9QYU5HySO14Gi9PDIClacBnC0C8wqPwXsNHUNG_vXlEiEAggzU80ZOd9DWuCBdp"
30 "6bzpGcC-oj1yrwdVCHGg_yeaAQ=";
31
32// The long-term public key possessed by the responder device.
33const char kResponderPersistentPublicKey[] = "responder persistent public key";
34
35// Used as a callback for message creation operations to save |message| into
36// |out_message|.
37void SaveMessageResult(std::string* out_message, const std::string& message) {
38 *out_message = message;
39}
40
41// Used as a callback for validation operations to save |success| and into
42// |out_success|.
43void SaveValidationResult(bool* out_success, bool success) {
44 *out_success = success;
45}
46
47// Used as a callback for the ValidateResponderAuthMessage and
48// ValidateHelloMessage operations, saving both the outcome and the returned
49// key.
50void SaveValidationResultWithKey(bool* out_success,
51 std::string* out_key,
52 bool success,
53 const std::string& key) {
54 *out_success = success;
55 *out_key = key;
56}
57
sacomoto005557782017-05-23 12:04:2758void SaveValidationResultWithSessionKeys(bool* out_success,
59 SessionKeys* out_keys,
60 bool success,
61 const SessionKeys& keys) {
62 *out_success = success;
63 *out_keys = keys;
64}
65
tengs0b8ae152015-07-23 21:23:3166} // namespace
67
Kyle Horimoto2693aa82017-07-27 17:08:0168class CryptAuthDeviceToDeviceOperationsTest : public testing::Test {
tengs0b8ae152015-07-23 21:23:3169 protected:
Kyle Horimoto2693aa82017-07-27 17:08:0170 CryptAuthDeviceToDeviceOperationsTest() {}
71 ~CryptAuthDeviceToDeviceOperationsTest() override {}
tengs0b8ae152015-07-23 21:23:3172
73 void SetUp() override {
petere0807cf2015-11-20 14:46:2474 ASSERT_TRUE(
75 base::Base64UrlDecode(kInitiatorSessionPublicKeyBase64,
76 base::Base64UrlDecodePolicy::REQUIRE_PADDING,
77 &local_session_public_key_));
tengs0b8ae152015-07-23 21:23:3178 local_session_private_key_ =
79 secure_message_delegate_.GetPrivateKeyForPublicKey(
80 local_session_public_key_);
81
petere0807cf2015-11-20 14:46:2482 ASSERT_TRUE(
83 base::Base64UrlDecode(kResponderSessionPublicKeyBase64,
84 base::Base64UrlDecodePolicy::REQUIRE_PADDING,
85 &remote_session_public_key_));
tengs0b8ae152015-07-23 21:23:3186 remote_session_private_key_ =
87 secure_message_delegate_.GetPrivateKeyForPublicKey(
88 remote_session_public_key_);
89
khorimotocec3fb22017-01-20 02:06:4890 // Note: FakeSecureMessageDelegate functions are synchronous.
tengs0b8ae152015-07-23 21:23:3191 secure_message_delegate_.DeriveKey(
92 local_session_private_key_, remote_session_public_key_,
93 base::Bind(&SaveMessageResult, &session_symmetric_key_));
sacomoto005557782017-05-23 12:04:2794 session_keys_ = SessionKeys(session_symmetric_key_);
tengs0b8ae152015-07-23 21:23:3195
96 persistent_symmetric_key_ = "persistent symmetric key";
Kyle Horimoto2693aa82017-07-27 17:08:0197
Gyuyoung Kim6afb5082018-01-19 13:35:5798 helper_ = std::make_unique<DeviceToDeviceInitiatorHelper>();
tengs0b8ae152015-07-23 21:23:3199 }
100
101 // Creates the initator's [Hello] message.
102 std::string CreateHelloMessage() {
103 std::string hello_message;
Kyle Horimoto2693aa82017-07-27 17:08:01104 helper_->CreateHelloMessage(local_session_public_key_,
105 persistent_symmetric_key_,
106 &secure_message_delegate_,
107 base::Bind(&SaveMessageResult, &hello_message));
tengs0b8ae152015-07-23 21:23:31108 EXPECT_FALSE(hello_message.empty());
109 return hello_message;
110 }
111
112 // Creates the responder's [Remote Auth] message.
113 std::string CreateResponderAuthMessage(const std::string& hello_message) {
114 std::string persistent_responder_private_key =
115 secure_message_delegate_.GetPrivateKeyForPublicKey(
116 kResponderPersistentPublicKey);
117
118 std::string remote_auth_message;
119 DeviceToDeviceResponderOperations::CreateResponderAuthMessage(
120 hello_message, remote_session_public_key_, remote_session_private_key_,
121 persistent_responder_private_key, persistent_symmetric_key_,
122 &secure_message_delegate_,
123 base::Bind(&SaveMessageResult, &remote_auth_message));
124 EXPECT_FALSE(remote_auth_message.empty());
125 return remote_auth_message;
126 }
127
128 // Creates the initiator's [Initiator Auth] message.
129 std::string CreateInitiatorAuthMessage(
130 const std::string& remote_auth_message) {
131 std::string local_auth_message;
Kyle Horimoto2693aa82017-07-27 17:08:01132 helper_->CreateInitiatorAuthMessage(
sacomoto005557782017-05-23 12:04:27133 session_keys_, persistent_symmetric_key_, remote_auth_message,
tengs0b8ae152015-07-23 21:23:31134 &secure_message_delegate_,
135 base::Bind(&SaveMessageResult, &local_auth_message));
136 EXPECT_FALSE(local_auth_message.empty());
137 return local_auth_message;
138 }
139
khorimotocec3fb22017-01-20 02:06:48140 FakeSecureMessageDelegate secure_message_delegate_;
tengs0b8ae152015-07-23 21:23:31141
142 std::string persistent_symmetric_key_;
143 std::string local_session_public_key_;
144 std::string local_session_private_key_;
145 std::string remote_session_public_key_;
146 std::string remote_session_private_key_;
147 std::string session_symmetric_key_;
sacomoto005557782017-05-23 12:04:27148 SessionKeys session_keys_;
tengs0b8ae152015-07-23 21:23:31149
Kyle Horimoto2693aa82017-07-27 17:08:01150 std::unique_ptr<DeviceToDeviceInitiatorHelper> helper_;
151
152 DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceToDeviceOperationsTest);
tengs0b8ae152015-07-23 21:23:31153};
154
Kyle Horimoto2693aa82017-07-27 17:08:01155TEST_F(CryptAuthDeviceToDeviceOperationsTest, ValidateHelloMessage_Success) {
tengs0b8ae152015-07-23 21:23:31156 bool validation_success = false;
157 std::string hello_public_key;
158 DeviceToDeviceResponderOperations::ValidateHelloMessage(
159 CreateHelloMessage(), persistent_symmetric_key_,
160 &secure_message_delegate_,
161 base::Bind(&SaveValidationResultWithKey, &validation_success,
162 &hello_public_key));
163
164 EXPECT_TRUE(validation_success);
165 EXPECT_EQ(local_session_public_key_, hello_public_key);
166}
167
Kyle Horimoto2693aa82017-07-27 17:08:01168TEST_F(CryptAuthDeviceToDeviceOperationsTest, ValidateHelloMessage_Failure) {
tengs0b8ae152015-07-23 21:23:31169 bool validation_success = true;
170 std::string hello_public_key = "non-empty string";
171 DeviceToDeviceResponderOperations::ValidateHelloMessage(
172 "some random string", persistent_symmetric_key_,
173 &secure_message_delegate_,
174 base::Bind(&SaveValidationResultWithKey, &validation_success,
175 &hello_public_key));
176
177 EXPECT_FALSE(validation_success);
178 EXPECT_TRUE(hello_public_key.empty());
179}
180
Kyle Horimoto2693aa82017-07-27 17:08:01181TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31182 ValidateResponderAuthMessage_Success) {
183 std::string hello_message = CreateHelloMessage();
184 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
185
186 bool validation_success = false;
sacomoto005557782017-05-23 12:04:27187 SessionKeys session_keys;
Kyle Horimoto2693aa82017-07-27 17:08:01188 helper_->ValidateResponderAuthMessage(
tengs0b8ae152015-07-23 21:23:31189 remote_auth_message, kResponderPersistentPublicKey,
190 persistent_symmetric_key_, local_session_private_key_, hello_message,
191 &secure_message_delegate_,
sacomoto005557782017-05-23 12:04:27192 base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
193 &session_keys));
tengs0b8ae152015-07-23 21:23:31194
195 EXPECT_TRUE(validation_success);
sacomoto005557782017-05-23 12:04:27196 EXPECT_EQ(session_keys_.initiator_encode_key(),
197 session_keys.initiator_encode_key());
198 EXPECT_EQ(session_keys_.responder_encode_key(),
199 session_keys.responder_encode_key());
tengs0b8ae152015-07-23 21:23:31200}
201
Kyle Horimoto2693aa82017-07-27 17:08:01202TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31203 ValidateResponderAuthMessage_InvalidHelloMessage) {
204 std::string hello_message = CreateHelloMessage();
205 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
206
207 bool validation_success = true;
sacomoto005557782017-05-23 12:04:27208 SessionKeys session_keys("non empty");
Kyle Horimoto2693aa82017-07-27 17:08:01209 helper_->ValidateResponderAuthMessage(
tengs0b8ae152015-07-23 21:23:31210 remote_auth_message, kResponderPersistentPublicKey,
211 persistent_symmetric_key_, local_session_private_key_,
212 "invalid hello message", &secure_message_delegate_,
sacomoto005557782017-05-23 12:04:27213 base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
214 &session_keys));
tengs0b8ae152015-07-23 21:23:31215
216 EXPECT_FALSE(validation_success);
sacomoto005557782017-05-23 12:04:27217 EXPECT_TRUE(session_keys.initiator_encode_key().empty());
218 EXPECT_TRUE(session_keys.responder_encode_key().empty());
tengs0b8ae152015-07-23 21:23:31219}
220
Kyle Horimoto2693aa82017-07-27 17:08:01221TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31222 ValidateResponderAuthMessage_InvalidPSK) {
223 std::string hello_message = CreateHelloMessage();
224 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
225
226 bool validation_success = true;
sacomoto005557782017-05-23 12:04:27227 SessionKeys session_keys("non empty");
Kyle Horimoto2693aa82017-07-27 17:08:01228 helper_->ValidateResponderAuthMessage(
tengs0b8ae152015-07-23 21:23:31229 remote_auth_message, kResponderPersistentPublicKey,
230 "invalid persistent symmetric key", local_session_private_key_,
231 hello_message, &secure_message_delegate_,
sacomoto005557782017-05-23 12:04:27232 base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
233 &session_keys));
tengs0b8ae152015-07-23 21:23:31234
235 EXPECT_FALSE(validation_success);
sacomoto005557782017-05-23 12:04:27236 EXPECT_TRUE(session_keys.initiator_encode_key().empty());
237 EXPECT_TRUE(session_keys.responder_encode_key().empty());
tengs0b8ae152015-07-23 21:23:31238}
239
Kyle Horimoto2693aa82017-07-27 17:08:01240TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31241 ValidateInitiatorAuthMessage_Success) {
242 std::string hello_message = CreateHelloMessage();
243 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
244 std::string local_auth_message =
245 CreateInitiatorAuthMessage(remote_auth_message);
246
247 bool validation_success = false;
248 DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
sacomoto005557782017-05-23 12:04:27249 local_auth_message, session_keys_, persistent_symmetric_key_,
tengs0b8ae152015-07-23 21:23:31250 remote_auth_message, &secure_message_delegate_,
251 base::Bind(&SaveValidationResult, &validation_success));
252
253 EXPECT_TRUE(validation_success);
254}
255
Kyle Horimoto2693aa82017-07-27 17:08:01256TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31257 ValidateInitiatorAuthMessage_InvalidRemoteAuth) {
258 std::string hello_message = CreateHelloMessage();
259 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
260 std::string local_auth_message =
261 CreateInitiatorAuthMessage(remote_auth_message);
262
263 bool validation_success = true;
264 DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
sacomoto005557782017-05-23 12:04:27265 local_auth_message, session_keys_, persistent_symmetric_key_,
tengs0b8ae152015-07-23 21:23:31266 "invalid remote auth", &secure_message_delegate_,
267 base::Bind(&SaveValidationResult, &validation_success));
268
269 EXPECT_FALSE(validation_success);
270}
271
Kyle Horimoto2693aa82017-07-27 17:08:01272TEST_F(CryptAuthDeviceToDeviceOperationsTest,
tengs0b8ae152015-07-23 21:23:31273 ValidateInitiatorAuthMessage_InvalidPSK) {
274 std::string hello_message = CreateHelloMessage();
275 std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
276 std::string local_auth_message =
277 CreateInitiatorAuthMessage(remote_auth_message);
278
279 bool validation_success = true;
280 DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
sacomoto005557782017-05-23 12:04:27281 local_auth_message, session_keys_, "invalid persistent symmetric key",
282 remote_auth_message, &secure_message_delegate_,
tengs0b8ae152015-07-23 21:23:31283 base::Bind(&SaveValidationResult, &validation_success));
284
285 EXPECT_FALSE(validation_success);
286}
287
khorimotocec3fb22017-01-20 02:06:48288} // namespace cryptauth