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

Side by Side Diff: chrome/browser/policy/cloud_policy_validator.cc

Issue 10828032: Add DeviceSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/policy/cloud_policy_validator.h" 5 #include "chrome/browser/policy/cloud_policy_validator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/stl_util.h"
10 #include "chrome/browser/policy/cloud_policy_constants.h" 11 #include "chrome/browser/policy/cloud_policy_constants.h"
11 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" 12 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
12 #include "chrome/browser/policy/proto/cloud_policy.pb.h" 13 #include "chrome/browser/policy/proto/cloud_policy.pb.h"
13 #include "chrome/browser/policy/proto/device_management_backend.pb.h" 14 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
14 #include "chrome/common/net/gaia/gaia_auth_util.h" 15 #include "chrome/common/net/gaia/gaia_auth_util.h"
15 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
16 #include "crypto/signature_verifier.h" 17 #include "crypto/signature_verifier.h"
17 18
18 namespace em = enterprise_management; 19 namespace em = enterprise_management;
19 20
20 namespace policy { 21 namespace policy {
21 22
22 namespace { 23 namespace {
23 24
24 // Grace interval for policy timestamp checks, in seconds. 25 // Grace interval for policy timestamp checks, in seconds.
25 const int kTimestampGraceIntervalSeconds = 60; 26 const int kTimestampGraceIntervalSeconds = 60;
26 27
27 // DER-encoded ASN.1 object identifier for the SHA1-RSA signature algorithm. 28 // DER-encoded ASN.1 object identifier for the SHA1-RSA signature algorithm.
28 const uint8 kSignatureAlgorithm[] = { 29 const uint8 kSignatureAlgorithm[] = {
29 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 30 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
30 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 31 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00
31 }; 32 };
32 33
33 } // namespace 34 } // namespace
34 35
35 CloudPolicyValidatorBase::~CloudPolicyValidatorBase() {} 36 CloudPolicyValidatorBase::~CloudPolicyValidatorBase() {}
36 37
37 void CloudPolicyValidatorBase::ValidateTimestamp(base::Time not_before, 38 void CloudPolicyValidatorBase::ValidateTimestamp(base::Time not_before,
38 base::Time now) { 39 base::Time now,
40 bool allow_missing_timestamp) {
39 // Timestamp should be from the past. We allow for a 1-minute grace interval 41 // Timestamp should be from the past. We allow for a 1-minute grace interval
40 // to cover clock drift. 42 // to cover clock drift.
41 validation_flags_ |= VALIDATE_TIMESTAMP; 43 validation_flags_ |= VALIDATE_TIMESTAMP;
42 timestamp_not_before_ = not_before; 44 timestamp_not_before_ =
45 (not_before - base::Time::UnixEpoch()).InMilliseconds();
43 timestamp_not_after_ = 46 timestamp_not_after_ =
44 now + base::TimeDelta::FromSeconds(kTimestampGraceIntervalSeconds); 47 ((now + base::TimeDelta::FromSeconds(kTimestampGraceIntervalSeconds)) -
48 base::Time::UnixEpoch()).InMillisecondsRoundedUp();
49 allow_missing_timestamp_ = allow_missing_timestamp;
45 } 50 }
46 51
47 void CloudPolicyValidatorBase::ValidateUsername( 52 void CloudPolicyValidatorBase::ValidateUsername(
48 const std::string& expected_user) { 53 const std::string& expected_user) {
49 validation_flags_ |= VALIDATE_USERNAME; 54 validation_flags_ |= VALIDATE_USERNAME;
50 user_ = gaia::CanonicalizeEmail(expected_user); 55 user_ = gaia::CanonicalizeEmail(expected_user);
51 } 56 }
52 57
53 void CloudPolicyValidatorBase::ValidateDomain( 58 void CloudPolicyValidatorBase::ValidateDomain(
54 const std::string& expected_domain) { 59 const std::string& expected_domain) {
55 validation_flags_ |= VALIDATE_DOMAIN; 60 validation_flags_ |= VALIDATE_DOMAIN;
56 domain_ = gaia::CanonicalizeDomain(expected_domain); 61 domain_ = gaia::CanonicalizeDomain(expected_domain);
57 } 62 }
58 63
59 void CloudPolicyValidatorBase::ValidateDMToken(const std::string& token) { 64 void CloudPolicyValidatorBase::ValidateDMToken(const std::string& token) {
60 validation_flags_ |= VALIDATE_TOKEN; 65 validation_flags_ |= VALIDATE_TOKEN;
61 token_ = token; 66 token_ = token;
62 } 67 }
63 68
64 void CloudPolicyValidatorBase::ValidatePolicyType( 69 void CloudPolicyValidatorBase::ValidatePolicyType(
65 const std::string& policy_type) { 70 const std::string& policy_type) {
66 validation_flags_ |= VALIDATE_POLICY_TYPE; 71 validation_flags_ |= VALIDATE_POLICY_TYPE;
67 policy_type_ = policy_type; 72 policy_type_ = policy_type;
68 } 73 }
69 74
70 void CloudPolicyValidatorBase::ValidatePayload() { 75 void CloudPolicyValidatorBase::ValidatePayload() {
71 validation_flags_ |= VALIDATE_PAYLOAD; 76 validation_flags_ |= VALIDATE_PAYLOAD;
72 } 77 }
73 78
74 void CloudPolicyValidatorBase::ValidateSignature(const std::string& key) { 79 void CloudPolicyValidatorBase::ValidateSignature(const std::vector<uint8>& key,
80 bool allow_key_rotation) {
75 validation_flags_ |= VALIDATE_SIGNATURE; 81 validation_flags_ |= VALIDATE_SIGNATURE;
76 key_ = key; 82 key_ = std::string(reinterpret_cast<const char*>(vector_as_array(&key)),
83 key.size());
84 allow_key_rotation_ = allow_key_rotation;
77 } 85 }
78 86
79 void CloudPolicyValidatorBase::ValidateInitialKey() { 87 void CloudPolicyValidatorBase::ValidateInitialKey() {
80 validation_flags_ |= VALIDATE_INITIAL_KEY; 88 validation_flags_ |= VALIDATE_INITIAL_KEY;
81 } 89 }
82 90
83 void CloudPolicyValidatorBase::ValidateAgainstCurrentPolicy( 91 void CloudPolicyValidatorBase::ValidateAgainstCurrentPolicy(
84 const em::PolicyData* policy_data) { 92 const em::PolicyData* policy_data,
93 bool allow_missing_timestamp) {
85 base::Time last_policy_timestamp; 94 base::Time last_policy_timestamp;
86 std::string expected_dm_token; 95 std::string expected_dm_token;
87 if (policy_data) { 96 if (policy_data) {
88 last_policy_timestamp = 97 last_policy_timestamp =
89 base::Time::UnixEpoch() + 98 base::Time::UnixEpoch() +
90 base::TimeDelta::FromMilliseconds(policy_data->timestamp()); 99 base::TimeDelta::FromMilliseconds(policy_data->timestamp());
91 expected_dm_token = policy_data->request_token(); 100 expected_dm_token = policy_data->request_token();
92 } 101 }
93 ValidateTimestamp(last_policy_timestamp, base::Time::NowFromSystemTime()); 102 ValidateTimestamp(last_policy_timestamp, base::Time::NowFromSystemTime(),
103 allow_missing_timestamp);
94 if (!expected_dm_token.empty()) 104 if (!expected_dm_token.empty())
95 ValidateDMToken(expected_dm_token); 105 ValidateDMToken(expected_dm_token);
96 } 106 }
97 107
98 void CloudPolicyValidatorBase::StartValidation() { 108 void CloudPolicyValidatorBase::StartValidation() {
99 content::BrowserThread::PostTask( 109 content::BrowserThread::PostTask(
100 content::BrowserThread::FILE, FROM_HERE, 110 content::BrowserThread::FILE, FROM_HERE,
101 base::Bind(&CloudPolicyValidatorBase::PerformValidation, 111 base::Bind(&CloudPolicyValidatorBase::PerformValidation,
102 base::Passed(scoped_ptr<CloudPolicyValidatorBase>(this)), 112 base::Passed(scoped_ptr<CloudPolicyValidatorBase>(this)),
103 MessageLoop::current()->message_loop_proxy())); 113 MessageLoop::current()->message_loop_proxy()));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckFunctions); ++i) { 181 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckFunctions); ++i) {
172 if (validation_flags_ & kCheckFunctions[i].flag) { 182 if (validation_flags_ & kCheckFunctions[i].flag) {
173 status_ = (this->*(kCheckFunctions[i].checkFunction))(); 183 status_ = (this->*(kCheckFunctions[i].checkFunction))();
174 if (status_ != VALIDATION_OK) 184 if (status_ != VALIDATION_OK)
175 break; 185 break;
176 } 186 }
177 } 187 }
178 } 188 }
179 189
180 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckSignature() { 190 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckSignature() {
181 std::string signature_key(key_); 191 const std::string* signature_key = &key_;
182 if (policy_->has_new_public_key()) { 192 if (policy_->has_new_public_key() && allow_key_rotation_) {
183 signature_key = policy_->new_public_key(); 193 signature_key = &policy_->new_public_key();
184 if (!policy_->has_new_public_key_signature() || 194 if (!policy_->has_new_public_key_signature() ||
185 !VerifySignature(policy_->new_public_key(), key_, 195 !VerifySignature(policy_->new_public_key(), key_,
186 policy_->new_public_key_signature())) { 196 policy_->new_public_key_signature())) {
187 LOG(ERROR) << "New public key signature verification failed"; 197 LOG(ERROR) << "New public key signature verification failed";
188 return VALIDATION_BAD_SIGNATURE; 198 return VALIDATION_BAD_SIGNATURE;
189 } 199 }
190 } 200 }
191 201
192 if (!policy_->has_policy_data_signature() || 202 if (!policy_->has_policy_data_signature() ||
193 !VerifySignature(policy_->policy_data(), signature_key, 203 !VerifySignature(policy_->policy_data(), *signature_key,
194 policy_->policy_data_signature())) { 204 policy_->policy_data_signature())) {
195 LOG(ERROR) << "Policy signature validation failed"; 205 LOG(ERROR) << "Policy signature validation failed";
196 return VALIDATION_BAD_SIGNATURE; 206 return VALIDATION_BAD_SIGNATURE;
197 } 207 }
198 208
199 return VALIDATION_OK; 209 return VALIDATION_OK;
200 } 210 }
201 211
202 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckInitialKey() { 212 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckInitialKey() {
203 if (!policy_->has_new_public_key() || 213 if (!policy_->has_new_public_key() ||
(...skipping 11 matching lines...) Expand all
215 if (!policy_data_->has_policy_type() || 225 if (!policy_data_->has_policy_type() ||
216 policy_data_->policy_type() != policy_type_) { 226 policy_data_->policy_type() != policy_type_) {
217 LOG(ERROR) << "Wrong policy type " << policy_data_->policy_type(); 227 LOG(ERROR) << "Wrong policy type " << policy_data_->policy_type();
218 return VALIDATION_WRONG_POLICY_TYPE; 228 return VALIDATION_WRONG_POLICY_TYPE;
219 } 229 }
220 230
221 return VALIDATION_OK; 231 return VALIDATION_OK;
222 } 232 }
223 233
224 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckTimestamp() { 234 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckTimestamp() {
225 base::Time policy_time =
226 base::Time::UnixEpoch() +
227 base::TimeDelta::FromMilliseconds(policy_data_->timestamp());
228 if (!policy_data_->has_timestamp()) { 235 if (!policy_data_->has_timestamp()) {
229 LOG(ERROR) << "Policy timestamp missing"; 236 if (allow_missing_timestamp_) {
230 return VALIDATION_BAD_TIMESTAMP; 237 return VALIDATION_OK;
238 } else {
239 LOG(ERROR) << "Policy timestamp missing";
240 return VALIDATION_BAD_TIMESTAMP;
241 }
231 } 242 }
232 if (policy_time < timestamp_not_before_) { 243
244 if (policy_data_->timestamp() < timestamp_not_before_) {
233 LOG(ERROR) << "Policy too old: " << policy_data_->timestamp(); 245 LOG(ERROR) << "Policy too old: " << policy_data_->timestamp();
234 return VALIDATION_BAD_TIMESTAMP; 246 return VALIDATION_BAD_TIMESTAMP;
235 } 247 }
236 if (policy_time > timestamp_not_after_) { 248 if (policy_data_->timestamp() > timestamp_not_after_) {
237 LOG(ERROR) << "Policy in the future: " << policy_data_->timestamp(); 249 LOG(ERROR) << "Policy from the future: " << policy_data_->timestamp();
238 return VALIDATION_BAD_TIMESTAMP; 250 return VALIDATION_BAD_TIMESTAMP;
239 } 251 }
240 252
241 return VALIDATION_OK; 253 return VALIDATION_OK;
242 } 254 }
243 255
244 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckToken() { 256 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckToken() {
245 if (!policy_data_->has_request_token() || 257 if (!policy_data_->has_request_token() ||
246 policy_data_->request_token() != token_) { 258 policy_data_->request_token() != token_) {
247 LOG(ERROR) << "Invalid DM token " << policy_data_->request_token(); 259 LOG(ERROR) << "Invalid DM token " << policy_data_->request_token();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 : CloudPolicyValidatorBase(policy_response.Pass(), payload.get(), 350 : CloudPolicyValidatorBase(policy_response.Pass(), payload.get(),
339 base::Bind(completion_callback, this)), 351 base::Bind(completion_callback, this)),
340 payload_(payload.Pass()) {} 352 payload_(payload.Pass()) {}
341 353
342 template class CloudPolicyValidator< 354 template class CloudPolicyValidator<
343 enterprise_management::ChromeDeviceSettingsProto>; 355 enterprise_management::ChromeDeviceSettingsProto>;
344 template class CloudPolicyValidator< 356 template class CloudPolicyValidator<
345 enterprise_management::CloudPolicySettings>; 357 enterprise_management::CloudPolicySettings>;
346 358
347 } // namespace policy 359 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/cloud_policy_validator.h ('k') | chrome/browser/policy/cloud_policy_validator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698