OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |