| 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 |