| // 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/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/time/time.h" |
| #include "base/timer/timer.h" |
| #include "chromeos/attestation/attestation_constants.h" |
| #include "chromeos/chromeos_export.h" |
| #include "chromeos/dbus/dbus_method_call_status.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| class AccountId; |
| |
| namespace cryptohome { |
| |
| class AsyncMethodCaller; |
| |
| } // namespace cryptohome |
| |
| namespace chromeos { |
| |
| class CryptohomeClient; |
| |
| namespace attestation { |
| |
| // Interface for access to the Privacy CA server. |
| class CHROMEOS_EXPORT ServerProxy { |
| public: |
| typedef base::Callback<void(bool success, |
| const std::string& data)> DataCallback; |
| virtual ~ServerProxy(); |
| virtual void SendEnrollRequest(const std::string& request, |
| const DataCallback& on_response) = 0; |
| virtual void SendCertificateRequest(const std::string& request, |
| const DataCallback& on_response) = 0; |
| virtual PrivacyCAType GetType(); |
| }; |
| |
| // 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(AsyncMethodCaller::GetInstance(), |
| // DBusThreadManager::Get().GetCryptohomeClient(), |
| // std::move(my_server_proxy)); |
| // AttestationFlow::CertificateCallback callback = base::Bind(&MyCallback); |
| // flow.GetCertificate(ENTERPRISE_USER_CERTIFICATE, false, callback); |
| // |
| // This class is not thread safe. |
| class CHROMEOS_EXPORT AttestationFlow { |
| public: |
| typedef base::Callback<void(bool success, |
| const std::string& pem_certificate_chain)> |
| CertificateCallback; |
| |
| // 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); |
| |
| // Returns the name of the key for a given certificate profile. The |
| // |request_origin| parameter is for PROFILE_CONTENT_PROTECTION_CERTIFICATE |
| // profiles and is ignored for other profiles. |
| // |
| // Parameters |
| // certificate_profile - Specifies what kind of certificate the key is for. |
| // request_origin - For content protection profiles, certificate requests |
| // are origin-specific. This string must uniquely identify |
| // the origin of the request. |
| static std::string GetKeyNameForProfile( |
| AttestationCertificateProfile certificate_profile, |
| const std::string& request_origin); |
| |
| AttestationFlow(cryptohome::AsyncMethodCaller* async_caller, |
| CryptohomeClient* cryptohome_client, |
| std::unique_ptr<ServerProxy> server_proxy); |
| 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. |
| // 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 CertificateCallback& callback); |
| |
| private: |
| // 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 |
| // retries_left - Number of retries left (-1 for infinite retries). |
| // on_failure - Called if any failure occurs. |
| // next_task - Called on successful enrollment. |
| void WaitForAttestationReadyAndStartEnroll(base::TimeTicks end_time, |
| const base::Closure& on_failure, |
| const base::Closure& next_task); |
| |
| // Called when attestation is prepared, to start the actual enrollment flow. |
| // |
| // Parameters |
| // on_failure - Called if any failure occurs. |
| // next_task - Called on successful enrollment. |
| void StartEnroll(const base::Closure& on_failure, |
| const base::Closure& next_task); |
| |
| // 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 |
| // on_failure - Called if any failure occurs. |
| // next_task - Called on successful enrollment. |
| // success - The status of request creation. |
| // data - The request data for the Privacy CA. |
| void SendEnrollRequestToPCA(const base::Closure& on_failure, |
| const base::Closure& next_task, |
| bool success, |
| const std::string& data); |
| |
| // 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 |
| // on_failure - Called if any failure occurs. |
| // next_task - Called on successful enrollment. |
| // success - The status of the Privacy CA operation. |
| // data - The response data from the Privacy CA. |
| void SendEnrollResponseToDaemon(const base::Closure& on_failure, |
| const base::Closure& next_task, |
| 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 |
| // on_failure - Called if any failure occurs. |
| // next_task - Called on successful enrollment. |
| // success - The status of the enrollment operation. |
| // not_used - An artifact of the cryptohome D-Bus interface; ignored. |
| void OnEnrollComplete(const base::Closure& on_failure, |
| const base::Closure& next_task, |
| bool success, |
| cryptohome::MountError not_used); |
| |
| // 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. |
| // callback - Called when the operation completes. |
| void StartCertificateRequest( |
| const AttestationCertificateProfile certificate_profile, |
| const AccountId& account_id, |
| const std::string& request_origin, |
| bool generate_new_key, |
| const CertificateCallback& callback); |
| |
| // 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. |
| // success - The status of request creation. |
| // data - The request data for the Privacy CA. |
| void SendCertificateRequestToPCA(AttestationKeyType key_type, |
| const AccountId& account_id, |
| const std::string& key_name, |
| const CertificateCallback& callback, |
| bool success, |
| const std::string& data); |
| |
| // 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, |
| const CertificateCallback& callback, |
| bool success, |
| const std::string& data); |
| |
| // Gets an existing certificate from the attestation daemon. |
| // |
| // 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. |
| void GetExistingCertificate(AttestationKeyType key_type, |
| const AccountId& account_id, |
| const std::string& key_name, |
| const CertificateCallback& callback); |
| |
| // Checks whether attestation is ready. If it is, runs |next_task|. If not, |
| // reschedules a check after a delay unless we are out of retry time, in |
| // which case we run |on_failure|. |
| // |
| // Parameters |
| // end_time - The time at or past which we give up retrying. |
| // on_failure - Called if any failure occurs or after we give up retrying. |
| // next_task - Called when attestation is ready. |
| void CheckAttestationReadyAndReschedule(base::TimeTicks end_time, |
| const base::Closure& on_failure, |
| const base::Closure& next_task); |
| |
| cryptohome::AsyncMethodCaller* async_caller_; |
| CryptohomeClient* cryptohome_client_; |
| std::unique_ptr<ServerProxy> server_proxy_; |
| |
| base::TimeDelta ready_timeout_; |
| base::TimeDelta retry_delay_; |
| |
| base::WeakPtrFactory<AttestationFlow> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AttestationFlow); |
| }; |
| |
| } // namespace attestation |
| } // namespace chromeos |
| |
| #endif // CHROMEOS_ATTESTATION_ATTESTATION_FLOW_H_ |