Home | History | Annotate | Download | only in cloud
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/policy/core/common/cloud/policy_builder.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/stl_util.h"
     10 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
     11 #include "crypto/signature_creator.h"
     12 
     13 namespace em = enterprise_management;
     14 
     15 namespace policy {
     16 
     17 namespace {
     18 
     19 // Signing key test data in DER-encoded PKCS8 format.
     20 const uint8 kSigningKey[] = {
     21     0x30, 0x82, 0x01, 0x55, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
     22     0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
     23     0x01, 0x3f, 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
     24     0xd9, 0xcd, 0xca, 0xcd, 0xc3, 0xea, 0xbe, 0x72, 0x79, 0x1c, 0x29, 0x37,
     25     0x39, 0x99, 0x1f, 0xd4, 0xb3, 0x0e, 0xf0, 0x7b, 0x78, 0x77, 0x0e, 0x05,
     26     0x3b, 0x65, 0x34, 0x12, 0x62, 0xaf, 0xa6, 0x8d, 0x33, 0xce, 0x78, 0xf8,
     27     0x47, 0x05, 0x1d, 0x98, 0xaa, 0x1b, 0x1f, 0x50, 0x05, 0x5b, 0x3c, 0x19,
     28     0x3f, 0x80, 0x83, 0x63, 0x63, 0x3a, 0xec, 0xcb, 0x2e, 0x90, 0x4f, 0xf5,
     29     0x26, 0x76, 0xf1, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x64,
     30     0x29, 0xc2, 0xd9, 0x6b, 0xfe, 0xf9, 0x84, 0x75, 0x73, 0xe0, 0xf4, 0x77,
     31     0xb5, 0x96, 0xb0, 0xdf, 0x83, 0xc0, 0x4e, 0x57, 0xf1, 0x10, 0x6e, 0x91,
     32     0x89, 0x12, 0x30, 0x5e, 0x57, 0xff, 0x14, 0x59, 0x5f, 0x18, 0x86, 0x4e,
     33     0x4b, 0x17, 0x56, 0xfc, 0x8d, 0x40, 0xdd, 0x74, 0x65, 0xd3, 0xff, 0x67,
     34     0x64, 0xcb, 0x9c, 0xb4, 0x14, 0x8a, 0x06, 0xb7, 0x13, 0x45, 0x94, 0x16,
     35     0x7d, 0x3f, 0xe1, 0x02, 0x21, 0x00, 0xf6, 0x0f, 0x31, 0x6d, 0x06, 0xcc,
     36     0x3b, 0xa0, 0x44, 0x1f, 0xf5, 0xc2, 0x45, 0x2b, 0x10, 0x6c, 0xf9, 0x6f,
     37     0x8f, 0x87, 0x3d, 0xc0, 0x3b, 0x55, 0x13, 0x37, 0x80, 0xcd, 0x9f, 0xe1,
     38     0xb7, 0xd9, 0x02, 0x21, 0x00, 0xe2, 0x9a, 0x5f, 0xbf, 0x95, 0x74, 0xb5,
     39     0x7a, 0x6a, 0xa6, 0x97, 0xbd, 0x75, 0x8c, 0x97, 0x18, 0x24, 0xd6, 0x09,
     40     0xcd, 0xdc, 0xb5, 0x94, 0xbf, 0xe2, 0x78, 0xaa, 0x20, 0x47, 0x9f, 0x68,
     41     0x5d, 0x02, 0x21, 0x00, 0xaf, 0x8f, 0x97, 0x8c, 0x5a, 0xd5, 0x4d, 0x95,
     42     0xc4, 0x05, 0xa9, 0xab, 0xba, 0xfe, 0x46, 0xf1, 0xf9, 0xe7, 0x07, 0x59,
     43     0x4f, 0x4d, 0xe1, 0x07, 0x8a, 0x76, 0x87, 0x88, 0x2f, 0x13, 0x35, 0xc1,
     44     0x02, 0x20, 0x24, 0xc3, 0xd9, 0x2f, 0x13, 0x47, 0x99, 0x3e, 0x20, 0x59,
     45     0xa1, 0x1a, 0xeb, 0x1c, 0x81, 0x53, 0x38, 0x7e, 0xc5, 0x9e, 0x71, 0xe5,
     46     0xc0, 0x19, 0x95, 0xdb, 0xef, 0xf6, 0x46, 0xc8, 0x95, 0x3d, 0x02, 0x21,
     47     0x00, 0xaa, 0xb1, 0xff, 0x8a, 0xa2, 0xb2, 0x2b, 0xef, 0x9a, 0x83, 0x3f,
     48     0xc5, 0xbc, 0xd4, 0x6a, 0x07, 0xe8, 0xc7, 0x0b, 0x2e, 0xd4, 0x0f, 0xf8,
     49     0x98, 0x68, 0xe1, 0x04, 0xa8, 0x92, 0xd0, 0x10, 0xaa,
     50 };
     51 
     52 // SHA256 signature of kSigningKey for "example.com" domain.
     53 const uint8 kSigningKeySignature[] = {
     54     0x97, 0xEB, 0x13, 0xE6, 0x6C, 0xE2, 0x7A, 0x2F, 0xC6, 0x6E, 0x68, 0x8F,
     55     0xED, 0x5B, 0x51, 0x08, 0x27, 0xF0, 0xA5, 0x97, 0x20, 0xEE, 0xE2, 0x9B,
     56     0x5B, 0x63, 0xA5, 0x9C, 0xAE, 0x41, 0xFD, 0x34, 0xC4, 0x2E, 0xEB, 0x63,
     57     0x10, 0x80, 0x0C, 0x74, 0x77, 0x6E, 0x34, 0x1C, 0x1B, 0x3B, 0x8E, 0x2A,
     58     0x3A, 0x7F, 0xF9, 0x73, 0xB6, 0x2B, 0xB6, 0x45, 0xDB, 0x05, 0xE8, 0x5A,
     59     0x68, 0x36, 0x05, 0x3C, 0x62, 0x3A, 0x6C, 0x64, 0xDB, 0x0E, 0x61, 0xBD,
     60     0x29, 0x1C, 0x61, 0x4B, 0xE0, 0xDA, 0x07, 0xBA, 0x29, 0x81, 0xF0, 0x90,
     61     0x58, 0xB8, 0xBB, 0xF4, 0x69, 0xFF, 0x8F, 0x2B, 0x4A, 0x2D, 0x98, 0x51,
     62     0x37, 0xF5, 0x52, 0xCB, 0xE3, 0xC4, 0x6D, 0xEC, 0xEA, 0x32, 0x2D, 0xDD,
     63     0xD7, 0xFC, 0x43, 0xC6, 0x54, 0xE1, 0xC1, 0x66, 0x43, 0x37, 0x09, 0xE1,
     64     0xBF, 0xD1, 0x11, 0xFC, 0xDB, 0xBF, 0xDF, 0x66, 0x53, 0x8F, 0x38, 0x2D,
     65     0xAA, 0x89, 0xD2, 0x9F, 0x60, 0x90, 0xB7, 0x05, 0xC2, 0x20, 0x82, 0xE6,
     66     0xE0, 0x57, 0x55, 0xFF, 0x5F, 0xC1, 0x76, 0x66, 0x46, 0xF8, 0x67, 0xB8,
     67     0x8B, 0x81, 0x53, 0xA9, 0x8B, 0x48, 0x9E, 0x2A, 0xF9, 0x60, 0x57, 0xBA,
     68     0xD7, 0x52, 0x97, 0x53, 0xF0, 0x2F, 0x78, 0x68, 0x50, 0x18, 0x12, 0x00,
     69     0x5E, 0x8E, 0x2A, 0x62, 0x0D, 0x48, 0xA9, 0xB5, 0x6B, 0xBC, 0xA0, 0x52,
     70     0x53, 0xD7, 0x65, 0x23, 0xA4, 0xA5, 0xF5, 0x32, 0x49, 0x2D, 0xB2, 0x77,
     71     0x2C, 0x66, 0x97, 0xBA, 0x58, 0xE0, 0x16, 0x1C, 0x8C, 0x02, 0x5D, 0xE0,
     72     0x73, 0x2E, 0xDF, 0xB4, 0x2F, 0x4C, 0xA2, 0x11, 0x26, 0xC1, 0xAF, 0xAC,
     73     0x73, 0xBC, 0xB6, 0x98, 0xE0, 0x20, 0x61, 0x0E, 0x52, 0x4A, 0x6C, 0x80,
     74     0xB5, 0x0C, 0x10, 0x80, 0x09, 0x17, 0xF4, 0x9D, 0xFE, 0xB5, 0xFC, 0x63,
     75     0x9A, 0x80, 0x3F, 0x76,
     76 };
     77 
     78 // New signing key test data in DER-encoded PKCS8 format.
     79 const uint8 kNewSigningKey[] = {
     80     0x30, 0x82, 0x01, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
     81     0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
     82     0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
     83     0x99, 0x98, 0x6b, 0x79, 0x5d, 0x38, 0x33, 0x79, 0x27, 0x0a, 0x2e, 0xb0,
     84     0x89, 0xba, 0xf8, 0xf6, 0x80, 0xde, 0xb0, 0x79, 0xf2, 0xd4, 0x6d, 0xf7,
     85     0x3c, 0xa3, 0x97, 0xf6, 0x4a, 0x3c, 0xa5, 0xcc, 0x40, 0x8a, 0xef, 0x59,
     86     0xaa, 0xc2, 0x82, 0x8f, 0xbc, 0x0d, 0x5b, 0x63, 0xc6, 0xaa, 0x72, 0xe2,
     87     0xf3, 0x57, 0xdd, 0x74, 0x00, 0xb0, 0x42, 0xd6, 0x27, 0xe7, 0x17, 0x61,
     88     0x0a, 0xdc, 0xc1, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x34,
     89     0xcf, 0xc9, 0xb4, 0x73, 0x2f, 0x0d, 0xd3, 0xcc, 0x6e, 0x9d, 0xdb, 0x29,
     90     0xa0, 0x56, 0x56, 0x3b, 0xbd, 0x56, 0x24, 0xb8, 0x2f, 0xfe, 0x97, 0x92,
     91     0x0c, 0x16, 0x06, 0x23, 0x44, 0x73, 0x25, 0x1d, 0x65, 0xf4, 0xda, 0x77,
     92     0xe7, 0x91, 0x2e, 0x91, 0x05, 0x10, 0xc1, 0x1b, 0x39, 0x5e, 0xb2, 0xf7,
     93     0xbd, 0x14, 0x19, 0xcb, 0x6b, 0xc3, 0xa9, 0xe8, 0x91, 0xf7, 0xa7, 0xa9,
     94     0x90, 0x08, 0x51, 0x02, 0x21, 0x00, 0xcc, 0x9e, 0x03, 0x54, 0x8f, 0x24,
     95     0xde, 0x90, 0x25, 0xec, 0x21, 0xaf, 0xe6, 0x27, 0x2a, 0x16, 0x42, 0x74,
     96     0xda, 0xf8, 0x84, 0xc4, 0x8c, 0x1e, 0x86, 0x12, 0x04, 0x5c, 0x17, 0x01,
     97     0xea, 0x9d, 0x02, 0x21, 0x00, 0xc0, 0x2a, 0x6c, 0xe9, 0xa1, 0x1a, 0x41,
     98     0x11, 0x94, 0x50, 0xf7, 0x1a, 0xd3, 0xbc, 0xf3, 0xa2, 0xf8, 0x46, 0xbc,
     99     0x26, 0x77, 0x78, 0xef, 0xc0, 0x54, 0xec, 0x22, 0x3f, 0x2c, 0x57, 0xe0,
    100     0xa3, 0x02, 0x20, 0x31, 0xf2, 0xc8, 0xa1, 0x55, 0xa8, 0x0c, 0x64, 0x67,
    101     0xbd, 0x72, 0xa3, 0xbb, 0xad, 0x07, 0xcb, 0x13, 0x41, 0xef, 0x4a, 0x07,
    102     0x2e, 0xeb, 0x7d, 0x70, 0x00, 0xe9, 0xeb, 0x88, 0xfa, 0x40, 0xc9, 0x02,
    103     0x20, 0x3a, 0xe0, 0xc4, 0xde, 0x10, 0x6e, 0x6a, 0xe1, 0x68, 0x00, 0x26,
    104     0xb6, 0x21, 0x8a, 0x13, 0x5c, 0x2b, 0x96, 0x00, 0xb0, 0x08, 0x8b, 0x15,
    105     0x6a, 0x68, 0x9a, 0xb1, 0x23, 0x8a, 0x02, 0xa2, 0xe1, 0x02, 0x21, 0x00,
    106     0xa3, 0xf2, 0x2d, 0x55, 0xc1, 0x6d, 0x40, 0xfa, 0x1d, 0xf7, 0xba, 0x86,
    107     0xef, 0x50, 0x98, 0xfc, 0xee, 0x09, 0xcc, 0xe7, 0x22, 0xb9, 0x4e, 0x80,
    108     0x32, 0x1a, 0x6b, 0xb3, 0x5f, 0x35, 0xbd, 0xf3,
    109 };
    110 
    111 // SHA256 signature of kNewSigningKey for "example.com" domain.
    112 const uint8 kNewSigningKeySignature[] = {
    113     0x70, 0xED, 0x27, 0x42, 0x34, 0x69, 0xB6, 0x47, 0x9E, 0x7C, 0xA0, 0xF0,
    114     0xE5, 0x0A, 0x49, 0x49, 0x00, 0xDA, 0xBC, 0x70, 0x01, 0xC5, 0x4B, 0xDB,
    115     0x47, 0xD5, 0xAF, 0xA1, 0xAD, 0xB7, 0xE4, 0xE1, 0xBD, 0x5A, 0x1C, 0x35,
    116     0x44, 0x5A, 0xAA, 0xDB, 0x27, 0xBA, 0xA4, 0xA9, 0xC8, 0xDD, 0xEC, 0xD6,
    117     0xEB, 0xFE, 0xDB, 0xE0, 0x03, 0x5C, 0xA6, 0x2E, 0x5A, 0xEC, 0x75, 0x79,
    118     0xB8, 0x5F, 0x0A, 0xEE, 0x05, 0xB2, 0x61, 0xDC, 0x58, 0xF0, 0xD1, 0xCB,
    119     0x7B, 0x2A, 0xDB, 0xC1, 0x7C, 0x60, 0xE6, 0x3E, 0x87, 0x02, 0x61, 0xE6,
    120     0x90, 0xFD, 0x54, 0x65, 0xC7, 0xFF, 0x74, 0x09, 0xD6, 0xAA, 0x8E, 0xDC,
    121     0x5B, 0xC8, 0x38, 0x0C, 0x84, 0x0E, 0x84, 0x2E, 0x37, 0x2A, 0x4B, 0xDE,
    122     0x31, 0x82, 0x76, 0x1E, 0x77, 0xA5, 0xC1, 0xD5, 0xED, 0xFF, 0xBC, 0xEA,
    123     0x91, 0xB7, 0xBC, 0xFF, 0x76, 0x23, 0xE2, 0x78, 0x63, 0x01, 0x47, 0x80,
    124     0x47, 0x1F, 0x3A, 0x49, 0xBF, 0x0D, 0xCF, 0x27, 0x70, 0x92, 0xBB, 0xEA,
    125     0xB3, 0x92, 0x70, 0xFF, 0x1E, 0x4B, 0x1B, 0xE0, 0x4E, 0x0C, 0x4C, 0x6B,
    126     0x5D, 0x77, 0x06, 0xBB, 0xFB, 0x9B, 0x0E, 0x55, 0xB8, 0x8A, 0xF2, 0x45,
    127     0xA9, 0xF3, 0x54, 0x3D, 0x0C, 0xAC, 0xA8, 0x15, 0xD2, 0x31, 0x8D, 0x97,
    128     0x08, 0x73, 0xC9, 0x0F, 0x1D, 0xDE, 0x10, 0x22, 0xC6, 0x55, 0x53, 0x7F,
    129     0x7C, 0x50, 0x16, 0x5A, 0x08, 0xCC, 0x1C, 0x53, 0x9B, 0x02, 0xB8, 0x80,
    130     0xB7, 0x46, 0xF5, 0xF1, 0xC7, 0x3D, 0x36, 0xBD, 0x26, 0x02, 0xDE, 0x10,
    131     0xAB, 0x5A, 0x03, 0xCD, 0x67, 0x00, 0x1C, 0x23, 0xC7, 0x13, 0xEE, 0x5D,
    132     0xAF, 0xC5, 0x1F, 0xE3, 0xA0, 0x54, 0xAC, 0xC2, 0xC9, 0x44, 0xD4, 0x4A,
    133     0x09, 0x8E, 0xEB, 0xAE, 0xCA, 0x08, 0x8A, 0x7F, 0x41, 0x7B, 0xD8, 0x2C,
    134     0xDD, 0x6F, 0x80, 0xC3,
    135 };
    136 
    137 }  // namespace
    138 
    139 // Constants used as dummy data for filling the PolicyData protobuf.
    140 const char PolicyBuilder::kFakeDeviceId[] = "device-id";
    141 const char PolicyBuilder::kFakeDomain[] = "example.com";
    142 const char PolicyBuilder::kFakeMachineName[] = "machine-name";
    143 const char PolicyBuilder::kFakePolicyType[] = "policy type";
    144 const int PolicyBuilder::kFakePublicKeyVersion = 17;
    145 const int64 PolicyBuilder::kFakeTimestamp = 365LL * 24 * 60 * 60 * 1000;
    146 const char PolicyBuilder::kFakeToken[] = "token";
    147 const char PolicyBuilder::kFakeUsername[] = "username (at) example.com";
    148 const char PolicyBuilder::kFakeServiceAccountIdentity[] = "robot4test (at) g.com";
    149 
    150 PolicyBuilder::PolicyBuilder()
    151     : policy_data_(new em::PolicyData()) {
    152   SetDefaultSigningKey();
    153   policy_data_->set_policy_type(kFakePolicyType);
    154   policy_data_->set_timestamp(kFakeTimestamp);
    155   policy_data_->set_request_token(kFakeToken);
    156   policy_data_->set_machine_name(kFakeMachineName);
    157   policy_data_->set_public_key_version(kFakePublicKeyVersion);
    158   policy_data_->set_username(kFakeUsername);
    159   policy_data_->set_device_id(kFakeDeviceId);
    160   policy_data_->set_state(em::PolicyData::ACTIVE);
    161   policy_data_->set_service_account_identity(kFakeServiceAccountIdentity);
    162 }
    163 
    164 PolicyBuilder::~PolicyBuilder() {}
    165 
    166 scoped_ptr<crypto::RSAPrivateKey> PolicyBuilder::GetSigningKey() {
    167   if (raw_signing_key_.empty())
    168     return scoped_ptr<crypto::RSAPrivateKey>();
    169   return scoped_ptr<crypto::RSAPrivateKey>(
    170       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(raw_signing_key_));
    171 }
    172 
    173 void PolicyBuilder::SetSigningKey(const crypto::RSAPrivateKey& key) {
    174   key.ExportPrivateKey(&raw_signing_key_);
    175 }
    176 
    177 void PolicyBuilder::SetDefaultSigningKey() {
    178   std::vector<uint8> key(kSigningKey, kSigningKey + arraysize(kSigningKey));
    179   raw_signing_key_.swap(key);
    180 }
    181 
    182 void PolicyBuilder::UnsetSigningKey() {
    183   raw_signing_key_.clear();
    184 }
    185 
    186 scoped_ptr<crypto::RSAPrivateKey> PolicyBuilder::GetNewSigningKey() {
    187   if (raw_new_signing_key_.empty())
    188     return scoped_ptr<crypto::RSAPrivateKey>();
    189   return scoped_ptr<crypto::RSAPrivateKey>(
    190       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(raw_new_signing_key_));
    191 }
    192 
    193 void PolicyBuilder::SetDefaultNewSigningKey() {
    194   std::vector<uint8> key(kNewSigningKey,
    195                          kNewSigningKey + arraysize(kNewSigningKey));
    196   raw_new_signing_key_.swap(key);
    197   raw_new_signing_key_signature_ = GetTestOtherSigningKeySignature();
    198 }
    199 
    200 void PolicyBuilder::SetDefaultInitialSigningKey() {
    201   std::vector<uint8> key(kSigningKey,
    202                          kSigningKey + arraysize(kSigningKey));
    203   raw_new_signing_key_.swap(key);
    204   raw_new_signing_key_signature_ = GetTestSigningKeySignature();
    205   UnsetSigningKey();
    206 }
    207 
    208 void PolicyBuilder::UnsetNewSigningKey() {
    209   raw_new_signing_key_.clear();
    210   raw_new_signing_key_signature_.clear();
    211 }
    212 
    213 void PolicyBuilder::Build() {
    214   // Generate signatures if applicable.
    215   scoped_ptr<crypto::RSAPrivateKey> policy_signing_key = GetNewSigningKey();
    216   if (policy_signing_key) {
    217     // Add the new public key.
    218     std::vector<uint8> raw_new_public_signing_key;
    219     CHECK(policy_signing_key->ExportPublicKey(&raw_new_public_signing_key));
    220     policy_.set_new_public_key(vector_as_array(&raw_new_public_signing_key),
    221                                raw_new_public_signing_key.size());
    222 
    223     policy_.set_new_public_key_verification_signature(
    224         raw_new_signing_key_signature_);
    225 
    226     // The new public key must be signed by the old key.
    227     scoped_ptr<crypto::RSAPrivateKey> old_signing_key = GetSigningKey();
    228     if (old_signing_key) {
    229       SignData(policy_.new_public_key(),
    230                old_signing_key.get(),
    231                policy_.mutable_new_public_key_signature());
    232     }
    233   } else {
    234     // No new signing key, so clear the old public key (this allows us to
    235     // reuse the same PolicyBuilder to build multiple policy blobs).
    236     policy_.clear_new_public_key();
    237     policy_.clear_new_public_key_signature();
    238     policy_signing_key = GetSigningKey();
    239   }
    240 
    241   // Policy isn't signed, so there shouldn't be a public key version.
    242   if (!policy_signing_key)
    243     policy_data_->clear_public_key_version();
    244 
    245   // Serialize the policy data.
    246   if (policy_data_.get())
    247     CHECK(policy_data_->SerializeToString(policy_.mutable_policy_data()));
    248 
    249   // PolicyData signature.
    250   if (policy_signing_key) {
    251     SignData(policy_.policy_data(), policy_signing_key.get(),
    252              policy_.mutable_policy_data_signature());
    253   }
    254 }
    255 
    256 std::string PolicyBuilder::GetBlob() {
    257   return policy_.SerializeAsString();
    258 }
    259 
    260 scoped_ptr<em::PolicyFetchResponse> PolicyBuilder::GetCopy() {
    261   scoped_ptr<em::PolicyFetchResponse> result(new em::PolicyFetchResponse());
    262   result->CopyFrom(policy_);
    263   return result.Pass();
    264 }
    265 
    266 // static
    267 scoped_ptr<crypto::RSAPrivateKey> PolicyBuilder::CreateTestSigningKey() {
    268   std::vector<uint8> raw_signing_key(
    269       kSigningKey, kSigningKey + arraysize(kSigningKey));
    270   return scoped_ptr<crypto::RSAPrivateKey>(
    271       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(raw_signing_key));
    272 }
    273 
    274 // static
    275 scoped_ptr<crypto::RSAPrivateKey> PolicyBuilder::CreateTestOtherSigningKey() {
    276   std::vector<uint8> raw_new_signing_key(
    277       kNewSigningKey, kNewSigningKey + arraysize(kNewSigningKey));
    278   return scoped_ptr<crypto::RSAPrivateKey>(
    279       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(raw_new_signing_key));
    280 }
    281 
    282 // static
    283 std::string PolicyBuilder::GetTestSigningKeySignature() {
    284   return std::string(reinterpret_cast<const char*>(kSigningKeySignature),
    285                      sizeof(kSigningKeySignature));
    286 }
    287 
    288 // static
    289 std::string PolicyBuilder::GetTestOtherSigningKeySignature() {
    290   return std::string(reinterpret_cast<const char*>(kNewSigningKeySignature),
    291                      sizeof(kNewSigningKeySignature));
    292 }
    293 
    294 void PolicyBuilder::SignData(const std::string& data,
    295                              crypto::RSAPrivateKey* key,
    296                              std::string* signature) {
    297   scoped_ptr<crypto::SignatureCreator> signature_creator(
    298       crypto::SignatureCreator::Create(key,
    299                                        crypto::SignatureCreator::SHA1));
    300   signature_creator->Update(reinterpret_cast<const uint8*>(data.c_str()),
    301                             data.size());
    302   std::vector<uint8> signature_bytes;
    303   CHECK(signature_creator->Final(&signature_bytes));
    304   signature->assign(
    305       reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
    306       signature_bytes.size());
    307 }
    308 
    309 template<>
    310 TypedPolicyBuilder<em::CloudPolicySettings>::TypedPolicyBuilder()
    311     : payload_(new em::CloudPolicySettings()) {
    312   policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
    313 }
    314 
    315 // Have the instantiation compiled into the module.
    316 template class TypedPolicyBuilder<em::CloudPolicySettings>;
    317 
    318 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    319 template<>
    320 TypedPolicyBuilder<em::ExternalPolicyData>::TypedPolicyBuilder()
    321     : payload_(new em::ExternalPolicyData()) {
    322   policy_data().set_policy_type(dm_protocol::kChromeExtensionPolicyType);
    323 }
    324 
    325 template class TypedPolicyBuilder<em::ExternalPolicyData>;
    326 #endif
    327 
    328 }  // namespace policy
    329