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

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: 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 eb936b136e864acf58cf4766d02139b79e7d083e..ddc9fa9a2133a33e1ede83b19fa6c135184b57cc 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,9 @@ const char kStateStoreSPKI[] = "SPKI";
const char kStateStoreSignOnce[] = "signOnce";
const char kStateStoreSignUnlimited[] = "signUnlimited";
+const char kPrefIsCorporateKey[] = "is_platform_key";
+const char kPolicyAllowCorporateKeyUsage[] = "allowCorporateKeyUsage";
+
} // namespace
struct KeyPermissions::PermissionsForExtension::KeyEntry {
@@ -51,9 +62,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 +71,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);
@@ -73,14 +90,21 @@ KeyPermissions::PermissionsForExtension::~PermissionsForExtension() {
bool KeyPermissions::PermissionsForExtension::CanUseKeyForSigning(
const std::string& public_key_spki_der) {
- KeyEntry* matching_entry = GetKeyEntry(public_key_spki_der);
+ KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der);
+ if (matching_entry->sign_once)
+ return true;
+
+ if (key_permissions_->IsCorporateKey(public_key_spki_der)) {
+ LOG(ERROR) << "is corporate key";
+ return PolicyAllowsCorporateKeyUsage();
+ }
- return matching_entry->sign_once || matching_entry->sign_unlimited;
+ return matching_entry->sign_unlimited;
}
void KeyPermissions::PermissionsForExtension::SetKeyUsedForSigning(
const std::string& public_key_spki_der) {
- KeyEntry* matching_entry = GetKeyEntry(public_key_spki_der);
+ KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der);
if (!matching_entry->sign_once) {
if (matching_entry->sign_unlimited)
@@ -96,7 +120,7 @@ void KeyPermissions::PermissionsForExtension::SetKeyUsedForSigning(
void KeyPermissions::PermissionsForExtension::RegisterKeyForCorporateUsage(
const std::string& public_key_spki_der) {
- KeyEntry* matching_entry = GetKeyEntry(public_key_spki_der);
+ KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der);
if (matching_entry->sign_once) {
VLOG(1) << "Key is already allowed for signing, skipping.";
@@ -105,11 +129,27 @@ 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->SetBooleanWithoutPathExpansion(kPrefIsCorporateKey, true);
+
+ std::string public_key_spki_der_b64;
+ base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
+
+ update->SetWithoutPathExpansion(public_key_spki_der_b64,
+ new_pref_entry.release());
}
void KeyPermissions::PermissionsForExtension::SetUserGrantedPermission(
const std::string& public_key_spki_der) {
- KeyEntry* matching_entry = GetKeyEntry(public_key_spki_der);
+ if (key_permissions_->IsCorporateKey(public_key_spki_der)) {
+ LOG(WARNING) << "Tried to grant permission for corporate key.";
+ return;
+ }
+
+ KeyEntry* matching_entry = GetStateStoreEntry(public_key_spki_der);
if (matching_entry->sign_unlimited) {
VLOG(1) << "Key is already allowed for signing, skipping.";
@@ -120,6 +160,39 @@ 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);
+LOG(ERROR) << "policy value " << policy_value;
+ if (!policy_value)
+ return false;
+LOG(ERROR) << *policy_value;
+
+ 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) {
+LOG(ERROR) << "no entry for " << extension_id_;
+ return false;
+}
+
+ bool allow_corporate_key_usage = false;
+ key_permissions_for_ext->GetBooleanWithoutPathExpansion(
+ kPolicyAllowCorporateKeyUsage, &allow_corporate_key_usage);
+
+LOG(ERROR) << "policy allows corp usage " << allow_corporate_key_usage;
+ return allow_corporate_key_usage;
+}
+
void KeyPermissions::PermissionsForExtension::WriteToStateStore() {
key_permissions_->SetPlatformKeysOfExtension(extension_id_,
KeyEntriesToState());
@@ -191,7 +264,7 @@ KeyPermissions::PermissionsForExtension::KeyEntriesToState() {
// Searches |platform_keys| for an entry for |public_key_spki_der_b64|. If found
// returns a pointer to it, otherwise returns null.
KeyPermissions::PermissionsForExtension::KeyEntry*
-KeyPermissions::PermissionsForExtension::GetKeyEntry(
+KeyPermissions::PermissionsForExtension::GetStateStoreEntry(
const std::string& public_key_spki_der) {
std::string public_key_spki_der_b64;
base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
@@ -207,8 +280,18 @@ KeyPermissions::PermissionsForExtension::GetKeyEntry(
return &state_store_entries_.back();
}
-KeyPermissions::KeyPermissions(extensions::StateStore* extensions_state_store)
- : extensions_state_store_(extensions_state_store), weak_factory_(this) {
+KeyPermissions::KeyPermissions(PrefService* profile_prefs,
+ bool profile_is_managed,
+ policy::PolicyService* profile_policies,
+ extensions::StateStore* extensions_state_store)
+ : profile_prefs_(profile_prefs),
+ profile_is_managed_(profile_is_managed),
+ 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() {
@@ -223,18 +306,61 @@ void KeyPermissions::GetPermissionsForExtension(
weak_factory_.GetWeakPtr(), extension_id, callback));
}
-void KeyPermissions::SetPlatformKeysOfExtension(const std::string& extension_id,
- scoped_ptr<base::Value> value) {
- extensions_state_store_->SetExtensionValue(
- extension_id, kStateStorePlatformKeys, value.Pass());
+bool KeyPermissions::CanUserGrantPermissionFor(
+ const std::string& public_key_spki_der) {
+LOG(ERROR) << "profile is managed " << profile_is_managed_;
+ // As keys cannot be tagged for non-corporate usage, the user can currently
+ // not grant any permissions if the profile is managed.
+ if (profile_is_managed_)
+ return false;
+
+ // 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);
+}
+
+bool KeyPermissions::IsCorporateKey(const std::string& public_key_spki_der) {
+ const base::DictionaryValue* prefs_entry = GetPrefsEntry(public_key_spki_der);
+ if (prefs_entry) {
+ bool is_corporate_key = false;
+ prefs_entry->GetBooleanWithoutPathExpansion(kPrefIsCorporateKey,
+ &is_corporate_key);
+ return is_corporate_key;
+ }
+ 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) {
+ std::string public_key_spki_der_b64;
+ base::Base64Encode(public_key_spki_der, &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