pkcs11_key_store_test.cc revision f71393a1fa1b6f036bcc74b770d044845d9dee07
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#include "attestation/server/pkcs11_key_store.h"
18
19#include <map>
20#include <string>
21#include <vector>
22
23#include <base/logging.h>
24#include <base/strings/string_number_conversions.h>
25#include <chaps/attributes.h>
26#include <chaps/chaps_proxy_mock.h>
27#include <chaps/token_manager_client_mock.h>
28#include <brillo/cryptohome.h>
29#include <brillo/map_utils.h>
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32
33using ::testing::_;
34using ::testing::DoAll;
35using ::testing::Invoke;
36using ::testing::NiceMock;
37using ::testing::Return;
38using ::testing::SetArgumentPointee;
39
40namespace {
41
42const uint64_t kSession = 7;  // Arbitrary non-zero value.
43const char kDefaultUser[] = "test_user";
44
45const char kValidPublicKeyHex[] =
46    "3082010A0282010100"
47    "961037BC12D2A298BEBF06B2D5F8C9B64B832A2237F8CF27D5F96407A6041A4D"
48    "AD383CB5F88E625F412E8ACD5E9D69DF0F4FA81FCE7955829A38366CBBA5A2B1"
49    "CE3B48C14B59E9F094B51F0A39155874C8DE18A0C299EBF7A88114F806BE4F25"
50    "3C29A509B10E4B19E31675AFE3B2DA77077D94F43D8CE61C205781ED04D183B4"
51    "C349F61B1956C64B5398A3A98FAFF17D1B3D9120C832763EDFC8F4137F6EFBEF"
52    "46D8F6DE03BD00E49DEF987C10BDD5B6F8758B6A855C23C982DDA14D8F0F2B74"
53    "E6DEFA7EEE5A6FC717EB0FF103CB8049F693A2C8A5039EF1F5C025DC44BD8435"
54    "E8D8375DADE00E0C0F5C196E04B8483CC98B1D5B03DCD7E0048B2AB343FFC11F"
55    "0203"
56    "010001";
57
58const char kValidCertificateHex[] =
59    "3082040f308202f7a003020102020900bd0f8fd6bf496b67300d06092a864886"
60    "f70d01010b050030819d310b3009060355040613025553311330110603550408"
61    "0c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e20"
62    "5669657731133011060355040a0c0a4368726f6d69756d4f533111300f060355"
63    "040b0c08556e6974546573743117301506035504030c0e506b637331314b6579"
64    "53746f72653120301e06092a864886f70d010901161174657374406368726f6d"
65    "69756d2e6f7267301e170d3135303231383137303132345a170d313731313133"
66    "3137303132345a30819d310b3009060355040613025553311330110603550408"
67    "0c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e20"
68    "5669657731133011060355040a0c0a4368726f6d69756d4f533111300f060355"
69    "040b0c08556e6974546573743117301506035504030c0e506b637331314b6579"
70    "53746f72653120301e06092a864886f70d010901161174657374406368726f6d"
71    "69756d2e6f726730820122300d06092a864886f70d01010105000382010f0030"
72    "82010a0282010100a8fb9e12b1e5298b9a24fabc3901d00c32057392c763836e"
73    "0b55cff8e67d39b9b9853920fd615688b3e13c03a10cb5668187819172d1d269"
74    "70f0ff8d4371ac581f6970a0e43a1d0d61a94741a771fe86aee45ab0ca059b1f"
75    "c067f7416f08544cc4d08ec884b6d4327bb3ec0dc0789639375bd159df0efd87"
76    "1cf4d605778c7a68c96b94cf0a6c29f9a23bc027e8250084eb2dfca817b20f57"
77    "a6fe09513f884389db7b90788aea70c6e1638f24e39553ac0f859e585965c425"
78    "9ed7b9680fde3e059f254d8c9494f6ab425ede80d63366dfcb7cc311f5bc6fb0"
79    "1c27d81f4c5112d04b7614c37ba19c014916816372c773e4e44564fac34565ad"
80    "ebf38fe56c1413170203010001a350304e301d0603551d0e04160414fe13c7db"
81    "459bd2881e9113198e1f072e16cea144301f0603551d23041830168014fe13c7"
82    "db459bd2881e9113198e1f072e16cea144300c0603551d13040530030101ff30"
83    "0d06092a864886f70d01010b05000382010100a163d636ac64bd6f67eca53708"
84    "5f92abc993a40fd0c0222a56b262c29f88057a3edf9abac024756ad85d7453d8"
85    "4782e0be65d176aecfb0fbfc88ca567d17124fa190cb5ce832264360dd6daee1"
86    "e121428de28dda0b8ba117a1be3cf438efd060a3b5fc812e7eba70cec12cb609"
87    "738fc7d0912546c42b5aaadb142adce2167c7f30cd9e0049687d384334335aff"
88    "72aebd1745a0aac4be816365969347f064f36f7fdec69f970f28b87061650470"
89    "c63be8475bb23d0485985fb77c7cdd9d9fe008211a9ddd0fe68efb0b47cf629c"
90    "941d31e3c2f88e670e7e4ef1129febad000e6a16222779fbfe34641e5243ca38"
91    "74e2ad06f9585a00bec014744d3175ecc4808d";
92
93std::string HexDecode(const std::string hex) {
94  std::vector<uint8_t> output;
95  CHECK(base::HexStringToBytes(hex, &output));
96  return std::string(reinterpret_cast<char*>(output.data()), output.size());
97}
98
99class ScopedFakeSalt {
100 public:
101  ScopedFakeSalt() : salt_(128, 0) {
102    brillo::cryptohome::home::SetSystemSalt(&salt_);
103  }
104  ~ScopedFakeSalt() {
105    brillo::cryptohome::home::SetSystemSalt(nullptr);
106  }
107
108 private:
109  std::string salt_;
110};
111
112class ScopedDisableVerboseLogging {
113 public:
114  ScopedDisableVerboseLogging()
115      : original_severity_(logging::GetMinLogLevel()) {
116    logging::SetMinLogLevel(logging::LOG_INFO);
117  }
118  ~ScopedDisableVerboseLogging() {
119    logging::SetMinLogLevel(original_severity_);
120  }
121
122 private:
123  logging::LogSeverity original_severity_;
124};
125
126}  // namespace
127
128namespace attestation {
129
130typedef chaps::ChapsProxyMock Pkcs11Mock;
131
132// Implements a fake PKCS #11 object store.  Labeled data blobs can be stored
133// and later retrieved.  The mocked interface is ChapsInterface so these
134// tests must be linked with the Chaps PKCS #11 library.  The mock class itself
135// is part of the Chaps package; it is reused here to avoid duplication (see
136// chaps_proxy_mock.h).
137class KeyStoreTest : public testing::Test {
138 public:
139  KeyStoreTest()
140      : pkcs11_(false),  // Do not pre-initialize the mock PKCS #11 library.
141                         // This just controls whether the first call to
142                         // C_Initialize returns 'already initialized'.
143        next_handle_(1) {}
144  ~KeyStoreTest() override = default;
145
146  void SetUp() override {
147    std::vector<uint64_t> slot_list = {0, 1};
148    ON_CALL(pkcs11_, GetSlotList(_, _, _))
149        .WillByDefault(DoAll(SetArgumentPointee<2>(slot_list), Return(0)));
150    ON_CALL(pkcs11_, OpenSession(_, _, _, _))
151        .WillByDefault(DoAll(SetArgumentPointee<3>(kSession), Return(0)));
152    ON_CALL(pkcs11_, CloseSession(_, _))
153        .WillByDefault(Return(0));
154    ON_CALL(pkcs11_, CreateObject(_, _, _, _))
155        .WillByDefault(Invoke(this, &KeyStoreTest::CreateObject));
156    ON_CALL(pkcs11_, DestroyObject(_, _, _))
157        .WillByDefault(Invoke(this, &KeyStoreTest::DestroyObject));
158    ON_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
159        .WillByDefault(Invoke(this, &KeyStoreTest::GetAttributeValue));
160    ON_CALL(pkcs11_, SetAttributeValue(_, _, _, _))
161        .WillByDefault(Invoke(this, &KeyStoreTest::SetAttributeValue));
162    ON_CALL(pkcs11_, FindObjectsInit(_, _, _))
163        .WillByDefault(Invoke(this, &KeyStoreTest::FindObjectsInit));
164    ON_CALL(pkcs11_, FindObjects(_, _, _, _))
165        .WillByDefault(Invoke(this, &KeyStoreTest::FindObjects));
166    ON_CALL(pkcs11_, FindObjectsFinal(_, _))
167        .WillByDefault(Return(0));
168    base::FilePath system_path("/var/lib/chaps");
169    ON_CALL(token_manager_, GetTokenPath(_, 0, _))
170        .WillByDefault(DoAll(SetArgumentPointee<2>(system_path), Return(true)));
171    base::FilePath user_path(brillo::cryptohome::home::GetDaemonPath(
172        kDefaultUser, "chaps"));
173    ON_CALL(token_manager_, GetTokenPath(_, 1, _))
174        .WillByDefault(DoAll(SetArgumentPointee<2>(user_path), Return(true)));
175  }
176
177  // Stores a new labeled object, only CKA_LABEL and CKA_VALUE are relevant.
178  virtual uint32_t CreateObject(const brillo::SecureBlob& isolate,
179                                uint64_t session_id,
180                                const std::vector<uint8_t>& attributes,
181                                uint64_t* new_object_handle) {
182    *new_object_handle = next_handle_++;
183    std::string label = GetValue(attributes, CKA_LABEL);
184    handles_[*new_object_handle] = label;
185    values_[label] = GetValue(attributes, CKA_VALUE);
186    labels_[label] = *new_object_handle;
187    return CKR_OK;
188  }
189
190  // Deletes a labeled object.
191  virtual uint32_t DestroyObject(const brillo::SecureBlob& isolate,
192                                 uint64_t session_id,
193                                 uint64_t object_handle) {
194    std::string label = handles_[object_handle];
195    handles_.erase(object_handle);
196    values_.erase(label);
197    labels_.erase(label);
198    return CKR_OK;
199  }
200
201  // Supports reading CKA_VALUE.
202  virtual uint32_t GetAttributeValue(const brillo::SecureBlob& isolate,
203                                     uint64_t session_id,
204                                     uint64_t object_handle,
205                                     const std::vector<uint8_t>& attributes_in,
206                                     std::vector<uint8_t>* attributes_out) {
207    std::string label = handles_[object_handle];
208    std::string value = values_[label];
209    chaps::Attributes parsed;
210    parsed.Parse(attributes_in);
211    if (parsed.num_attributes() == 1 &&
212        parsed.attributes()[0].type == CKA_LABEL)
213      value = label;
214    if (parsed.num_attributes() != 1 ||
215        (parsed.attributes()[0].type != CKA_VALUE &&
216         parsed.attributes()[0].type != CKA_LABEL) ||
217        (parsed.attributes()[0].pValue &&
218         parsed.attributes()[0].ulValueLen != value.size()))
219      return CKR_GENERAL_ERROR;
220    parsed.attributes()[0].ulValueLen = value.size();
221    if (parsed.attributes()[0].pValue)
222      memcpy(parsed.attributes()[0].pValue, value.data(), value.size());
223    parsed.Serialize(attributes_out);
224    return CKR_OK;
225  }
226
227  // Supports writing CKA_VALUE.
228  virtual uint32_t SetAttributeValue(
229      const brillo::SecureBlob& isolate,
230      uint64_t session_id,
231      uint64_t object_handle,
232      const std::vector<uint8_t>& attributes) {
233    values_[handles_[object_handle]] = GetValue(attributes, CKA_VALUE);
234    return CKR_OK;
235  }
236
237  // Finds stored objects by CKA_LABEL or CKA_VALUE. If no CKA_LABEL or
238  // CKA_VALUE, find all objects.
239  virtual uint32_t FindObjectsInit(const brillo::SecureBlob& isolate,
240                                   uint64_t session_id,
241                                   const std::vector<uint8_t>& attributes) {
242    std::string label = GetValue(attributes, CKA_LABEL);
243    std::string value = GetValue(attributes, CKA_VALUE);
244    found_objects_.clear();
245    if (label.empty() && value.empty()) {
246      // Find all objects.
247      found_objects_ = brillo::GetMapKeysAsVector(handles_);
248    } else if (!label.empty() && labels_.count(label) > 0) {
249      // Find only the object with |label|.
250      found_objects_.push_back(labels_[label]);
251    } else {
252      // Find all objects with |value|.
253      for (const auto& item : values_) {
254        if (item.second == value && labels_.count(item.first) > 0) {
255          found_objects_.push_back(labels_[item.first]);
256        }
257      }
258    }
259    return CKR_OK;
260  }
261
262  // Reports a 'found' object based on find_status_.
263  virtual uint32_t FindObjects(const brillo::SecureBlob& isolate,
264                               uint64_t session_id,
265                               uint64_t max_object_count,
266                               std::vector<uint64_t>* object_list) {
267    while (!found_objects_.empty() && object_list->size() < max_object_count) {
268      object_list->push_back(found_objects_.back());
269      found_objects_.pop_back();
270    }
271    return CKR_OK;
272  }
273
274 protected:
275  NiceMock<Pkcs11Mock> pkcs11_;
276  NiceMock<chaps::TokenManagerClientMock> token_manager_;
277
278 private:
279  // A helper to pull the value for a given attribute out of a serialized
280  // template.
281  std::string GetValue(const std::vector<uint8_t>& attributes,
282                       CK_ATTRIBUTE_TYPE type) {
283    chaps::Attributes parsed;
284    parsed.Parse(attributes);
285    CK_ATTRIBUTE_PTR array = parsed.attributes();
286    for (CK_ULONG i = 0; i < parsed.num_attributes(); ++i) {
287      if (array[i].type == type) {
288        if (!array[i].pValue)
289          return "";
290        return std::string(reinterpret_cast<char*>(array[i].pValue),
291                           array[i].ulValueLen);
292      }
293    }
294    return "";
295  }
296
297  std::map<std::string, std::string> values_;  // The fake store: label->value
298  std::map<uint64_t, std::string> handles_;    // The fake store: handle->label
299  std::map<std::string, uint64_t> labels_;     // The fake store: label->handle
300  std::vector<uint64_t> found_objects_;        // The most recent search results
301  uint64_t next_handle_;                       // Tracks handle assignment
302  ScopedFakeSalt fake_system_salt_;
303  // We want to avoid all the Chaps verbose logging.
304  ScopedDisableVerboseLogging no_verbose_logging;
305
306  DISALLOW_COPY_AND_ASSIGN(KeyStoreTest);
307};
308
309// This test assumes that chaps in not available on the system running the test.
310// The purpose of this test is to exercise the C_Initialize failure code path.
311// Without a mock, the Chaps library will attempt to connect to the Chaps daemon
312// unsuccessfully, resulting in a C_Initialize failure.
313TEST(KeyStoreTest_NoMock, Pkcs11NotAvailable) {
314  chaps::TokenManagerClient token_manager;
315  Pkcs11KeyStore key_store(&token_manager);
316  std::string blob;
317  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
318  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", blob));
319  EXPECT_FALSE(key_store.Read("", "test", &blob));
320  EXPECT_FALSE(key_store.Write("", "test", blob));
321}
322
323// Exercises the key store when PKCS #11 returns success.  This exercises all
324// non-error-handling code paths.
325TEST_F(KeyStoreTest, Pkcs11Success) {
326  Pkcs11KeyStore key_store(&token_manager_);
327  std::string blob;
328  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
329  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
330  EXPECT_TRUE(key_store.Read(kDefaultUser, "test", &blob));
331  EXPECT_EQ("test_data", blob);
332  // Try with a different key name.
333  EXPECT_FALSE(key_store.Read(kDefaultUser, "test2", &blob));
334  EXPECT_TRUE(key_store.Write(kDefaultUser, "test2", "test_data2"));
335  EXPECT_TRUE(key_store.Read(kDefaultUser, "test2", &blob));
336  EXPECT_EQ("test_data2", blob);
337  // Read the original key again.
338  EXPECT_TRUE(key_store.Read(kDefaultUser, "test", &blob));
339  EXPECT_EQ("test_data", blob);
340  // Replace key data.
341  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data3"));
342  EXPECT_TRUE(key_store.Read(kDefaultUser, "test", &blob));
343  EXPECT_EQ("test_data3", blob);
344  // Delete key data.
345  EXPECT_TRUE(key_store.Delete(kDefaultUser, "test2"));
346  EXPECT_FALSE(key_store.Read(kDefaultUser, "test2", &blob));
347  EXPECT_TRUE(key_store.Read(kDefaultUser, "test", &blob));
348}
349
350TEST_F(KeyStoreTest, Pkcs11Success_NoUser) {
351  Pkcs11KeyStore key_store(&token_manager_);
352  std::string blob;
353  EXPECT_FALSE(key_store.Read("", "test", &blob));
354  EXPECT_TRUE(key_store.Write("", "test", "test_data"));
355  EXPECT_TRUE(key_store.Read("", "test", &blob));
356  EXPECT_EQ("test_data", blob);
357  // Try with a different key name.
358  EXPECT_FALSE(key_store.Read("", "test2", &blob));
359  EXPECT_TRUE(key_store.Write("", "test2", "test_data2"));
360  EXPECT_TRUE(key_store.Read("", "test2", &blob));
361  EXPECT_EQ("test_data2", blob);
362  // Read the original key again.
363  EXPECT_TRUE(key_store.Read("", "test", &blob));
364  EXPECT_EQ("test_data", blob);
365  // Replace key data.
366  EXPECT_TRUE(key_store.Write("", "test", "test_data3"));
367  EXPECT_TRUE(key_store.Read("", "test", &blob));
368  EXPECT_EQ("test_data3", blob);
369  // Delete key data.
370  EXPECT_TRUE(key_store.Delete("", "test2"));
371  EXPECT_FALSE(key_store.Read("", "test2", &blob));
372  EXPECT_TRUE(key_store.Read("", "test", &blob));
373}
374
375// Tests the key store when PKCS #11 has no token for the given user.
376TEST_F(KeyStoreTest, TokenNotAvailable) {
377  EXPECT_CALL(token_manager_, GetTokenPath(_, _, _))
378      .WillRepeatedly(Return(false));
379  Pkcs11KeyStore key_store(&token_manager_);
380  std::string blob;
381  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
382  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", blob));
383  EXPECT_FALSE(key_store.Read("", "test", &blob));
384  EXPECT_FALSE(key_store.Write("", "test", blob));
385}
386
387// Tests the key store when PKCS #11 fails to open a session.
388TEST_F(KeyStoreTest, NoSession) {
389  EXPECT_CALL(pkcs11_, OpenSession(_, _, _, _))
390      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
391  Pkcs11KeyStore key_store(&token_manager_);
392  std::string blob;
393  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", "test_data"));
394  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
395}
396
397// Tests the key store when PKCS #11 fails to create an object.
398TEST_F(KeyStoreTest, CreateObjectFail) {
399  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
400      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
401  Pkcs11KeyStore key_store(&token_manager_);
402  std::string blob;
403  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", "test_data"));
404  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
405}
406
407// Tests the key store when PKCS #11 fails to read attribute values.
408TEST_F(KeyStoreTest, ReadValueFail) {
409  EXPECT_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
410      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
411  Pkcs11KeyStore key_store(&token_manager_);
412  std::string blob;
413  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
414  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
415}
416
417// Tests the key store when PKCS #11 fails to delete key data.
418TEST_F(KeyStoreTest, DeleteValueFail) {
419  EXPECT_CALL(pkcs11_, DestroyObject(_, _, _))
420      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
421  Pkcs11KeyStore key_store(&token_manager_);
422  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
423  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", "test_data2"));
424  EXPECT_FALSE(key_store.Delete(kDefaultUser, "test"));
425}
426
427// Tests the key store when PKCS #11 fails to find objects.  Tests each part of
428// the multi-part find operation individually.
429TEST_F(KeyStoreTest, FindFail) {
430  EXPECT_CALL(pkcs11_, FindObjectsInit(_, _, _))
431      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
432  Pkcs11KeyStore key_store(&token_manager_);
433  std::string blob;
434  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
435  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
436
437  EXPECT_CALL(pkcs11_, FindObjectsInit(_, _, _))
438      .WillRepeatedly(Return(CKR_OK));
439  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
440      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
441  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
442  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
443
444  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
445      .WillRepeatedly(Return(CKR_OK));
446  EXPECT_CALL(pkcs11_, FindObjectsFinal(_, _))
447      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
448  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
449  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
450}
451
452// Tests the key store when PKCS #11 successfully finds zero objects.
453TEST_F(KeyStoreTest, FindNoObjects) {
454  std::vector<uint64_t> empty;
455  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
456      .WillRepeatedly(DoAll(SetArgumentPointee<3>(empty), Return(CKR_OK)));
457  Pkcs11KeyStore key_store(&token_manager_);
458  std::string blob;
459  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
460  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
461}
462
463TEST_F(KeyStoreTest, RegisterKeyWithoutCertificate) {
464  Pkcs11KeyStore key_store(&token_manager_);
465  // Try with a malformed public key.
466  EXPECT_FALSE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
467                                  KEY_USAGE_SIGN, "private_key_blob",
468                                  "bad_pubkey", ""));
469  // Try with a well-formed public key.
470  std::string public_key_der = HexDecode(kValidPublicKeyHex);
471  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
472      .Times(2)  // Public, private (no certificate).
473      .WillRepeatedly(Return(CKR_OK));
474  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
475                                 KEY_USAGE_SIGN, "private_key_blob",
476                                 public_key_der, ""));
477}
478
479TEST_F(KeyStoreTest, RegisterKeyWithCertificate) {
480  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
481      .Times(3)  // Public, private, and certificate.
482      .WillRepeatedly(Return(CKR_OK));
483  Pkcs11KeyStore key_store(&token_manager_);
484  std::string public_key_der = HexDecode(kValidPublicKeyHex);
485  std::string certificate_der = HexDecode(kValidCertificateHex);
486  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
487                                 KEY_USAGE_SIGN, "private_key_blob",
488                                 public_key_der, certificate_der));
489  // Also try with the system token.
490  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
491      .Times(3)  // Public, private, and certificate.
492      .WillRepeatedly(Return(CKR_OK));
493  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
494                                 KEY_USAGE_SIGN, "private_key_blob",
495                                 public_key_der, certificate_der));
496}
497
498TEST_F(KeyStoreTest, RegisterKeyWithBadCertificate) {
499  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
500      .Times(3)  // Public, private, and certificate.
501      .WillRepeatedly(Return(CKR_OK));
502  Pkcs11KeyStore key_store(&token_manager_);
503  std::string public_key_der = HexDecode(kValidPublicKeyHex);
504  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
505                                 KEY_USAGE_SIGN, "private_key_blob",
506                                 public_key_der, "bad_certificate"));
507}
508
509TEST_F(KeyStoreTest, RegisterWithUnsupportedKeyType) {
510  Pkcs11KeyStore key_store(&token_manager_);
511  std::string public_key_der = HexDecode(kValidPublicKeyHex);
512  EXPECT_FALSE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_ECC,
513                                  KEY_USAGE_SIGN, "private_key_blob",
514                                  public_key_der, ""));
515}
516
517TEST_F(KeyStoreTest, RegisterDecryptionKey) {
518  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
519      .WillRepeatedly(Return(CKR_OK));
520  Pkcs11KeyStore key_store(&token_manager_);
521  std::string public_key_der = HexDecode(kValidPublicKeyHex);
522  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
523                                 KEY_USAGE_DECRYPT, "private_key_blob",
524                                 public_key_der, ""));
525}
526
527TEST_F(KeyStoreTest, RegisterCertificate) {
528  Pkcs11KeyStore key_store(&token_manager_);
529  std::string certificate_der = HexDecode(kValidCertificateHex);
530  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
531      .Times(2);  // Once for valid, once for invalid.
532  // Try with a valid certificate (hit multiple times to check dup logic).
533  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
534  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
535  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
536  // Try with an invalid certificate.
537  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, "bad_certificate"));
538}
539
540TEST_F(KeyStoreTest, RegisterCertificateError) {
541  Pkcs11KeyStore key_store(&token_manager_);
542  std::string certificate_der = HexDecode(kValidCertificateHex);
543  // Handle an error from PKCS #11.
544  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
545      .WillOnce(Return(CKR_GENERAL_ERROR));
546  EXPECT_FALSE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
547}
548
549TEST_F(KeyStoreTest, RegisterCertificateSystemToken) {
550  Pkcs11KeyStore key_store(&token_manager_);
551  std::string certificate_der = HexDecode(kValidCertificateHex);
552  // Try with the system token.
553  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
554      .WillOnce(Return(CKR_OK));
555  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
556}
557
558// Tests that the DeleteByPrefix() method removes the correct objects and only
559// the correct objects.
560TEST_F(KeyStoreTest, DeleteByPrefix) {
561  Pkcs11KeyStore key_store(&token_manager_);
562
563  // Test with no keys.
564  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultUser, "prefix"));
565
566  // Test with a single matching key.
567  ASSERT_TRUE(key_store.Write(kDefaultUser, "prefix_test", "test"));
568  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultUser, "prefix"));
569  std::string blob;
570  EXPECT_FALSE(key_store.Read(kDefaultUser, "prefix_test", &blob));
571
572  // Test with a single non-matching key.
573  ASSERT_TRUE(key_store.Write(kDefaultUser, "_prefix_", "test"));
574  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultUser, "prefix"));
575  EXPECT_TRUE(key_store.Read(kDefaultUser, "_prefix_", &blob));
576
577  // Test with an empty prefix.
578  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultUser, ""));
579  EXPECT_FALSE(key_store.Read(kDefaultUser, "_prefix_", &blob));
580
581  // Test with multiple matching and non-matching keys.
582  const int kNumKeys = 110;  // Pkcs11KeyStore max is 100 for FindObjects.
583  key_store.Write(kDefaultUser, "other1", "test");
584  for (int i = 0; i < kNumKeys; ++i) {
585    std::string key_name = std::string("prefix") + base::IntToString(i);
586    key_store.Write(kDefaultUser, key_name, std::string(key_name));
587  }
588  ASSERT_TRUE(key_store.Write(kDefaultUser, "other2", "test"));
589  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultUser, "prefix"));
590  EXPECT_TRUE(key_store.Read(kDefaultUser, "other1", &blob));
591  EXPECT_TRUE(key_store.Read(kDefaultUser, "other2", &blob));
592  for (int i = 0; i < kNumKeys; ++i) {
593    std::string key_name = std::string("prefix") + base::IntToString(i);
594    EXPECT_FALSE(key_store.Read(kDefaultUser, key_name, &blob));
595  }
596}
597
598}  // namespace attestation
599