OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include <vector> | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/message_loop.h" | |
10 #include "base/string_util.h" | |
11 #include "chrome/browser/policy/cloud_policy_constants.h" | |
12 #include "chrome/browser/policy/cloud_policy_validator.h" | |
13 #include "chrome/browser/policy/policy_builder.h" | |
14 #include "content/public/test/test_browser_thread.h" | |
15 #include "crypto/rsa_private_key.h" | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace em = enterprise_management; | |
20 | |
21 using testing::Invoke; | |
22 using testing::Mock; | |
23 | |
24 namespace policy { | |
25 | |
26 namespace { | |
27 | |
28 ACTION_P(CheckStatus, expected_status) { | |
29 EXPECT_EQ(expected_status, arg0->status()); | |
30 }; | |
31 | |
32 class CloudPolicyValidatorTest : public testing::Test { | |
33 public: | |
34 CloudPolicyValidatorTest() | |
35 : loop_(MessageLoop::TYPE_UI), | |
36 timestamp_(base::Time::UnixEpoch() + | |
37 base::TimeDelta::FromMilliseconds( | |
38 PolicyBuilder::kFakeTimestamp)), | |
39 ignore_missing_timestamp_(false), | |
40 allow_key_rotation_(true), | |
41 file_thread_(content::BrowserThread::FILE, &loop_) { | |
42 policy_.set_new_signing_key(PolicyBuilder::CreateTestNewSigningKey()); | |
43 } | |
44 | |
45 void Validate(testing::Action<void(UserCloudPolicyValidator*)> check_action) { | |
46 // Create a validator. | |
47 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator(); | |
48 | |
49 // Run validation and check the result. | |
50 EXPECT_CALL(*this, ValidationCompletion(validator.get())).WillOnce( | |
51 check_action); | |
52 validator.release()->StartValidation( | |
53 base::Bind(&CloudPolicyValidatorTest::ValidationCompletion, | |
54 base::Unretained(this))); | |
55 loop_.RunUntilIdle(); | |
56 Mock::VerifyAndClearExpectations(this); | |
57 } | |
58 | |
59 scoped_ptr<UserCloudPolicyValidator> CreateValidator() { | |
60 std::vector<uint8> public_key; | |
61 EXPECT_TRUE( | |
62 PolicyBuilder::CreateTestSigningKey()->ExportPublicKey(&public_key)); | |
63 policy_.Build(); | |
64 | |
65 UserCloudPolicyValidator* validator = | |
66 UserCloudPolicyValidator::Create(policy_.GetCopy()); | |
67 validator->ValidateTimestamp(timestamp_, timestamp_, | |
68 ignore_missing_timestamp_); | |
69 validator->ValidateUsername(PolicyBuilder::kFakeUsername); | |
70 validator->ValidateDomain(PolicyBuilder::kFakeDomain); | |
71 validator->ValidateDMToken(PolicyBuilder::kFakeToken); | |
72 validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType); | |
73 validator->ValidatePayload(); | |
74 validator->ValidateSignature(public_key, allow_key_rotation_); | |
75 if (allow_key_rotation_) | |
76 validator->ValidateInitialKey(); | |
77 return make_scoped_ptr(validator); | |
78 } | |
79 | |
80 | |
81 void CheckSuccessfulValidation(UserCloudPolicyValidator* validator) { | |
82 EXPECT_TRUE(validator->success()); | |
83 EXPECT_EQ(policy_.policy().SerializeAsString(), | |
84 validator->policy()->SerializeAsString()); | |
85 EXPECT_EQ(policy_.policy_data().SerializeAsString(), | |
86 validator->policy_data()->SerializeAsString()); | |
87 EXPECT_EQ(policy_.payload().SerializeAsString(), | |
88 validator->payload()->SerializeAsString()); | |
89 } | |
90 | |
91 MessageLoop loop_; | |
92 base::Time timestamp_; | |
93 bool ignore_missing_timestamp_; | |
94 std::string signing_key_; | |
95 bool allow_key_rotation_; | |
96 | |
97 UserPolicyBuilder policy_; | |
98 | |
99 private: | |
100 MOCK_METHOD1(ValidationCompletion, void(UserCloudPolicyValidator* validator)); | |
101 | |
102 content::TestBrowserThread file_thread_; | |
103 | |
104 DISALLOW_COPY_AND_ASSIGN(CloudPolicyValidatorTest); | |
105 }; | |
106 | |
107 TEST_F(CloudPolicyValidatorTest, SuccessfulValidation) { | |
108 Validate(Invoke(this, &CloudPolicyValidatorTest::CheckSuccessfulValidation)); | |
109 } | |
110 | |
111 TEST_F(CloudPolicyValidatorTest, SuccessfulRunValidation) { | |
112 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator(); | |
113 // Run validation immediately (no background tasks). | |
114 validator->RunValidation(); | |
115 CheckSuccessfulValidation(validator.get()); | |
116 } | |
117 | |
118 TEST_F(CloudPolicyValidatorTest, UsernameCanonicalization) { | |
119 policy_.policy_data().set_username( | |
120 StringToUpperASCII(std::string(PolicyBuilder::kFakeUsername))); | |
121 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_OK)); | |
122 } | |
123 | |
124 TEST_F(CloudPolicyValidatorTest, ErrorNoPolicyType) { | |
125 policy_.policy_data().clear_policy_type(); | |
126 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_POLICY_TYPE)); | |
127 } | |
128 | |
129 TEST_F(CloudPolicyValidatorTest, ErrorWrongPolicyType) { | |
130 policy_.policy_data().set_policy_type("invalid"); | |
131 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_POLICY_TYPE)); | |
132 } | |
133 | |
134 TEST_F(CloudPolicyValidatorTest, ErrorNoTimestamp) { | |
135 policy_.policy_data().clear_timestamp(); | |
136 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_TIMESTAMP)); | |
137 } | |
138 | |
139 TEST_F(CloudPolicyValidatorTest, IgnoreMissingTimestamp) { | |
140 ignore_missing_timestamp_ = true; | |
141 policy_.policy_data().clear_timestamp(); | |
142 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_OK)); | |
143 } | |
144 | |
145 TEST_F(CloudPolicyValidatorTest, ErrorOldTimestamp) { | |
146 base::Time timestamp(timestamp_ - base::TimeDelta::FromMinutes(5)); | |
147 policy_.policy_data().set_timestamp( | |
148 (timestamp - base::Time::UnixEpoch()).InMilliseconds()); | |
149 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_TIMESTAMP)); | |
150 } | |
151 | |
152 TEST_F(CloudPolicyValidatorTest, ErrorTimestampFromTheFuture) { | |
153 base::Time timestamp(timestamp_ + base::TimeDelta::FromMinutes(5)); | |
154 policy_.policy_data().set_timestamp( | |
155 (timestamp - base::Time::UnixEpoch()).InMilliseconds()); | |
156 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_TIMESTAMP)); | |
157 } | |
158 | |
159 TEST_F(CloudPolicyValidatorTest, ErrorNoRequestToken) { | |
160 policy_.policy_data().clear_request_token(); | |
161 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); | |
162 } | |
163 | |
164 TEST_F(CloudPolicyValidatorTest, ErrorInvalidRequestToken) { | |
165 policy_.policy_data().set_request_token("invalid"); | |
166 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); | |
167 } | |
168 | |
169 TEST_F(CloudPolicyValidatorTest, ErrorNoPolicyValue) { | |
170 policy_.clear_payload(); | |
171 Validate( | |
172 CheckStatus(CloudPolicyValidatorBase::VALIDATION_POLICY_PARSE_ERROR)); | |
173 } | |
174 | |
175 TEST_F(CloudPolicyValidatorTest, ErrorInvalidPolicyValue) { | |
176 policy_.clear_payload(); | |
177 policy_.policy_data().set_policy_value("invalid"); | |
178 Validate( | |
179 CheckStatus(CloudPolicyValidatorBase::VALIDATION_POLICY_PARSE_ERROR)); | |
180 } | |
181 | |
182 TEST_F(CloudPolicyValidatorTest, ErrorNoUsername) { | |
183 policy_.policy_data().clear_username(); | |
184 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_USERNAME)); | |
185 } | |
186 | |
187 TEST_F(CloudPolicyValidatorTest, ErrorInvalidUsername) { | |
188 policy_.policy_data().set_username("invalid"); | |
189 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_USERNAME)); | |
190 } | |
191 | |
192 TEST_F(CloudPolicyValidatorTest, ErrorErrorMessage) { | |
193 policy_.policy().set_error_message("error"); | |
194 Validate( | |
195 CheckStatus(CloudPolicyValidatorBase::VALIDATION_ERROR_CODE_PRESENT)); | |
196 } | |
197 | |
198 TEST_F(CloudPolicyValidatorTest, ErrorErrorCode) { | |
199 policy_.policy().set_error_code(42); | |
200 Validate( | |
201 CheckStatus(CloudPolicyValidatorBase::VALIDATION_ERROR_CODE_PRESENT)); | |
202 } | |
203 | |
204 TEST_F(CloudPolicyValidatorTest, ErrorNoSignature) { | |
205 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
206 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
207 policy_.policy().clear_policy_data_signature(); | |
208 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
209 } | |
210 | |
211 TEST_F(CloudPolicyValidatorTest, ErrorInvalidSignature) { | |
212 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
213 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
214 policy_.policy().set_policy_data_signature("invalid"); | |
215 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
216 } | |
217 | |
218 TEST_F(CloudPolicyValidatorTest, ErrorNoPublicKey) { | |
219 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
220 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
221 policy_.policy().clear_new_public_key(); | |
222 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
223 } | |
224 | |
225 TEST_F(CloudPolicyValidatorTest, ErrorInvalidPublicKey) { | |
226 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
227 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
228 policy_.policy().set_new_public_key("invalid"); | |
229 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
230 } | |
231 | |
232 TEST_F(CloudPolicyValidatorTest, ErrorNoPublicKeySignature) { | |
233 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
234 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
235 policy_.policy().clear_new_public_key_signature(); | |
236 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
237 } | |
238 | |
239 TEST_F(CloudPolicyValidatorTest, ErrorInvalidPublicKeySignature) { | |
240 policy_.set_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
241 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
242 policy_.policy().set_new_public_key_signature("invalid"); | |
243 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
244 } | |
245 | |
246 TEST_F(CloudPolicyValidatorTest, ErrorNoRotationAllowed) { | |
247 allow_key_rotation_ = false; | |
248 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE)); | |
249 } | |
250 | |
251 TEST_F(CloudPolicyValidatorTest, NoRotation) { | |
252 allow_key_rotation_ = false; | |
253 policy_.set_new_signing_key(scoped_ptr<crypto::RSAPrivateKey>()); | |
254 Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_OK)); | |
255 } | |
256 | |
257 } // namespace | |
258 | |
259 } // namespace policy | |
OLD | NEW |