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. set_crypto_utility(CryptoUtility * crypto_utility)95 void set_crypto_utility(CryptoUtility* crypto_utility) { 96 crypto_utility_ = crypto_utility; 97 } 98 set_database(Database * database)99 void set_database(Database* database) { database_ = database; } 100 set_http_transport(const std::shared_ptr<brillo::http::Transport> & transport)101 void set_http_transport( 102 const std::shared_ptr<brillo::http::Transport>& transport) { 103 http_transport_ = transport; 104 } 105 set_key_store(KeyStore * key_store)106 void set_key_store(KeyStore* key_store) { key_store_ = key_store; } 107 set_tpm_utility(TpmUtility * tpm_utility)108 void set_tpm_utility(TpmUtility* tpm_utility) { tpm_utility_ = tpm_utility; } 109 110 // So tests don't need to duplicate URL decisions. attestation_ca_origin()111 const std::string& attestation_ca_origin() { return attestation_ca_origin_; } 112 113 private: 114 enum ACARequestType { 115 kEnroll, // Enrolls a device, certifying an identity key. 116 kGetCertificate, // Issues a certificate for a TPM-backed key. 117 }; 118 119 // A relay callback which allows the use of weak pointer semantics for a reply 120 // to TaskRunner::PostTaskAndReply. 121 template <typename ReplyProtobufType> TaskRelayCallback(const base::Callback<void (const ReplyProtobufType &)> callback,const std::shared_ptr<ReplyProtobufType> & reply)122 void TaskRelayCallback( 123 const base::Callback<void(const ReplyProtobufType&)> callback, 124 const std::shared_ptr<ReplyProtobufType>& reply) { 125 callback.Run(*reply); 126 } 127 128 // A blocking implementation of CreateGoogleAttestedKey appropriate to run on 129 // the worker thread. 130 void CreateGoogleAttestedKeyTask( 131 const CreateGoogleAttestedKeyRequest& request, 132 const std::shared_ptr<CreateGoogleAttestedKeyReply>& result); 133 134 // A blocking implementation of GetKeyInfo. 135 void GetKeyInfoTask(const GetKeyInfoRequest& request, 136 const std::shared_ptr<GetKeyInfoReply>& result); 137 138 // A blocking implementation of GetEndorsementInfo. 139 void GetEndorsementInfoTask( 140 const GetEndorsementInfoRequest& request, 141 const std::shared_ptr<GetEndorsementInfoReply>& result); 142 143 // A blocking implementation of GetAttestationKeyInfo. 144 void GetAttestationKeyInfoTask( 145 const GetAttestationKeyInfoRequest& request, 146 const std::shared_ptr<GetAttestationKeyInfoReply>& result); 147 148 // A blocking implementation of ActivateAttestationKey. 149 void ActivateAttestationKeyTask( 150 const ActivateAttestationKeyRequest& request, 151 const std::shared_ptr<ActivateAttestationKeyReply>& result); 152 153 // A blocking implementation of CreateCertifiableKey. 154 void CreateCertifiableKeyTask( 155 const CreateCertifiableKeyRequest& request, 156 const std::shared_ptr<CreateCertifiableKeyReply>& result); 157 158 // A blocking implementation of Decrypt. 159 void DecryptTask(const DecryptRequest& request, 160 const std::shared_ptr<DecryptReply>& result); 161 162 // A blocking implementation of Sign. 163 void SignTask(const SignRequest& request, 164 const std::shared_ptr<SignReply>& result); 165 166 // A synchronous implementation of RegisterKeyWithChapsToken. 167 void RegisterKeyWithChapsTokenTask( 168 const RegisterKeyWithChapsTokenRequest& request, 169 const std::shared_ptr<RegisterKeyWithChapsTokenReply>& result); 170 171 // Returns true iff all information required for enrollment with the Google 172 // Attestation CA is available. 173 bool IsPreparedForEnrollment(); 174 175 // Returns true iff enrollment with the Google Attestation CA has been 176 // completed. 177 bool IsEnrolled(); 178 179 // Creates an enrollment request compatible with the Google Attestation CA. 180 // Returns true on success. 181 bool CreateEnrollRequest(std::string* enroll_request); 182 183 // Finishes enrollment given an |enroll_response| from the Google Attestation 184 // CA. Returns true on success. On failure, returns false and sets 185 // |server_error| to the error string from the CA. 186 bool FinishEnroll(const std::string& enroll_response, 187 std::string* server_error); 188 189 // Creates a |certificate_request| compatible with the Google Attestation CA 190 // for the given |key|, according to the given |profile|, |username| and 191 // |origin|. 192 bool CreateCertificateRequest(const std::string& username, 193 const CertifiedKey& key, 194 CertificateProfile profile, 195 const std::string& origin, 196 std::string* certificate_request, 197 std::string* message_id); 198 199 // Finishes a certificate request by decoding the |certificate_response| to 200 // recover the |certificate_chain| and storing it in association with the 201 // |key| identified by |username| and |key_label|. Returns true on success. On 202 // failure, returns false and sets |server_error| to the error string from the 203 // CA. 204 bool FinishCertificateRequest(const std::string& certificate_response, 205 const std::string& username, 206 const std::string& key_label, 207 const std::string& message_id, 208 CertifiedKey* key, 209 std::string* certificate_chain, 210 std::string* server_error); 211 212 // Sends a |request_type| |request| to the Google Attestation CA and waits for 213 // the |reply|. Returns true on success. 214 bool SendACARequestAndBlock(ACARequestType request_type, 215 const std::string& request, 216 std::string* reply); 217 218 // Creates, certifies, and saves a new |key| for |username| with the given 219 // |key_label|, |key_type|, and |key_usage|. Returns true on success. 220 bool CreateKey(const std::string& username, 221 const std::string& key_label, 222 KeyType key_type, 223 KeyUsage key_usage, 224 CertifiedKey* key); 225 226 // Finds the |key| associated with |username| and |key_label|. Returns false 227 // if such a key does not exist. 228 bool FindKeyByLabel(const std::string& username, 229 const std::string& key_label, 230 CertifiedKey* key); 231 232 // Saves the |key| associated with |username| and |key_label|. Returns true on 233 // success. 234 bool SaveKey(const std::string& username, 235 const std::string& key_label, 236 const CertifiedKey& key); 237 238 // Deletes the key associated with |username| and |key_label|. 239 void DeleteKey(const std::string& username, const std::string& key_label); 240 241 // Adds named device-wide key to the attestation database. 242 bool AddDeviceKey(const std::string& key_label, const CertifiedKey& key); 243 244 // Removes a device-wide key from the attestation database. 245 void RemoveDeviceKey(const std::string& key_label); 246 247 // Creates a PEM certificate chain from the credential fields of a |key|. 248 std::string CreatePEMCertificateChain(const CertifiedKey& key); 249 250 // Creates a certificate in PEM format from a DER encoded X.509 certificate. 251 std::string CreatePEMCertificate(const std::string& certificate); 252 253 // Chooses a temporal index which will be used by the ACA to create a 254 // certificate. This decision factors in the currently signed-in |user| and 255 // the |origin| of the certificate request. The strategy is to find an index 256 // which has not already been used by another user for the same origin. 257 int ChooseTemporalIndex(const std::string& user, const std::string& origin); 258 259 // Creates a Google Attestation CA URL for the given |request_type|. 260 std::string GetACAURL(ACARequestType request_type) const; 261 262 // Creates a X.509/DER SubjectPublicKeyInfo for the given |key_type| and 263 // |public_key|. On success returns true and provides |public_key_info|. 264 bool GetSubjectPublicKeyInfo(KeyType key_type, 265 const std::string& public_key, 266 std::string* public_key_info) const; 267 268 base::WeakPtr<AttestationService> GetWeakPtr(); 269 270 const std::string attestation_ca_origin_; 271 272 // Other than initialization and destruction, these are used only by the 273 // worker thread. 274 CryptoUtility* crypto_utility_{nullptr}; 275 Database* database_{nullptr}; 276 std::shared_ptr<brillo::http::Transport> http_transport_; 277 KeyStore* key_store_{nullptr}; 278 TpmUtility* tpm_utility_{nullptr}; 279 280 // Default implementations for the above interfaces. These will be setup 281 // during Initialize() if the corresponding interface has not been set with a 282 // mutator. 283 std::unique_ptr<CryptoUtilityImpl> default_crypto_utility_; 284 std::unique_ptr<DatabaseImpl> default_database_; 285 std::unique_ptr<Pkcs11KeyStore> default_key_store_; 286 std::unique_ptr<chaps::TokenManagerClient> pkcs11_token_manager_; 287 std::unique_ptr<TpmUtilityV1> default_tpm_utility_; 288 289 // All work is done in the background. This serves to serialize requests and 290 // allow synchronous implementation of complex methods. This is intentionally 291 // declared after the thread-owned members. 292 std::unique_ptr<base::Thread> worker_thread_; 293 294 // Declared last so any weak pointers are destroyed first. 295 base::WeakPtrFactory<AttestationService> weak_factory_; 296 297 DISALLOW_COPY_AND_ASSIGN(AttestationService); 298 }; 299 300 } // namespace attestation 301 302 #endif // ATTESTATION_SERVER_ATTESTATION_SERVICE_H_ 303