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

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

Powered by Google App Engine
This is Rietveld 408576698