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

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: Some renamings according to feedback 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),
197 policy_key_loaded_(false),
198 weak_factory_(this) {} 196 weak_factory_(this) {}
199 197
200 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} 198 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {}
201 199
202 void UserCloudPolicyStoreChromeOS::Store( 200 void UserCloudPolicyStoreChromeOS::Store(
203 const em::PolicyFetchResponse& policy) { 201 const em::PolicyFetchResponse& policy) {
204 // Cancel all pending requests. 202 // Cancel all pending requests.
205 weak_factory_.InvalidateWeakPtrs(); 203 weak_factory_.InvalidateWeakPtrs();
206 std::unique_ptr<em::PolicyFetchResponse> response( 204 std::unique_ptr<em::PolicyFetchResponse> response(
207 new em::PolicyFetchResponse(policy)); 205 new em::PolicyFetchResponse(policy));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 248
251 std::string sanitized_username = 249 std::string sanitized_username =
252 cryptohome_client_->BlockingGetSanitizedUsername( 250 cryptohome_client_->BlockingGetSanitizedUsername(
253 cryptohome::Identification(account_id_)); 251 cryptohome::Identification(account_id_));
254 if (sanitized_username.empty()) { 252 if (sanitized_username.empty()) {
255 status_ = STATUS_LOAD_ERROR; 253 status_ = STATUS_LOAD_ERROR;
256 NotifyStoreError(); 254 NotifyStoreError();
257 return; 255 return;
258 } 256 }
259 257
260 policy_key_path_ = user_policy_key_dir_.Append( 258 cached_policy_key_path_ = user_policy_key_dir_.Append(
261 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); 259 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str()));
262 LoadPolicyKey(policy_key_path_, &policy_key_); 260 LoadPolicyKey(cached_policy_key_path_, &cached_policy_key_);
263 policy_key_loaded_ = true; 261 is_cached_policy_key_loaded_ = true;
264 262
265 std::unique_ptr<UserCloudPolicyValidator> validator = 263 std::unique_ptr<UserCloudPolicyValidator> validator =
266 CreateValidatorForLoad(std::move(policy)); 264 CreateValidatorForLoad(std::move(policy));
267 validator->RunValidation(); 265 validator->RunValidation();
268 OnRetrievedPolicyValidated(validator.get()); 266 OnRetrievedPolicyValidated(validator.get());
269 } 267 }
270 268
271 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( 269 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore(
272 std::unique_ptr<em::PolicyFetchResponse> policy) { 270 std::unique_ptr<em::PolicyFetchResponse> policy) {
273 // Create and configure a validator. 271 // Create and configure a validator.
274 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( 272 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
275 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); 273 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED);
276 validator->ValidateUsername(account_id_.GetUserEmail(), true); 274 validator->ValidateUsername(account_id_.GetUserEmail(), true);
277 if (policy_key_.empty()) { 275 if (cached_policy_key_.empty()) {
278 validator->ValidateInitialKey(GetPolicyVerificationKey(), 276 validator->ValidateInitialKey(GetPolicyVerificationKey(),
279 ExtractDomain(account_id_.GetUserEmail())); 277 ExtractDomain(account_id_.GetUserEmail()));
280 } else { 278 } else {
281 validator->ValidateSignatureAllowingRotation( 279 validator->ValidateSignatureAllowingRotation(
282 policy_key_, GetPolicyVerificationKey(), 280 cached_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 policy_signature_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 |cached_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()), cached_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 */);
Thiemo Nagel 2016/11/22 11:57:15 Nit: policy_signature_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 policy_signature_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();
479 } 481 }
480 482
481 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( 483 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey(
482 const base::Closure& callback) { 484 const base::Closure& callback) {
483 std::string* key = new std::string(); 485 std::string* key = new std::string();
484 background_task_runner()->PostTaskAndReply( 486 background_task_runner()->PostTaskAndReply(
485 FROM_HERE, 487 FROM_HERE, base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey,
486 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, 488 cached_policy_key_path_, key),
487 policy_key_path_,
488 key),
489 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, 489 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded,
490 weak_factory_.GetWeakPtr(), 490 weak_factory_.GetWeakPtr(), base::Owned(key), callback));
491 base::Owned(key),
492 callback));
493 } 491 }
494 492
495 // static 493 // static
496 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, 494 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path,
497 std::string* key) { 495 std::string* key) {
498 if (!base::PathExists(path)) { 496 if (!base::PathExists(path)) {
499 // There is no policy key the first time that a user fetches policy. If 497 // There is no policy key the first time that a user fetches policy. If
500 // |path| does not exist then that is the most likely scenario, so there's 498 // |path| does not exist then that is the most likely scenario, so there's
501 // no need to sample a failure. 499 // no need to sample a failure.
502 VLOG(1) << "No key at " << path.value(); 500 VLOG(1) << "No key at " << path.value();
(...skipping 13 matching lines...) Expand all
516 LOG(ERROR) << "Failed to read key at " << path.value(); 514 LOG(ERROR) << "Failed to read key at " << path.value();
517 } 515 }
518 516
519 if (key->empty()) 517 if (key->empty())
520 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); 518 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY);
521 } 519 }
522 520
523 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( 521 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded(
524 std::string* key, 522 std::string* key,
525 const base::Closure& callback) { 523 const base::Closure& callback) {
526 policy_key_ = *key; 524 cached_policy_key_ = *key;
527 policy_key_loaded_ = true; 525 is_cached_policy_key_loaded_ = true;
528 callback.Run(); 526 callback.Run();
529 } 527 }
530 528
531 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( 529 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded(
532 const base::Closure& callback) { 530 const base::Closure& callback) {
533 if (policy_key_loaded_) { 531 if (is_cached_policy_key_loaded_) {
534 callback.Run(); 532 callback.Run();
535 } else { 533 } else {
536 // Get the hashed username that's part of the key's path, to determine 534 // Get the hashed username that's part of the key's path, to determine
537 // |policy_key_path_|. 535 // |cached_policy_key_path_|.
538 cryptohome_client_->GetSanitizedUsername( 536 cryptohome_client_->GetSanitizedUsername(
539 cryptohome::Identification(account_id_), 537 cryptohome::Identification(account_id_),
540 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, 538 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername,
541 weak_factory_.GetWeakPtr(), callback)); 539 weak_factory_.GetWeakPtr(), callback));
542 } 540 }
543 } 541 }
544 542
545 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( 543 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername(
546 const base::Closure& callback, 544 const base::Closure& callback,
547 chromeos::DBusMethodCallStatus call_status, 545 chromeos::DBusMethodCallStatus call_status,
548 const std::string& sanitized_username) { 546 const std::string& sanitized_username) {
549 // The default empty path will always yield an empty key. 547 // The default empty path will always yield an empty key.
550 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && 548 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS &&
551 !sanitized_username.empty()) { 549 !sanitized_username.empty()) {
552 policy_key_path_ = user_policy_key_dir_.Append( 550 cached_policy_key_path_ = user_policy_key_dir_.Append(
553 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); 551 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str()));
554 } else { 552 } else {
555 SampleValidationFailure(VALIDATION_FAILURE_DBUS); 553 SampleValidationFailure(VALIDATION_FAILURE_DBUS);
556 } 554 }
557 ReloadPolicyKey(callback); 555 ReloadPolicyKey(callback);
558 } 556 }
559 557
560 std::unique_ptr<UserCloudPolicyValidator> 558 std::unique_ptr<UserCloudPolicyValidator>
561 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( 559 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad(
562 std::unique_ptr<em::PolicyFetchResponse> policy) { 560 std::unique_ptr<em::PolicyFetchResponse> policy) {
563 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( 561 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
564 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); 562 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE);
565 validator->ValidateUsername(account_id_.GetUserEmail(), true); 563 validator->ValidateUsername(account_id_.GetUserEmail(), true);
566 // The policy loaded from session manager need not be validated using the 564 // 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 565 // verification key since it is secure, and since there may be legacy policy
568 // data that was stored without a verification key. 566 // data that was stored without a verification key.
569 validator->ValidateSignature(policy_key_); 567 validator->ValidateSignature(cached_policy_key_);
570 return validator; 568 return validator;
571 } 569 }
570
572 } // namespace policy 571 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698