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

Side by Side Diff: chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc

Issue 2488573003: Expose signing key from cloud policy stores (Closed)
Patch Set: Expose public key only on successful store Created 4 years, 1 month 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
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/chromeos/policy/user_cloud_policy_store_chromeos.h" 5 #include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 const base::FilePath& legacy_policy_cache_file) 186 const base::FilePath& legacy_policy_cache_file)
187 : UserCloudPolicyStoreBase(background_task_runner), 187 : UserCloudPolicyStoreBase(background_task_runner),
188 cryptohome_client_(cryptohome_client), 188 cryptohome_client_(cryptohome_client),
189 session_manager_client_(session_manager_client), 189 session_manager_client_(session_manager_client),
190 account_id_(account_id), 190 account_id_(account_id),
191 user_policy_key_dir_(user_policy_key_dir), 191 user_policy_key_dir_(user_policy_key_dir),
192 legacy_cache_dir_(legacy_token_cache_file.DirName()), 192 legacy_cache_dir_(legacy_token_cache_file.DirName()),
193 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, 193 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file,
194 legacy_policy_cache_file, 194 legacy_policy_cache_file,
195 background_task_runner)), 195 background_task_runner)),
196 legacy_caches_loaded_(false), 196 owning_domain_(ExtractDomain(account_id_.GetUserEmail())),
197 policy_key_loaded_(false),
198 weak_factory_(this) {} 197 weak_factory_(this) {}
199 198
200 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} 199 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {}
201 200
202 void UserCloudPolicyStoreChromeOS::Store( 201 void UserCloudPolicyStoreChromeOS::Store(
203 const em::PolicyFetchResponse& policy) { 202 const em::PolicyFetchResponse& policy) {
204 // Cancel all pending requests. 203 // Cancel all pending requests.
205 weak_factory_.InvalidateWeakPtrs(); 204 weak_factory_.InvalidateWeakPtrs();
206 std::unique_ptr<em::PolicyFetchResponse> response( 205 std::unique_ptr<em::PolicyFetchResponse> response(
207 new em::PolicyFetchResponse(policy)); 206 new em::PolicyFetchResponse(policy));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 cryptohome_client_->BlockingGetSanitizedUsername( 251 cryptohome_client_->BlockingGetSanitizedUsername(
253 cryptohome::Identification(account_id_)); 252 cryptohome::Identification(account_id_));
254 if (sanitized_username.empty()) { 253 if (sanitized_username.empty()) {
255 status_ = STATUS_LOAD_ERROR; 254 status_ = STATUS_LOAD_ERROR;
256 NotifyStoreError(); 255 NotifyStoreError();
257 return; 256 return;
258 } 257 }
259 258
260 policy_key_path_ = user_policy_key_dir_.Append( 259 policy_key_path_ = user_policy_key_dir_.Append(
261 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); 260 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str()));
262 LoadPolicyKey(policy_key_path_, &policy_key_); 261 LoadPolicyKey(policy_key_path_, &loaded_policy_key_);
263 policy_key_loaded_ = true; 262 is_policy_key_loaded_ = true;
264 263
265 std::unique_ptr<UserCloudPolicyValidator> validator = 264 std::unique_ptr<UserCloudPolicyValidator> validator =
266 CreateValidatorForLoad(std::move(policy)); 265 CreateValidatorForLoad(std::move(policy));
267 validator->RunValidation(); 266 validator->RunValidation();
268 OnRetrievedPolicyValidated(validator.get()); 267 OnRetrievedPolicyValidated(validator.get());
269 } 268 }
270 269
271 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( 270 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore(
272 std::unique_ptr<em::PolicyFetchResponse> policy) { 271 std::unique_ptr<em::PolicyFetchResponse> policy) {
273 // Create and configure a validator. 272 // Create and configure a validator.
274 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( 273 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
275 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); 274 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED);
276 validator->ValidateUsername(account_id_.GetUserEmail(), true); 275 validator->ValidateUsername(account_id_.GetUserEmail(), true);
277 if (policy_key_.empty()) { 276 if (loaded_policy_key_.empty()) {
278 validator->ValidateInitialKey(GetPolicyVerificationKey(), 277 validator->ValidateInitialKey(GetPolicyVerificationKey(), owning_domain_);
279 ExtractDomain(account_id_.GetUserEmail()));
280 } else { 278 } else {
281 validator->ValidateSignatureAllowingRotation( 279 validator->ValidateSignatureAllowingRotation(
282 policy_key_, GetPolicyVerificationKey(), 280 loaded_policy_key_, GetPolicyVerificationKey(),
283 ExtractDomain(account_id_.GetUserEmail())); 281 ExtractDomain(account_id_.GetUserEmail()));
284 } 282 }
285 283
286 // Start validation. The Validator will delete itself once validation is 284 // Start validation. The Validator will delete itself once validation is
287 // complete. 285 // complete.
288 validator.release()->StartValidation( 286 validator.release()->StartValidation(
289 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, 287 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
290 weak_factory_.GetWeakPtr())); 288 weak_factory_.GetWeakPtr()));
291 } 289 }
292 290
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // load; reload the key for that validation too, in case it was rotated. 326 // load; reload the key for that validation too, in case it was rotated.
329 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load, 327 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load,
330 weak_factory_.GetWeakPtr())); 328 weak_factory_.GetWeakPtr()));
331 } 329 }
332 } 330 }
333 331
334 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( 332 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved(
335 const std::string& policy_blob) { 333 const std::string& policy_blob) {
336 if (policy_blob.empty()) { 334 if (policy_blob.empty()) {
337 // Policy fetch failed. Try legacy caches if we haven't done that already. 335 // Policy fetch failed. Try legacy caches if we haven't done that already.
338 if (!legacy_caches_loaded_ && legacy_loader_.get()) { 336 if (!is_legacy_caches_load_performed_ && legacy_loader_.get()) {
339 legacy_caches_loaded_ = true; 337 is_legacy_caches_load_performed_ = true;
340 legacy_loader_->Load( 338 legacy_loader_->Load(
341 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished, 339 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished,
342 weak_factory_.GetWeakPtr())); 340 weak_factory_.GetWeakPtr()));
343 } else { 341 } else {
344 // session_manager doesn't have policy. Adjust internal state and notify 342 // session_manager doesn't have policy. Adjust internal state and notify
345 // the world about the policy update. 343 // the world about the policy update.
344 policy_map_.Clear();
346 policy_.reset(); 345 policy_.reset();
346 public_key_.clear();
347 NotifyStoreLoaded(); 347 NotifyStoreLoaded();
348 } 348 }
349 return; 349 return;
350 } 350 }
351 351
352 // Policy is supplied by session_manager. Disregard legacy data from now on. 352 // Policy is supplied by session_manager. Disregard legacy data from now on.
353 legacy_loader_.reset(); 353 legacy_loader_.reset();
354 354
355 std::unique_ptr<em::PolicyFetchResponse> policy( 355 std::unique_ptr<em::PolicyFetchResponse> policy(
356 new em::PolicyFetchResponse()); 356 new em::PolicyFetchResponse());
357 if (!policy->ParseFromString(policy_blob)) { 357 if (!policy->ParseFromString(policy_blob)) {
358 status_ = STATUS_PARSE_ERROR; 358 status_ = STATUS_PARSE_ERROR;
359 NotifyStoreError(); 359 NotifyStoreError();
360 return; 360 return;
361 } 361 }
362 362
363 // Load |policy_key_| to verify the loaded policy. 363 // Load |loaded_policy_key_| to verify the loaded policy.
364 EnsurePolicyKeyLoaded( 364 EnsurePolicyKeyLoaded(
365 base::Bind(&UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy, 365 base::Bind(&UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy,
366 weak_factory_.GetWeakPtr(), 366 weak_factory_.GetWeakPtr(),
367 base::Passed(&policy))); 367 base::Passed(&policy)));
368 } 368 }
369 369
370 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( 370 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy(
371 std::unique_ptr<em::PolicyFetchResponse> policy) { 371 std::unique_ptr<em::PolicyFetchResponse> policy) {
372 // Create and configure a validator for the loaded policy. 372 // Create and configure a validator for the loaded policy.
373 std::unique_ptr<UserCloudPolicyValidator> validator = 373 std::unique_ptr<UserCloudPolicyValidator> validator =
(...skipping 14 matching lines...) Expand all
388 validation_status_, 388 validation_status_,
389 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE); 389 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE);
390 390
391 if (!validator->success()) { 391 if (!validator->success()) {
392 status_ = STATUS_VALIDATION_ERROR; 392 status_ = STATUS_VALIDATION_ERROR;
393 NotifyStoreError(); 393 NotifyStoreError();
394 return; 394 return;
395 } 395 }
396 396
397 InstallPolicy(std::move(validator->policy_data()), 397 InstallPolicy(std::move(validator->policy_data()),
398 std::move(validator->payload())); 398 std::move(validator->payload()), loaded_policy_key_);
399 status_ = STATUS_OK; 399 status_ = STATUS_OK;
400 400
401 // Policy has been loaded successfully. This indicates that new-style policy 401 // Policy has been loaded successfully. This indicates that new-style policy
402 // is working, so the legacy cache directory can be removed. 402 // is working, so the legacy cache directory can be removed.
403 if (!legacy_cache_dir_.empty()) { 403 if (!legacy_cache_dir_.empty()) {
404 background_task_runner()->PostTask( 404 background_task_runner()->PostTask(
405 FROM_HERE, 405 FROM_HERE,
406 base::Bind(&UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir, 406 base::Bind(&UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir,
407 legacy_cache_dir_)); 407 legacy_cache_dir_));
408 legacy_cache_dir_.clear(); 408 legacy_cache_dir_.clear();
(...skipping 24 matching lines...) Expand all
433 } 433 }
434 434
435 void UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated( 435 void UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated(
436 const std::string& dm_token, 436 const std::string& dm_token,
437 const std::string& device_id, 437 const std::string& device_id,
438 UserCloudPolicyValidator* validator) { 438 UserCloudPolicyValidator* validator) {
439 validation_status_ = validator->status(); 439 validation_status_ = validator->status();
440 if (validator->success()) { 440 if (validator->success()) {
441 status_ = STATUS_OK; 441 status_ = STATUS_OK;
442 InstallPolicy(std::move(validator->policy_data()), 442 InstallPolicy(std::move(validator->policy_data()),
443 std::move(validator->payload())); 443 std::move(validator->payload()),
444 std::string() /* public_key */);
444 445
445 // Clear the public key version. The public key version field would 446 // Clear the public key version. The public key version field would
446 // otherwise indicate that we have key installed in the store when in fact 447 // otherwise indicate that we have key installed in the store when in fact
447 // we haven't. This may result in policy updates failing signature 448 // we haven't. This may result in policy updates failing signature
448 // verification. 449 // verification.
449 policy_->clear_public_key_version(); 450 policy_->clear_public_key_version();
450 } else { 451 } else {
451 status_ = STATUS_VALIDATION_ERROR; 452 status_ = STATUS_VALIDATION_ERROR;
452 } 453 }
453 454
454 InstallLegacyTokens(dm_token, device_id); 455 InstallLegacyTokens(dm_token, device_id);
455 } 456 }
456 457
457 void UserCloudPolicyStoreChromeOS::InstallLegacyTokens( 458 void UserCloudPolicyStoreChromeOS::InstallLegacyTokens(
458 const std::string& dm_token, 459 const std::string& dm_token,
459 const std::string& device_id) { 460 const std::string& device_id) {
460 // Write token and device ID to |policy_|, giving them precedence over the 461 // Write token and device ID to |policy_|, giving them precedence over the
461 // policy blob. This is to match the legacy behavior, which used token and 462 // policy blob. This is to match the legacy behavior, which used token and
462 // device id exclusively from the token cache file. 463 // device id exclusively from the token cache file.
463 if (!dm_token.empty() && !device_id.empty()) { 464 if (!dm_token.empty() && !device_id.empty()) {
464 if (!policy_.get()) 465 if (!policy_.get())
465 policy_.reset(new em::PolicyData()); 466 policy_.reset(new em::PolicyData());
466 policy_->set_request_token(dm_token); 467 policy_->set_request_token(dm_token);
467 policy_->set_device_id(device_id); 468 policy_->set_device_id(device_id);
468 } 469 }
470 public_key_.clear();
469 471
470 // Tell the rest of the world that the policy load completed. 472 // Tell the rest of the world that the policy load completed.
471 NotifyStoreLoaded(); 473 NotifyStoreLoaded();
472 } 474 }
473 475
474 // static 476 // static
475 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir( 477 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir(
476 const base::FilePath& dir) { 478 const base::FilePath& dir) {
477 if (base::PathExists(dir) && !base::DeleteFile(dir, true)) 479 if (base::PathExists(dir) && !base::DeleteFile(dir, true))
478 LOG(ERROR) << "Failed to remove cache dir " << dir.value(); 480 LOG(ERROR) << "Failed to remove cache dir " << dir.value();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 LOG(ERROR) << "Failed to read key at " << path.value(); 518 LOG(ERROR) << "Failed to read key at " << path.value();
517 } 519 }
518 520
519 if (key->empty()) 521 if (key->empty())
520 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); 522 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY);
521 } 523 }
522 524
523 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( 525 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded(
524 std::string* key, 526 std::string* key,
525 const base::Closure& callback) { 527 const base::Closure& callback) {
526 policy_key_ = *key; 528 loaded_policy_key_ = *key;
527 policy_key_loaded_ = true; 529 is_policy_key_loaded_ = true;
528 callback.Run(); 530 callback.Run();
529 } 531 }
530 532
531 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( 533 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded(
532 const base::Closure& callback) { 534 const base::Closure& callback) {
533 if (policy_key_loaded_) { 535 if (is_policy_key_loaded_) {
534 callback.Run(); 536 callback.Run();
535 } else { 537 } else {
536 // Get the hashed username that's part of the key's path, to determine 538 // Get the hashed username that's part of the key's path, to determine
537 // |policy_key_path_|. 539 // |policy_key_path_|.
538 cryptohome_client_->GetSanitizedUsername( 540 cryptohome_client_->GetSanitizedUsername(
539 cryptohome::Identification(account_id_), 541 cryptohome::Identification(account_id_),
540 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, 542 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername,
541 weak_factory_.GetWeakPtr(), callback)); 543 weak_factory_.GetWeakPtr(), callback));
542 } 544 }
543 } 545 }
(...skipping 15 matching lines...) Expand all
559 561
560 std::unique_ptr<UserCloudPolicyValidator> 562 std::unique_ptr<UserCloudPolicyValidator>
561 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( 563 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad(
562 std::unique_ptr<em::PolicyFetchResponse> policy) { 564 std::unique_ptr<em::PolicyFetchResponse> policy) {
563 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( 565 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
564 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); 566 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE);
565 validator->ValidateUsername(account_id_.GetUserEmail(), true); 567 validator->ValidateUsername(account_id_.GetUserEmail(), true);
566 // The policy loaded from session manager need not be validated using the 568 // The policy loaded from session manager need not be validated using the
567 // verification key since it is secure, and since there may be legacy policy 569 // verification key since it is secure, and since there may be legacy policy
568 // data that was stored without a verification key. 570 // data that was stored without a verification key.
569 validator->ValidateSignature(policy_key_); 571 validator->ValidateSignature(loaded_policy_key_);
570 return validator; 572 return validator;
571 } 573 }
574
572 } // namespace policy 575 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698