Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: chrome/browser/chromeos/login/quick_unlock/pin_storage.cc

Issue 1977923002: Implement pin storage backend. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage.h"
6
7 #include "base/base64.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/string_util.h"
10 #include "chrome/browser/chromeos/profiles/profile_helper.h"
11 #include "chrome/common/pref_names.h"
12 #include "chromeos/login/auth/key.h"
13 #include "components/prefs/pref_service.h"
14 #include "crypto/random.h"
15 #include "extensions/browser/browser_context_keyed_api_factory.h"
16
17 namespace chromeos {
18
19 namespace {
20
21 const int kSaltByteSize = 16;
22
23 class PinStorageImpl : public PinStorage,
24 public extensions::BrowserContextKeyedAPI {
25 public:
26 explicit PinStorageImpl(content::BrowserContext* context);
27 ~PinStorageImpl() override;
achuithb 2016/05/13 23:34:56 Can this be protected?
jdufault 2016/05/16 22:08:47 Done.
28
29 // PinStorage implementation:
achuithb 2016/05/13 23:34:56 Everything below here can be private, right?
jdufault 2016/05/16 22:08:47 Done.
30 void MarkStrongAuth() override;
31 base::TimeDelta TimeSinceLastStrongAuth() override;
32
33 void AddUnlockAttempt() override;
34 void ResetUnlockAttemptCount() override;
35 int UnlockAttemptCount() override;
achuithb 2016/05/13 23:34:56 const
jdufault 2016/05/16 22:08:47 Done.
36
37 // PIN storage management.
38 bool HasPin() const override;
39 void SetPin(const std::string& raw_pin) override;
40 void RemovePin() override;
41
42 // The salt and hash for the pin. These methods can only be called if HasPin
43 // returns true.
44 std::string pin_salt() const override;
45 std::string pin_secret() const override;
46
47 // Fetches an instance for the given context.
48 static PinStorageImpl* Get(content::BrowserContext* context);
49
50 // BrowserContextKeyedAPI implementation:
51 static extensions::BrowserContextKeyedAPIFactory<PinStorageImpl>*
52 GetFactoryInstance();
53 static const bool kServiceIsCreatedWithBrowserContext = false;
54
55 private:
56 PrefService* pref_service_;
57 int attempt_count_;
58 base::Time last_strong_auth_;
achuithb 2016/05/13 23:34:57 should this be initialized to something?
jdufault 2016/05/16 22:08:47 It's default constructed to the "null" time (IsPin
59
60 friend class extensions::BrowserContextKeyedAPIFactory<PinStorageImpl>;
61 // BrowserContextKeyedAPI implementation:
62 static const char* service_name() { return "PinStorageImpl"; }
63
64 DISALLOW_COPY_AND_ASSIGN(PinStorageImpl);
65 };
66
67 static base::LazyInstance<
68 extensions::BrowserContextKeyedAPIFactory<PinStorageImpl>>
69 g_factory = LAZY_INSTANCE_INITIALIZER;
70
71 // static
72 extensions::BrowserContextKeyedAPIFactory<PinStorageImpl>*
73 PinStorageImpl::GetFactoryInstance() {
74 return g_factory.Pointer();
75 }
76
77 // static
78 PinStorageImpl* PinStorageImpl::Get(content::BrowserContext* context) {
79 return extensions::BrowserContextKeyedAPIFactory<PinStorageImpl>::Get(
80 context);
81 }
82
83 PinStorageImpl::PinStorageImpl(content::BrowserContext* context)
84 : pref_service_(Profile::FromBrowserContext(context)->GetPrefs()),
85 attempt_count_(0) {}
achuithb 2016/05/13 23:34:56 move to class
jdufault 2016/05/16 22:08:47 Done.
86
87 PinStorageImpl::~PinStorageImpl() {}
88
89 void PinStorageImpl::MarkStrongAuth() {
90 last_strong_auth_ = base::Time::Now();
91 }
92
93 base::TimeDelta PinStorageImpl::TimeSinceLastStrongAuth() {
94 // TODO: Verify last_strong_auth_ has a good initial value.
95 return base::Time::Now() - last_strong_auth_;
96 }
97
98 void PinStorageImpl::AddUnlockAttempt() {
99 ++attempt_count_;
100 }
101
102 void PinStorageImpl::ResetUnlockAttemptCount() {
103 attempt_count_ = 0;
104 }
105
106 int PinStorageImpl::UnlockAttemptCount() {
107 return attempt_count_;
108 }
109
110 bool PinStorageImpl::HasPin() const {
111 return !pin_salt().empty() && !pin_secret().empty();
112 }
113
114 void PinStorageImpl::SetPin(const std::string& raw_pin) {
achuithb 2016/05/13 23:34:56 This method is probably the most significant bit o
jdufault 2016/05/16 22:08:48 I haven't been able to figure out any tests that w
115 // Compute salt. base64 encode it so it is a UTF8 string, which is required by
achuithb 2016/05/13 23:34:57 Generate random salt.
jdufault 2016/05/16 22:08:48 Done.
116 // the pref service.
117 std::string salt;
118 crypto::RandBytes(base::WriteInto(&salt, kSaltByteSize + 1), kSaltByteSize);
119 base::Base64Encode(salt, &salt);
120 DCHECK(!salt.empty());
121
122 // Compute secret.
123 Key key(raw_pin);
124 key.Transform(Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234, salt);
125 std::string secret = key.GetSecret();
achuithb 2016/05/13 23:34:57 const
jdufault 2016/05/16 22:08:47 Done.
126
127 // Store them.
128 pref_service_->SetString(prefs::kQuickUnlockPinSalt, salt);
129 pref_service_->SetString(prefs::kQuickUnlockPinSecret, secret);
130 }
131
132 void PinStorageImpl::RemovePin() {
133 // Clear prefs to their default values.
134 pref_service_->SetString(prefs::kQuickUnlockPinSalt, "");
135 pref_service_->SetString(prefs::kQuickUnlockPinSecret, "");
136 }
137
138 std::string PinStorageImpl::pin_salt() const {
achuithb 2016/05/13 23:34:56 PinSalt?
jdufault 2016/05/16 22:08:48 Done.
139 return pref_service_->GetString(prefs::kQuickUnlockPinSalt);
140 }
141
142 std::string PinStorageImpl::pin_secret() const {
achuithb 2016/05/13 23:34:57 PinSecret?
jdufault 2016/05/16 22:08:47 Done.
143 return pref_service_->GetString(prefs::kQuickUnlockPinSecret);
144 }
145
146 } // namespace
147
148 PinStorage::PinStorage() {}
149
150 PinStorage::~PinStorage() {}
151
152 // static
153 void PinStorage::RegisterProfilePrefs(
154 user_prefs::PrefRegistrySyncable* registry) {
155 registry->RegisterStringPref(prefs::kQuickUnlockPinSalt, "",
156 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
achuithb 2016/05/13 23:34:57 Do we want this to be syncable?
jdufault 2016/05/16 22:08:47 Security is fine with it, but we're still not sure
157 registry->RegisterStringPref(prefs::kQuickUnlockPinSecret, "",
158 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
159 }
160
161 // static
162 PinStorage* PinStorage::GetInstance(Profile* profile) {
163 return PinStorageImpl::Get(profile);
164 }
165
166 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698