2 * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved
4 * Contact: Kyungwook Tak <k.tak@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
23 #include <boost/test/unit_test.hpp>
24 #include <test_common.h>
25 #include <DBFixture.h>
30 static void copyFile(const char *src, const char *dst)
32 std::ifstream f1(src, std::fstream::binary);
33 std::ofstream f2(dst, std::fstream::trunc | std::fstream::binary);
41 void DBFixture::unlinkDb()
43 for (const auto f : {m_crypto_legacy_db_fname, m_crypto_db_fname})
44 BOOST_REQUIRE_MESSAGE(!unlink(f) || errno == ENOENT, "unlink " << f);
47 DBFixture::DBFixture(DBCryptoThrows dbCryptoThrows)
52 DBFixture::DBFixture(const char *legacy_db_fname, const char *db_fname, DBCryptoThrows dbCryptoThrows)
54 BOOST_REQUIRE(legacy_db_fname || db_fname);
58 copyFile(legacy_db_fname, m_crypto_legacy_db_fname);
60 copyFile(db_fname, m_crypto_db_fname);
65 void DBFixture::init(DBCryptoThrows dbCryptoThrows)
67 switch (dbCryptoThrows) {
68 case DBCryptoThrows::yes:
69 BOOST_REQUIRE_THROW(m_db = DB::Crypto(m_crypto_legacy_db_fname, m_crypto_db_fname, defaultPass), Exc::DatabaseFailed);
71 case DBCryptoThrows::no:
72 BOOST_REQUIRE_NO_THROW(m_db = DB::Crypto(m_crypto_legacy_db_fname, m_crypto_db_fname, defaultPass));
73 BOOST_REQUIRE(access(m_crypto_legacy_db_fname, F_OK) && ENOENT == errno);
77 void DBFixture::generate_name(unsigned int id, Name &output)
80 ss << "name_no_" << id;
84 void DBFixture::generate_owner(unsigned int id, ClientId &output)
87 ss << "label_no_" << id;
91 void DBFixture::generate_db(unsigned int num_name, unsigned int names_per_owner)
93 // to speed up data creation - cache the row
94 DB::Row rowPattern = create_default_row(DataType::BINARY_DATA);
95 rowPattern.data = RawBuffer(100, 20);
96 rowPattern.dataSize = rowPattern.data.size();
97 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
99 for (unsigned int i = 0; i < num_name; i++) {
100 generate_name(i, rowPattern.name);
101 generate_owner(i / names_per_owner, rowPattern.owner);
103 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
107 long DBFixture::add_full_access_rights(unsigned int num_name,
108 unsigned int num_name_per_owner)
111 unsigned int num_owners = num_name / num_name_per_owner;
113 ClientId owner, accessor;
115 for (unsigned int a = 0; a < num_name; a++) {
116 generate_name(a, name);
117 generate_owner(a / num_name_per_owner, owner);
119 for (unsigned int l = 0; l < num_owners; l++) {
121 if (l == (a / num_name_per_owner))
125 generate_owner(l, accessor);
126 add_permission(name, owner, accessor);
134 DB::Row DBFixture::create_default_row(DataType type)
136 return create_default_row(m_default_name, m_default_owner, type);
139 DB::Row DBFixture::create_default_row(const Name &name,
140 const ClientId &owner,
147 row.algorithmType = DBCMAlgType::AES_GCM_256;
149 row.iv = createDefaultPass();
150 row.encryptionScheme = 0;
152 row.backendId = CryptoBackend::OpenSSL;
157 DB::Row DBFixture::create_default_binary_row()
159 DB::Row row = create_default_row(m_default_name, m_default_owner, DataType::BINARY_DATA);
160 row.data = RawBuffer(100, 20);
161 row.dataSize = row.data.size();
162 row.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
167 void DBFixture::compare_row(const DB::Row &lhs, const DB::Row &rhs)
169 BOOST_CHECK_MESSAGE(lhs.name == rhs.name,
170 "namees didn't match! Got: " << rhs.name
171 << " , expected : " << lhs.name);
173 BOOST_CHECK_MESSAGE(lhs.owner == rhs.owner,
174 "owner didn't match! Got: " << rhs.owner
175 << " , expected : " << lhs.owner);
177 BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable,
178 "exportable didn't match! Got: " << rhs.exportable
179 << " , expected : " << lhs.exportable);
181 BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv,
182 "iv didn't match! Got: " << rhs.iv.size()
183 << " , expected : " << lhs.iv.size());
185 BOOST_CHECK_MESSAGE(lhs.data == rhs.data,
186 "data didn't match! Got: " << rhs.data.size()
187 << " , expected : " << lhs.data.size());
189 BOOST_CHECK_MESSAGE(lhs.backendId == rhs.backendId,
190 "backendId didn't match! Got: " << static_cast<int>(rhs.backendId)
191 << " , expected : " << static_cast<int>(lhs.backendId));
194 void DBFixture::check_DB_integrity(const DB::Row &rowPattern)
196 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
198 DB::Crypto::RowOptional optional_row;
199 BOOST_REQUIRE_NO_THROW(optional_row = m_db.getRow(m_default_name, m_default_owner,
200 DataType::BINARY_DATA));
201 BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row");
203 compare_row(*optional_row, rowPattern);
204 DB::Row name_duplicate = rowPattern;
205 name_duplicate.data = createDefaultPass();
206 name_duplicate.dataSize = name_duplicate.data.size();
209 BOOST_REQUIRE_NO_THROW(erased = m_db.deleteRow(m_default_name, m_default_owner));
210 BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db");
212 DB::Crypto::RowOptional row_optional;
213 BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name, m_default_owner,
214 DataType::BINARY_DATA));
215 BOOST_REQUIRE_MESSAGE(!row_optional,
216 "Select should not return row after deletion");
219 void DBFixture::insert_row()
221 insert_row(m_default_name, m_default_owner);
224 void DBFixture::insert_row(const Name &name, const ClientId &owner)
226 DB::Row rowPattern = create_default_row(name, owner,
227 DataType::BINARY_DATA);
228 rowPattern.data = RawBuffer(100, 20);
229 rowPattern.dataSize = rowPattern.data.size();
230 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
231 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
234 void DBFixture::delete_row(const Name &name, const ClientId &owner)
237 BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteRow(name, owner));
238 BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed");
241 void DBFixture::add_permission(const Name &name, const ClientId &owner,
242 const ClientId &accessor)
244 BOOST_REQUIRE_NO_THROW(m_db.setPermission(name,
247 CKM::Permission::READ | CKM::Permission::REMOVE));
250 void DBFixture::read_row_expect_success(const Name &name,
251 const ClientId &owner)
253 DB::Crypto::RowOptional row;
254 BOOST_REQUIRE_NO_THROW(row = m_db.getRow(name, owner,
255 DataType::BINARY_DATA));
256 BOOST_REQUIRE_MESSAGE(row, "row is empty");
257 BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid");