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 #ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ | 5 #ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ |
6 #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ | 6 #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 namespace policy { | 40 namespace policy { |
41 | 41 |
42 // Helper class that implements the gory details of validating a policy blob. | 42 // Helper class that implements the gory details of validating a policy blob. |
43 // Since signature checks are expensive, validation can happen on a background | 43 // Since signature checks are expensive, validation can happen on a background |
44 // thread. The pattern is to create a validator, configure its behavior through | 44 // thread. The pattern is to create a validator, configure its behavior through |
45 // the ValidateXYZ() functions, and then call StartValidation(). Alternatively, | 45 // the ValidateXYZ() functions, and then call StartValidation(). Alternatively, |
46 // RunValidation() can be used to perform validation on the current thread. | 46 // RunValidation() can be used to perform validation on the current thread. |
47 class POLICY_EXPORT CloudPolicyValidatorBase { | 47 class POLICY_EXPORT CloudPolicyValidatorBase { |
48 public: | 48 public: |
49 // Validation result codes. These values are also used for UMA histograms; | 49 // Validation result codes. These values are also used for UMA histograms by |
50 // they must stay stable, and the UMA counters must be updated if new elements | 50 // UserCloudPolicyStoreChromeOS and must stay stable - new elements should |
51 // are appended at the end. | 51 // be added at the end before VALIDATION_STATUS_SIZE. |
52 enum Status { | 52 enum Status { |
53 // Indicates successful validation. | 53 // Indicates successful validation. |
54 VALIDATION_OK, | 54 VALIDATION_OK, |
55 // Bad signature on the initial key. | 55 // Bad signature on the initial key. |
56 VALIDATION_BAD_INITIAL_SIGNATURE, | 56 VALIDATION_BAD_INITIAL_SIGNATURE, |
57 // Bad signature. | 57 // Bad signature. |
58 VALIDATION_BAD_SIGNATURE, | 58 VALIDATION_BAD_SIGNATURE, |
59 // Policy blob contains error code. | 59 // Policy blob contains error code. |
60 VALIDATION_ERROR_CODE_PRESENT, | 60 VALIDATION_ERROR_CODE_PRESENT, |
61 // Policy payload failed to decode. | 61 // Policy payload failed to decode. |
62 VALIDATION_PAYLOAD_PARSE_ERROR, | 62 VALIDATION_PAYLOAD_PARSE_ERROR, |
63 // Unexpected policy type. | 63 // Unexpected policy type. |
64 VALIDATION_WRONG_POLICY_TYPE, | 64 VALIDATION_WRONG_POLICY_TYPE, |
65 // Unexpected settings entity id. | 65 // Unexpected settings entity id. |
66 VALIDATION_WRONG_SETTINGS_ENTITY_ID, | 66 VALIDATION_WRONG_SETTINGS_ENTITY_ID, |
67 // Time stamp from the future. | 67 // Time stamp from the future. |
68 VALIDATION_BAD_TIMESTAMP, | 68 VALIDATION_BAD_TIMESTAMP, |
69 // Token doesn't match. | 69 // Token doesn't match. |
70 VALIDATION_WRONG_TOKEN, | 70 VALIDATION_WRONG_TOKEN, |
71 // Username doesn't match. | 71 // Username doesn't match. |
72 VALIDATION_BAD_USERNAME, | 72 VALIDATION_BAD_USERNAME, |
73 // Policy payload protobuf parse error. | 73 // Policy payload protobuf parse error. |
74 VALIDATION_POLICY_PARSE_ERROR, | 74 VALIDATION_POLICY_PARSE_ERROR, |
| 75 // Policy key signature could not be verified using the hard-coded |
| 76 // verification key. |
| 77 VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE, |
| 78 VALIDATION_STATUS_SIZE // MUST BE LAST |
75 }; | 79 }; |
76 | 80 |
77 enum ValidateDMTokenOption { | 81 enum ValidateDMTokenOption { |
78 // The policy must have a non-empty DMToken. | 82 // The policy must have a non-empty DMToken. |
79 DM_TOKEN_REQUIRED, | 83 DM_TOKEN_REQUIRED, |
80 | 84 |
81 // The policy may have an empty or missing DMToken, if the expected token | 85 // The policy may have an empty or missing DMToken, if the expected token |
82 // is also empty. | 86 // is also empty. |
83 DM_TOKEN_NOT_REQUIRED, | 87 DM_TOKEN_NOT_REQUIRED, |
84 }; | 88 }; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 140 |
137 // Validates the policy type. | 141 // Validates the policy type. |
138 void ValidatePolicyType(const std::string& policy_type); | 142 void ValidatePolicyType(const std::string& policy_type); |
139 | 143 |
140 // Validates the settings_entity_id value. | 144 // Validates the settings_entity_id value. |
141 void ValidateSettingsEntityId(const std::string& settings_entity_id); | 145 void ValidateSettingsEntityId(const std::string& settings_entity_id); |
142 | 146 |
143 // Validates that the payload can be decoded successfully. | 147 // Validates that the payload can be decoded successfully. |
144 void ValidatePayload(); | 148 void ValidatePayload(); |
145 | 149 |
146 // Verifies that the signature on the policy blob verifies against |key|. If | | 150 // Verifies that the signature on the policy blob verifies against |key|. If |
147 // |allow_key_rotation| is true and there is a key rotation present in the | 151 // |allow_key_rotation| is true and there is a key rotation present in the |
148 // policy blob, this checks the signature on the new key against |key| and the | 152 // policy blob, this checks the signature on the new key against |key| and the |
149 // policy blob against the new key. | 153 // policy blob against the new key. New key is also validated using the passed |
150 void ValidateSignature(const std::vector<uint8>& key, | 154 // |verification_key| and the |new_public_key_verification_signature| field. |
| 155 // If |key_signature| is non-empty, then |key| is also verified against that |
| 156 // signature (useful when dealing with cached keys from untrusted sources). |
| 157 void ValidateSignature(const std::string& key, |
| 158 const std::string& verification_key, |
| 159 const std::string& key_signature, |
151 bool allow_key_rotation); | 160 bool allow_key_rotation); |
152 | 161 |
153 // Similar to StartSignatureVerification(), this checks the signature on the | 162 // Similar to ValidateSignature(), this checks the signature on the |
154 // policy blob. However, this variant expects a new policy key set in the | 163 // policy blob. However, this variant expects a new policy key set in the |
155 // policy blob and makes sure the policy is signed using that key. This should | 164 // policy blob and makes sure the policy is signed using that key. This should |
156 // be called at setup time when there is no existing policy key present to | 165 // be called at setup time when there is no existing policy key present to |
157 // check against. | 166 // check against. New key is validated using the passed |verification_key| and |
158 void ValidateInitialKey(); | 167 // the new_public_key_verification_signature field. |
| 168 void ValidateInitialKey(const std::string& verification_key); |
159 | 169 |
160 // Convenience helper that configures timestamp and token validation based on | 170 // Convenience helper that configures timestamp and token validation based on |
161 // the current policy blob. |policy_data| may be NULL, in which case the | 171 // the current policy blob. |policy_data| may be NULL, in which case the |
162 // timestamp validation will drop the lower bound. |dm_token_option| | 172 // timestamp validation will drop the lower bound. |dm_token_option| |
163 // and |timestamp_option| have the same effect as the corresponding | 173 // and |timestamp_option| have the same effect as the corresponding |
164 // parameters for ValidateTimestamp() and ValidateDMToken(). | 174 // parameters for ValidateTimestamp() and ValidateDMToken(). |
165 void ValidateAgainstCurrentPolicy( | 175 void ValidateAgainstCurrentPolicy( |
166 const enterprise_management::PolicyData* policy_data, | 176 const enterprise_management::PolicyData* policy_data, |
167 ValidateTimestampOption timestamp_option, | 177 ValidateTimestampOption timestamp_option, |
168 ValidateDMTokenOption dm_token_option); | 178 ValidateDMTokenOption dm_token_option); |
(...skipping 19 matching lines...) Expand all Loading... |
188 enum ValidationFlags { | 198 enum ValidationFlags { |
189 VALIDATE_TIMESTAMP = 1 << 0, | 199 VALIDATE_TIMESTAMP = 1 << 0, |
190 VALIDATE_USERNAME = 1 << 1, | 200 VALIDATE_USERNAME = 1 << 1, |
191 VALIDATE_DOMAIN = 1 << 2, | 201 VALIDATE_DOMAIN = 1 << 2, |
192 VALIDATE_TOKEN = 1 << 3, | 202 VALIDATE_TOKEN = 1 << 3, |
193 VALIDATE_POLICY_TYPE = 1 << 4, | 203 VALIDATE_POLICY_TYPE = 1 << 4, |
194 VALIDATE_ENTITY_ID = 1 << 5, | 204 VALIDATE_ENTITY_ID = 1 << 5, |
195 VALIDATE_PAYLOAD = 1 << 6, | 205 VALIDATE_PAYLOAD = 1 << 6, |
196 VALIDATE_SIGNATURE = 1 << 7, | 206 VALIDATE_SIGNATURE = 1 << 7, |
197 VALIDATE_INITIAL_KEY = 1 << 8, | 207 VALIDATE_INITIAL_KEY = 1 << 8, |
| 208 VALIDATE_SIGNED_KEY = 1 << 9, |
198 }; | 209 }; |
199 | 210 |
200 // Performs validation, called on a background thread. | 211 // Performs validation, called on a background thread. |
201 static void PerformValidation( | 212 static void PerformValidation( |
202 scoped_ptr<CloudPolicyValidatorBase> self, | 213 scoped_ptr<CloudPolicyValidatorBase> self, |
203 scoped_refptr<base::MessageLoopProxy> message_loop, | 214 scoped_refptr<base::MessageLoopProxy> message_loop, |
204 const base::Closure& completion_callback); | 215 const base::Closure& completion_callback); |
205 | 216 |
206 // Reports completion to the |completion_callback_|. | 217 // Reports completion to the |completion_callback_|. |
207 static void ReportCompletion(scoped_ptr<CloudPolicyValidatorBase> self, | 218 static void ReportCompletion(scoped_ptr<CloudPolicyValidatorBase> self, |
208 const base::Closure& completion_callback); | 219 const base::Closure& completion_callback); |
209 | 220 |
210 // Invokes all the checks and reports the result. | 221 // Invokes all the checks and reports the result. |
211 void RunChecks(); | 222 void RunChecks(); |
212 | 223 |
| 224 // Helper routine that verifies that the new public key in the policy blob |
| 225 // is properly signed by the |verification_key_|. |
| 226 bool CheckNewPublicKeyVerificationSignature(); |
| 227 |
| 228 // Helper routine that performs a verification-key-based signature check, |
| 229 // which includes the domain name associated with this policy. Returns true |
| 230 // if the verification succeeds, or if |signature| is empty. |
| 231 bool CheckVerificationKeySignature(const std::string& key_to_verify, |
| 232 const std::string& server_key, |
| 233 const std::string& signature); |
| 234 |
| 235 // Sets the key used to verify new public keys, and ensures that callers |
| 236 // don't try to set conflicting keys. |
| 237 void set_verification_key(const std::string& verification_key); |
| 238 |
213 // Helper functions implementing individual checks. | 239 // Helper functions implementing individual checks. |
214 Status CheckTimestamp(); | 240 Status CheckTimestamp(); |
215 Status CheckUsername(); | 241 Status CheckUsername(); |
216 Status CheckDomain(); | 242 Status CheckDomain(); |
217 Status CheckToken(); | 243 Status CheckToken(); |
218 Status CheckPolicyType(); | 244 Status CheckPolicyType(); |
219 Status CheckEntityId(); | 245 Status CheckEntityId(); |
220 Status CheckPayload(); | 246 Status CheckPayload(); |
221 Status CheckSignature(); | 247 Status CheckSignature(); |
222 Status CheckInitialKey(); | 248 Status CheckInitialKey(); |
(...skipping 12 matching lines...) Expand all Loading... |
235 int64 timestamp_not_before_; | 261 int64 timestamp_not_before_; |
236 int64 timestamp_not_after_; | 262 int64 timestamp_not_after_; |
237 ValidateTimestampOption timestamp_option_; | 263 ValidateTimestampOption timestamp_option_; |
238 ValidateDMTokenOption dm_token_option_; | 264 ValidateDMTokenOption dm_token_option_; |
239 std::string user_; | 265 std::string user_; |
240 std::string domain_; | 266 std::string domain_; |
241 std::string token_; | 267 std::string token_; |
242 std::string policy_type_; | 268 std::string policy_type_; |
243 std::string settings_entity_id_; | 269 std::string settings_entity_id_; |
244 std::string key_; | 270 std::string key_; |
| 271 std::string key_signature_; |
| 272 std::string verification_key_; |
245 bool allow_key_rotation_; | 273 bool allow_key_rotation_; |
246 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; | 274 scoped_refptr<base::SequencedTaskRunner> background_task_runner_; |
247 | 275 |
248 DISALLOW_COPY_AND_ASSIGN(CloudPolicyValidatorBase); | 276 DISALLOW_COPY_AND_ASSIGN(CloudPolicyValidatorBase); |
249 }; | 277 }; |
250 | 278 |
251 // A simple type-parameterized extension of CloudPolicyValidator that | 279 // A simple type-parameterized extension of CloudPolicyValidator that |
252 // facilitates working with the actual protobuf payload type. | 280 // facilitates working with the actual protobuf payload type. |
253 template<typename PayloadProto> | 281 template<typename PayloadProto> |
254 class POLICY_EXPORT CloudPolicyValidator : public CloudPolicyValidatorBase { | 282 class POLICY_EXPORT CloudPolicyValidator : public CloudPolicyValidatorBase { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 UserCloudPolicyValidator; | 329 UserCloudPolicyValidator; |
302 | 330 |
303 #if !defined(OS_ANDROID) && !defined(OS_IOS) | 331 #if !defined(OS_ANDROID) && !defined(OS_IOS) |
304 typedef CloudPolicyValidator<enterprise_management::ExternalPolicyData> | 332 typedef CloudPolicyValidator<enterprise_management::ExternalPolicyData> |
305 ComponentCloudPolicyValidator; | 333 ComponentCloudPolicyValidator; |
306 #endif | 334 #endif |
307 | 335 |
308 } // namespace policy | 336 } // namespace policy |
309 | 337 |
310 #endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ | 338 #endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_VALIDATOR_H_ |
OLD | NEW |