15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/rsa_private_key.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "policy/proto/cloud_policy.pb.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/chrome_extension_policy.pb.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper class for testing that provides a straightforward interface for
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructing policy blobs for use in testing. NB: This uses fake data and
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hard-coded signing keys by default, so should not be used in production code.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PolicyBuilder {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants used as dummy data for filling the PolicyData protobuf.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakeDeviceId[];
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakeDomain[];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakeMachineName[];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakePolicyType[];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kFakePublicKeyVersion;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int64 kFakeTimestamp;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakeToken[];
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kFakeUsername[];
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static const char kFakeServiceAccountIdentity[];
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a policy builder. The builder will have all PolicyData fields
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized to dummy values and use the test signing keys.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBuilder();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PolicyBuilder();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use this member to access the PolicyData protobuf.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enterprise_management::PolicyData& policy_data() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!policy_data_.get())
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_data_.reset(new enterprise_management::PolicyData());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *policy_data_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_policy_data() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy_data_.reset();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enterprise_management::PolicyFetchResponse& policy() {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return policy_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_ptr<crypto::RSAPrivateKey> GetSigningKey();
602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void SetSigningKey(const crypto::RSAPrivateKey& key);
612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void SetDefaultSigningKey();
622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void UnsetSigningKey();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Sets the default initial signing key - the resulting policy will be signed
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // by the default signing key, and will have that key set as the
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new_public_key field, as if it were an initial key provision.
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetDefaultInitialSigningKey();
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_ptr<crypto::RSAPrivateKey> GetNewSigningKey();
702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void SetDefaultNewSigningKey();
712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void UnsetNewSigningKey();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assembles the policy components. The resulting policy protobuf is available
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // through policy() after this call.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Build();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a copy of policy().
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<enterprise_management::PolicyFetchResponse> GetCopy();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a binary policy blob, i.e. an encoded PolicyFetchResponse.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetBlob();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These return hard-coded testing keys. Don't use in production!
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<crypto::RSAPrivateKey> CreateTestSigningKey();
852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  static scoped_ptr<crypto::RSAPrivateKey> CreateTestOtherSigningKey();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verification signatures for the two hard-coded testing keys above. These
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // signatures are valid only for the kFakeDomain domain.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static std::string GetTestSigningKeySignature();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static std::string GetTestOtherSigningKeySignature();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<uint8> raw_signing_key() { return raw_signing_key_; }
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<uint8> raw_new_signing_key() { return raw_new_signing_key_; }
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Produces |key|'s signature over |data| and stores it in |signature|.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SignData(const std::string& data,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                crypto::RSAPrivateKey* key,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                std::string* signature);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enterprise_management::PolicyFetchResponse policy_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<enterprise_management::PolicyData> policy_data_;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string payload_data_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // The keys cannot be stored in NSS. Temporary keys are not guaranteed to
1062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // remain in the database. Persistent keys require a persistent database,
1072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // which would coincide with the user's database. However, these keys are used
1082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // for signing the policy and don't have to coincide with the user's known
1092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // keys. Instead, we store the private keys as raw bytes. Where needed, a
1102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // temporary RSAPrivateKey is created.
1112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::vector<uint8> raw_signing_key_;
1122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::vector<uint8> raw_new_signing_key_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string raw_new_signing_key_signature_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PolicyBuilder);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Type-parameterized PolicyBuilder extension that allows for building policy
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// blobs carrying protobuf payloads.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename PayloadProto>
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TypedPolicyBuilder : public PolicyBuilder {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TypedPolicyBuilder();
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TypedPolicyBuilder() {}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a reference to the payload protobuf being built.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PayloadProto& payload() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!payload_.get())
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      payload_.reset(new PayloadProto());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *payload_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_payload() {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    payload_.reset();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PolicyBuilder:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Build() OVERRIDE {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (payload_.get())
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CHECK(payload_->SerializeToString(policy_data().mutable_policy_value()));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PolicyBuilder::Build();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<PayloadProto> payload_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TypedPolicyBuilder);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef TypedPolicyBuilder<enterprise_management::CloudPolicySettings>
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UserPolicyBuilder;
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef TypedPolicyBuilder<enterprise_management::ExternalPolicyData>
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ComponentPolicyBuilder;
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_BUILDER_H_
161