| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_H_ |
| #define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/callback_forward.h" |
| #include "base/macros.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| |
| class PrefService; |
| |
| namespace base { |
| class DictionaryValue; |
| class Value; |
| } |
| |
| namespace extensions { |
| class StateStore; |
| } |
| |
| namespace policy { |
| class PolicyService; |
| } |
| |
| namespace user_prefs { |
| class PrefRegistrySyncable; |
| } |
| |
| namespace chromeos { |
| |
| // This class manages permissions for extensions to use private keys through |
| // chrome.platformKeys or chrome.enterprise.platformKeys . |
| // The permission model depends on whether the user account is managed or not. |
| // |
| // ** If the user account is not managed ** |
| // The user is under full control of the keys that are generated or imported |
| // while the device is not managed. For that, a user can grant a specific |
| // extension the permission to sign arbitrary data with a specific key for an |
| // unlimited number of times. |
| // |
| // ** If the user account is managed ** |
| // The administrator is in charge of granting access to keys that are meant for |
| // corporate usage. |
| // |
| // As not every key is meant for corporate usage but probably for the user's |
| // private usage, this class introduces the concept of tagging keys with the |
| // intended purpose of the key. Currently, the only usage that can be assigned |
| // to a key is "corporate". |
| // |
| // Every key that is generated by the chrome.enterprise.platformKeys API (which |
| // requires the user account to be managed), is marked for corporate usage. |
| // Any key that is generated or imported by other means is currently not marked |
| // for corporate usage. |
| // |
| // The KeyPermissions policy allows the administrator to list exactly the |
| // extensions that are allowed to use such corporate keys. Non-corporate keys |
| // are not affected. This policy is the only means to grant this permission. |
| // |
| // ** One-off Permission for the Certification Requests ** |
| // Independent of the above, the extension that generates a key using the |
| // chrome.enterprise.platformKeys API is allowed to sign arbitrary data with the |
| // private key for a single time in order to create a certification request. |
| // The assumption is that certification requests usually require a signature of |
| // data including the public key. So the one-off permission implies that once a |
| // certificate authority creates the certificate of the generated key, the |
| // generating extension isn't able to use the key anymore except if explicitly |
| // permitted by the administrator. |
| class KeyPermissions { |
| public: |
| // Allows querying and modifying permissions and registering keys for a |
| // specific extension. |
| class PermissionsForExtension { |
| public: |
| // |key_permissions| must not be null and outlive this object. |
| // Methods of this object refer implicitly to the extension with the id |
| // |extension_id|. Don't use this constructor directly. Call |
| // |KeyPermissions::GetPermissionsForExtension| instead. |
| PermissionsForExtension(const std::string& extension_id, |
| scoped_ptr<base::Value> state_store_value, |
| PrefService* profile_prefs, |
| policy::PolicyService* profile_policies, |
| KeyPermissions* key_permissions); |
| |
| ~PermissionsForExtension(); |
| |
| // Returns true if the private key matching |public_key_spki_der| can be |
| // used for signing by the extension with id |extension_id|. |
| // |public_key_spki_der| must be the DER of a Subject Public Key Info. |
| bool CanUseKeyForSigning(const std::string& public_key_spki_der); |
| |
| // Registers the key |public_key_spki_der| as being generated by the |
| // extension with id |extension_id| and marks it for corporate usage. |
| // |public_key_spki_der| must be the DER of a Subject Public Key Info. |
| void RegisterKeyForCorporateUsage(const std::string& public_key_spki_der); |
| |
| // Sets the user granted permission that the extension with id |
| // |extension_id| can use the private key matching |public_key_spki_der| for |
| // signing. |
| // |public_key_spki_der| must be the DER of a Subject Public Key Info. |
| void SetUserGrantedPermission(const std::string& public_key_spki_der); |
| |
| // Must be called when the extension with id |extension_id| used the private |
| // key matching |public_key_spki_der| for signing. |
| // Updates the permissions accordingly. E.g. if this extension generated the |
| // key and no other permission was granted then the permission to sign with |
| // this key is removed. |
| // |public_key_spki_der| must be the DER of a Subject Public Key Info. |
| void SetKeyUsedForSigning(const std::string& public_key_spki_der); |
| |
| private: |
| struct KeyEntry; |
| |
| // Writes the current |state_store_entries_| to the state store of |
| // |extension_id_|. |
| void WriteToStateStore(); |
| |
| // Reads a KeyEntry list from |state| and stores them in |
| // |state_store_entries_|. |
| void KeyEntriesFromState(const base::Value& state); |
| |
| // Converts |state_store_entries_| to a base::Value for storing in the state |
| // store. |
| scoped_ptr<base::Value> KeyEntriesToState(); |
| |
| // Returns an existing entry for |public_key_spki_der_b64| from |
| // |state_store_entries_|. If there is no existing entry, creates, adds and |
| // returns a new entry. |
| // |public_key_spki_der| must be the base64 encoding of the DER of a Subject |
| // Public Key Info. |
| KeyPermissions::PermissionsForExtension::KeyEntry* GetStateStoreEntry( |
| const std::string& public_key_spki_der_b64); |
| |
| bool PolicyAllowsCorporateKeyUsage() const; |
| |
| const std::string extension_id_; |
| std::vector<KeyEntry> state_store_entries_; |
| PrefService* const profile_prefs_; |
| policy::PolicyService* const profile_policies_; |
| KeyPermissions* const key_permissions_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PermissionsForExtension); |
| }; |
| |
| // |profile_prefs| and |extensions_state_store| must not be null and must |
| // outlive this object. |
| // If |profile_is_managed| is false, |profile_policies| is ignored. Otherwise, |
| // |profile_policies| must not be null and must outlive this object. |
| // |profile_is_managed| determines the default usage and permissions for |
| // keys without explicitly assigned usage. |
| KeyPermissions(bool profile_is_managed, |
| PrefService* profile_prefs, |
| policy::PolicyService* profile_policies, |
| extensions::StateStore* extensions_state_store); |
| |
| ~KeyPermissions(); |
| |
| using PermissionsCallback = |
| base::Callback<void(scoped_ptr<PermissionsForExtension>)>; |
| |
| // Passes an object managing the key permissions of the extension with id |
| // |extension_id| to |callback|. This can happen synchronously or |
| // asynchronously. |
| void GetPermissionsForExtension(const std::string& extension_id, |
| const PermissionsCallback& callback); |
| |
| // Returns true if the user can grant any permission for |public_key_spki_der| |
| // to extensions. |public_key_spki_der| must be the DER of a Subject Public |
| // Key Info. |
| bool CanUserGrantPermissionFor(const std::string& public_key_spki_der) const; |
| |
| static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); |
| |
| private: |
| bool IsCorporateKey(const std::string& public_key_spki_der_b64) const; |
| |
| // Creates a PermissionsForExtension object from |extension_id| and |value| |
| // and passes the object to |callback|. |
| void CreatePermissionObjectAndPassToCallback( |
| const std::string& extension_id, |
| const PermissionsCallback& callback, |
| scoped_ptr<base::Value> value); |
| |
| // Writes |value| to the state store of the extension with id |extension_id|. |
| void SetPlatformKeysOfExtension(const std::string& extension_id, |
| scoped_ptr<base::Value> value); |
| |
| const base::DictionaryValue* GetPrefsEntry( |
| const std::string& public_key_spki_der_b64) const; |
| |
| const bool profile_is_managed_; |
| PrefService* const profile_prefs_; |
| policy::PolicyService* const profile_policies_; |
| extensions::StateStore* const extensions_state_store_; |
| base::WeakPtrFactory<KeyPermissions> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(KeyPermissions); |
| }; |
| |
| } // namespace chromeos |
| |
| #endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_H_ |