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

Unified Diff: session_manager_service.cc

Issue 6793055: [login_manager] Allow new owner keys to be pushed with StorePolicy (Closed) Base URL: http://git.chromium.org/git/login_manager.git@master
Patch Set: remove some debugging code Created 9 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: session_manager_service.cc
diff --git a/session_manager_service.cc b/session_manager_service.cc
index a5e9c27b79b645e2bcac204157306c09292108ca..25afa85a3fc59f03c59662b225e5861f21dbc7e4 100644
--- a/session_manager_service.cc
+++ b/session_manager_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -550,7 +550,7 @@ void SessionManagerService::HandleKeygenExit(GPid pid,
void SessionManagerService::ValidateAndStoreOwnerKey(const std::string& buf) {
std::vector<uint8> pub_key;
- NssUtil::KeyFromBuffer(buf, &pub_key);
+ NssUtil::BlobFromBuffer(buf, &pub_key);
if (!CurrentUserHasOwnerKey(pub_key, NULL)) {
SendSignal(chromium::kOwnerKeySetSignal, false);
@@ -745,30 +745,63 @@ void SessionManagerService::SendBooleanReply(DBusGMethodInvocation* context,
gboolean SessionManagerService::StorePolicy(GArray* policy_blob,
DBusGMethodInvocation* context) {
std::string policy_str(policy_blob->data, policy_blob->len);
- GError* error = NULL;
enterprise_management::PolicyFetchResponse policy;
if (!policy.ParseFromString(policy_str) ||
!policy.has_policy_data() ||
!policy.has_policy_data_signature()) {
const char msg[] = "Unable to parse policy protobuf.";
LOG(ERROR) << msg;
- SetGError(&error, CHROMEOS_LOGIN_ERROR_DECODE_FAIL, msg);
- dbus_g_method_return_error(context, error);
- g_error_free(error);
+ SetAndSendGError(CHROMEOS_LOGIN_ERROR_DECODE_FAIL, context, msg);
return FALSE;
}
+
+ // Determine if the policy has pushed a new owner key and, if so, set it and
+ // schedule a task to persist it to disk.
+ if (policy.has_new_public_key() && !key_->Equals(policy.new_public_key())) {
+ // The policy contains a new key, and it is different from |key_|.
+ std::vector<uint8> der;
+ nss_->BlobFromBuffer(policy.new_public_key(), &der);
+
+ if (session_started_) {
+ bool rotated = false;
+ if (policy.has_new_public_key_signature()) {
+ // Graceful key rotation.
+ std::vector<uint8> sig;
+ nss_->BlobFromBuffer(policy.new_public_key_signature(), &sig);
+ rotated = key_->Rotate(der, sig);
+ }
+ if (!rotated) {
+ const char msg[] = "Failed attempted key rotation!";
+ LOG(ERROR) << msg;
+ SetAndSendGError(CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, context, msg);
+ return FALSE;
+ }
+ } else {
+ // Force a new key, regardless of whether we have one or not.
+ if (key_->IsPopulated()) {
+ key_->ClobberCompromisedKey(der);
+ LOG(INFO) << "Clobbered existing key outside of session";
+ } else {
+ CHECK(key_->PopulateFromBuffer(der)); // Should be unable to fail.
+ LOG(INFO) << "Setting key outside of session";
+ }
+ }
+ // If here, need to persit new key to disk. Already loaded key into memory.
+ io_thread_.message_loop()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &SessionManagerService::PersistKey));
+ }
+
+ // Validate signature on policy and persist to disk
const std::string& sig = policy.policy_data_signature();
SessionManagerService::SigReturnCode verify_result =
VerifyHelper(policy.policy_data(), sig.c_str(), sig.length());
if (verify_result == NO_KEY) {
- const char msg[] = "Attempt to store policy before owner's key is set.";
- LOG(ERROR) << msg;
- SetGError(&error, CHROMEOS_LOGIN_ERROR_NO_OWNER_KEY, msg);
+ NOTREACHED() << "Should have set the key earlier in this function!";
return FALSE;
} else if (verify_result == SIGNATURE_FAIL) {
const char msg[] = "Signature could not be verified in StorePolicy.";
LOG(ERROR) << msg;
- SetGError(&error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg);
+ SetAndSendGError(CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, context, msg);
return FALSE;
}
policy_->Set(policy);
@@ -1000,6 +1033,15 @@ void SessionManagerService::SetGError(GError** error,
g_set_error(error, CHROMEOS_LOGIN_ERROR, code, "Login error: %s", message);
}
+// static
+void SessionManagerService::SetAndSendGError(ChromeOSLoginError code,
+ DBusGMethodInvocation* context,
+ const char* msg) {
+ GError* error = NULL;
+ SetGError(&error, code, msg);
+ dbus_g_method_return_error(context, error);
+ g_error_free(error);
+}
///////////////////////////////////////////////////////////////////////////////
// Utility Methods
@@ -1102,10 +1144,7 @@ gboolean SessionManagerService::CurrentUserIsOwner(GError** error) {
std::string was_signed = base::StringPrintf("%s=%s",
kDeviceOwnerPref,
value.c_str());
- if (!key_->Verify(was_signed.c_str(),
- was_signed.length(),
- decoded.c_str(),
- decoded.length())) {
+ if (VerifyHelper(was_signed, decoded.c_str(), decoded.length()) != SUCCESS) {
const char msg[] = "Owner pref signature could not be verified.";
LOG(ERROR) << msg;
SetGError(error, CHROMEOS_LOGIN_ERROR_VERIFY_FAIL, msg);
@@ -1203,7 +1242,8 @@ gboolean SessionManagerService::SignAndStoreProperty(const std::string& name,
std::string to_sign = base::StringPrintf("%s=%s",
kDeviceOwnerPref,
current_user_.c_str());
- if (!key_->Sign(to_sign.c_str(), to_sign.length(), &signature)) {
+ const uint8* data = reinterpret_cast<const uint8*>(to_sign.c_str());
+ if (!key_->Sign(data, to_sign.length(), &signature)) {
LOG_IF(ERROR, error) << err_msg;
LOG_IF(WARNING, !error) << err_msg;
SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str());
@@ -1221,7 +1261,8 @@ gboolean SessionManagerService::SignAndWhitelist(const std::string& email,
const std::string& err_msg,
GError** error) {
std::vector<uint8> signature;
- if (!key_->Sign(current_user_.c_str(), current_user_.length(), &signature)) {
+ const uint8* data = reinterpret_cast<const uint8*>(current_user_.c_str());
+ if (!key_->Sign(data, current_user_.length(), &signature)) {
LOG_IF(ERROR, error) << err_msg;
LOG_IF(WARNING, !error) << err_msg;
SetGError(error, CHROMEOS_LOGIN_ERROR_ILLEGAL_PUBKEY, err_msg.c_str());
@@ -1260,8 +1301,12 @@ SessionManagerService::VerifyHelper(const std::string& data,
uint32 sig_len) {
if (!key_->IsPopulated())
return NO_KEY;
- if (!key_->Verify(data.c_str(), data.length(), sig, sig_len))
+ if (!key_->Verify(reinterpret_cast<const uint8*>(data.c_str()),
+ data.length(),
+ reinterpret_cast<const uint8*>(sig),
+ sig_len)) {
return SIGNATURE_FAIL;
+ }
return SUCCESS;
}
« no previous file with comments | « session_manager_service.h ('k') | session_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698