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