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

Unified Diff: chrome/browser/chromeos/platform_keys/key_permissions.cc

Issue 1150373002: platformKeys: Add policy and corporate key tagging. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@key_perm
Patch Set: Rebased. Created 5 years, 6 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
Index: chrome/browser/chromeos/platform_keys/key_permissions.cc
diff --git a/chrome/browser/chromeos/platform_keys/key_permissions.cc b/chrome/browser/chromeos/platform_keys/key_permissions.cc
index 7f184a7c37f5ebf7ca71a4ebdc62f198f60f6eb9..417257f6312de2ab41caf6631260ccca1adaa5b7 100644
--- a/chrome/browser/chromeos/platform_keys/key_permissions.cc
+++ b/chrome/browser/chromeos/platform_keys/key_permissions.cc
@@ -8,8 +8,16 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
#include "base/values.h"
+#include "chrome/common/pref_names.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_namespace.h"
+#include "components/policy/core/common/policy_service.h"
+#include "components/pref_registry/pref_registry_syncable.h"
#include "extensions/browser/state_store.h"
+#include "policy/policy_constants.h"
namespace chromeos {
@@ -35,6 +43,10 @@ const char kStateStoreSPKI[] = "SPKI";
const char kStateStoreSignOnce[] = "signOnce";
const char kStateStoreSignUnlimited[] = "signUnlimited";
+const char kPrefKeyUsage[] = "keyUsage";
+const char kPrefKeyUsageCorporate[] = "corporate";
+const char kPolicyAllowCorporateKeyUsage[] = "allowCorporateKeyUsage";
+
} // namespace
struct KeyPermissions::PermissionsForExtension::KeyEntry {
@@ -51,9 +63,8 @@ struct KeyPermissions::PermissionsForExtension::KeyEntry {
bool sign_once = false;
// True if the key can be used for signing an unlimited number of times.
- // This permission is granted by the user or by policy to allow the extension
- // to use the key for signing through the enterprise.platformKeys or
- // platformKeys API.
+ // This permission is granted by the user to allow the extension to use the
+ // key for signing through the enterprise.platformKeys or platformKeys API.
// This permission is granted until revoked by the user or the policy.
bool sign_unlimited = false;
};
@@ -61,8 +72,15 @@ struct KeyPermissions::PermissionsForExtension::KeyEntry {
KeyPermissions::PermissionsForExtension::PermissionsForExtension(
const std::string& extension_id,
scoped_ptr<base::Value> state_store_value,
+ PrefService* profile_prefs,
+ policy::PolicyService* profile_policies,
KeyPermissions* key_permissions)
- : extension_id_(extension_id), key_permissions_(key_permissions) {
+ : extension_id_(extension_id),
+ profile_prefs_(profile_prefs),
+ profile_policies_(profile_policies),
+ key_permissions_(key_permissions) {
+ DCHECK(profile_prefs_);
+ DCHECK(profile_policies_);
DCHECK(key_permissions_);
if (state_store_value)
KeyEntriesFromState(*state_store_value);
@@ -77,8 +95,13 @@ bool KeyPermissions::PermissionsForExtension::CanUseKeyForSigning(
base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der_b64);
+ if (matching_entry->sign_once)
+ return true;
+
+ if (key_permissions_->IsCorporateKey(public_key_spki_der_b64))
+ return PolicyAllowsCorporateKeyUsage();
- return matching_entry->sign_once || matching_entry->sign_unlimited;
+ return matching_entry->sign_unlimited;
}
void KeyPermissions::PermissionsForExtension::SetKeyUsedForSigning(
@@ -114,6 +137,15 @@ void KeyPermissions::PermissionsForExtension::RegisterKeyForCorporateUsage(
matching_entry->sign_once = true;
WriteToStateStore();
+
+ DictionaryPrefUpdate update(profile_prefs_, prefs::kPlatformKeys);
+
+ scoped_ptr<base::DictionaryValue> new_pref_entry(new base::DictionaryValue);
+ new_pref_entry->SetStringWithoutPathExpansion(kPrefKeyUsage,
+ kPrefKeyUsageCorporate);
+
+ update->SetWithoutPathExpansion(public_key_spki_der_b64,
+ new_pref_entry.release());
}
void KeyPermissions::PermissionsForExtension::SetUserGrantedPermission(
@@ -121,6 +153,11 @@ void KeyPermissions::PermissionsForExtension::SetUserGrantedPermission(
std::string public_key_spki_der_b64;
base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
+ if (key_permissions_->IsCorporateKey(public_key_spki_der_b64)) {
+ LOG(WARNING) << "Tried to grant permission for corporate key.";
+ return;
+ }
+
KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der_b64);
if (matching_entry->sign_unlimited) {
@@ -132,6 +169,36 @@ void KeyPermissions::PermissionsForExtension::SetUserGrantedPermission(
WriteToStateStore();
}
+bool KeyPermissions::PermissionsForExtension::PolicyAllowsCorporateKeyUsage() {
+ const policy::PolicyMap& policies = profile_policies_->GetPolicies(
+ policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()));
+ const base::Value* policy_value =
+ policies.GetValue(policy::key::kKeyPermissions);
+ if (!policy_value)
+ return false;
+
+ const base::DictionaryValue* key_permissions_map = nullptr;
+ policy_value->GetAsDictionary(&key_permissions_map);
+ if (!key_permissions_map) {
+ LOG(ERROR) << "Expected policy to be a dictionary.";
+ return false;
+ }
+
+ const base::DictionaryValue* key_permissions_for_ext = nullptr;
+ key_permissions_map->GetDictionaryWithoutPathExpansion(
+ extension_id_, &key_permissions_for_ext);
+ if (!key_permissions_for_ext)
+ return false;
+
+ bool allow_corporate_key_usage = false;
+ key_permissions_for_ext->GetBooleanWithoutPathExpansion(
+ kPolicyAllowCorporateKeyUsage, &allow_corporate_key_usage);
+
+ VLOG_IF(allow_corporate_key_usage, 2)
+ << "Policy allows usage of corporate keys by extension " << extension_id_;
+ return allow_corporate_key_usage;
+}
+
void KeyPermissions::PermissionsForExtension::WriteToStateStore() {
key_permissions_->SetPlatformKeysOfExtension(extension_id_,
KeyEntriesToState());
@@ -215,10 +282,17 @@ KeyPermissions::PermissionsForExtension::GetStateStoreEntry(
}
KeyPermissions::KeyPermissions(bool profile_is_managed,
+ PrefService* profile_prefs,
+ policy::PolicyService* profile_policies,
extensions::StateStore* extensions_state_store)
: profile_is_managed_(profile_is_managed),
+ profile_prefs_(profile_prefs),
+ profile_policies_(profile_policies),
extensions_state_store_(extensions_state_store),
weak_factory_(this) {
+ DCHECK(profile_prefs_);
+ DCHECK(extensions_state_store_);
+ DCHECK(!profile_is_managed_ || profile_policies_);
}
KeyPermissions::~KeyPermissions() {
@@ -237,21 +311,57 @@ bool KeyPermissions::CanUserGrantPermissionFor(
const std::string& public_key_spki_der) {
// As keys cannot be tagged for non-corporate usage, the user can currently
// not grant any permissions if the profile is managed.
- return !profile_is_managed_;
+ if (profile_is_managed_)
+ return false;
+
+ std::string public_key_spki_der_b64;
+ base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
+
+ // If this profile is not managed but we find a corporate key, don't allow
+ // the user to grant permissions.
+ return !IsCorporateKey(public_key_spki_der_b64);
}
-void KeyPermissions::SetPlatformKeysOfExtension(const std::string& extension_id,
- scoped_ptr<base::Value> value) {
- extensions_state_store_->SetExtensionValue(
- extension_id, kStateStorePlatformKeys, value.Pass());
+bool KeyPermissions::IsCorporateKey(
+ const std::string& public_key_spki_der_b64) {
+ const base::DictionaryValue* prefs_entry =
+ GetPrefsEntry(public_key_spki_der_b64);
+ if (prefs_entry) {
+ std::string key_usage;
+ prefs_entry->GetStringWithoutPathExpansion(kPrefKeyUsage, &key_usage);
+ return key_usage == kPrefKeyUsageCorporate;
+ }
+ return false;
+}
+
+void KeyPermissions::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterDictionaryPref(prefs::kPlatformKeys);
}
void KeyPermissions::CreatePermissionObjectAndPassToCallback(
const std::string& extension_id,
const PermissionsCallback& callback,
scoped_ptr<base::Value> value) {
- callback.Run(make_scoped_ptr(
- new PermissionsForExtension(extension_id, value.Pass(), this)));
+ callback.Run(make_scoped_ptr(new PermissionsForExtension(
+ extension_id, value.Pass(), profile_prefs_, profile_policies_, this)));
+}
+
+void KeyPermissions::SetPlatformKeysOfExtension(const std::string& extension_id,
+ scoped_ptr<base::Value> value) {
+ extensions_state_store_->SetExtensionValue(
+ extension_id, kStateStorePlatformKeys, value.Pass());
+}
+
+const base::DictionaryValue* KeyPermissions::GetPrefsEntry(
+ const std::string& public_key_spki_der_b64) {
+ const base::DictionaryValue* platform_keys =
+ profile_prefs_->GetDictionary(prefs::kPlatformKeys);
+
+ const base::DictionaryValue* key_entry = nullptr;
+ platform_keys->GetDictionaryWithoutPathExpansion(public_key_spki_der_b64,
+ &key_entry);
+ return key_entry;
}
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698