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
41namespace 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.
64class 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) { database_ = database; }
100
101  void set_http_transport(
102      const std::shared_ptr<brillo::http::Transport>& transport) {
103    http_transport_ = transport;
104  }
105
106  void set_key_store(KeyStore* key_store) { key_store_ = key_store; }
107
108  void set_tpm_utility(TpmUtility* tpm_utility) { tpm_utility_ = tpm_utility; }
109
110  // So tests don't need to duplicate URL decisions.
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>
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