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) { 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