1 // Copyright 2019 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_CHROMEOS_ATTESTATION_MACHINE_CERTIFICATE_UPLOADER_IMPL_H_ 6 #define CHROME_BROWSER_CHROMEOS_ATTESTATION_MACHINE_CERTIFICATE_UPLOADER_IMPL_H_ 7 8 #include <string> 9 10 #include "base/callback.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/optional.h" 13 #include "chrome/browser/chromeos/attestation/machine_certificate_uploader.h" 14 #include "chromeos/dbus/attestation/interface.pb.h" 15 #include "chromeos/dbus/constants/attestation_constants.h" 16 17 namespace policy { 18 class CloudPolicyClient; 19 } 20 21 namespace chromeos { 22 23 namespace attestation { 24 25 class AttestationFlow; 26 27 // A class which uploads enterprise machine certificates. 28 class MachineCertificateUploaderImpl : public MachineCertificateUploader { 29 public: 30 explicit MachineCertificateUploaderImpl( 31 policy::CloudPolicyClient* policy_client); 32 33 // A constructor which allows custom AttestationFlow implementations. Useful 34 // for testing. 35 MachineCertificateUploaderImpl(policy::CloudPolicyClient* policy_client, 36 AttestationFlow* attestation_flow); 37 38 ~MachineCertificateUploaderImpl() override; 39 40 // Sets the retry limit in number of tries; useful in testing. set_retry_limit(int limit)41 void set_retry_limit(int limit) { retry_limit_ = limit; } 42 // Sets the retry delay in seconds; useful in testing. set_retry_delay(int retry_delay)43 void set_retry_delay(int retry_delay) { retry_delay_ = retry_delay; } 44 45 using UploadCallback = 46 base::OnceCallback<void(bool /*certificate_uploaded*/)>; 47 48 // Checks if the machine certificate has been uploaded, and if not, do so. 49 // A certificate will be obtained if needed. 50 void UploadCertificateIfNeeded(UploadCallback callback) override; 51 52 // Refreshes a fresh machine certificate and uploads it. 53 void RefreshAndUploadCertificate(UploadCallback callback) override; 54 55 // Non-blocking wait for a certificate to be uploaded. Calls the |callback| 56 // immediately if the certificate was already uploaded or wait for the next 57 // attempt to do so. 58 void WaitForUploadComplete(UploadCallback callback) override; 59 60 private: 61 // Starts certificate obtention and upload. 62 void Start(); 63 64 // Gets a new certificate for the Enterprise Machine Key (EMK). 65 void GetNewCertificate(); 66 67 // Called when `GetKeyInfo()` returned to check the existing certificate. 68 // There are 3 cases by the status replied from attestation service: 69 // 1. If the existing EMK is found, calls `CheckCertificateExpiry()`. 70 // 2. If the key does not exist, calls `GetNewCertificate()`. 71 // 3. Otherwise, there is an error and `Reschedule()` is called to retry. 72 void OnGetExistingCertificate(const ::attestation::GetKeyInfoReply& reply); 73 74 // Checks if any certificate in the given `reply` is expired and, if so, gets 75 // a new one. If not renewing, calls `CheckIfUploaded()`. 76 void CheckCertificateExpiry(const ::attestation::GetKeyInfoReply& reply); 77 78 // Uploads a machine certificate to the policy server. 79 void UploadCertificate(const std::string& pem_certificate_chain); 80 81 // Checks if a certificate in `reply` has already been uploaded and, if not, 82 // upload. 83 void CheckIfUploaded(const ::attestation::GetKeyInfoReply& reply); 84 85 // Called when a certificate upload operation completes. On success, |status| 86 // will be true. 87 void OnUploadComplete(bool status); 88 89 // Marks a key as uploaded in the payload proto. 90 void MarkAsUploaded(const ::attestation::GetKeyInfoReply& reply); 91 92 // Handles failure of getting a certificate. 93 void HandleGetCertificateFailure(AttestationStatus status); 94 95 // Reschedules a policy check (i.e. a call to Start) for a later time. 96 // TODO(dkrahn): A better solution would be to wait for a dbus signal which 97 // indicates the system is ready to process this task. See crbug.com/256845. 98 void Reschedule(); 99 100 void RunCallbacks(bool status); 101 102 policy::CloudPolicyClient* policy_client_ = nullptr; 103 AttestationFlow* attestation_flow_ = nullptr; 104 std::unique_ptr<AttestationFlow> default_attestation_flow_; 105 bool refresh_certificate_ = false; 106 std::vector<UploadCallback> callbacks_; 107 int num_retries_ = {}; 108 int retry_limit_ = {}; 109 int retry_delay_ = {}; 110 base::Optional<bool> certificate_uploaded_; 111 112 // Note: This should remain the last member so it'll be destroyed and 113 // invalidate the weak pointers before any other members are destroyed. 114 base::WeakPtrFactory<MachineCertificateUploaderImpl> weak_factory_{this}; 115 116 DISALLOW_COPY_AND_ASSIGN(MachineCertificateUploaderImpl); 117 }; 118 119 } // namespace attestation 120 } // namespace chromeos 121 122 #endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_MACHINE_CERTIFICATE_UPLOADER_IMPL_H_ 123