1// Copyright (c) 2013 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#ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
6#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
7
8#include <string>
9
10#include "base/callback.h"
11#include "base/compiler_specific.h"
12#include "base/memory/scoped_ptr.h"
13#include "chrome/browser/extensions/chrome_extension_function.h"
14#include "chrome/common/extensions/api/enterprise_platform_keys_private.h"
15#include "chromeos/attestation/attestation_constants.h"
16#include "chromeos/attestation/attestation_flow.h"
17#include "chromeos/dbus/cryptohome_client.h"
18#include "chromeos/dbus/dbus_method_call_status.h"
19#include "third_party/cros_system_api/dbus/service_constants.h"
20
21class PrefService;
22
23namespace chromeos {
24class CryptohomeClient;
25}
26
27namespace cryptohome {
28class AsyncMethodCaller;
29}
30
31namespace policy {
32class EnterpriseInstallAttributes;
33}
34
35namespace user_prefs {
36class PrefRegistrySyncable;
37}
38
39namespace extensions {
40
41class EPKPChallengeKeyBase : public ChromeAsyncExtensionFunction {
42 public:
43  static const char kChallengeBadBase64Error[];
44  static const char kDevicePolicyDisabledError[];
45  static const char kExtensionNotWhitelistedError[];
46  static const char kResponseBadBase64Error[];
47  static const char kSignChallengeFailedError[];
48  static const char kUserNotManaged[];
49
50 protected:
51  enum PrepareKeyResult {
52    PREPARE_KEY_OK = 0,
53    PREPARE_KEY_DBUS_ERROR,
54    PREPARE_KEY_USER_REJECTED,
55    PREPARE_KEY_GET_CERTIFICATE_FAILED,
56    PREPARE_KEY_RESET_REQUIRED
57  };
58
59  EPKPChallengeKeyBase();
60  EPKPChallengeKeyBase(
61      chromeos::CryptohomeClient* cryptohome_client,
62      cryptohome::AsyncMethodCaller* async_caller,
63      chromeos::attestation::AttestationFlow* attestation_flow,
64      policy::EnterpriseInstallAttributes* install_attributes);
65  virtual ~EPKPChallengeKeyBase();
66
67  // Returns a trusted value from CroSettings indicating if the device
68  // attestation is enabled.
69  void GetDeviceAttestationEnabled(
70      const base::Callback<void(bool)>& callback) const;
71
72  // Returns true if the device is enterprise managed.
73  bool IsEnterpriseDevice() const;
74
75  // Returns true if the extension is white-listed in the user policy.
76  bool IsExtensionWhitelisted() const;
77
78  // Returns true if the user is enterprise managed.
79  bool IsUserManaged() const;
80
81  // Returns the enterprise domain the device is enrolled to.
82  std::string GetEnterpriseDomain() const;
83
84  // Returns the user email.
85  std::string GetUserEmail() const;
86
87  // Returns the enterprise virtual device ID.
88  std::string GetDeviceId() const;
89
90  // Prepares the key for signing. It will first check if the key exists. If
91  // the key does not exist, it will call AttestationFlow::GetCertificate() to
92  // get a new one. If require_user_consent is true, it will explicitly ask for
93  // user consent before calling GetCertificate().
94  void PrepareKey(
95      chromeos::attestation::AttestationKeyType key_type,
96      const std::string& user_id,
97      const std::string& key_name,
98      chromeos::attestation::AttestationCertificateProfile certificate_profile,
99      bool require_user_consent,
100      const base::Callback<void(PrepareKeyResult)>& callback);
101
102  chromeos::CryptohomeClient* cryptohome_client_;
103  cryptohome::AsyncMethodCaller* async_caller_;
104  chromeos::attestation::AttestationFlow* attestation_flow_;
105  scoped_ptr<chromeos::attestation::AttestationFlow> default_attestation_flow_;
106
107 private:
108  // Holds the context of a PrepareKey() operation.
109  struct PrepareKeyContext {
110    PrepareKeyContext(
111        chromeos::attestation::AttestationKeyType key_type,
112        const std::string& user_id,
113        const std::string& key_name,
114        chromeos::attestation::AttestationCertificateProfile
115            certificate_profile,
116        bool require_user_consent,
117        const base::Callback<void(PrepareKeyResult)>& callback);
118    ~PrepareKeyContext();
119
120    chromeos::attestation::AttestationKeyType key_type;
121    const std::string user_id;
122    const std::string key_name;
123    chromeos::attestation::AttestationCertificateProfile certificate_profile;
124    bool require_user_consent;
125    const base::Callback<void(PrepareKeyResult)> callback;
126  };
127
128  void IsAttestationPreparedCallback(
129      const PrepareKeyContext& context,
130      chromeos::DBusMethodCallStatus status,
131      bool result);
132  void DoesKeyExistCallback(
133      const PrepareKeyContext& context,
134      chromeos::DBusMethodCallStatus status,
135      bool result);
136  void AskForUserConsent(const base::Callback<void(bool)>& callback) const;
137  void AskForUserConsentCallback(
138      const PrepareKeyContext& context,
139      bool result);
140  void GetCertificateCallback(
141      const base::Callback<void(PrepareKeyResult)>& callback,
142      bool success,
143      const std::string& pem_certificate_chain);
144
145  policy::EnterpriseInstallAttributes* install_attributes_;
146};
147
148class EPKPChallengeMachineKey : public EPKPChallengeKeyBase {
149 public:
150  static const char kGetCertificateFailedError[];
151  static const char kNonEnterpriseDeviceError[];
152
153  EPKPChallengeMachineKey();
154  EPKPChallengeMachineKey(
155      chromeos::CryptohomeClient* cryptohome_client,
156      cryptohome::AsyncMethodCaller* async_caller,
157      chromeos::attestation::AttestationFlow* attestation_flow,
158      policy::EnterpriseInstallAttributes* install_attributes);
159
160 protected:
161  virtual bool RunAsync() OVERRIDE;
162
163 private:
164  static const char kKeyName[];
165
166  virtual ~EPKPChallengeMachineKey();
167
168  void GetDeviceAttestationEnabledCallback(const std::string& challenge,
169                                           bool enabled);
170  void PrepareKeyCallback(const std::string& challenge,
171                          PrepareKeyResult result);
172  void SignChallengeCallback(bool success, const std::string& response);
173
174  DECLARE_EXTENSION_FUNCTION(
175      "enterprise.platformKeysPrivate.challengeMachineKey",
176      ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEMACHINEKEY);
177};
178
179typedef EPKPChallengeMachineKey
180    EnterprisePlatformKeysPrivateChallengeMachineKeyFunction;
181
182class EPKPChallengeUserKey : public EPKPChallengeKeyBase {
183 public:
184  static const char kGetCertificateFailedError[];
185  static const char kKeyRegistrationFailedError[];
186  static const char kUserPolicyDisabledError[];
187
188  EPKPChallengeUserKey();
189  EPKPChallengeUserKey(
190      chromeos::CryptohomeClient* cryptohome_client,
191      cryptohome::AsyncMethodCaller* async_caller,
192      chromeos::attestation::AttestationFlow* attestation_flow,
193      policy::EnterpriseInstallAttributes* install_attributes);
194
195  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
196
197 protected:
198  virtual bool RunAsync() OVERRIDE;
199
200 private:
201  static const char kKeyName[];
202
203  virtual ~EPKPChallengeUserKey();
204
205  void GetDeviceAttestationEnabledCallback(const std::string& challenge,
206                                           bool register_key,
207                                           bool require_user_consent,
208                                           bool enabled);
209  void PrepareKeyCallback(const std::string& challenge,
210                          bool register_key,
211                          PrepareKeyResult result);
212  void SignChallengeCallback(bool register_key,
213                             bool success,
214                             const std::string& response);
215  void RegisterKeyCallback(const std::string& response,
216                           bool success,
217                           cryptohome::MountError return_code);
218
219  bool IsRemoteAttestationEnabledForUser() const;
220
221  DECLARE_EXTENSION_FUNCTION(
222      "enterprise.platformKeysPrivate.challengeUserKey",
223      ENTERPRISE_PLATFORMKEYSPRIVATE_CHALLENGEUSERKEY);
224};
225
226typedef EPKPChallengeUserKey
227    EnterprisePlatformKeysPrivateChallengeUserKeyFunction;
228
229}  // namespace extensions
230
231#endif  // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_PRIVATE_ENTERPRISE_PLATFORM_KEYS_PRIVATE_API_H__
232