OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/prefs/pref_hash_calculator.h" | 5 #include "chrome/browser/prefs/pref_hash_calculator.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/json/json_string_value_serializer.h" | 10 #include "base/json/json_string_value_serializer.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/threading/thread_restrictions.h" | |
15 #include "base/values.h" | 14 #include "base/values.h" |
16 #include "chrome/browser/prefs/tracked/pref_hash_calculator_helper.h" | 15 #include "chrome/browser/prefs/tracked/pref_hash_calculator_helper.h" |
17 #include "crypto/hmac.h" | 16 #include "crypto/hmac.h" |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 // Calculates an HMAC of |message| using |key|, encoded as a hexadecimal string. | 20 // Calculates an HMAC of |message| using |key|, encoded as a hexadecimal string. |
22 std::string GetDigestString(const std::string& key, | 21 std::string GetDigestString(const std::string& key, |
23 const std::string& message) { | 22 const std::string& message) { |
24 crypto::HMAC hmac(crypto::HMAC::SHA256); | 23 crypto::HMAC hmac(crypto::HMAC::SHA256); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 std::string GenerateDeviceIdLikePrefMetricsServiceDid( | 84 std::string GenerateDeviceIdLikePrefMetricsServiceDid( |
86 const std::string& original_device_id) { | 85 const std::string& original_device_id) { |
87 if (original_device_id.empty()) | 86 if (original_device_id.empty()) |
88 return std::string(); | 87 return std::string(); |
89 return StringToLowerASCII( | 88 return StringToLowerASCII( |
90 GetDigestString(original_device_id, "PrefMetricsService")); | 89 GetDigestString(original_device_id, "PrefMetricsService")); |
91 } | 90 } |
92 | 91 |
93 } // namespace | 92 } // namespace |
94 | 93 |
95 // static | |
96 base::LazyInstance<scoped_ptr<const std::string> >::Leaky | |
97 PrefHashCalculator::legacy_device_id_instance_ = LAZY_INSTANCE_INITIALIZER; | |
98 | |
99 PrefHashCalculator::PrefHashCalculator(const std::string& seed, | 94 PrefHashCalculator::PrefHashCalculator(const std::string& seed, |
100 const std::string& device_id) | 95 const std::string& device_id) |
101 : seed_(seed), | 96 : seed_(seed), |
102 device_id_(GenerateDeviceIdLikePrefMetricsServiceDid(device_id)), | 97 device_id_(GenerateDeviceIdLikePrefMetricsServiceDid(device_id)), |
103 raw_device_id_(device_id), | 98 raw_device_id_(device_id), |
104 get_legacy_device_id_callback_(base::Bind(&GetLegacyDeviceId)) {} | 99 get_legacy_device_id_callback_(base::Bind(&GetLegacyDeviceId)) {} |
105 | 100 |
106 PrefHashCalculator::PrefHashCalculator( | 101 PrefHashCalculator::PrefHashCalculator( |
107 const std::string& seed, | 102 const std::string& seed, |
108 const std::string& device_id, | 103 const std::string& device_id, |
(...skipping 25 matching lines...) Expand all Loading... |
134 value_as_string), | 129 value_as_string), |
135 digest_string)) { | 130 digest_string)) { |
136 return VALID_SECURE_LEGACY; | 131 return VALID_SECURE_LEGACY; |
137 } | 132 } |
138 if (VerifyDigestString(seed_, value_as_string, digest_string)) | 133 if (VerifyDigestString(seed_, value_as_string, digest_string)) |
139 return VALID_WEAK_LEGACY; | 134 return VALID_WEAK_LEGACY; |
140 return INVALID; | 135 return INVALID; |
141 } | 136 } |
142 | 137 |
143 std::string PrefHashCalculator::RetrieveLegacyDeviceId() const { | 138 std::string PrefHashCalculator::RetrieveLegacyDeviceId() const { |
144 scoped_ptr<const std::string>* legacy_device_id_ptr = | 139 if (!legacy_device_id_instance_) { |
145 legacy_device_id_instance_.Pointer(); | 140 legacy_device_id_instance_.reset( |
146 if (!legacy_device_id_ptr->get()) { | |
147 // Allow IO on this thread to retrieve the legacy device ID. The result of | |
148 // this operation is stored in |legacy_device_id_instance_| and will thus | |
149 // only happen once in this browser's lifetime (as verified by the DCHECK | |
150 // below). This is not ideal, but this value is required synchronously to be | |
151 // able to continue loading prefs for this profile. This profile should then | |
152 // be migrated to a modern device ID and subsequent loads of this profile | |
153 // shouldn't need to run this code ever again. Another option would be to | |
154 // kick an early task on the FILE thread to start retrieving this ID on | |
155 // every startup and block here if the result still hasn't made it in when | |
156 // we need it, but this isn't great either as in most cases it will be | |
157 // computed for nothing. | |
158 // TODO(gab): Remove this when the legacy device ID (M33) becomes | |
159 // irrelevant. | |
160 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
161 static bool legacy_device_id_computed = false; | |
162 DCHECK(!legacy_device_id_computed); | |
163 legacy_device_id_ptr->reset( | |
164 new std::string(GenerateDeviceIdLikePrefMetricsServiceDid( | 141 new std::string(GenerateDeviceIdLikePrefMetricsServiceDid( |
165 get_legacy_device_id_callback_.Run(raw_device_id_)))); | 142 get_legacy_device_id_callback_.Run(raw_device_id_)))); |
166 legacy_device_id_computed = true; | |
167 } | 143 } |
168 return *legacy_device_id_ptr->get(); | 144 return *legacy_device_id_instance_; |
169 } | 145 } |
OLD | NEW |