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 "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"
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
) {
28 // Import the key structure.
29 scoped_ptr
<crypto::SymmetricKey
> key(
30 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES
, raw_key
));
35 std::string
iv(raw_key
.size(), ' ');
36 crypto::Encryptor encryptor
;
37 if (!encryptor
.Init(key
.get(), crypto::Encryptor::CBC
, iv
))
41 if (!encryptor
.Decrypt(wrapped_secret
, &secret
))
47 void DefaultAuthAttemptFinalizedHandler(
48 EasyUnlockAuthAttempt::Type auth_attempt_type
,
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())
56 switch (auth_attempt_type
) {
57 case EasyUnlockAuthAttempt::TYPE_UNLOCK
:
59 proximity_auth::ScreenlockBridge::Get()->lock_handler()->Unlock(
62 proximity_auth::ScreenlockBridge::Get()->lock_handler()->EnableInput();
65 case EasyUnlockAuthAttempt::TYPE_SIGNIN
:
67 proximity_auth::ScreenlockBridge::Get()
69 ->AttemptEasySignin(user_id
, key_secret
, key_label
);
71 // Attempting signin with an empty secret is equivalent to canceling the
73 proximity_auth::ScreenlockBridge::Get()
75 ->AttemptEasySignin(user_id
, std::string(), std::string());
83 EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(
84 EasyUnlockAppManager
* app_manager
,
85 const std::string
& user_id
,
87 const FinalizedCallback
& finalized_callback
)
88 : app_manager_(app_manager
),
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
)
102 bool EasyUnlockAuthAttempt::Start() {
103 DCHECK_EQ(STATE_IDLE
, state_
);
105 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
108 proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type
=
109 proximity_auth::ScreenlockBridge::Get()->lock_handler()->GetAuthType(
112 if (auth_type
!= proximity_auth::ScreenlockBridge::LockHandler::USER_CLICK
) {
117 state_
= STATE_RUNNING
;
119 if (!app_manager_
->SendAuthAttemptEvent()) {
127 void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string
& user_id
,
129 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
132 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
135 if (type_
!= TYPE_UNLOCK
) {
140 finalized_callback_
.Run(type_
, success
, user_id
, std::string(),
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_
)
151 if (!proximity_auth::ScreenlockBridge::Get()->IsLocked())
154 if (type_
!= TYPE_SIGNIN
) {
159 if (wrapped_secret
.empty()) {
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
,
177 void EasyUnlockAuthAttempt::Cancel(const std::string
& user_id
) {
180 const bool kFailure
= false;
181 finalized_callback_
.Run(type_
, kFailure
, user_id
, std::string(),