1 // 2 // Copyright (C) 2015 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef ATTESTATION_SERVER_ATTESTATION_SERVICE_H_ 18 #define ATTESTATION_SERVER_ATTESTATION_SERVICE_H_ 19 20 #include "attestation/common/attestation_interface.h" 21 22 #include <memory> 23 #include <string> 24 25 #include <base/callback.h> 26 #include <base/macros.h> 27 #include <base/memory/weak_ptr.h> 28 #include <base/threading/thread.h> 29 #include <brillo/bind_lambda.h> 30 #include <brillo/http/http_transport.h> 31 32 #include "attestation/common/crypto_utility.h" 33 #include "attestation/common/crypto_utility_impl.h" 34 #include "attestation/common/tpm_utility.h" 35 #include "attestation/common/tpm_utility_v1.h" 36 #include "attestation/server/database.h" 37 #include "attestation/server/database_impl.h" 38 #include "attestation/server/key_store.h" 39 #include "attestation/server/pkcs11_key_store.h" 40 41 namespace attestation { 42 43 // An implementation of AttestationInterface for the core attestation service. 44 // Access to TPM, network and local file-system resources occurs asynchronously 45 // with the exception of Initialize(). All methods must be called on the same 46 // thread that originally called Initialize(). 47 // Usage: 48 // std::unique_ptr<AttestationInterface> attestation = 49 // new AttestationService(); 50 // CHECK(attestation->Initialize()); 51 // attestation->CreateGoogleAttestedKey(...); 52 // 53 // THREADING NOTES: 54 // This class runs a worker thread and delegates all calls to it. This keeps the 55 // public methods non-blocking while allowing complex implementation details 56 // with dependencies on the TPM, network, and filesystem to be coded in a more 57 // readable way. It also serves to serialize method execution which reduces 58 // complexity with TPM state. 59 // 60 // Tasks that run on the worker thread are bound with base::Unretained which is 61 // safe because the thread is owned by this class (so it is guaranteed not to 62 // process a task after destruction). Weak pointers are used to post replies 63 // back to the main thread. 64 class AttestationService : public AttestationInterface { 65 public: 66 AttestationService(); 67 ~AttestationService() override = default; 68 69 // AttestationInterface methods. 70 bool Initialize() override; 71 void CreateGoogleAttestedKey( 72 const CreateGoogleAttestedKeyRequest& request, 73 const CreateGoogleAttestedKeyCallback& callback) override; 74 void GetKeyInfo(const GetKeyInfoRequest& request, 75 const GetKeyInfoCallback& callback) override; 76 void GetEndorsementInfo(const GetEndorsementInfoRequest& request, 77 const GetEndorsementInfoCallback& callback) override; 78 void GetAttestationKeyInfo( 79 const GetAttestationKeyInfoRequest& request, 80 const GetAttestationKeyInfoCallback& callback) override; 81 void ActivateAttestationKey( 82 const ActivateAttestationKeyRequest& request, 83 const ActivateAttestationKeyCallback& callback) override; 84 void CreateCertifiableKey( 85 const CreateCertifiableKeyRequest& request, 86 const CreateCertifiableKeyCallback& callback) override; 87 void Decrypt(const DecryptRequest& request, 88 const DecryptCallback& callback) override; 89 void Sign(const SignRequest& request, const SignCallback& callback) override; 90 void RegisterKeyWithChapsToken( 91 const RegisterKeyWithChapsTokenRequest& request, 92 const RegisterKeyWithChapsTokenCallback& callback) override; 93 94 // Mutators useful for testing. 95 void set_crypto_utility(CryptoUtility* crypto_utility) { 96 crypto_utility_ = crypto_utility; 97 } 98 99 void set_database(Database* database) { 100 database_ = database; 101 } 102 103 void set_http_transport( 104 const std::shared_ptr<brillo::http::Transport>& transport) { 105 http_transport_ = transport; 106 } 107 108 void set_key_store(KeyStore* key_store) { 109 key_store_ = key_store; 110 } 111 112 void set_tpm_utility(TpmUtility* tpm_utility) { 113 tpm_utility_ = tpm_utility; 114 } 115 116 // So tests don't need to duplicate URL decisions. 117 const std::string& attestation_ca_origin() { 118 return attestation_ca_origin_; 119 } 120 121 private: 122 enum ACARequestType { 123 kEnroll, // Enrolls a device, certifying an identity key. 124 kGetCertificate, // Issues a certificate for a TPM-backed key. 125 }; 126 127 // A relay callback which allows the use of weak pointer semantics for a reply 128 // to TaskRunner::PostTaskAndReply. 129 template<typename ReplyProtobufType> 130 void TaskRelayCallback( 131 const base::Callback<void(const ReplyProtobufType&)> callback, 132 const std::shared_ptr<ReplyProtobufType>& reply) { 133 callback.Run(*reply); 134 } 135 136 // A blocking implementation of CreateGoogleAttestedKey appropriate to run on 137 // the worker thread. 138 void CreateGoogleAttestedKeyTask( 139 const CreateGoogleAttestedKeyRequest& request, 140 const std::shared_ptr<CreateGoogleAttestedKeyReply>& result); 141 142 // A blocking implementation of GetKeyInfo. 143 void GetKeyInfoTask( 144 const GetKeyInfoRequest& request, 145 const std::shared_ptr<GetKeyInfoReply>& result); 146 147 // A blocking implementation of GetEndorsementInfo. 148 void GetEndorsementInfoTask( 149 const GetEndorsementInfoRequest& request, 150 const std::shared_ptr<GetEndorsementInfoReply>& result); 151 152 // A blocking implementation of GetAttestationKeyInfo. 153 void GetAttestationKeyInfoTask( 154 const GetAttestationKeyInfoRequest& request, 155 const std::shared_ptr<GetAttestationKeyInfoReply>& result); 156 157 // A blocking implementation of ActivateAttestationKey. 158 void ActivateAttestationKeyTask( 159 const ActivateAttestationKeyRequest& request, 160 const std::shared_ptr<ActivateAttestationKeyReply>& result); 161 162 // A blocking implementation of CreateCertifiableKey. 163 void CreateCertifiableKeyTask( 164 const CreateCertifiableKeyRequest& request, 165 const std::shared_ptr<CreateCertifiableKeyReply>& result); 166 167 // A blocking implementation of Decrypt. 168 void DecryptTask(const DecryptRequest& request, 169 const std::shared_ptr<DecryptReply>& result); 170 171 // A blocking implementation of Sign. 172 void SignTask(const SignRequest& request, 173 const std::shared_ptr<SignReply>& result); 174 175 // A synchronous implementation of RegisterKeyWithChapsToken. 176 void RegisterKeyWithChapsTokenTask( 177 const RegisterKeyWithChapsTokenRequest& request, 178 const std::shared_ptr<RegisterKeyWithChapsTokenReply>& result); 179 180 // Returns true iff all information required for enrollment with the Google 181 // Attestation CA is available. 182 bool IsPreparedForEnrollment(); 183 184 // Returns true iff enrollment with the Google Attestation CA has been 185 // completed. 186 bool IsEnrolled(); 187 188 // Creates an enrollment request compatible with the Google Attestation CA. 189 // Returns true on success. 190 bool CreateEnrollRequest(std::string* enroll_request); 191 192 // Finishes enrollment given an |enroll_response| from the Google Attestation 193 // CA. Returns true on success. On failure, returns false and sets 194 // |server_error| to the error string from the CA. 195 bool FinishEnroll(const std::string& enroll_response, 196 std::string* server_error); 197 198 // Creates a |certificate_request| compatible with the Google Attestation CA 199 // for the given |key|, according to the given |profile|, |username| and 200 // |origin|. 201 bool CreateCertificateRequest(const std::string& username, 202 const CertifiedKey& key, 203 CertificateProfile profile, 204 const std::string& origin, 205 std::string* certificate_request, 206 std::string* message_id); 207 208 // Finishes a certificate request by decoding the |certificate_response| to 209 // recover the |certificate_chain| and storing it in association with the 210 // |key| identified by |username| and |key_label|. Returns true on success. On 211 // failure, returns false and sets |server_error| to the error string from the 212 // CA. 213 bool FinishCertificateRequest(const std::string& certificate_response, 214 const std::string& username, 215 const std::string& key_label, 216 const std::string& message_id, 217 CertifiedKey* key, 218 std::string* certificate_chain, 219 std::string* server_error); 220 221 // Sends a |request_type| |request| to the Google Attestation CA and waits for 222 // the |reply|. Returns true on success. 223 bool SendACARequestAndBlock(ACARequestType request_type, 224 const std::string& request, 225 std::string* reply); 226 227 // Creates, certifies, and saves a new |key| for |username| with the given 228 // |key_label|, |key_type|, and |key_usage|. Returns true on success. 229 bool CreateKey(const std::string& username, 230 const std::string& key_label, 231 KeyType key_type, 232 KeyUsage key_usage, 233 CertifiedKey* key); 234 235 // Finds the |key| associated with |username| and |key_label|. Returns false 236 // if such a key does not exist. 237 bool FindKeyByLabel(const std::string& username, 238 const std::string& key_label, 239 CertifiedKey* key); 240 241 // Saves the |key| associated with |username| and |key_label|. Returns true on 242 // success. 243 bool SaveKey(const std::string& username, 244 const std::string& key_label, 245 const CertifiedKey& key); 246 247 // Deletes the key associated with |username| and |key_label|. 248 void DeleteKey(const std::string& username, 249 const std::string& key_label); 250 251 // Adds named device-wide key to the attestation database. 252 bool AddDeviceKey(const std::string& key_label, const CertifiedKey& key); 253 254 // Removes a device-wide key from the attestation database. 255 void RemoveDeviceKey(const std::string& key_label); 256 257 // Creates a PEM certificate chain from the credential fields of a |key|. 258 std::string CreatePEMCertificateChain(const CertifiedKey& key); 259 260 // Creates a certificate in PEM format from a DER encoded X.509 certificate. 261 std::string CreatePEMCertificate(const std::string& certificate); 262 263 // Chooses a temporal index which will be used by the ACA to create a 264 // certificate. This decision factors in the currently signed-in |user| and 265 // the |origin| of the certificate request. The strategy is to find an index 266 // which has not already been used by another user for the same origin. 267 int ChooseTemporalIndex(const std::string& user, const std::string& origin); 268 269 // Creates a Google Attestation CA URL for the given |request_type|. 270 std::string GetACAURL(ACARequestType request_type) const; 271 272 // Creates a X.509/DER SubjectPublicKeyInfo for the given |key_type| and 273 // |public_key|. On success returns true and provides |public_key_info|. 274 bool GetSubjectPublicKeyInfo(KeyType key_type, 275 const std::string& public_key, 276 std::string* public_key_info) const; 277 278 base::WeakPtr<AttestationService> GetWeakPtr(); 279 280 281 const std::string attestation_ca_origin_; 282 283 // Other than initialization and destruction, these are used only by the 284 // worker thread. 285 CryptoUtility* crypto_utility_{nullptr}; 286 Database* database_{nullptr}; 287 std::shared_ptr<brillo::http::Transport> http_transport_; 288 KeyStore* key_store_{nullptr}; 289 TpmUtility* tpm_utility_{nullptr}; 290 291 // Default implementations for the above interfaces. These will be setup 292 // during Initialize() if the corresponding interface has not been set with a 293 // mutator. 294 std::unique_ptr<CryptoUtilityImpl> default_crypto_utility_; 295 std::unique_ptr<DatabaseImpl> default_database_; 296 std::unique_ptr<Pkcs11KeyStore> default_key_store_; 297 std::unique_ptr<chaps::TokenManagerClient> pkcs11_token_manager_; 298 std::unique_ptr<TpmUtilityV1> default_tpm_utility_; 299 300 // All work is done in the background. This serves to serialize requests and 301 // allow synchronous implementation of complex methods. This is intentionally 302 // declared after the thread-owned members. 303 std::unique_ptr<base::Thread> worker_thread_; 304 305 // Declared last so any weak pointers are destroyed first. 306 base::WeakPtrFactory<AttestationService> weak_factory_; 307 308 DISALLOW_COPY_AND_ASSIGN(AttestationService); 309 }; 310 311 } // namespace attestation 312 313 #endif // ATTESTATION_SERVER_ATTESTATION_SERVICE_H_ 314