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"
8 #include "base/logging.h"
9 #include "chrome/browser/signin/easy_unlock_app_manager.h"
10 #include "chrome/browser/signin/proximity_auth_facade.h"
11 #include "components/proximity_auth/screenlock_bridge.h"
12 #include "crypto/encryptor.h"
13 #include "crypto/symmetric_key.h"
15 #if defined(OS_CHROMEOS)
16 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
21 // Decrypts the secret that should be used to login from |wrapped_secret| using
22 // raw AES key |raw_key|.
23 // In a case of error, an empty string is returned.
24 std::string
UnwrapSecret(const std::string
& wrapped_secret
,
25 const std::string
& raw_key
) {
29 // Import the key structure.
30 scoped_ptr
<crypto::SymmetricKey
> key(
31 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES
, raw_key
));
36 std::string
iv(raw_key
.size(), ' ');
37 crypto::Encryptor encryptor
;
38 if (!encryptor
.Init(key
.get(), crypto::Encryptor::CBC
, iv
))
42 if (!encryptor
.Decrypt(wrapped_secret
, &secret
))
48 void DefaultAuthAttemptFinalizedHandler(
49 EasyUnlockAuthAttempt::Type auth_attempt_type
,
51 const std::string
& user_id
,
52 const std::string
& key_secret
,
53 const std::string
& key_label
) {
54 if (!GetScreenlockBridgeInstance()->IsLocked())
57 switch (auth_attempt_type
) {
58 case EasyUnlockAuthAttempt::TYPE_UNLOCK
:
60 GetScreenlockBridgeInstance()->lock_handler()->Unlock(user_id
);
62 GetScreenlockBridgeInstance()->lock_handler()->EnableInput();
65 case EasyUnlockAuthAttempt::TYPE_SIGNIN
:
67 GetScreenlockBridgeInstance()->lock_handler()->AttemptEasySignin(
68 user_id
, key_secret
, key_label
);
70 // Attempting signin with an empty secret is equivalent to canceling the
72 GetScreenlockBridgeInstance()->lock_handler()->AttemptEasySignin(
73 user_id
, std::string(), std::string());
81 EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(
82 EasyUnlockAppManager
* app_manager
,
83 const std::string
& user_id
,
85 const FinalizedCallback
& finalized_callback
)
86 : app_manager_(app_manager
),
90 finalized_callback_(finalized_callback
) {
91 if (finalized_callback_
.is_null())
92 finalized_callback_
= base::Bind(&DefaultAuthAttemptFinalizedHandler
);
95 EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
96 if (state_
== STATE_RUNNING
)
100 bool EasyUnlockAuthAttempt::Start() {
101 DCHECK_EQ(STATE_IDLE
, state_
);
103 if (!GetScreenlockBridgeInstance()->IsLocked())
106 proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type
=
107 GetScreenlockBridgeInstance()->lock_handler()->GetAuthType(user_id_
);
109 if (auth_type
!= proximity_auth::ScreenlockBridge::LockHandler::USER_CLICK
) {
114 state_
= STATE_RUNNING
;
116 if (!app_manager_
->SendAuthAttemptEvent()) {
124 void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string
& user_id
,
126 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
129 if (!GetScreenlockBridgeInstance()->IsLocked())
132 if (type_
!= TYPE_UNLOCK
) {
137 finalized_callback_
.Run(type_
, success
, user_id
, std::string(),
142 void EasyUnlockAuthAttempt::FinalizeSignin(const std::string
& user_id
,
143 const std::string
& wrapped_secret
,
144 const std::string
& raw_session_key
) {
145 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
148 if (!GetScreenlockBridgeInstance()->IsLocked())
151 if (type_
!= TYPE_SIGNIN
) {
156 if (wrapped_secret
.empty()) {
161 std::string unwrapped_secret
= UnwrapSecret(wrapped_secret
, raw_session_key
);
163 std::string key_label
;
164 #if defined(OS_CHROMEOS)
165 key_label
= chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
166 #endif // defined(OS_CHROMEOS)
168 const bool kSuccess
= true;
169 finalized_callback_
.Run(type_
, kSuccess
, user_id
, unwrapped_secret
,
174 void EasyUnlockAuthAttempt::Cancel(const std::string
& user_id
) {
177 const bool kFailure
= false;
178 finalized_callback_
.Run(type_
, kFailure
, user_id
, std::string(),