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/logging.h"
8 #include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/signin/screenlock_bridge.h"
11 #include "crypto/encryptor.h"
12 #include "crypto/symmetric_key.h"
15 #if defined(OS_CHROMEOS)
16 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
21 // Fake secret used to force invalid login.
22 const char kStubSecret
[] = "\xFF\x00";
24 // Decrypts the secret that should be used to login from |wrapped_secret| using
25 // raw AES key |raw_key|.
26 // In a case of error, an empty string is returned.
27 std::string
UnwrapSecret(const std::string
& wrapped_secret
,
28 const std::string
& raw_key
) {
32 // Import the key structure.
33 scoped_ptr
<crypto::SymmetricKey
> key(
34 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES
, raw_key
));
39 std::string
iv(raw_key
.size(), ' ');
40 crypto::Encryptor encryptor
;
41 if (!encryptor
.Init(key
.get(), crypto::Encryptor::CBC
, iv
))
45 if (!encryptor
.Decrypt(wrapped_secret
, &secret
))
53 EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(Profile
* profile
,
54 const std::string
& user_id
,
62 EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
63 if (state_
== STATE_RUNNING
)
67 bool EasyUnlockAuthAttempt::Start(const std::string
& user_id
) {
68 DCHECK(state_
== STATE_IDLE
);
70 if (!ScreenlockBridge::Get()->IsLocked())
73 if (user_id
!= user_id_
) {
78 ScreenlockBridge::LockHandler::AuthType auth_type
=
79 ScreenlockBridge::Get()->lock_handler()->GetAuthType(user_id
);
81 if (auth_type
!= ScreenlockBridge::LockHandler::USER_CLICK
) {
86 state_
= STATE_RUNNING
;
88 // TODO(tbarzic): Replace this with an easyUnlockPrivate event that will
89 // report more context to the app (e.g. user id, whether the attempt is for
91 extensions::ScreenlockPrivateEventRouter
* router
=
92 extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
94 return router
->OnAuthAttempted(auth_type
, "");
97 void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string
& user_id
,
99 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
102 if (type_
!= TYPE_UNLOCK
) {
107 if (!ScreenlockBridge::Get()->IsLocked())
111 ScreenlockBridge::Get()->lock_handler()->Unlock(user_id_
);
113 ScreenlockBridge::Get()->lock_handler()->EnableInput();
119 void EasyUnlockAuthAttempt::FinalizeSignin(const std::string
& user_id
,
120 const std::string
& wrapped_secret
,
121 const std::string
& raw_session_key
) {
122 if (state_
!= STATE_RUNNING
|| user_id
!= user_id_
)
125 if (type_
!= TYPE_SIGNIN
) {
130 if (!ScreenlockBridge::Get()->IsLocked())
134 std::string unwrapped_secret
= UnwrapSecret(wrapped_secret
, raw_session_key
);
136 // If secret is not set, set it to an arbitrary value, otherwise there will
137 // be no authenitcation attempt and the ui will get stuck.
138 // TODO(tbarzic): Find a better way to handle this case.
139 if (unwrapped_secret
.empty())
140 unwrapped_secret
= kStubSecret
;
142 std::string key_label
;
143 #if defined(OS_CHROMEOS)
144 key_label
= chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
145 #endif // defined(OS_CHROMEOS)
147 ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
154 void EasyUnlockAuthAttempt::Cancel(const std::string
& user_id
) {
155 if (type_
== TYPE_UNLOCK
)
156 FinalizeUnlock(user_id
, false);
158 FinalizeSignin(user_id
, "", "");