Home | History | Annotate | Download | only in server
      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