OLD | NEW |
---|---|
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/cloud_policy_validator.h" | 5 #include "chrome/browser/policy/cloud/cloud_policy_validator.h" |
6 | 6 |
7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
8 #include "base/hash.h" | |
8 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
10 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 11 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" |
11 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 12 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" |
12 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
13 #include "crypto/signature_verifier.h" | 14 #include "crypto/signature_verifier.h" |
14 #include "google_apis/gaia/gaia_auth_util.h" | 15 #include "google_apis/gaia/gaia_auth_util.h" |
15 | 16 |
16 namespace em = enterprise_management; | 17 namespace em = enterprise_management; |
17 | 18 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 validation_flags_ |= VALIDATE_SIGNATURE; | 89 validation_flags_ |= VALIDATE_SIGNATURE; |
89 key_ = std::string(reinterpret_cast<const char*>(vector_as_array(&key)), | 90 key_ = std::string(reinterpret_cast<const char*>(vector_as_array(&key)), |
90 key.size()); | 91 key.size()); |
91 allow_key_rotation_ = allow_key_rotation; | 92 allow_key_rotation_ = allow_key_rotation; |
92 } | 93 } |
93 | 94 |
94 void CloudPolicyValidatorBase::ValidateInitialKey() { | 95 void CloudPolicyValidatorBase::ValidateInitialKey() { |
95 validation_flags_ |= VALIDATE_INITIAL_KEY; | 96 validation_flags_ |= VALIDATE_INITIAL_KEY; |
96 } | 97 } |
97 | 98 |
99 void CloudPolicyValidatorBase::ValidateHashValue() { | |
100 validation_flags_ |= VALIDATE_HASH_VALUE; | |
101 } | |
102 | |
98 void CloudPolicyValidatorBase::ValidateAgainstCurrentPolicy( | 103 void CloudPolicyValidatorBase::ValidateAgainstCurrentPolicy( |
99 const em::PolicyData* policy_data, | 104 const em::PolicyData* policy_data, |
100 ValidateTimestampOption timestamp_option, | 105 ValidateTimestampOption timestamp_option, |
101 ValidateDMTokenOption dm_token_option) { | 106 ValidateDMTokenOption dm_token_option) { |
102 base::Time last_policy_timestamp; | 107 base::Time last_policy_timestamp; |
103 std::string expected_dm_token; | 108 std::string expected_dm_token; |
104 if (policy_data) { | 109 if (policy_data) { |
105 last_policy_timestamp = | 110 last_policy_timestamp = |
106 base::Time::UnixEpoch() + | 111 base::Time::UnixEpoch() + |
107 base::TimeDelta::FromMilliseconds(policy_data->timestamp()); | 112 base::TimeDelta::FromMilliseconds(policy_data->timestamp()); |
108 expected_dm_token = policy_data->request_token(); | 113 expected_dm_token = policy_data->request_token(); |
109 } | 114 } |
110 ValidateTimestamp(last_policy_timestamp, base::Time::NowFromSystemTime(), | 115 ValidateTimestamp(last_policy_timestamp, base::Time::NowFromSystemTime(), |
111 timestamp_option); | 116 timestamp_option); |
112 ValidateDMToken(expected_dm_token, dm_token_option); | 117 ValidateDMToken(expected_dm_token, dm_token_option); |
113 } | 118 } |
114 | 119 |
115 CloudPolicyValidatorBase::CloudPolicyValidatorBase( | 120 CloudPolicyValidatorBase::CloudPolicyValidatorBase( |
116 scoped_ptr<em::PolicyFetchResponse> policy_response, | 121 scoped_ptr<em::PolicyFetchResponse> policy_response, |
117 google::protobuf::MessageLite* payload) | 122 google::protobuf::MessageLite* payload) |
118 : status_(VALIDATION_OK), | 123 : status_(VALIDATION_OK), |
119 policy_(policy_response.Pass()), | 124 policy_(policy_response.Pass()), |
120 payload_(payload), | 125 payload_(payload), |
126 hash_value_(0), | |
121 validation_flags_(0), | 127 validation_flags_(0), |
122 timestamp_not_before_(0), | 128 timestamp_not_before_(0), |
123 timestamp_not_after_(0), | 129 timestamp_not_after_(0), |
124 timestamp_option_(TIMESTAMP_REQUIRED), | 130 timestamp_option_(TIMESTAMP_REQUIRED), |
125 dm_token_option_(DM_TOKEN_REQUIRED), | 131 dm_token_option_(DM_TOKEN_REQUIRED), |
126 allow_key_rotation_(false) {} | 132 allow_key_rotation_(false) {} |
127 | 133 |
128 void CloudPolicyValidatorBase::PostValidationTask( | 134 void CloudPolicyValidatorBase::PostValidationTask( |
129 const base::Closure& completion_callback) { | 135 const base::Closure& completion_callback) { |
130 content::BrowserThread::PostTask( | 136 content::BrowserThread::PostTask( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 } kCheckFunctions[] = { | 196 } kCheckFunctions[] = { |
191 { VALIDATE_SIGNATURE, &CloudPolicyValidatorBase::CheckSignature }, | 197 { VALIDATE_SIGNATURE, &CloudPolicyValidatorBase::CheckSignature }, |
192 { VALIDATE_INITIAL_KEY, &CloudPolicyValidatorBase::CheckInitialKey }, | 198 { VALIDATE_INITIAL_KEY, &CloudPolicyValidatorBase::CheckInitialKey }, |
193 { VALIDATE_POLICY_TYPE, &CloudPolicyValidatorBase::CheckPolicyType }, | 199 { VALIDATE_POLICY_TYPE, &CloudPolicyValidatorBase::CheckPolicyType }, |
194 { VALIDATE_ENTITY_ID, &CloudPolicyValidatorBase::CheckEntityId }, | 200 { VALIDATE_ENTITY_ID, &CloudPolicyValidatorBase::CheckEntityId }, |
195 { VALIDATE_TOKEN, &CloudPolicyValidatorBase::CheckToken }, | 201 { VALIDATE_TOKEN, &CloudPolicyValidatorBase::CheckToken }, |
196 { VALIDATE_USERNAME, &CloudPolicyValidatorBase::CheckUsername }, | 202 { VALIDATE_USERNAME, &CloudPolicyValidatorBase::CheckUsername }, |
197 { VALIDATE_DOMAIN, &CloudPolicyValidatorBase::CheckDomain }, | 203 { VALIDATE_DOMAIN, &CloudPolicyValidatorBase::CheckDomain }, |
198 { VALIDATE_TIMESTAMP, &CloudPolicyValidatorBase::CheckTimestamp }, | 204 { VALIDATE_TIMESTAMP, &CloudPolicyValidatorBase::CheckTimestamp }, |
199 { VALIDATE_PAYLOAD, &CloudPolicyValidatorBase::CheckPayload }, | 205 { VALIDATE_PAYLOAD, &CloudPolicyValidatorBase::CheckPayload }, |
206 { VALIDATE_HASH_VALUE, &CloudPolicyValidatorBase::CheckHashValue }, | |
200 }; | 207 }; |
201 | 208 |
202 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckFunctions); ++i) { | 209 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckFunctions); ++i) { |
203 if (validation_flags_ & kCheckFunctions[i].flag) { | 210 if (validation_flags_ & kCheckFunctions[i].flag) { |
204 status_ = (this->*(kCheckFunctions[i].checkFunction))(); | 211 status_ = (this->*(kCheckFunctions[i].checkFunction))(); |
205 if (status_ != VALIDATION_OK) | 212 if (status_ != VALIDATION_OK) |
206 break; | 213 break; |
207 } | 214 } |
208 } | 215 } |
209 } | 216 } |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 if (!policy_data_->has_policy_value() || | 352 if (!policy_data_->has_policy_value() || |
346 !payload_->ParseFromString(policy_data_->policy_value()) || | 353 !payload_->ParseFromString(policy_data_->policy_value()) || |
347 !payload_->IsInitialized()) { | 354 !payload_->IsInitialized()) { |
348 LOG(ERROR) << "Failed to decode policy payload protobuf"; | 355 LOG(ERROR) << "Failed to decode policy payload protobuf"; |
349 return VALIDATION_POLICY_PARSE_ERROR; | 356 return VALIDATION_POLICY_PARSE_ERROR; |
350 } | 357 } |
351 | 358 |
352 return VALIDATION_OK; | 359 return VALIDATION_OK; |
353 } | 360 } |
354 | 361 |
362 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckHashValue() { | |
363 hash_value_ = base::Hash(policy_data_->policy_value()); | |
Joao da Silva
2013/07/23 20:44:47
This isn't a validation of the policy (it can't fa
Steve Condie
2013/07/24 01:42:04
I agree the way you suggested is cleaner. The only
| |
364 return VALIDATION_OK; | |
365 } | |
366 | |
355 // static | 367 // static |
356 bool CloudPolicyValidatorBase::VerifySignature(const std::string& data, | 368 bool CloudPolicyValidatorBase::VerifySignature(const std::string& data, |
357 const std::string& key, | 369 const std::string& key, |
358 const std::string& signature) { | 370 const std::string& signature) { |
359 crypto::SignatureVerifier verifier; | 371 crypto::SignatureVerifier verifier; |
360 | 372 |
361 if (!verifier.VerifyInit(kSignatureAlgorithm, sizeof(kSignatureAlgorithm), | 373 if (!verifier.VerifyInit(kSignatureAlgorithm, sizeof(kSignatureAlgorithm), |
362 reinterpret_cast<const uint8*>(signature.c_str()), | 374 reinterpret_cast<const uint8*>(signature.c_str()), |
363 signature.size(), | 375 signature.size(), |
364 reinterpret_cast<const uint8*>(key.c_str()), | 376 reinterpret_cast<const uint8*>(key.c_str()), |
365 key.size())) { | 377 key.size())) { |
366 return false; | 378 return false; |
367 } | 379 } |
368 verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()), | 380 verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()), |
369 data.size()); | 381 data.size()); |
370 return verifier.VerifyFinal(); | 382 return verifier.VerifyFinal(); |
371 } | 383 } |
372 | 384 |
373 template class CloudPolicyValidator<em::CloudPolicySettings>; | 385 template class CloudPolicyValidator<em::CloudPolicySettings>; |
374 template class CloudPolicyValidator<em::ExternalPolicyData>; | 386 template class CloudPolicyValidator<em::ExternalPolicyData>; |
375 | 387 |
376 } // namespace policy | 388 } // namespace policy |
OLD | NEW |