Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / attestation / platform_verification_flow.h
blobeaa6abb1c7a2e87120242e1b17c193c3c597355e
1 // Copyright 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.
5 #ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_
6 #define CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_
8 #include <string>
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 #include "url/gurl.h"
18 namespace content {
19 class WebContents;
22 namespace cryptohome {
23 class AsyncMethodCaller;
26 namespace user_manager {
27 class User;
30 namespace chromeos {
32 class CryptohomeClient;
34 namespace attestation {
36 class AttestationFlow;
37 class PlatformVerificationFlowTest;
39 // This class allows platform verification for the content protection use case.
40 // All methods must only be called on the UI thread. Example:
41 // scoped_refptr<PlatformVerificationFlow> verifier =
42 // new PlatformVerificationFlow();
43 // PlatformVerificationFlow::Callback callback = base::Bind(&MyCallback);
44 // verifier->ChallengePlatformKey(my_web_contents, "my_id", "some_challenge",
45 // callback);
47 // This class is RefCountedThreadSafe because it may need to outlive its caller.
48 // The attestation flow that needs to happen to establish a certified platform
49 // key may take minutes on some hardware. This class will timeout after a much
50 // shorter time so the caller can proceed without platform verification but it
51 // is important that the pending operation be allowed to finish. If the
52 // attestation flow is aborted at any stage, it will need to start over. If we
53 // use weak pointers, the attestation flow will stop when the next callback is
54 // run. So we need the instance to stay alive until the platform key is fully
55 // certified so the next time ChallegePlatformKey() is invoked it will be quick.
56 class PlatformVerificationFlow
57 : public base::RefCountedThreadSafe<PlatformVerificationFlow> {
58 public:
59 // These values are reported to UMA. DO NOT CHANGE THE EXISTING VALUES!
60 enum Result {
61 SUCCESS, // The operation succeeded.
62 INTERNAL_ERROR, // The operation failed unexpectedly.
63 PLATFORM_NOT_VERIFIED, // The platform cannot be verified. For example:
64 // - It is not a Chrome device.
65 // - It is not running a verified OS image.
66 USER_REJECTED, // The user explicitly rejected the operation.
67 POLICY_REJECTED, // The operation is not allowed by policy/settings.
68 TIMEOUT, // The operation timed out.
71 // An interface which allows settings and UI to be abstracted for testing
72 // purposes. For normal operation the default implementation should be used.
73 class Delegate {
74 public:
75 virtual ~Delegate() {}
77 // Gets the URL associated with the given |web_contents|.
78 virtual const GURL& GetURL(content::WebContents* web_contents) = 0;
80 // Gets the user associated with the given |web_contents|. NULL may be
81 // returned.
82 virtual const user_manager::User* GetUser(
83 content::WebContents* web_contents) = 0;
85 // Checks whether attestation is permitted by user.
86 virtual bool IsPermittedByUser(content::WebContents* web_contents) = 0;
88 // Returns true iff the device is in a mode that supports platform
89 // verification. For example, platform verification is not supported in
90 // guest or incognito mode. It is also not supported in dev mode unless
91 // overridden by a flag.
92 virtual bool IsInSupportedMode(content::WebContents* web_contents) = 0;
95 // This callback will be called when a challenge operation completes. If
96 // |result| is SUCCESS then |signed_data| holds the data which was signed
97 // by the platform key (this is the original challenge appended with a random
98 // nonce) and |signature| holds the RSA-PKCS1-v1.5 signature. The
99 // |platform_key_certificate| certifies the key used to generate the
100 // signature. This key may be generated on demand and is not guaranteed to
101 // persist across multiple calls to this method. The browser does not check
102 // the validity of |signature| or |platform_key_certificate|.
103 typedef base::Callback<void(Result result,
104 const std::string& signed_data,
105 const std::string& signature,
106 const std::string& platform_key_certificate)>
107 ChallengeCallback;
109 // A constructor that uses the default implementation of all dependencies
110 // including Delegate.
111 PlatformVerificationFlow();
113 // An alternate constructor which specifies dependent objects explicitly.
114 // This is useful in testing. The caller retains ownership of all pointers.
115 PlatformVerificationFlow(AttestationFlow* attestation_flow,
116 cryptohome::AsyncMethodCaller* async_caller,
117 CryptohomeClient* cryptohome_client,
118 Delegate* delegate);
120 // Invokes an asynchronous operation to challenge a platform key. Any user
121 // interaction will be associated with |web_contents|. The |service_id| is an
122 // arbitrary value but it should uniquely identify the origin of the request
123 // and should not be determined by that origin; its purpose is to prevent
124 // collusion between multiple services. The |challenge| is also an arbitrary
125 // value but it should be time sensitive or associated to some kind of session
126 // because its purpose is to prevent certificate replay. The |callback| will
127 // be called when the operation completes. The duration of the operation can
128 // vary depending on system state, hardware capabilities, and interaction with
129 // the user.
130 void ChallengePlatformKey(content::WebContents* web_contents,
131 const std::string& service_id,
132 const std::string& challenge,
133 const ChallengeCallback& callback);
135 void set_timeout_delay(const base::TimeDelta& timeout_delay) {
136 timeout_delay_ = timeout_delay;
139 private:
140 friend class base::RefCountedThreadSafe<PlatformVerificationFlow>;
141 friend class PlatformVerificationFlowTest;
143 // Holds the arguments of a ChallengePlatformKey call. This is convenient for
144 // use with base::Bind so we don't get too many arguments.
145 struct ChallengeContext {
146 ChallengeContext(content::WebContents* web_contents,
147 const std::string& service_id,
148 const std::string& challenge,
149 const ChallengeCallback& callback);
150 ~ChallengeContext();
152 content::WebContents* web_contents;
153 std::string service_id;
154 std::string challenge;
155 ChallengeCallback callback;
158 ~PlatformVerificationFlow();
160 // Callback for attestation preparation. The arguments to ChallengePlatformKey
161 // are in |context|, and |attestation_prepared| specifies whether attestation
162 // has been prepared on this device.
163 void OnAttestationPrepared(const ChallengeContext& context,
164 bool attestation_prepared);
166 // Initiates the flow to get a platform key certificate. The arguments to
167 // ChallengePlatformKey are in |context|. |user_id| identifies the user for
168 // which to get a certificate. If |force_new_key| is true then any existing
169 // key for the same user and service will be ignored and a new key will be
170 // generated and certified.
171 void GetCertificate(const ChallengeContext& context,
172 const std::string& user_id,
173 bool force_new_key);
175 // A callback called when an attestation certificate request operation
176 // completes. The arguments to ChallengePlatformKey are in |context|.
177 // |user_id| identifies the user for which the certificate was requested.
178 // |operation_success| is true iff the certificate request operation
179 // succeeded. |certificate| holds the certificate for the platform key on
180 // success. If the certificate request was successful, this method invokes a
181 // request to sign the challenge. If the operation timed out prior to this
182 // method being called, this method does nothing - notably, the callback is
183 // not invoked.
184 void OnCertificateReady(const ChallengeContext& context,
185 const std::string& user_id,
186 scoped_ptr<base::Timer> timer,
187 bool operation_success,
188 const std::string& certificate);
190 // A callback run after a constant delay to handle timeouts for lengthy
191 // certificate requests. |context.callback| will be invoked with a TIMEOUT
192 // result.
193 void OnCertificateTimeout(const ChallengeContext& context);
195 // A callback called when a challenge signing request has completed. The
196 // |certificate| is the platform certificate for the key which signed the
197 // |challenge|. The arguments to ChallengePlatformKey are in |context|.
198 // |operation_success| is true iff the challenge signing operation was
199 // successful. If it was successful, |response_data| holds the challenge
200 // response and the method will invoke |context.callback|.
201 void OnChallengeReady(const ChallengeContext& context,
202 const std::string& certificate,
203 bool operation_success,
204 const std::string& response_data);
206 // Checks whether attestation for content protection is allowed by policy.
207 bool IsAttestationAllowedByPolicy();
209 // Returns true iff |certificate| is an expired X.509 certificate.
210 bool IsExpired(const std::string& certificate);
212 AttestationFlow* attestation_flow_;
213 scoped_ptr<AttestationFlow> default_attestation_flow_;
214 cryptohome::AsyncMethodCaller* async_caller_;
215 CryptohomeClient* cryptohome_client_;
216 Delegate* delegate_;
217 scoped_ptr<Delegate> default_delegate_;
218 base::TimeDelta timeout_delay_;
220 DISALLOW_COPY_AND_ASSIGN(PlatformVerificationFlow);
223 } // namespace attestation
224 } // namespace chromeos
226 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_PLATFORM_VERIFICATION_FLOW_H_