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
29namespace 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.
44class 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