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