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