| // 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 CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_ |
| #define CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/callback_forward.h" |
| #include "base/component_export.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "base/timer/timer.h" |
| #include "chromeos/dbus/attestation/interface.pb.h" |
| #include "chromeos/dbus/constants/attestation_constants.h" |
| #include "chromeos/dbus/dbus_method_call_status.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| class AccountId; |
| |
| namespace chromeos { |
| |
| class AttestationClient; |
| |
| namespace attestation { |
| |
| // Interface for access to the Privacy CA server. |
| class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) ServerProxy { |
| public: |
| using DataCallback = |
| base::OnceCallback<void(bool success, const std::string& data)>; |
| using ProxyPresenceCallback = |
| base::OnceCallback<void(bool is_any_proxy_present)>; |
| virtual ~ServerProxy(); |
| virtual void SendEnrollRequest(const std::string& request, |
| DataCallback on_response) = 0; |
| virtual void SendCertificateRequest(const std::string& request, |
| DataCallback on_response) = 0; |
| virtual PrivacyCAType GetType(); |
| |
| // Looks ahead and checks if `SendEnrollRequest()` or |
| // `SendCertificateRequest()` uses any server proxy for real. Note that the |
| // callback only returns a boolean value; in case of any error, it is assumed |
| // to have proxies. This decision is motivated by the only caller, |
| // `AttestationFlowAdaptive`, has to assume the presence of the proxy if the |
| // information is not available. |
| virtual void CheckIfAnyProxyPresent(ProxyPresenceCallback callback) = 0; |
| }; |
| |
| // Implements the message flow for Chrome OS attestation tasks. Generally this |
| // consists of coordinating messages between the Chrome OS attestation service |
| // and the Chrome OS Privacy CA server. Sample usage: |
| // |
| // AttestationFlow flow(std::move(my_server_proxy)); |
| // AttestationFlow::CertificateCallback callback = |
| // base::BindOnce(&MyCallback); |
| // flow.GetCertificate(ENTERPRISE_USER_CERTIFICATE, false, callback); |
| // |
| // This class is not thread safe. |
| class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow { |
| public: |
| using CertificateCallback = |
| base::OnceCallback<void(AttestationStatus status, |
| const std::string& pem_certificate_chain)>; |
| |
| // Returns the attestation key type for a given |certificate_profile|. |
| // |
| // Parameters |
| // certificate_profile - Specifies what kind of certificate the key is for. |
| static AttestationKeyType GetKeyTypeForProfile( |
| AttestationCertificateProfile certificate_profile); |
| |
| explicit AttestationFlow(std::unique_ptr<ServerProxy> server_proxy); |
| AttestationFlow(std::unique_ptr<ServerProxy> server_proxy, |
| ::attestation::KeyType crypto_key_type); |
| |
| AttestationFlow(const AttestationFlow&) = delete; |
| AttestationFlow& operator=(const AttestationFlow&) = delete; |
| |
| virtual ~AttestationFlow(); |
| |
| // Sets the timeout for attestation to be ready. |
| void set_ready_timeout(base::TimeDelta ready_timeout) { |
| ready_timeout_ = ready_timeout; |
| } |
| // Gets the timeout for attestation to be ready. |
| base::TimeDelta ready_timeout() const { return ready_timeout_; } |
| |
| // Sets the retry delay. |
| void set_retry_delay(base::TimeDelta retry_delay) { |
| retry_delay_ = retry_delay; |
| } |
| |
| // Returns the retry delay. |
| base::TimeDelta retry_delay() { return retry_delay_; } |
| |
| // Gets an attestation certificate for a hardware-protected key. If a key for |
| // the given profile does not exist, it will be generated and a certificate |
| // request will be made to the Chrome OS Privacy CA to issue a certificate for |
| // the key. If the key already exists and |force_new_key| is false, the |
| // existing certificate is returned. |
| // |
| // Parameters |
| // certificate_profile - Specifies what kind of certificate should be |
| // requested from the CA. |
| // account_id - Identifies the currently active user. This is ignored when |
| // using the enterprise machine cert profile. |
| // request_origin - For content protection profiles, certificate requests |
| // are origin-specific. This string must uniquely identify |
| // the origin of the request. |
| // force_new_key - If set to true, a new key will be generated even if a key |
| // already exists for the profile. The new key will replace |
| // the existing key on success. |
| // key_name - The name of the key. If left empty, a default name derived |
| // from the |certificate_profile| and |account_id| will be used. |
| // callback - A callback which will be called when the operation completes. |
| // On success |result| will be true and |data| will contain the |
| // PCA-issued certificate chain in PEM format. |
| virtual void GetCertificate(AttestationCertificateProfile certificate_profile, |
| const AccountId& account_id, |
| const std::string& request_origin, |
| bool force_new_key, |
| const std::string& key_name, |
| CertificateCallback callback); |
| |
| private: |
| // Handles the result of a call to `GetStatus()` for enrollment status. |
| // Reports success if enrollment is complete and otherwise starts the process. |
| // |
| // Parameters |
| // callback - Called with the success or failure of the enrollment. |
| // result - Result of `GetStatus()`, which contains `enrolled` field. |
| void OnEnrollmentCheckComplete(base::OnceCallback<void(bool)> callback, |
| const ::attestation::GetStatusReply& reply); |
| |
| // Asynchronously waits for attestation to be ready and start enrollment once |
| // it is. If attestation is not ready by the time the flow's timeout is |
| // reached, fail. |
| // |
| // Parameters |
| // end_time - Time after which preparation should time out. |
| // callback - Called with the success or failure of the enrollment. |
| void WaitForAttestationPrepared(base::TimeTicks end_time, |
| base::OnceCallback<void(bool)> callback); |
| |
| // Handles the result of a call to GetEnrollmentPreparations. Starts |
| // enrollment on success and retries after |retry_delay_| if not. |
| // |
| // Parameters |
| // end_time - Time after which preparation should time out. |
| // callback - Called with the success or failure of the enrollment. |
| // reply - Reply from the attestation service. |
| void OnPreparedCheckComplete( |
| base::TimeTicks end_time, |
| base::OnceCallback<void(bool)> callback, |
| const ::attestation::GetEnrollmentPreparationsReply& reply); |
| |
| // Called when the attestation daemon has finished creating an enrollment |
| // request for the Privacy CA. The request is asynchronously forwarded as-is |
| // to the PCA. |
| // |
| // Parameters |
| // callback - Called with the success or failure of the enrollment. |
| // reply - The reply of `CreateEnrollRequest()`. |
| void SendEnrollRequestToPCA( |
| base::OnceCallback<void(bool)> callback, |
| const ::attestation::CreateEnrollRequestReply& reply); |
| |
| // Called when the Privacy CA responds to an enrollment request. The response |
| // is asynchronously forwarded as-is to the attestation daemon in order to |
| // complete the enrollment operation. |
| // |
| // Parameters |
| // callback - Called with the success or failure of the enrollment. |
| // success - The status of the Privacy CA operation. |
| // data - The response data from the Privacy CA. |
| void SendEnrollResponseToDaemon(base::OnceCallback<void(bool)> callback, |
| bool success, |
| const std::string& data); |
| |
| // Called when the attestation daemon completes an enrollment operation. If |
| // the operation was successful, the next_task callback is called. |
| // |
| // Parameters |
| // callback - Called with the success or failure of the enrollment. |
| // reply - The reply of `FinishEnroll()`. |
| void OnEnrollComplete(base::OnceCallback<void(bool)> callback, |
| const ::attestation::FinishEnrollReply& reply); |
| |
| // Asynchronously initiates the certificate request flow. Attestation |
| // enrollment must complete successfully before this operation can succeed. |
| // |
| // Parameters |
| // certificate_profile - Specifies what kind of certificate should be |
| // requested from the CA. |
| // account_id - Identifies the active user. |
| // request_origin - An identifier for the origin of this request. |
| // generate_new_key - If set to true a new key is generated. |
| // key_name - The name of the key. If left empty, a default name derived |
| // from the |certificate_profile| and |account_id| will be used. |
| // callback - Called when the operation completes. |
| // enrolled - Success or failure of the enrollment phase. |
| void StartCertificateRequest( |
| const AttestationCertificateProfile certificate_profile, |
| const AccountId& account_id, |
| const std::string& request_origin, |
| bool generate_new_key, |
| const std::string& key_name, |
| CertificateCallback callback, |
| bool enrolled); |
| |
| // Called with the reply to `GetKeyInfo()`. Will query the existing |
| // certificate if it exists and otherwise start a new certificate request. |
| // |
| // Parameters |
| // certificate_profile - Specifies what kind of certificate should be |
| // requested from the CA. |
| // account_id - Identifies the active user. |
| // request_origin - An identifier for the origin of this request. |
| // generate_new_key - If set to true a new key is generated. |
| // key_name - The name of the key. If left empty, a default name derived |
| // from the |certificate_profile| and |account_id| will be used. |
| // callback - Called when the operation completes. |
| // reply - The reply of `GetKeyInfo()`. |
| void OnGetKeyInfoComplete(AttestationCertificateProfile certificate_profile, |
| const AccountId& account_id, |
| const std::string& request_origin, |
| const std::string& key_name, |
| AttestationKeyType key_type, |
| CertificateCallback callback, |
| const ::attestation::GetKeyInfoReply& reply); |
| |
| // Called when the attestation daemon has finished creating a certificate |
| // request for the Privacy CA. The request is asynchronously forwarded as-is |
| // to the PCA. |
| // |
| // Parameters |
| // key_type - The type of the key for which a certificate is requested. |
| // account_id - Identifies the active user. |
| // key_name - The name of the key for which a certificate is requested. |
| // callback - Called when the operation completes. |
| // reply - the result returned by |AttestationClient|. |
| void SendCertificateRequestToPCA( |
| AttestationKeyType key_type, |
| const AccountId& account_id, |
| const std::string& key_name, |
| CertificateCallback callback, |
| const ::attestation::CreateCertificateRequestReply& reply); |
| |
| // Called when the Privacy CA responds to a certificate request. The response |
| // is asynchronously forwarded as-is to the attestation daemon in order to |
| // complete the operation. |
| // |
| // Parameters |
| // key_type - The type of the key for which a certificate is requested. |
| // account_id - Identifies the active user. |
| // key_name - The name of the key for which a certificate is requested. |
| // callback - Called when the operation completes. |
| // success - The status of the Privacy CA operation. |
| // data - The response data from the Privacy CA. |
| void SendCertificateResponseToDaemon(AttestationKeyType key_type, |
| const AccountId& account_id, |
| const std::string& key_name, |
| CertificateCallback callback, |
| bool success, |
| const std::string& data); |
| |
| // Called after attestation service finishes processing of a certificate |
| // request. |
| // |
| // Parameters |
| // callback - Called when the operation completes. |
| // reply - The reply of `FinishCertificateRequest()`. |
| void OnCertRequestFinished( |
| CertificateCallback callback, |
| const ::attestation::FinishCertificateRequestReply& reply); |
| |
| AttestationClient* attestation_client_; |
| std::unique_ptr<ServerProxy> server_proxy_; |
| |
| // The key type that asks attestation service to create with. |
| const ::attestation::KeyType crypto_key_type_; |
| |
| base::TimeDelta ready_timeout_; |
| base::TimeDelta retry_delay_; |
| |
| base::WeakPtrFactory<AttestationFlow> weak_factory_{this}; |
| }; |
| |
| } // namespace attestation |
| } // namespace chromeos |
| |
| // TODO(https://crbug.com/1164001): remove when //chromeos/attestation |
| // moved to ash |
| namespace ash { |
| namespace attestation { |
| using ::chromeos::attestation::AttestationFlow; |
| using ::chromeos::attestation::ServerProxy; |
| } // namespace attestation |
| } // namespace ash |
| |
| #endif // CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_ |