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/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 (!ScreenlockBridge::Get()->IsLocked())
56 switch (auth_attempt_type
) {
57 case EasyUnlockAuthAttempt::TYPE_UNLOCK
:
59 ScreenlockBridge::Get()->lock_handler()->Unlock(user_id
);
61 ScreenlockBridge::Get()->lock_handler()->EnableInput();
64 case EasyUnlockAuthAttempt::TYPE_SIGNIN
:
66 ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
67 user_id
, key_secret
, key_label
);
69 // Attempting signin with an empty secret is equivalent to canceling the
71 ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
72 user_id
, std::string(), std::string());
80 EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(
81 EasyUnlockAppManager
* app_manager
,
82 const std::string
& user_id
,
84 const FinalizedCallback
& finalized_callback
)
85 : app_manager_(app_manager
),
89 finalized_callback_(finalized_callback
) {
90 if (finalized_callback_
.is_null())
91 finalized_callback_
= base::Bind(&DefaultAuthAttemptFinalizedHandler
);
94 EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
95 if (state_
== STATE_RUNNING
)
99 bool EasyUnlockAuthAttempt::Start() {
100 DCHECK_EQ(STATE_IDLE
, state_
);
102 if (!ScreenlockBridge::Get()->IsLocked())
105 ScreenlockBridge::LockHandler::AuthType auth_type
=
106 ScreenlockBridge::Get()->lock_handler()->GetAuthType(user_id_
);
108 if (auth_type
!= ScreenlockBridge::LockHandler::USER_CLICK
) {
113 state_
= STATE_RUNNING
;
115 if (!app_manager_
->SendAuthAttemptEvent()) {
123 void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string
& user_id
,
125 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
128 if (!ScreenlockBridge::Get()->IsLocked())
131 if (type_
!= TYPE_UNLOCK
) {
136 finalized_callback_
.Run(type_
, success
, user_id
, std::string(),
141 void EasyUnlockAuthAttempt::FinalizeSignin(const std::string
& user_id
,
142 const std::string
& wrapped_secret
,
143 const std::string
& raw_session_key
) {
144 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
147 if (!ScreenlockBridge::Get()->IsLocked())
150 if (type_
!= TYPE_SIGNIN
) {
155 if (wrapped_secret
.empty()) {
160 std::string unwrapped_secret
= UnwrapSecret(wrapped_secret
, raw_session_key
);
162 std::string key_label
;
163 #if defined(OS_CHROMEOS)
164 key_label
= chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
165 #endif // defined(OS_CHROMEOS)
167 const bool kSuccess
= true;
168 finalized_callback_
.Run(type_
, kSuccess
, user_id
, unwrapped_secret
,
173 void EasyUnlockAuthAttempt::Cancel(const std::string
& user_id
) {
176 const bool kFailure
= false;
177 finalized_callback_
.Run(type_
, kFailure
, user_id
, std::string(),