#include "base/stl_util.h"
#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
-#include "base/time/time.h"
#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
-#include "chrome/browser/chromeos/settings/owner_key_util.h"
+#include "chrome/browser/net/nss_context.h"
+#include "components/ownership/owner_key_util.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/rsa_private_key.h"
#include "crypto/signature_creator.h"
#include "policy/proto/device_management_backend.pb.h"
+using ownership::OwnerKeyUtil;
+using ownership::PublicKey;
+
namespace em = enterprise_management;
namespace chromeos {
SessionManagerOperation::SessionManagerOperation(const Callback& callback)
: session_manager_client_(NULL),
- weak_factory_(this),
callback_(callback),
force_key_load_(false),
- is_loading_(false) {}
+ is_loading_(false),
+ weak_factory_(this) {}
SessionManagerOperation::~SessionManagerOperation() {}
void SessionManagerOperation::Start(
SessionManagerClient* session_manager_client,
scoped_refptr<OwnerKeyUtil> owner_key_util,
- scoped_refptr<OwnerKey> owner_key) {
+ scoped_refptr<PublicKey> public_key) {
session_manager_client_ = session_manager_client;
owner_key_util_ = owner_key_util;
- owner_key_ = owner_key;
+ public_key_ = public_key;
Run();
}
void SessionManagerOperation::RestartLoad(bool key_changed) {
if (key_changed)
- owner_key_ = NULL;
+ public_key_ = NULL;
if (!is_loading_)
return;
if (is_loading_)
return;
is_loading_ = true;
- EnsureOwnerKey(base::Bind(&SessionManagerOperation::RetrieveDeviceSettings,
- weak_factory_.GetWeakPtr()));
+ EnsurePublicKey(base::Bind(&SessionManagerOperation::RetrieveDeviceSettings,
+ weak_factory_.GetWeakPtr()));
}
void SessionManagerOperation::ReportResult(
callback_.Run(this, status);
}
-void SessionManagerOperation::EnsureOwnerKey(const base::Closure& callback) {
- if (force_key_load_ || !owner_key_.get() || !owner_key_->public_key()) {
+void SessionManagerOperation::EnsurePublicKey(const base::Closure& callback) {
+ if (force_key_load_ || !public_key_.get() || !public_key_->is_loaded()) {
scoped_refptr<base::TaskRunner> task_runner =
- content::BrowserThread::GetBlockingPool()->
- GetTaskRunnerWithShutdownBehavior(
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+ content::BrowserThread::GetBlockingPool()
+ ->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
base::PostTaskAndReplyWithResult(
task_runner.get(),
FROM_HERE,
- base::Bind(&SessionManagerOperation::LoadOwnerKey,
- owner_key_util_, owner_key_),
- base::Bind(&SessionManagerOperation::StoreOwnerKey,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&SessionManagerOperation::LoadPublicKey,
+ owner_key_util_,
+ public_key_),
+ base::Bind(&SessionManagerOperation::StorePublicKey,
+ weak_factory_.GetWeakPtr(),
+ callback));
} else {
callback.Run();
}
}
// static
-scoped_refptr<OwnerKey> SessionManagerOperation::LoadOwnerKey(
+scoped_refptr<PublicKey> SessionManagerOperation::LoadPublicKey(
scoped_refptr<OwnerKeyUtil> util,
- scoped_refptr<OwnerKey> current_key) {
- scoped_ptr<std::vector<uint8> > public_key;
- scoped_ptr<crypto::RSAPrivateKey> private_key;
-
- // Keep any already-existing keys.
- if (current_key.get()) {
- if (current_key->public_key())
- public_key.reset(new std::vector<uint8>(*current_key->public_key()));
- if (current_key->private_key())
- private_key.reset(current_key->private_key()->Copy());
- }
+ scoped_refptr<PublicKey> current_key) {
+ scoped_refptr<PublicKey> public_key(new PublicKey());
- if (!public_key.get() && util->IsPublicKeyPresent()) {
- public_key.reset(new std::vector<uint8>());
- if (!util->ImportPublicKey(public_key.get()))
- LOG(ERROR) << "Failed to load public owner key.";
+ // Keep already-existing public key.
+ if (current_key.get() && current_key->is_loaded()) {
+ public_key->data() = current_key->data();
}
-
- if (public_key.get() && !private_key.get()) {
- private_key.reset(util->FindPrivateKey(*public_key));
- if (!private_key.get())
- VLOG(1) << "Failed to load private owner key.";
+ if (!public_key->is_loaded() && util->IsPublicKeyPresent()) {
+ if (!util->ImportPublicKey(&public_key->data()))
+ LOG(ERROR) << "Failed to load public owner key.";
}
- return new OwnerKey(public_key.Pass(), private_key.Pass());
+ return public_key;
}
-void SessionManagerOperation::StoreOwnerKey(const base::Closure& callback,
- scoped_refptr<OwnerKey> new_key) {
+void SessionManagerOperation::StorePublicKey(const base::Closure& callback,
+ scoped_refptr<PublicKey> new_key) {
force_key_load_ = false;
- owner_key_ = new_key;
+ public_key_ = new_key;
- if (!owner_key_.get() || !owner_key_->public_key()) {
+ if (!public_key_.get() || !public_key_->is_loaded()) {
ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
return;
}
validator->ValidatePayload();
// We don't check the DMServer verification key below, because the signing
// key is validated when it is installed.
- validator->ValidateSignature(owner_key_->public_key_as_string(),
+ validator->ValidateSignature(public_key_->as_string(),
std::string(), // No key validation check.
std::string(),
false);
SignAndStoreSettingsOperation::SignAndStoreSettingsOperation(
const Callback& callback,
- scoped_ptr<em::ChromeDeviceSettingsProto> new_settings,
- const std::string& username)
+ scoped_ptr<em::PolicyData> new_policy)
: SessionManagerOperation(callback),
- new_settings_(new_settings.Pass()),
- username_(username),
+ new_policy_(new_policy.Pass()),
weak_factory_(this) {
- DCHECK(new_settings_.get());
}
SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {}
void SignAndStoreSettingsOperation::Run() {
- EnsureOwnerKey(base::Bind(&SignAndStoreSettingsOperation::StartSigning,
- weak_factory_.GetWeakPtr()));
-}
-
-void SignAndStoreSettingsOperation::StartSigning() {
- if (!owner_key().get() || !owner_key()->private_key() || username_.empty()) {
+ if (!new_policy_) {
+ ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
+ return;
+ }
+ if (!owner_settings_service_) {
ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
return;
}
-
- base::PostTaskAndReplyWithResult(
- content::BrowserThread::GetBlockingPool(),
- FROM_HERE,
- base::Bind(&SignAndStoreSettingsOperation::AssembleAndSignPolicy,
- base::Passed(&new_settings_), username_, owner_key()),
- base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettingsBlob,
+ owner_settings_service_->IsOwnerAsync(
+ base::Bind(&SignAndStoreSettingsOperation::StartSigning,
weak_factory_.GetWeakPtr()));
}
-// static
-std::string SignAndStoreSettingsOperation::AssembleAndSignPolicy(
- scoped_ptr<em::ChromeDeviceSettingsProto> device_settings,
- const std::string& username,
- scoped_refptr<OwnerKey> owner_key) {
- // Assemble the policy.
- em::PolicyFetchResponse policy_response;
- em::PolicyData policy;
- policy.set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
- policy.set_timestamp((base::Time::NowFromSystemTime() -
- base::Time::UnixEpoch()).InMilliseconds());
- policy.set_username(username);
- if (!device_settings->SerializeToString(policy.mutable_policy_value()) ||
- !policy.SerializeToString(policy_response.mutable_policy_data())) {
- LOG(ERROR) << "Failed to encode policy payload.";
- return std::string();
+void SignAndStoreSettingsOperation::StartSigning(bool is_owner) {
+ if (!owner_settings_service_ || !is_owner) {
+ ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
+ return;
}
- // Generate the signature.
- scoped_ptr<crypto::SignatureCreator> signature_creator(
- crypto::SignatureCreator::Create(owner_key->private_key()));
- signature_creator->Update(
- reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()),
- policy_response.policy_data().size());
- std::vector<uint8> signature_bytes;
- std::string policy_blob;
- if (!signature_creator->Final(&signature_bytes)) {
- LOG(ERROR) << "Failed to create policy signature.";
- return std::string();
+ bool rv = owner_settings_service_->AssembleAndSignPolicyAsync(
+ content::BrowserThread::GetBlockingPool(),
+ new_policy_.Pass(),
+ base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettings,
+ weak_factory_.GetWeakPtr()));
+ if (!rv) {
+ ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
+ return;
}
-
- policy_response.mutable_policy_data_signature()->assign(
- reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
- signature_bytes.size());
- return policy_response.SerializeAsString();
}
-void SignAndStoreSettingsOperation::StoreDeviceSettingsBlob(
- std::string device_settings_blob) {
- if (device_settings_blob.empty()) {
+void SignAndStoreSettingsOperation::StoreDeviceSettings(
+ scoped_ptr<em::PolicyFetchResponse> policy_response) {
+ if (!policy_response.get()) {
ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
return;
}
session_manager_client()->StoreDevicePolicy(
- device_settings_blob,
+ policy_response->SerializeAsString(),
base::Bind(&SignAndStoreSettingsOperation::HandleStoreResult,
weak_factory_.GetWeakPtr()));
}