Change char unique_ptr to char vector
[platform/core/security/key-manager.git] / tests / DBFixture.cpp
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Kyungwook Tak <k.tak@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  *
18  * @file        DBFixture.cpp
19  * @author      Maciej Karpiuk (m.karpiuk2@samsung.com)
20  * @version
21  * @brief
22  */
23 #include <boost/test/unit_test.hpp>
24 #include <db-crypto.h>
25 #include <ckm/ckm-error.h>
26 #include <DBFixture.h>
27 #include <fstream>
28
29 using namespace CKM;
30 using namespace std::chrono;
31
32
33 DBFixture::DBFixture()
34 {
35     BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT);
36     init();
37 }
38 DBFixture::DBFixture(const char *db_fname)
39 {
40     BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT);
41
42     // copy file
43     std::ifstream f1(db_fname, std::fstream::binary);
44     std::ofstream f2(m_crypto_db_fname, std::fstream::trunc|std::fstream::binary);
45     f2 << f1.rdbuf();
46     f2.close();
47     f1.close();
48
49     init();
50 }
51
52 void DBFixture::init()
53 {
54     high_resolution_clock::time_point srand_feed = high_resolution_clock::now();
55     srand(srand_feed.time_since_epoch().count());
56
57     BOOST_REQUIRE_NO_THROW(m_db = DB::Crypto(m_crypto_db_fname, defaultPass));
58 }
59
60 double DBFixture::performance_get_time_elapsed_ms()
61 {
62     return duration_cast<milliseconds>(m_end_time - m_start_time).count();
63 }
64
65 void DBFixture::performance_start(const char *operation_name)
66 {
67     m_operation = std::string(operation_name?operation_name:"unknown");
68     BOOST_TEST_MESSAGE("\t<performance> running " << m_operation << " performance test...");
69     m_start_time = high_resolution_clock::now();
70 }
71
72 void DBFixture::performance_stop(long num_operations_performed)
73 {
74     m_end_time = high_resolution_clock::now();
75     double time_elapsed_ms = performance_get_time_elapsed_ms();
76     BOOST_TEST_MESSAGE("\t<performance> time elapsed: " << time_elapsed_ms << "[ms], number of " << m_operation << ": " << num_operations_performed);
77     if(num_operations_performed>0)
78         BOOST_TEST_MESSAGE("\t<performance> average time per " << m_operation << ": " << time_elapsed_ms/num_operations_performed << "[ms]");
79 }
80
81 void DBFixture::generate_name(unsigned int id, Name & output)
82 {
83     std::stringstream ss;
84     ss << "name_no_" << id;
85     output = ss.str();
86 }
87
88 void DBFixture::generate_label(unsigned int id, Label & output)
89 {
90     std::stringstream ss;
91     ss << "label_no_" << id;
92     output = ss.str();
93 }
94
95 void DBFixture::generate_perf_DB(unsigned int num_name, unsigned int num_elements)
96 {
97     // to speed up data creation - cache the row
98     DB::Row rowPattern = create_default_row(DataType::BINARY_DATA);
99     rowPattern.data = RawBuffer(100, 20);
100     rowPattern.dataSize = rowPattern.data.size();
101     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
102
103     for(unsigned int i=0; i<num_name; i++)
104     {
105         generate_name(i, rowPattern.name);
106         generate_label(i/num_elements, rowPattern.ownerLabel);
107
108         BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
109     }
110 }
111
112 long DBFixture::add_full_access_rights(unsigned int num_name, unsigned int num_name_per_label)
113 {
114     long iterations = 0;
115     unsigned int num_labels = num_name / num_name_per_label;
116     Name name;
117     Label owner_label, accessor_label;
118     for(unsigned int a=0; a<num_name; a++)
119     {
120         generate_name(a, name);
121         generate_label(a/num_name_per_label, owner_label);
122         for(unsigned int l=0; l<num_labels; l++)
123         {
124             // bypass the owner label
125             if(l == (a/num_name_per_label))
126                 continue;
127
128             // add permission
129             generate_label(l, accessor_label);
130             add_permission(name, owner_label, accessor_label);
131             iterations ++;
132         }
133     }
134
135     return iterations;
136 }
137
138 DB::Row DBFixture::create_default_row(DataType type)
139 {
140     return create_default_row(m_default_name, m_default_label, type);
141 }
142
143 DB::Row DBFixture::create_default_row(const Name &name,
144                                     const Label &label,
145                                     DataType type)
146 {
147     DB::Row row;
148     row.name = name;
149     row.ownerLabel = label;
150     row.exportable = 1;
151     row.algorithmType = DBCMAlgType::AES_GCM_256;
152     row.dataType = type;
153     row.iv = createDefaultPass();
154     row.encryptionScheme = 0;
155     row.dataSize = 0;
156     row.backendId = CryptoBackend::OpenSSL;
157
158     return row;
159 }
160
161 void DBFixture::compare_row(const DB::Row &lhs, const DB::Row &rhs)
162 {
163     BOOST_CHECK_MESSAGE(lhs.name == rhs.name,
164             "namees didn't match! Got: " << rhs.name
165                 << " , expected : " << lhs.name);
166
167     BOOST_CHECK_MESSAGE(lhs.ownerLabel == rhs.ownerLabel,
168             "smackLabel didn't match! Got: " << rhs.ownerLabel
169                 << " , expected : " << lhs.ownerLabel);
170
171     BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable,
172             "exportable didn't match! Got: " << rhs.exportable
173                 << " , expected : " << lhs.exportable);
174
175     BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv,
176             "iv didn't match! Got: " << rhs.iv.size()
177                 << " , expected : " << lhs.iv.size());
178
179     BOOST_CHECK_MESSAGE(lhs.data == rhs.data,
180             "data didn't match! Got: " << rhs.data.size()
181                 << " , expected : " << lhs.data.size());
182
183     BOOST_CHECK_MESSAGE(lhs.backendId == rhs.backendId,
184             "backendId didn't match! Got: " << static_cast<int>(rhs.backendId)
185                 << " , expected : " << static_cast<int>(lhs.backendId));
186 }
187
188 void DBFixture::check_DB_integrity(const DB::Row &rowPattern)
189 {
190     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
191
192     DB::Crypto::RowOptional optional_row;
193     BOOST_REQUIRE_NO_THROW(optional_row = m_db.getRow("name", "label", DataType::BINARY_DATA));
194     BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row");
195
196     compare_row(*optional_row, rowPattern);
197     DB::Row name_duplicate = rowPattern;
198     name_duplicate.data = createDefaultPass();
199     name_duplicate.dataSize = name_duplicate.data.size();
200
201     unsigned int erased;
202     BOOST_REQUIRE_NO_THROW(erased = m_db.deleteRow("name", "label"));
203     BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db");
204
205     DB::Crypto::RowOptional row_optional;
206     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow("name", "label", DataType::BINARY_DATA));
207     BOOST_REQUIRE_MESSAGE(!row_optional, "Select should not return row after deletion");
208 }
209
210 void DBFixture::insert_row()
211 {
212     insert_row(m_default_name, m_default_label);
213 }
214
215 void DBFixture::insert_row(const Name &name, const Label &owner_label)
216 {
217     DB::Row rowPattern = create_default_row(name, owner_label, DataType::BINARY_DATA);
218     rowPattern.data = RawBuffer(100, 20);
219     rowPattern.dataSize = rowPattern.data.size();
220     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
221     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
222 }
223
224 void DBFixture::delete_row(const Name &name, const Label &owner_label)
225 {
226     bool exit_flag;
227     BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteRow(name, owner_label));
228     BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed");
229 }
230
231 void DBFixture::add_permission(const Name &name, const Label &owner_label, const Label &accessor_label)
232 {
233     BOOST_REQUIRE_NO_THROW(m_db.setPermission(name,
234                                               owner_label,
235                                               accessor_label,
236                                               CKM::Permission::READ | CKM::Permission::REMOVE));
237 }
238
239 void DBFixture::read_row_expect_success(const Name &name, const Label &owner_label)
240 {
241     DB::Crypto::RowOptional row;
242     BOOST_REQUIRE_NO_THROW(row = m_db.getRow(name, owner_label, DataType::BINARY_DATA));
243     BOOST_REQUIRE_MESSAGE(row, "row is empty");
244     BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid");
245 }