| // Copyright (c) 2012 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 COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_ |
| #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "build/build_config.h" |
| #include "components/account_id/account_id.h" |
| #include "components/policy/proto/cloud_policy.pb.h" |
| #include "components/policy/proto/device_management_backend.pb.h" |
| #include "crypto/rsa_private_key.h" |
| |
| #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| #include "components/policy/proto/chrome_extension_policy.pb.h" |
| #endif |
| |
| namespace policy { |
| |
| // A helper class for testing that provides a straightforward interface for |
| // constructing policy blobs for use in testing. NB: This uses fake data and |
| // hard-coded signing keys by default, so should not be used in production code. |
| // TODO: Add "ForTesting" suffix to trigger presubmit checks. |
| class PolicyBuilder { |
| public: |
| // Constants used as dummy data for filling the PolicyData protobuf. |
| static const char kFakeDeviceId[]; |
| static const char kFakeDomain[]; |
| static const char kFakeGaiaId[]; |
| static const char kFakeMachineName[]; |
| static const char kFakePolicyType[]; |
| static const int kFakePublicKeyVersion; |
| static const int64_t kFakeTimestamp; |
| static const char kFakeToken[]; |
| static const char kFakeUsername[]; |
| static const char kFakeServiceAccountIdentity[]; |
| |
| // Creates a policy builder. The builder will have all |policy_data_| fields |
| // initialized to dummy values and use the test signing keys. |
| PolicyBuilder(); |
| virtual ~PolicyBuilder(); |
| |
| // Returns a reference to the policy data protobuf being built. Note that an |
| // initial policy data payload protobuf is created and filled with testing |
| // values in the constructor. Note also that the public_key_version field will |
| // be filled with the right values only after the Build() method call. |
| enterprise_management::PolicyData& policy_data() { return *policy_data_; } |
| const enterprise_management::PolicyData& policy_data() const { |
| return *policy_data_; |
| } |
| void clear_policy_data() { policy_data_.reset(); } |
| void CreatePolicyData() { |
| policy_data_ = std::make_unique<enterprise_management::PolicyData>(); |
| } |
| |
| // Returns a reference to the policy protobuf being built. Note that the |
| // fields relating to the public key, serialized policy data and signature |
| // will be filled with the right values only after the Build() method call. |
| enterprise_management::PolicyFetchResponse& policy() { return policy_; } |
| const enterprise_management::PolicyFetchResponse& policy() const { |
| return policy_; |
| } |
| |
| // Use these methods for obtaining and changing the current signing key. |
| // Note that, by default, a hard-coded testing signing key is used. |
| std::unique_ptr<crypto::RSAPrivateKey> GetSigningKey() const; |
| void SetSigningKey(const crypto::RSAPrivateKey& key); |
| void SetDefaultSigningKey(); |
| void UnsetSigningKey(); |
| |
| // Use these methods for obtaining and changing the new signing key. |
| // By default, there is no new signing key. |
| std::unique_ptr<crypto::RSAPrivateKey> GetNewSigningKey() const; |
| void SetDefaultNewSigningKey(); |
| void UnsetNewSigningKey(); |
| |
| // Sets the default initial signing key - the resulting policy will be signed |
| // by the default signing key, and will have that key set as the |
| // new_public_key field, as if it were an initial key provision. |
| void SetDefaultInitialSigningKey(); |
| |
| // Assembles the policy components. The resulting policy protobuf is available |
| // through policy() after this call. |
| virtual void Build(); |
| |
| // Returns a copy of policy(). |
| std::unique_ptr<enterprise_management::PolicyFetchResponse> GetCopy() const; |
| |
| // Returns a binary policy blob, i.e. an encoded PolicyFetchResponse. |
| std::string GetBlob() const; |
| |
| // These return hard-coded testing keys. Don't use in production! |
| static std::unique_ptr<crypto::RSAPrivateKey> CreateTestSigningKey(); |
| static std::unique_ptr<crypto::RSAPrivateKey> CreateTestOtherSigningKey(); |
| |
| // Verification signatures for the two hard-coded testing keys above. These |
| // signatures are valid only for the kFakeDomain domain. |
| static std::string GetTestSigningKeySignature(); |
| static std::string GetTestOtherSigningKeySignature(); |
| |
| std::vector<uint8_t> raw_signing_key() const { return raw_signing_key_; } |
| std::vector<uint8_t> raw_new_signing_key() const { |
| return raw_new_signing_key_; |
| } |
| |
| // These methods return the public part of the corresponding signing keys, |
| // using the same binary format that is used for storing the public keys in |
| // the policy protobufs. |
| std::vector<uint8_t> GetPublicSigningKey() const; |
| std::vector<uint8_t> GetPublicNewSigningKey() const; |
| static std::vector<uint8_t> GetPublicTestKey(); |
| static std::vector<uint8_t> GetPublicTestOtherKey(); |
| |
| // These methods return the public part of the corresponding signing keys as a |
| // string, using the same binary format that is used for storing the public |
| // keys in the policy protobufs. |
| std::string GetPublicSigningKeyAsString() const; |
| std::string GetPublicNewSigningKeyAsString() const; |
| static std::string GetPublicTestKeyAsString(); |
| static std::string GetPublicTestOtherKeyAsString(); |
| |
| static std::vector<std::string> GetUserAffiliationIds(); |
| |
| // Created using dummy data used for filling the PolicyData protobuf. |
| static AccountId GetFakeAccountIdForTesting(); |
| |
| private: |
| enterprise_management::PolicyFetchResponse policy_; |
| std::unique_ptr<enterprise_management::PolicyData> policy_data_; |
| |
| // The keys cannot be stored in NSS. Temporary keys are not guaranteed to |
| // remain in the database. Persistent keys require a persistent database, |
| // which would coincide with the user's database. However, these keys are used |
| // for signing the policy and don't have to coincide with the user's known |
| // keys. Instead, we store the private keys as raw bytes. Where needed, a |
| // temporary RSAPrivateKey is created. |
| std::vector<uint8_t> raw_signing_key_; |
| std::vector<uint8_t> raw_new_signing_key_; |
| std::string raw_new_signing_key_signature_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PolicyBuilder); |
| }; |
| |
| // Type-parameterized PolicyBuilder extension that allows for building policy |
| // blobs carrying protobuf payloads. |
| template <typename PayloadProto> |
| class TypedPolicyBuilder : public PolicyBuilder { |
| public: |
| TypedPolicyBuilder(); |
| |
| // Returns a reference to the payload protobuf being built. Note that an |
| // initial payload protobuf is created in the constructor. |
| PayloadProto& payload() { return *payload_; } |
| const PayloadProto& payload() const { return *payload_; } |
| void clear_payload() { payload_.reset(); } |
| void CreatePayload() { payload_ = std::make_unique<PayloadProto>(); } |
| |
| // PolicyBuilder: |
| void Build() override { |
| if (payload_) |
| CHECK(payload_->SerializeToString(policy_data().mutable_policy_value())); |
| |
| PolicyBuilder::Build(); |
| } |
| |
| private: |
| std::unique_ptr<PayloadProto> payload_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TypedPolicyBuilder); |
| }; |
| |
| // PolicyBuilder extension that allows for building policy blobs carrying string |
| // payloads. |
| class StringPolicyBuilder : public PolicyBuilder { |
| public: |
| StringPolicyBuilder(); |
| void set_payload(std::string payload) { payload_ = std::move(payload); } |
| const std::string& payload() const { return payload_; } |
| void clear_payload() { payload_.clear(); } |
| |
| // PolicyBuilder: |
| void Build() override; |
| |
| private: |
| std::string payload_; |
| |
| DISALLOW_COPY_AND_ASSIGN(StringPolicyBuilder); |
| }; |
| |
| typedef TypedPolicyBuilder<enterprise_management::CloudPolicySettings> |
| UserPolicyBuilder; |
| |
| #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| using ComponentCloudPolicyBuilder = |
| TypedPolicyBuilder<enterprise_management::ExternalPolicyData>; |
| #endif |
| |
| #if defined(OS_CHROMEOS) |
| using ComponentActiveDirectoryPolicyBuilder = StringPolicyBuilder; |
| #endif |
| |
| } // namespace policy |
| |
| #endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_ |