Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_auth_attempt.cc
blobf55f4913926917a71f505b047d9474f52bb2ddfe
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/signin/easy_unlock_auth_attempt.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "chrome/browser/signin/easy_unlock_app_manager.h"
10 #include "components/proximity_auth/screenlock_bridge.h"
11 #include "crypto/encryptor.h"
12 #include "crypto/symmetric_key.h"
14 #if defined(OS_CHROMEOS)
15 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
16 #endif
18 namespace {
20 // Decrypts the secret that should be used to login from |wrapped_secret| using
21 // raw AES key |raw_key|.
22 // In a case of error, an empty string is returned.
23 std::string UnwrapSecret(const std::string& wrapped_secret,
24 const std::string& raw_key) {
25 if (raw_key.empty())
26 return std::string();
28 // Import the key structure.
29 scoped_ptr<crypto::SymmetricKey> key(
30 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, raw_key));
32 if (!key)
33 return std::string();
35 std::string iv(raw_key.size(), ' ');
36 crypto::Encryptor encryptor;
37 if (!encryptor.Init(key.get(), crypto::Encryptor::CBC, iv))
38 return std::string();
40 std::string secret;
41 if (!encryptor.Decrypt(wrapped_secret, &secret))
42 return std::string();
44 return secret;
47 void DefaultAuthAttemptFinalizedHandler(
48 EasyUnlockAuthAttempt::Type auth_attempt_type,
49 bool success,
50 const std::string& user_id,
51 const std::string& key_secret,
52 const std::string& key_label) {
53 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
54 return;
56 switch (auth_attempt_type) {
57 case EasyUnlockAuthAttempt::TYPE_UNLOCK:
58 if (success) {
59 proximity_auth::ScreenlockBridge::Get()->lock_handler()->Unlock(
60 user_id);
61 } else {
62 proximity_auth::ScreenlockBridge::Get()->lock_handler()->EnableInput();
64 return;
65 case EasyUnlockAuthAttempt::TYPE_SIGNIN:
66 if (success) {
67 proximity_auth::ScreenlockBridge::Get()
68 ->lock_handler()
69 ->AttemptEasySignin(user_id, key_secret, key_label);
70 } else {
71 // Attempting signin with an empty secret is equivalent to canceling the
72 // attempt.
73 proximity_auth::ScreenlockBridge::Get()
74 ->lock_handler()
75 ->AttemptEasySignin(user_id, std::string(), std::string());
77 return;
81 } // namespace
83 EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(
84 EasyUnlockAppManager* app_manager,
85 const std::string& user_id,
86 Type type,
87 const FinalizedCallback& finalized_callback)
88 : app_manager_(app_manager),
89 state_(STATE_IDLE),
90 user_id_(user_id),
91 type_(type),
92 finalized_callback_(finalized_callback) {
93 if (finalized_callback_.is_null())
94 finalized_callback_ = base::Bind(&DefaultAuthAttemptFinalizedHandler);
97 EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
98 if (state_ == STATE_RUNNING)
99 Cancel(user_id_);
102 bool EasyUnlockAuthAttempt::Start() {
103 DCHECK_EQ(STATE_IDLE, state_);
105 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
106 return false;
108 proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type =
109 proximity_auth::ScreenlockBridge::Get()->lock_handler()->GetAuthType(
110 user_id_);
112 if (auth_type != proximity_auth::ScreenlockBridge::LockHandler::USER_CLICK) {
113 Cancel(user_id_);
114 return false;
117 state_ = STATE_RUNNING;
119 if (!app_manager_->SendAuthAttemptEvent()) {
120 Cancel(user_id_);
121 return false;
124 return true;
127 void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string& user_id,
128 bool success) {
129 if (state_ != STATE_RUNNING || user_id != user_id_)
130 return;
132 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
133 return;
135 if (type_ != TYPE_UNLOCK) {
136 Cancel(user_id_);
137 return;
140 finalized_callback_.Run(type_, success, user_id, std::string(),
141 std::string());
142 state_ = STATE_DONE;
145 void EasyUnlockAuthAttempt::FinalizeSignin(const std::string& user_id,
146 const std::string& wrapped_secret,
147 const std::string& raw_session_key) {
148 if (state_ != STATE_RUNNING || user_id != user_id_)
149 return;
151 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
152 return;
154 if (type_ != TYPE_SIGNIN) {
155 Cancel(user_id_);
156 return;
159 if (wrapped_secret.empty()) {
160 Cancel(user_id_);
161 return;
164 std::string unwrapped_secret = UnwrapSecret(wrapped_secret, raw_session_key);
166 std::string key_label;
167 #if defined(OS_CHROMEOS)
168 key_label = chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
169 #endif // defined(OS_CHROMEOS)
171 const bool kSuccess = true;
172 finalized_callback_.Run(type_, kSuccess, user_id, unwrapped_secret,
173 key_label);
174 state_ = STATE_DONE;
177 void EasyUnlockAuthAttempt::Cancel(const std::string& user_id) {
178 state_ = STATE_DONE;
180 const bool kFailure = false;
181 finalized_callback_.Run(type_, kFailure, user_id, std::string(),
182 std::string());