Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: components/proximity_auth/webui/proximity_auth_webui_handler.cc

Issue 1264703003: Implement debugging local unlock keys in chrome://proximity-auth. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase + fixes Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/proximity_auth/webui/proximity_auth_webui_handler.h" 5 #include "components/proximity_auth/webui/proximity_auth_webui_handler.h"
6 6
7 #include <algorithm>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/i18n/time_formatting.h" 10 #include "base/i18n/time_formatting.h"
9 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/thread_task_runner_handle.h"
10 #include "base/time/default_clock.h" 13 #include "base/time/default_clock.h"
11 #include "base/values.h" 14 #include "base/values.h"
15 #include "components/proximity_auth/bluetooth_connection.h"
16 #include "components/proximity_auth/bluetooth_util.h"
17 #include "components/proximity_auth/client_impl.h"
12 #include "components/proximity_auth/cryptauth/base64url.h" 18 #include "components/proximity_auth/cryptauth/base64url.h"
13 #include "components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h" 19 #include "components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h"
14 #include "components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h" 20 #include "components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h"
15 #include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" 21 #include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
22 #include "components/proximity_auth/cryptauth/secure_message_delegate.h"
23 #include "components/proximity_auth/device_to_device_authenticator.h"
16 #include "components/proximity_auth/logging/logging.h" 24 #include "components/proximity_auth/logging/logging.h"
25 #include "components/proximity_auth/remote_status_update.h"
26 #include "components/proximity_auth/secure_context.h"
17 #include "components/proximity_auth/webui/cryptauth_enroller_factory_impl.h" 27 #include "components/proximity_auth/webui/cryptauth_enroller_factory_impl.h"
18 #include "components/proximity_auth/webui/proximity_auth_ui_delegate.h" 28 #include "components/proximity_auth/webui/proximity_auth_ui_delegate.h"
29 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/web_ui.h" 30 #include "content/public/browser/web_ui.h"
31 #include "device/bluetooth/bluetooth_uuid.h"
20 32
21 namespace proximity_auth { 33 namespace proximity_auth {
22 34
23 namespace { 35 namespace {
24 36
37 // The UUID of the Smart Lock Bluetooth service.
38 const char kBluetoothServiceUUID[] = "704EE561-3782-405A-A14B-2D47A2DDCDDF";
39
25 // Keys in the JSON representation of a log message. 40 // Keys in the JSON representation of a log message.
26 const char kLogMessageTextKey[] = "text"; 41 const char kLogMessageTextKey[] = "text";
27 const char kLogMessageTimeKey[] = "time"; 42 const char kLogMessageTimeKey[] = "time";
28 const char kLogMessageFileKey[] = "file"; 43 const char kLogMessageFileKey[] = "file";
29 const char kLogMessageLineKey[] = "line"; 44 const char kLogMessageLineKey[] = "line";
30 const char kLogMessageSeverityKey[] = "severity"; 45 const char kLogMessageSeverityKey[] = "severity";
31 46
32 // Keys in the JSON representation of a SyncState object for enrollment or 47 // Keys in the JSON representation of a SyncState object for enrollment or
33 // device sync. 48 // device sync.
34 const char kSyncStateLastSuccessTime[] = "lastSuccessTime"; 49 const char kSyncStateLastSuccessTime[] = "lastSuccessTime";
(...skipping 13 matching lines...) Expand all
48 dictionary->SetString(kLogMessageFileKey, log_message.file); 63 dictionary->SetString(kLogMessageFileKey, log_message.file);
49 dictionary->SetInteger(kLogMessageLineKey, log_message.line); 64 dictionary->SetInteger(kLogMessageLineKey, log_message.line);
50 dictionary->SetInteger(kLogMessageSeverityKey, 65 dictionary->SetInteger(kLogMessageSeverityKey,
51 static_cast<int>(log_message.severity)); 66 static_cast<int>(log_message.severity));
52 return dictionary.Pass(); 67 return dictionary.Pass();
53 } 68 }
54 69
55 // Keys in the JSON representation of an ExternalDeviceInfo proto. 70 // Keys in the JSON representation of an ExternalDeviceInfo proto.
56 const char kExternalDevicePublicKey[] = "publicKey"; 71 const char kExternalDevicePublicKey[] = "publicKey";
57 const char kExternalDeviceFriendlyName[] = "friendlyDeviceName"; 72 const char kExternalDeviceFriendlyName[] = "friendlyDeviceName";
73 const char kExternalDeviceBluetoothAddress[] = "bluetoothAddress";
58 const char kExternalDeviceUnlockKey[] = "unlockKey"; 74 const char kExternalDeviceUnlockKey[] = "unlockKey";
59 const char kExternalDeviceConnectionStatus[] = "connectionStatus"; 75 const char kExternalDeviceConnectionStatus[] = "connectionStatus";
76 const char kExternalDeviceRemoteState[] = "remoteState";
60 77
61 // The possible values of the |kExternalDeviceConnectionStatus| field. 78 // The possible values of the |kExternalDeviceConnectionStatus| field.
79 const char kExternalDeviceConnected[] = "connected";
62 const char kExternalDeviceDisconnected[] = "disconnected"; 80 const char kExternalDeviceDisconnected[] = "disconnected";
63 81 const char kExternalDeviceConnecting[] = "connecting";
64 // Converts an ExternalDeviceInfo proto to a JSON dictionary used in JavaScript.
65 scoped_ptr<base::DictionaryValue> ExternalDeviceInfoToDictionary(
66 const cryptauth::ExternalDeviceInfo& device_info) {
67 std::string base64_public_key;
68 Base64UrlEncode(device_info.public_key(), &base64_public_key);
69
70 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
71 dictionary->SetString(kExternalDevicePublicKey, base64_public_key);
72 dictionary->SetString(kExternalDeviceFriendlyName,
73 device_info.friendly_device_name());
74 dictionary->SetBoolean(kExternalDeviceUnlockKey, device_info.unlock_key());
75 dictionary->SetString(kExternalDeviceConnectionStatus,
76 kExternalDeviceDisconnected);
77 return dictionary.Pass();
78 }
79 82
80 // Keys in the JSON representation of an IneligibleDevice proto. 83 // Keys in the JSON representation of an IneligibleDevice proto.
81 const char kIneligibleDeviceReasons[] = "ineligibilityReasons"; 84 const char kIneligibleDeviceReasons[] = "ineligibilityReasons";
82 85
83 // Converts an IneligibleDevice proto to a JSON dictionary used in JavaScript.
84 scoped_ptr<base::DictionaryValue> IneligibleDeviceToDictionary(
85 const cryptauth::IneligibleDevice& ineligible_device) {
86 scoped_ptr<base::ListValue> ineligibility_reasons(new base::ListValue());
87 for (const std::string& reason : ineligible_device.reasons()) {
88 ineligibility_reasons->AppendString(reason);
89 }
90
91 scoped_ptr<base::DictionaryValue> device_dictionary =
92 ExternalDeviceInfoToDictionary(ineligible_device.device());
93 device_dictionary->Set(kIneligibleDeviceReasons,
94 ineligibility_reasons.Pass());
95 return device_dictionary;
96 }
97
98 // Creates a SyncState JSON object that can be passed to the WebUI. 86 // Creates a SyncState JSON object that can be passed to the WebUI.
99 scoped_ptr<base::DictionaryValue> CreateSyncStateDictionary( 87 scoped_ptr<base::DictionaryValue> CreateSyncStateDictionary(
100 double last_success_time, 88 double last_success_time,
101 double next_refresh_time, 89 double next_refresh_time,
102 bool is_recovering_from_failure, 90 bool is_recovering_from_failure,
103 bool is_enrollment_in_progress) { 91 bool is_enrollment_in_progress) {
104 scoped_ptr<base::DictionaryValue> sync_state(new base::DictionaryValue()); 92 scoped_ptr<base::DictionaryValue> sync_state(new base::DictionaryValue());
105 sync_state->SetDouble(kSyncStateLastSuccessTime, last_success_time); 93 sync_state->SetDouble(kSyncStateLastSuccessTime, last_success_time);
106 sync_state->SetDouble(kSyncStateNextRefreshTime, next_refresh_time); 94 sync_state->SetDouble(kSyncStateNextRefreshTime, next_refresh_time);
107 sync_state->SetBoolean(kSyncStateRecoveringFromFailure, 95 sync_state->SetBoolean(kSyncStateRecoveringFromFailure,
108 is_recovering_from_failure); 96 is_recovering_from_failure);
109 sync_state->SetBoolean(kSyncStateOperationInProgress, 97 sync_state->SetBoolean(kSyncStateOperationInProgress,
110 is_enrollment_in_progress); 98 is_enrollment_in_progress);
111 return sync_state; 99 return sync_state;
112 } 100 }
113 101
114 } // namespace 102 } // namespace
115 103
116 ProximityAuthWebUIHandler::ProximityAuthWebUIHandler( 104 ProximityAuthWebUIHandler::ProximityAuthWebUIHandler(
117 ProximityAuthUIDelegate* delegate) 105 ProximityAuthUIDelegate* delegate)
118 : delegate_(delegate), weak_ptr_factory_(this) { 106 : delegate_(delegate),
107 web_contents_initialized_(false),
108 weak_ptr_factory_(this) {
119 cryptauth_client_factory_ = delegate_->CreateCryptAuthClientFactory(); 109 cryptauth_client_factory_ = delegate_->CreateCryptAuthClientFactory();
120 } 110 }
121 111
122 ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() { 112 ProximityAuthWebUIHandler::~ProximityAuthWebUIHandler() {
123 LogBuffer::GetInstance()->RemoveObserver(this); 113 LogBuffer::GetInstance()->RemoveObserver(this);
124 if (enrollment_manager_)
125 enrollment_manager_->RemoveObserver(this);
126 } 114 }
127 115
128 void ProximityAuthWebUIHandler::RegisterMessages() { 116 void ProximityAuthWebUIHandler::RegisterMessages() {
129 web_ui()->RegisterMessageCallback( 117 web_ui()->RegisterMessageCallback(
130 "clearLogBuffer", base::Bind(&ProximityAuthWebUIHandler::ClearLogBuffer, 118 "clearLogBuffer", base::Bind(&ProximityAuthWebUIHandler::ClearLogBuffer,
131 base::Unretained(this))); 119 base::Unretained(this)));
132 120
133 web_ui()->RegisterMessageCallback( 121 web_ui()->RegisterMessageCallback(
134 "getLogMessages", base::Bind(&ProximityAuthWebUIHandler::GetLogMessages, 122 "getLogMessages", base::Bind(&ProximityAuthWebUIHandler::GetLogMessages,
135 base::Unretained(this))); 123 base::Unretained(this)));
136 124
137 web_ui()->RegisterMessageCallback( 125 web_ui()->RegisterMessageCallback(
138 "findEligibleUnlockDevices", 126 "findEligibleUnlockDevices",
139 base::Bind(&ProximityAuthWebUIHandler::FindEligibleUnlockDevices, 127 base::Bind(&ProximityAuthWebUIHandler::FindEligibleUnlockDevices,
140 base::Unretained(this))); 128 base::Unretained(this)));
141 129
142 web_ui()->RegisterMessageCallback( 130 web_ui()->RegisterMessageCallback(
143 "getSyncStates", base::Bind(&ProximityAuthWebUIHandler::GetSyncStates, 131 "getLocalState", base::Bind(&ProximityAuthWebUIHandler::GetLocalState,
144 base::Unretained(this))); 132 base::Unretained(this)));
145 133
146 web_ui()->RegisterMessageCallback( 134 web_ui()->RegisterMessageCallback(
147 "forceEnrollment", base::Bind(&ProximityAuthWebUIHandler::ForceEnrollment, 135 "forceEnrollment", base::Bind(&ProximityAuthWebUIHandler::ForceEnrollment,
148 base::Unretained(this))); 136 base::Unretained(this)));
149 137
150 web_ui()->RegisterMessageCallback( 138 web_ui()->RegisterMessageCallback(
151 "forceDeviceSync", base::Bind(&ProximityAuthWebUIHandler::ForceDeviceSync, 139 "forceDeviceSync", base::Bind(&ProximityAuthWebUIHandler::ForceDeviceSync,
152 base::Unretained(this))); 140 base::Unretained(this)));
153 141
154 LogBuffer::GetInstance()->AddObserver(this); 142 web_ui()->RegisterMessageCallback(
143 "toggleConnection",
144 base::Bind(&ProximityAuthWebUIHandler::ToggleConnection,
145 base::Unretained(this)));
155 146
156 InitGCMManager(); 147 InitGCMManager();
157 InitEnrollmentManager(); 148 InitEnrollmentManager();
158 InitDeviceManager(); 149 InitDeviceManager();
150 LogBuffer::GetInstance()->AddObserver(this);
159 } 151 }
160 152
161 void ProximityAuthWebUIHandler::OnLogMessageAdded( 153 void ProximityAuthWebUIHandler::OnLogMessageAdded(
162 const LogBuffer::LogMessage& log_message) { 154 const LogBuffer::LogMessage& log_message) {
163 scoped_ptr<base::DictionaryValue> dictionary = 155 scoped_ptr<base::DictionaryValue> dictionary =
164 LogMessageToDictionary(log_message); 156 LogMessageToDictionary(log_message);
165 web_ui()->CallJavascriptFunction("LogBufferInterface.onLogMessageAdded", 157 web_ui()->CallJavascriptFunction("LogBufferInterface.onLogMessageAdded",
166 *dictionary); 158 *dictionary);
167 } 159 }
168 160
169 void ProximityAuthWebUIHandler::OnLogBufferCleared() { 161 void ProximityAuthWebUIHandler::OnLogBufferCleared() {
170 web_ui()->CallJavascriptFunction("LogBufferInterface.onLogBufferCleared"); 162 web_ui()->CallJavascriptFunction("LogBufferInterface.onLogBufferCleared");
171 } 163 }
172 164
173 void ProximityAuthWebUIHandler::OnEnrollmentStarted() { 165 void ProximityAuthWebUIHandler::OnEnrollmentStarted() {
174 web_ui()->CallJavascriptFunction( 166 web_ui()->CallJavascriptFunction(
175 "SyncStateInterface.onEnrollmentStateChanged", 167 "LocalStateInterface.onEnrollmentStateChanged",
176 *GetEnrollmentStateDictionary()); 168 *GetEnrollmentStateDictionary());
177 } 169 }
178 170
179 void ProximityAuthWebUIHandler::OnEnrollmentFinished(bool success) { 171 void ProximityAuthWebUIHandler::OnEnrollmentFinished(bool success) {
180 scoped_ptr<base::DictionaryValue> enrollment_state = 172 scoped_ptr<base::DictionaryValue> enrollment_state =
181 GetEnrollmentStateDictionary(); 173 GetEnrollmentStateDictionary();
182 PA_LOG(INFO) << "Enrollment attempt completed with success=" << success 174 PA_LOG(INFO) << "Enrollment attempt completed with success=" << success
183 << ":\n" << *enrollment_state; 175 << ":\n" << *enrollment_state;
184 web_ui()->CallJavascriptFunction( 176 web_ui()->CallJavascriptFunction(
185 "SyncStateInterface.onEnrollmentStateChanged", *enrollment_state); 177 "LocalStateInterface.onEnrollmentStateChanged", *enrollment_state);
186 } 178 }
187 179
188 void ProximityAuthWebUIHandler::OnSyncStarted() { 180 void ProximityAuthWebUIHandler::OnSyncStarted() {
189 web_ui()->CallJavascriptFunction( 181 web_ui()->CallJavascriptFunction(
190 "SyncStateInterface.onDeviceSyncStateChanged", 182 "LocalStateInterface.onDeviceSyncStateChanged",
191 *GetDeviceSyncStateDictionary()); 183 *GetDeviceSyncStateDictionary());
192 } 184 }
193 185
194 void ProximityAuthWebUIHandler::OnSyncFinished( 186 void ProximityAuthWebUIHandler::OnSyncFinished(
195 CryptAuthDeviceManager::SyncResult sync_result, 187 CryptAuthDeviceManager::SyncResult sync_result,
196 CryptAuthDeviceManager::DeviceChangeResult device_change_result) { 188 CryptAuthDeviceManager::DeviceChangeResult device_change_result) {
197 scoped_ptr<base::DictionaryValue> device_sync_state = 189 scoped_ptr<base::DictionaryValue> device_sync_state =
198 GetDeviceSyncStateDictionary(); 190 GetDeviceSyncStateDictionary();
199 PA_LOG(INFO) << "Device sync completed with result=" 191 PA_LOG(INFO) << "Device sync completed with result="
200 << static_cast<int>(sync_result) << ":\n" << *device_sync_state; 192 << static_cast<int>(sync_result) << ":\n" << *device_sync_state;
201 web_ui()->CallJavascriptFunction( 193 web_ui()->CallJavascriptFunction(
202 "SyncStateInterface.onDeviceSyncStateChanged", *device_sync_state); 194 "LocalStateInterface.onDeviceSyncStateChanged", *device_sync_state);
195
196 if (device_change_result ==
197 CryptAuthDeviceManager::DeviceChangeResult::CHANGED) {
198 scoped_ptr<base::ListValue> unlock_keys = GetUnlockKeysList();
199 PA_LOG(INFO) << "New unlock keys obtained after device sync:\n"
200 << *unlock_keys;
201 web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
202 *unlock_keys);
203 }
203 } 204 }
204 205
205 void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) { 206 void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) {
206 base::ListValue json_logs; 207 base::ListValue json_logs;
207 for (const auto& log : *LogBuffer::GetInstance()->logs()) { 208 for (const auto& log : *LogBuffer::GetInstance()->logs()) {
208 json_logs.Append(LogMessageToDictionary(log).release()); 209 json_logs.Append(LogMessageToDictionary(log).release());
209 } 210 }
210 web_ui()->CallJavascriptFunction("LogBufferInterface.onGotLogMessages", 211 web_ui()->CallJavascriptFunction("LogBufferInterface.onGotLogMessages",
211 json_logs); 212 json_logs);
212 } 213 }
(...skipping 23 matching lines...) Expand all
236 enrollment_manager_->ForceEnrollmentNow( 237 enrollment_manager_->ForceEnrollmentNow(
237 cryptauth::INVOCATION_REASON_MANUAL); 238 cryptauth::INVOCATION_REASON_MANUAL);
238 } 239 }
239 } 240 }
240 241
241 void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) { 242 void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) {
242 if (device_manager_) 243 if (device_manager_)
243 device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); 244 device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL);
244 } 245 }
245 246
247 void ProximityAuthWebUIHandler::ToggleConnection(const base::ListValue* args) {
248 std::string b64_public_key;
249 std::string public_key;
250 if (!device_manager_ || !args->GetSize() ||
251 !args->GetString(0, &b64_public_key) ||
252 !Base64UrlDecode(b64_public_key, &public_key)) {
253 return;
254 }
255
256 Connection* connection = GetConnection();
257 for (const auto& unlock_key : device_manager_->unlock_keys()) {
258 if (unlock_key.public_key() == public_key) {
259 // Check if there is an existing connection to disconnect from first.
260 if (connection && connection->IsConnected() &&
261 connection->remote_device().public_key == public_key) {
262 PA_LOG(INFO) << "Disconnecting from "
263 << unlock_key.friendly_device_name() << "["
264 << unlock_key.bluetooth_address() << "]";
265 connection->Disconnect();
266 return;
267 }
268
269 // Derive the PSK before connecting to the device.
270 PA_LOG(INFO) << "Connecting to " << unlock_key.friendly_device_name()
271 << "[" << unlock_key.bluetooth_address() << "]";
272 secure_message_delegate_ = delegate_->CreateSecureMessageDelegate();
273 secure_message_delegate_->DeriveKey(
274 user_private_key_, unlock_key.public_key(),
275 base::Bind(&ProximityAuthWebUIHandler::OnPSKDerived,
276 weak_ptr_factory_.GetWeakPtr(), unlock_key));
277
278 return;
279 }
280 }
281
282 PA_LOG(ERROR) << "Unlock key (" << b64_public_key << ") not found";
283 }
284
246 void ProximityAuthWebUIHandler::InitGCMManager() { 285 void ProximityAuthWebUIHandler::InitGCMManager() {
247 gcm_manager_.reset(new CryptAuthGCMManagerImpl(delegate_->GetGCMDriver(), 286 gcm_manager_.reset(new CryptAuthGCMManagerImpl(delegate_->GetGCMDriver(),
248 delegate_->GetPrefService())); 287 delegate_->GetPrefService()));
249 } 288 }
250 289
251 void ProximityAuthWebUIHandler::InitEnrollmentManager() { 290 void ProximityAuthWebUIHandler::InitEnrollmentManager() {
252 #if defined(OS_CHROMEOS) 291 #if defined(OS_CHROMEOS)
253 // TODO(tengs): We initialize a CryptAuthEnrollmentManager here for 292 // TODO(tengs): We initialize a CryptAuthEnrollmentManager here for
254 // development and testing purposes until it is ready to be moved into Chrome. 293 // development and testing purposes until it is ready to be moved into Chrome.
255 // The public/private key pair has been generated and serialized in a previous 294 // The public/private key pair has been generated and serialized in a previous
256 // session. 295 // session.
257 std::string user_public_key;
258 Base64UrlDecode( 296 Base64UrlDecode(
259 "CAESRgohAD1lP_wgQ8XqVVwz4aK_89SqdvAQG5L_NZH5zXxwg5UbEiEAZFMlgCZ9h8OlyE4" 297 "CAESRgohAD1lP_wgQ8XqVVwz4aK_89SqdvAQG5L_NZH5zXxwg5UbEiEAZFMlgCZ9h8OlyE4"
260 "QYKY5oiOBu0FmLSKeTAXEq2jnVJI=", 298 "QYKY5oiOBu0FmLSKeTAXEq2jnVJI=",
261 &user_public_key); 299 &user_public_key_);
262 300
263 std::string user_private_key;
264 Base64UrlDecode( 301 Base64UrlDecode(
265 "MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP____8AAAABAAAAAAA" 302 "MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP____8AAAABAAAAAAA"
266 "AAAAAAAAA________________MFsEIP____8AAAABAAAAAAAAAAAAAAAA______________" 303 "AAAAAAAAA________________MFsEIP____8AAAABAAAAAAAAAAAAAAAA______________"
267 "_8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw-J9JgSwMVAMSdNgiG5wSTamZ44ROdJ" 304 "_8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw-J9JgSwMVAMSdNgiG5wSTamZ44ROdJ"
268 "reBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li_hp_m47n60p8" 305 "reBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li_hp_m47n60p8"
269 "D54WK84zV2sxXs7LtkBoN79R9QIhAP____8AAAAA__________-85vqtpxeehPO5ysL8YyV" 306 "D54WK84zV2sxXs7LtkBoN79R9QIhAP____8AAAAA__________-85vqtpxeehPO5ysL8YyV"
270 "RAgEBBG0wawIBAQQgKZ4Dsm5xe4p5U2XPGxjrG376ZWWIa9E6r0y1BdjIntyhRANCAAQ9ZT" 307 "RAgEBBG0wawIBAQQgKZ4Dsm5xe4p5U2XPGxjrG376ZWWIa9E6r0y1BdjIntyhRANCAAQ9ZT"
271 "_8IEPF6lVcM-Giv_PUqnbwEBuS_zWR-c18cIOVG2RTJYAmfYfDpchOEGCmOaIjgbtBZi0in" 308 "_8IEPF6lVcM-Giv_PUqnbwEBuS_zWR-c18cIOVG2RTJYAmfYfDpchOEGCmOaIjgbtBZi0in"
272 "kwFxKto51SS", 309 "kwFxKto51SS",
273 &user_private_key); 310 &user_private_key_);
274 311
275 // This serialized DeviceInfo proto was previously captured from a real 312 // This serialized DeviceInfo proto was previously captured from a real
276 // CryptAuth enrollment, and is replayed here for testing purposes. 313 // CryptAuth enrollment, and is replayed here for testing purposes.
277 std::string serialized_device_info; 314 std::string serialized_device_info;
278 Base64UrlDecode( 315 Base64UrlDecode(
279 "IkoIARJGCiEAX_ZjLSq73EVcrarX-7l7No7nSP86GEC322ocSZKqUKwSIQDbEDu9KN7AgLM" 316 "IkoIARJGCiEAX_ZjLSq73EVcrarX-7l7No7nSP86GEC322ocSZKqUKwSIQDbEDu9KN7AgLM"
280 "v_lzZZNui9zSOgXCeDpLhS2tgrYVXijoEbGlua0IFZW4tVVNKSggBEkYKIQBf9mMtKrvcRV" 317 "v_lzZZNui9zSOgXCeDpLhS2tgrYVXijoEbGlua0IFZW4tVVNKSggBEkYKIQBf9mMtKrvcRV"
281 "ytqtf7uXs2judI_zoYQLfbahxJkqpQrBIhANsQO70o3sCAsy_-XNlk26L3NI6BcJ4OkuFLa" 318 "ytqtf7uXs2judI_zoYQLfbahxJkqpQrBIhANsQO70o3sCAsy_-XNlk26L3NI6BcJ4OkuFLa"
282 "2CthVeKam9Nb3ppbGxhLzUuMCAoWDExOyBDck9TIHg4Nl82NCA3MTM0LjAuMCkgQXBwbGVX" 319 "2CthVeKam9Nb3ppbGxhLzUuMCAoWDExOyBDck9TIHg4Nl82NCA3MTM0LjAuMCkgQXBwbGVX"
283 "ZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzQ1LjAuMjQyMi4wIFN" 320 "ZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzQ1LjAuMjQyMi4wIFN"
(...skipping 11 matching lines...) Expand all
295 "bF9JVWY4YTJDSmJNbXFqaWpYUFYzaVV5dmJXSVRrR3d1bFRaVUs3RGVZczJtT0h5ZkQ1NWR" 332 "bF9JVWY4YTJDSmJNbXFqaWpYUFYzaVV5dmJXSVRrR3d1bFRaVUs3RGVZczJtT0h5ZkQ1NWR"
296 "HRXEtdnJTdVc4VEZ2Z1haa2xhVEZTN0dqM2xCVUktSHd5Z0h6bHZHX2NGLWtzQmw0dXdveG" 333 "HRXEtdnJTdVc4VEZ2Z1haa2xhVEZTN0dqM2xCVUktSHd5Z0h6bHZHX2NGLWtzQmw0dXdveG"
297 "VPWE1hRlJ3WGJHVUU1Tm9sLS1mdkRIcGVZVnJR", 334 "VPWE1hRlJ3WGJHVUU1Tm9sLS1mdkRIcGVZVnJR",
298 &serialized_device_info); 335 &serialized_device_info);
299 cryptauth::GcmDeviceInfo device_info; 336 cryptauth::GcmDeviceInfo device_info;
300 device_info.ParseFromString(serialized_device_info); 337 device_info.ParseFromString(serialized_device_info);
301 338
302 enrollment_manager_.reset(new CryptAuthEnrollmentManager( 339 enrollment_manager_.reset(new CryptAuthEnrollmentManager(
303 make_scoped_ptr(new base::DefaultClock()), 340 make_scoped_ptr(new base::DefaultClock()),
304 make_scoped_ptr(new CryptAuthEnrollerFactoryImpl(delegate_)), 341 make_scoped_ptr(new CryptAuthEnrollerFactoryImpl(delegate_)),
305 user_public_key, user_private_key, device_info, gcm_manager_.get(), 342 user_public_key_, user_private_key_, device_info, gcm_manager_.get(),
306 delegate_->GetPrefService())); 343 delegate_->GetPrefService()));
307 enrollment_manager_->AddObserver(this); 344 enrollment_manager_->AddObserver(this);
308 enrollment_manager_->Start(); 345 enrollment_manager_->Start();
309 #endif 346 #endif
310 } 347 }
311 348
312 void ProximityAuthWebUIHandler::InitDeviceManager() { 349 void ProximityAuthWebUIHandler::InitDeviceManager() {
313 // TODO(tengs): We initialize a CryptAuthDeviceManager here for 350 // TODO(tengs): We initialize a CryptAuthDeviceManager here for
314 // development and testing purposes until it is ready to be moved into Chrome. 351 // development and testing purposes until it is ready to be moved into Chrome.
315 device_manager_.reset(new CryptAuthDeviceManager( 352 device_manager_.reset(new CryptAuthDeviceManager(
(...skipping 23 matching lines...) Expand all
339 ineligible_devices.Append(IneligibleDeviceToDictionary(ineligible_device)); 376 ineligible_devices.Append(IneligibleDeviceToDictionary(ineligible_device));
340 } 377 }
341 378
342 PA_LOG(INFO) << "Found " << eligible_devices.GetSize() 379 PA_LOG(INFO) << "Found " << eligible_devices.GetSize()
343 << " eligible devices and " << ineligible_devices.GetSize() 380 << " eligible devices and " << ineligible_devices.GetSize()
344 << " ineligible devices."; 381 << " ineligible devices.";
345 web_ui()->CallJavascriptFunction("CryptAuthInterface.onGotEligibleDevices", 382 web_ui()->CallJavascriptFunction("CryptAuthInterface.onGotEligibleDevices",
346 eligible_devices, ineligible_devices); 383 eligible_devices, ineligible_devices);
347 } 384 }
348 385
349 void ProximityAuthWebUIHandler::GetSyncStates(const base::ListValue* args) { 386 void ProximityAuthWebUIHandler::GetLocalState(const base::ListValue* args) {
350 scoped_ptr<base::DictionaryValue> enrollment_state = 387 scoped_ptr<base::DictionaryValue> enrollment_state =
351 GetEnrollmentStateDictionary(); 388 GetEnrollmentStateDictionary();
352 scoped_ptr<base::DictionaryValue> device_sync_state = 389 scoped_ptr<base::DictionaryValue> device_sync_state =
353 GetDeviceSyncStateDictionary(); 390 GetDeviceSyncStateDictionary();
354 PA_LOG(INFO) << "Enrollment State: \n" << *enrollment_state 391 scoped_ptr<base::ListValue> unlock_keys = GetUnlockKeysList();
355 << "Device Sync State: \n" << *device_sync_state; 392
356 web_ui()->CallJavascriptFunction("SyncStateInterface.onGotSyncStates", 393 PA_LOG(INFO) << "==== Got Local State ====\n"
357 *enrollment_state, *device_sync_state); 394 << "Enrollment State: \n" << *enrollment_state
395 << "Device Sync State: \n" << *device_sync_state
396 << "Unlock Keys: \n" << *unlock_keys;
397 web_ui()->CallJavascriptFunction("LocalStateInterface.onGotLocalState",
398 *enrollment_state, *device_sync_state,
399 *unlock_keys);
358 } 400 }
359 401
360 scoped_ptr<base::DictionaryValue> 402 scoped_ptr<base::DictionaryValue>
361 ProximityAuthWebUIHandler::GetEnrollmentStateDictionary() { 403 ProximityAuthWebUIHandler::GetEnrollmentStateDictionary() {
362 if (!enrollment_manager_) 404 if (!enrollment_manager_)
363 return make_scoped_ptr(new base::DictionaryValue()); 405 return make_scoped_ptr(new base::DictionaryValue());
364 406
365 return CreateSyncStateDictionary( 407 return CreateSyncStateDictionary(
366 enrollment_manager_->GetLastEnrollmentTime().ToJsTime(), 408 enrollment_manager_->GetLastEnrollmentTime().ToJsTime(),
367 enrollment_manager_->GetTimeToNextAttempt().InMillisecondsF(), 409 enrollment_manager_->GetTimeToNextAttempt().InMillisecondsF(),
368 enrollment_manager_->IsRecoveringFromFailure(), 410 enrollment_manager_->IsRecoveringFromFailure(),
369 enrollment_manager_->IsEnrollmentInProgress()); 411 enrollment_manager_->IsEnrollmentInProgress());
370 } 412 }
371 413
372 scoped_ptr<base::DictionaryValue> 414 scoped_ptr<base::DictionaryValue>
373 ProximityAuthWebUIHandler::GetDeviceSyncStateDictionary() { 415 ProximityAuthWebUIHandler::GetDeviceSyncStateDictionary() {
374 if (!device_manager_) 416 if (!device_manager_)
375 return make_scoped_ptr(new base::DictionaryValue()); 417 return make_scoped_ptr(new base::DictionaryValue());
376 418
377 return CreateSyncStateDictionary( 419 return CreateSyncStateDictionary(
378 device_manager_->GetLastSyncTime().ToJsTime(), 420 device_manager_->GetLastSyncTime().ToJsTime(),
379 device_manager_->GetTimeToNextAttempt().InMillisecondsF(), 421 device_manager_->GetTimeToNextAttempt().InMillisecondsF(),
380 device_manager_->IsRecoveringFromFailure(), 422 device_manager_->IsRecoveringFromFailure(),
381 device_manager_->IsSyncInProgress()); 423 device_manager_->IsSyncInProgress());
382 } 424 }
383 425
426 scoped_ptr<base::ListValue> ProximityAuthWebUIHandler::GetUnlockKeysList() {
427 scoped_ptr<base::ListValue> unlock_keys(new base::ListValue());
428 if (!device_manager_)
429 return unlock_keys;
430
431 for (const auto& unlock_key : device_manager_->unlock_keys()) {
432 unlock_keys->Append(ExternalDeviceInfoToDictionary(unlock_key));
433 }
434
435 return unlock_keys;
436 }
437
438 Connection* ProximityAuthWebUIHandler::GetConnection() {
439 Connection* connection = bluetooth_connection_.get();
440 if (client_) {
441 DCHECK(!connection);
442 connection = client_->connection();
443 }
444 return connection;
445 }
446
447 void ProximityAuthWebUIHandler::OnPSKDerived(
448 const cryptauth::ExternalDeviceInfo& unlock_key,
449 const std::string& persistent_symmetric_key) {
450 if (persistent_symmetric_key.empty()) {
451 PA_LOG(ERROR) << "Failed to derive PSK.";
452 return;
453 }
454
455 RemoteDevice remote_device(
456 unlock_key.friendly_device_name(), unlock_key.public_key(),
457 unlock_key.bluetooth_address(), persistent_symmetric_key);
458
459 bluetooth_connection_.reset(new BluetoothConnection(
460 remote_device, device::BluetoothUUID(kBluetoothServiceUUID)));
461 bluetooth_connection_->AddObserver(this);
462
463 // This SeekDeviceByAddress operation is needed to connect to a device if
464 // it is not already known to the local device.
465 bluetooth_util::SeekDeviceByAddress(
466 remote_device.bluetooth_address,
467 base::Bind(&ProximityAuthWebUIHandler::OnSeekedDeviceByAddress,
468 weak_ptr_factory_.GetWeakPtr()),
469 base::Bind(&ProximityAuthWebUIHandler::OnSeekedDeviceByAddressError,
470 weak_ptr_factory_.GetWeakPtr()),
471 content::BrowserThread::GetBlockingPool()
472 ->GetTaskRunnerWithShutdownBehavior(
473 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
474 .get());
475 }
476
477 void ProximityAuthWebUIHandler::OnSeekedDeviceByAddress() {
478 PA_LOG(INFO) << "Found Bluetooth device: "
479 << bluetooth_connection_->remote_device().bluetooth_address;
480 bluetooth_connection_->Connect();
481 }
482
483 void ProximityAuthWebUIHandler::OnSeekedDeviceByAddressError(
484 const std::string& error_message) {
485 PA_LOG(WARNING) << "Failed to seek device by address: "
486 << bluetooth_connection_->remote_device().bluetooth_address;
487 }
488
489 void ProximityAuthWebUIHandler::OnAuthenticationResult(
490 Authenticator::Result result,
491 scoped_ptr<SecureContext> secure_context) {
492 secure_context_ = secure_context.Pass();
493
494 // Create the ClientImpl asynchronously. |client_| registers itself as an
495 // observer of |bluetooth_connection_|, so creating it synchronously would
496 // trigger |OnSendComplete()| as an observer call for |client_|.
497 base::ThreadTaskRunnerHandle::Get()->PostTask(
498 FROM_HERE,
499 base::Bind(&ProximityAuthWebUIHandler::CreateStatusUpdateClient,
500 weak_ptr_factory_.GetWeakPtr()));
501 }
502
503 void ProximityAuthWebUIHandler::CreateStatusUpdateClient() {
504 client_.reset(
505 new ClientImpl(bluetooth_connection_.Pass(), secure_context_.Pass()));
506 client_->AddObserver(this);
507 }
508
509 scoped_ptr<base::DictionaryValue>
510 ProximityAuthWebUIHandler::ExternalDeviceInfoToDictionary(
511 const cryptauth::ExternalDeviceInfo& device_info) {
512 std::string base64_public_key;
513 Base64UrlEncode(device_info.public_key(), &base64_public_key);
514
515 // Set the fields in the ExternalDeviceInfo proto.
516 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
517 dictionary->SetString(kExternalDevicePublicKey, base64_public_key);
518 dictionary->SetString(kExternalDeviceFriendlyName,
519 device_info.friendly_device_name());
520 dictionary->SetString(kExternalDeviceBluetoothAddress,
521 device_info.bluetooth_address());
522 dictionary->SetBoolean(kExternalDeviceUnlockKey, device_info.unlock_key());
523 dictionary->SetString(kExternalDeviceConnectionStatus,
524 kExternalDeviceDisconnected);
525
526 if (!device_manager_)
527 return dictionary;
528
529 // If |device_info| is a known unlock key, then combine the proto data with
530 // the corresponding local device data (e.g. connection status and remote
531 // status updates).
532 std::string public_key = device_info.public_key();
533 auto iterator = std::find_if(
534 device_manager_->unlock_keys().begin(),
535 device_manager_->unlock_keys().end(),
536 [&public_key](const cryptauth::ExternalDeviceInfo& unlock_key) {
537 return unlock_key.public_key() == public_key;
538 });
539
540 if (iterator == device_manager_->unlock_keys().end())
541 return dictionary;
542
543 // Fill in the current Bluetooth connection status.
544 Connection* connection = GetConnection();
545 if (!connection ||
546 connection->remote_device().public_key != device_info.public_key())
547 return dictionary;
548
549 std::string connection_status = kExternalDeviceDisconnected;
550 if (connection->IsConnected()) {
551 connection_status = kExternalDeviceConnected;
552 } else if (connection->status() == Connection::IN_PROGRESS) {
553 connection_status = kExternalDeviceConnecting;
554 }
555 dictionary->SetString(kExternalDeviceConnectionStatus, connection_status);
556
557 // Fill the remote status dictionary.
558 if (last_remote_status_update_) {
559 scoped_ptr<base::DictionaryValue> status_dictionary(
560 new base::DictionaryValue());
561 status_dictionary->SetInteger("userPresent",
562 last_remote_status_update_->user_presence);
563 status_dictionary->SetInteger(
564 "secureScreenLock",
565 last_remote_status_update_->secure_screen_lock_state);
566 status_dictionary->SetInteger(
567 "trustAgent", last_remote_status_update_->trust_agent_state);
568 dictionary->Set(kExternalDeviceRemoteState, status_dictionary.Pass());
569 }
570
571 return dictionary;
572 }
573
574 scoped_ptr<base::DictionaryValue>
575 ProximityAuthWebUIHandler::IneligibleDeviceToDictionary(
576 const cryptauth::IneligibleDevice& ineligible_device) {
577 scoped_ptr<base::ListValue> ineligibility_reasons(new base::ListValue());
578 for (const std::string& reason : ineligible_device.reasons()) {
579 ineligibility_reasons->AppendString(reason);
580 }
581
582 scoped_ptr<base::DictionaryValue> device_dictionary =
583 ExternalDeviceInfoToDictionary(ineligible_device.device());
584 device_dictionary->Set(kIneligibleDeviceReasons,
585 ineligibility_reasons.Pass());
586 return device_dictionary;
587 }
588
589 void ProximityAuthWebUIHandler::OnConnectionStatusChanged(
590 Connection* connection,
591 Connection::Status old_status,
592 Connection::Status new_status) {
593 PA_LOG(INFO) << "Connection status changed from " << old_status << " to "
594 << new_status;
595 if (new_status == Connection::CONNECTED) {
596 authenticator_.reset(new DeviceToDeviceAuthenticator(
597 connection, delegate_->GetAccountId(),
598 delegate_->CreateSecureMessageDelegate()));
599 authenticator_->Authenticate(
600 base::Bind(&ProximityAuthWebUIHandler::OnAuthenticationResult,
601 weak_ptr_factory_.GetWeakPtr()));
602 } else if (new_status == Connection::DISCONNECTED) {
603 last_remote_status_update_.reset();
604 }
605
606 scoped_ptr<base::ListValue> unlock_keys = GetUnlockKeysList();
607 web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
608 *unlock_keys);
609 }
610
611 void ProximityAuthWebUIHandler::OnMessageReceived(const Connection& connection,
612 const WireMessage& message) {
613 std::string address = connection.remote_device().bluetooth_address;
614 PA_LOG(INFO) << "Message received from " << address;
615 }
616
617 void ProximityAuthWebUIHandler::OnRemoteStatusUpdate(
618 const RemoteStatusUpdate& status_update) {
619 PA_LOG(INFO) << "Remote status update:"
620 << "\n user_presence: "
621 << static_cast<int>(status_update.user_presence)
622 << "\n secure_screen_lock_state: "
623 << static_cast<int>(status_update.secure_screen_lock_state)
624 << "\n trust_agent_state: "
625 << static_cast<int>(status_update.trust_agent_state);
626
627 last_remote_status_update_.reset(new RemoteStatusUpdate(status_update));
628 scoped_ptr<base::ListValue> unlock_keys = GetUnlockKeysList();
629 web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
630 *unlock_keys);
631 }
632
384 } // namespace proximity_auth 633 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698