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_PKCS11_KEY_STORE_H_
18 #define ATTESTATION_SERVER_PKCS11_KEY_STORE_H_
19 
20 #include "attestation/server/key_store.h"
21 
22 #include <string>
23 
24 #include <base/callback_forward.h>
25 #include <base/macros.h>
26 #include <chaps/pkcs11/cryptoki.h>
27 #include <chaps/token_manager_client.h>
28 
29 namespace attestation {
30 
31 // This class uses a PKCS #11 token as storage for key data.  The key data is
32 // stored in data objects with the following attributes:
33 // CKA_CLASS - CKO_DATA
34 // CKA_LABEL - A key name.
35 // CKA_VALUE - Binary key data (opaque to this class and the PKCS #11 token).
36 // CKA_APPLICATION - A constant value associated with this class.
37 // CKA_TOKEN - True
38 // CKA_PRIVATE - True
39 // CKA_MODIFIABLE - False
40 // There is no barrier between the objects created by this class and any other
41 // objects residing in the same token.  In practice, this means that any
42 // component with access to the PKCS #11 token also has access to read or delete
43 // key data.
44 class Pkcs11KeyStore : public KeyStore {
45  public:
46   // Does not take ownership of pointers.
47   explicit Pkcs11KeyStore(chaps::TokenManagerClient* token_manager);
48   ~Pkcs11KeyStore() override;
49 
50   // KeyStore interface.
51   bool Read(const std::string& username,
52             const std::string& key_name,
53             std::string* key_data) override;
54   bool Write(const std::string& username,
55              const std::string& key_name,
56              const std::string& key_data) override;
57   bool Delete(const std::string& username,
58               const std::string& key_name) override;
59   bool DeleteByPrefix(const std::string& username,
60                       const std::string& key_prefix) override;
61   bool Register(const std::string& username,
62                 const std::string& label,
63                 KeyType key_type,
64                 KeyUsage key_usage,
65                 const std::string& private_key_blob,
66                 const std::string& public_key_der,
67                 const std::string& certificate) override;
68   bool RegisterCertificate(const std::string& username,
69                            const std::string& certificate) override;
70 
71  private:
72   using EnumObjectsCallback =
73       base::Callback<bool(const std::string& key_name,
74                           CK_OBJECT_HANDLE object_handle)>;
75 
76   // Searches for a PKCS #11 object for a given key name.  If one exists, the
77   // object handle is returned, otherwise CK_INVALID_HANDLE is returned.
78   CK_OBJECT_HANDLE FindObject(CK_SESSION_HANDLE session_handle,
79                               const std::string& key_name);
80 
81   // Gets a slot for the given |username| if |is_user_specific| or the system
82   // slot otherwise. Returns false if no appropriate slot is found.
83   bool GetUserSlot(const std::string& username, CK_SLOT_ID_PTR slot);
84 
85   // Enumerates all PKCS #11 objects associated with keys.  The |callback| is
86   // called once for each object.
87   bool EnumObjects(CK_SESSION_HANDLE session_handle,
88                    const EnumObjectsCallback& callback);
89 
90   // Looks up the key name for the given |object_handle| which is associated
91   // with a key.  Returns true on success.
92   bool GetKeyName(CK_SESSION_HANDLE session_handle,
93                   CK_OBJECT_HANDLE object_handle,
94                   std::string* key_name);
95 
96   // An EnumObjectsCallback for use with DeleteByPrefix.  Destroys the key
97   // object identified by |object_handle| if |key_name| matches |key_prefix|.
98   // Returns true on success.
99   bool DeleteIfMatchesPrefix(CK_SESSION_HANDLE session_handle,
100                              const std::string& key_prefix,
101                              const std::string& key_name,
102                              CK_OBJECT_HANDLE object_handle);
103 
104   // Extracts the |subject|, |issuer|, and |serial_number| information from an
105   // X.509 |certificate|. Returns false if the value cannot be determined.
106   bool GetCertificateFields(const std::string& certificate,
107                             std::string* subject,
108                             std::string* issuer,
109                             std::string* serial_number);
110 
111   // Returns true iff the given certificate already exists in the token.
112   bool DoesCertificateExist(CK_SESSION_HANDLE session_handle,
113                             const std::string& certificate);
114 
115   chaps::TokenManagerClient* token_manager_;
116 
117   DISALLOW_COPY_AND_ASSIGN(Pkcs11KeyStore);
118 };
119 
120 }  // namespace attestation
121 
122 #endif  // ATTESTATION_SERVER_PKCS11_KEY_STORE_H_
123