4344541b08e06dd3c8bd748d153aa7446ec26b50
[platform/core/security/key-manager.git] / tests / test_db_crypto.cpp
1 #include <boost/test/unit_test.hpp>
2 #include <boost/test/results_reporter.hpp>
3 #include <unistd.h>
4 #include <db-crypto.h>
5 #include <iostream>
6 #include <ckm/ckm-type.h>
7 #include <ckm/ckm-error.h>
8 #include <errno.h>
9 #include <test_common.h>
10 #include <DBFixture.h>
11
12 BOOST_GLOBAL_FIXTURE(TestConfig)
13
14 using namespace CKM;
15
16 namespace
17 {
18 const int restricted_local = 1;
19 const int restricted_global = 0;
20
21 const unsigned int c_test_retries = 1000;
22 const unsigned int c_num_aliases = 500;
23 const unsigned int c_num_aliases_add_test = 5000;
24 const unsigned int c_alias_per_label = 15;
25 }
26
27
28 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_TEST, DBFixture)
29 BOOST_AUTO_TEST_CASE(DBtestSimple) {
30     DBRow rowPattern = create_default_row();
31     rowPattern.data = RawBuffer(32, 1);
32     rowPattern.dataSize = rowPattern.data.size();
33     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
34
35     check_DB_integrity(rowPattern);
36 }
37 BOOST_AUTO_TEST_CASE(DBtestBIG) {
38     DBRow rowPattern = create_default_row();
39     rowPattern.data = createBigBlob(4096);
40     rowPattern.dataSize = rowPattern.data.size();
41     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
42
43     check_DB_integrity(rowPattern);
44 }
45 BOOST_AUTO_TEST_CASE(DBtestGlobal) {
46     DBRow rowPattern = create_default_row();
47     rowPattern.data = RawBuffer(1024, 2);
48     rowPattern.dataSize = rowPattern.data.size();
49     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
50
51     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
52
53     DBRow alias_duplicate = rowPattern;
54     rowPattern.smackLabel = rowPattern.smackLabel + "1";
55
56     BOOST_REQUIRE_THROW(m_db.saveDBRow(alias_duplicate),
57             DBCrypto::Exception::AliasExists);
58 }
59 BOOST_AUTO_TEST_CASE(DBtestTransaction) {
60     DBRow rowPattern = create_default_row();
61     rowPattern.data = RawBuffer(100, 20);
62     rowPattern.dataSize = rowPattern.data.size();
63     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
64     DBCrypto::Transaction transaction(&m_db);
65
66     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
67     BOOST_REQUIRE_NO_THROW(transaction.rollback());
68
69     DBCrypto::DBRowOptional row_optional;
70     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getDBRow(m_default_alias, m_default_label,
71             DBDataType::BINARY_DATA));
72     BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback");
73
74 }
75
76 BOOST_AUTO_TEST_CASE(DBaddDataCheckIfPermissionIsAdded)
77 {
78     std::string row_A_alias, row_B_alias;
79     std::string row_A_label, row_B_label;
80     generate_alias(0, row_A_alias); generate_label(0, row_A_label);
81     generate_alias(1, row_B_alias); generate_label(1, row_B_label);
82
83     // insert initial data set
84     insert_row(row_A_alias, row_A_label);
85     insert_row(row_B_alias, row_B_label);
86     read_row_expect_success(row_A_alias, row_A_label);
87     read_row_expect_success(row_B_alias, row_B_label);
88
89     // verify that no entries present in the permission table
90     // read row A from label B and vice versa
91     read_row_expect_fail(row_A_alias, row_B_label);
92     read_row_expect_fail(row_B_alias, row_A_label);
93
94     // add appropriate permissions for label B
95     add_permission(row_A_alias, row_A_label, row_B_label);
96
97     // B should have access to A, while A should not to B
98     // read row A from label B and vice versa
99     read_row_expect_success(row_A_alias, row_B_label);
100     read_row_expect_fail(row_B_alias, row_A_label);
101
102     // add appropriate permissions for label A
103     add_permission(row_B_alias, row_B_label, row_A_label);
104
105     // B should have access to A, same as A have access to B
106     // read row A from label B and vice versa
107     read_row_expect_success(row_A_alias, row_B_label);
108     read_row_expect_success(row_B_alias, row_A_label);
109 }
110
111
112 BOOST_AUTO_TEST_CASE(DBremoveDataCheckIfPermissionIsRemoved)
113 {
114     std::string row_A_alias, row_B_alias, row_C_alias;
115     std::string row_A_label, row_B_label, row_C_label;
116     generate_alias(0, row_A_alias); generate_label(0, row_A_label);
117     generate_alias(1, row_B_alias); generate_label(1, row_B_label);
118     generate_alias(2, row_C_alias); generate_label(2, row_C_label);
119
120     // insert initial data set
121     insert_row(row_A_alias, row_A_label);
122     insert_row(row_B_alias, row_B_label);
123     insert_row(row_C_alias, row_C_label);
124     add_permission(row_A_alias, row_A_label, row_B_label);
125     add_permission(row_B_alias, row_B_label, row_A_label);
126     // to test multiple permissions removal
127     // put intentionally after row_B_alias permission entry
128     add_permission(row_A_alias, row_A_label, row_C_label);
129
130     // B should have access to A, same as A have access to B
131     // read row A from label B and vice versa
132     read_row_expect_success(row_A_alias, row_B_label);
133     read_row_expect_success(row_A_alias, row_C_label);
134     read_row_expect_success(row_B_alias, row_A_label);
135     read_row_expect_fail(row_B_alias, row_C_label);
136
137     // remove data A - expect permissions for B and C to be removed as well
138     delete_row(row_A_alias, row_A_label);
139     // insert it again - expect permissions for label B and C not to be there anymore
140     insert_row(row_A_alias, row_A_label);
141
142     // read row A from label B and vice versa
143     read_row_expect_fail(row_A_alias, row_B_label);
144     read_row_expect_fail(row_A_alias, row_C_label);
145     read_row_expect_success(row_B_alias, row_A_label);
146
147     // remove data B - expect permission to be removed as well
148     delete_row(row_B_alias, row_B_label);
149     // insert it again - expect permissions for label A not to be there anymore
150     insert_row(row_B_alias, row_B_label);
151
152     // read row A from label B and vice versa
153     read_row_expect_fail(row_A_alias, row_B_label);
154     read_row_expect_fail(row_A_alias, row_C_label);
155     read_row_expect_fail(row_B_alias, row_A_label);
156
157     // sanity check: data exists
158     read_row_expect_success(row_A_alias, row_A_label);
159     read_row_expect_success(row_B_alias, row_B_label);
160 }
161 BOOST_AUTO_TEST_SUITE_END()
162
163
164
165 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_PERF_TEST, DBFixture)
166
167 BOOST_AUTO_TEST_CASE(DBperfAddAliases)
168 {
169     // actual test
170     performance_start("saveDBRow");
171     {
172         generate_perf_DB(c_num_aliases_add_test, c_alias_per_label);
173     }
174     performance_stop(c_num_aliases_add_test);
175 }
176
177 BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner)
178 {
179     // prepare data
180     generate_perf_DB(c_num_aliases, c_alias_per_label);
181
182     unsigned int num_labels = c_num_aliases/c_alias_per_label;
183     std::string alias, label;
184
185     // actual test - successful lookup
186     performance_start("getDBRow");
187     for(unsigned int t=0; t<c_test_retries; t++)
188     {
189         int label_num = rand() % num_labels;
190         generate_label(label_num, label);
191
192         unsigned int start_alias = label_num*c_alias_per_label;
193         for(unsigned int alias_num=start_alias; alias_num<(start_alias+c_alias_per_label); alias_num++)
194         {
195             generate_alias(alias_num, alias);
196             read_row_expect_success(alias, label);
197         }
198     }
199     performance_stop(c_test_retries * c_num_aliases);
200 }
201
202 BOOST_AUTO_TEST_CASE(DBperfLookupAliasByNotAllowed)
203 {
204     // prepare data
205     generate_perf_DB(c_num_aliases, c_alias_per_label);
206
207     std::string alias, label;
208     const unsigned int unavailable_label_idx = (c_num_aliases/c_alias_per_label) + 1;
209     generate_label(unavailable_label_idx, label);
210
211     // actual test - failure lookup
212     performance_start("getDBRow");
213     for(unsigned int t=0; t<c_test_retries; t++)
214     {
215         generate_alias(rand()%c_num_aliases, alias);
216
217         read_row_expect_fail(alias, label);
218     }
219     performance_stop(c_test_retries * c_num_aliases);
220 }
221
222 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
223 {
224     // prepare data
225     generate_perf_DB(c_num_aliases, c_alias_per_label);
226
227     std::string alias, label;
228     unsigned int num_labels = c_num_aliases / c_alias_per_label;
229
230     // actual test - random lookup
231     performance_start("getDBRow");
232     for(unsigned int t=0; t<c_test_retries; t++)
233     {
234         generate_alias(rand()%c_num_aliases, alias);
235         generate_label(rand()%num_labels, label);
236
237         try
238         {
239             m_db.getDBRow(alias, label, DBDataType::BINARY_DATA);
240         }
241         catch (const DBCrypto::Exception::PermissionDenied &e) {}
242     }
243     performance_stop(c_test_retries * c_num_aliases);
244 }
245
246 BOOST_AUTO_TEST_CASE(DBperfAddPermissions)
247 {
248     // prepare data
249     generate_perf_DB(c_num_aliases, c_alias_per_label);
250
251     // actual test - add access rights
252     performance_start("setAccessRights");
253     long iterations = add_full_access_rights(c_num_aliases, c_alias_per_label);
254     performance_stop(iterations);
255 }
256
257 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipWithPermissions)
258 {
259     // prepare data
260     generate_perf_DB(c_num_aliases, c_alias_per_label);
261     add_full_access_rights(c_num_aliases, c_alias_per_label);
262
263     std::string alias, label;
264     unsigned int num_labels = c_num_aliases / c_alias_per_label;
265
266     // actual test - random lookup
267     performance_start("getDBRow/perm");
268     for(unsigned int t=0; t<c_test_retries; t++)
269     {
270         generate_alias(rand()%c_num_aliases, alias);
271         generate_label(rand()%num_labels, label);
272
273         read_row_expect_success(alias, label);
274     }
275     performance_stop(c_test_retries * c_num_aliases);
276 }
277
278 BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
279 {
280     // prepare data
281     generate_perf_DB(c_num_aliases, c_alias_per_label);
282     add_full_access_rights(c_num_aliases, c_alias_per_label);
283
284     // actual test - random lookup
285     performance_start("deleteDBRow");
286     std::string alias, label;
287     for(unsigned int t=0; t<c_num_aliases; t++)
288     {
289         generate_alias(t, alias);
290         generate_label(t/c_alias_per_label, label);
291
292         BOOST_REQUIRE_NO_THROW(m_db.deleteDBRow(alias, label));
293     }
294     performance_stop(c_num_aliases);
295
296     // verify everything has been removed
297     unsigned int num_labels = c_num_aliases / c_alias_per_label;
298     for(unsigned int l=0; l<num_labels; l++)
299     {
300         generate_label(l, label);
301         AliasVector expect_no_data;
302         BOOST_REQUIRE_NO_THROW(m_db.getAliases(label, DBDataType::BINARY_DATA, expect_no_data));
303         BOOST_REQUIRE(0 == expect_no_data.size());
304     }
305 }
306
307 BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
308 {
309     // prepare data
310     generate_perf_DB(c_num_aliases, c_alias_per_label);
311     add_full_access_rights(c_num_aliases, c_alias_per_label);
312
313     unsigned int num_labels = c_num_aliases / c_alias_per_label;
314     std::string label;
315
316     // actual test - random lookup
317     performance_start("getAliases");
318     for(unsigned int t=0; t<(c_test_retries/num_labels); t++)
319     {
320         AliasVector ret_list;
321         generate_label(rand()%num_labels, label);
322
323         BOOST_REQUIRE_NO_THROW(m_db.getAliases(label, DBDataType::BINARY_DATA, ret_list));
324         BOOST_REQUIRE(c_num_aliases == ret_list.size());
325         ret_list.clear();
326     }
327     performance_stop(c_test_retries/num_labels);
328 }
329
330 BOOST_AUTO_TEST_SUITE_END()