9946a34589870b99ef33b0a55f3fe89b22ec2ce6
[platform/core/security/key-manager.git] / tests / test_db_crypto.cpp
1 #include <boost/test/unit_test.hpp>
2 #include <unistd.h>
3 #include <db-crypto.h>
4 #include <iostream>
5 #include <ckm/ckm-type.h>
6 #include <ckm/ckm-error.h>
7 #include <errno.h>
8 #include <test_common.h>
9 #include <DBFixture.h>
10
11 using namespace CKM;
12
13 namespace
14 {
15 const int restricted_local = 1;
16 const int restricted_global = 0;
17
18 const unsigned int c_test_retries = 1000;
19 const unsigned int c_num_names = 500;
20 const unsigned int c_num_names_add_test = 5000;
21 const unsigned int c_names_per_label = 15;
22 } // namespace anonymous
23
24 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_TEST, DBFixture)
25 BOOST_AUTO_TEST_CASE(DBtestSimple) {
26     DB::Row rowPattern = create_default_row();
27     rowPattern.data = RawBuffer(32, 1);
28     rowPattern.dataSize = rowPattern.data.size();
29     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
30
31     check_DB_integrity(rowPattern);
32 }
33 BOOST_AUTO_TEST_CASE(DBtestBIG) {
34     DB::Row rowPattern = create_default_row();
35     rowPattern.data = createBigBlob(4096);
36     rowPattern.dataSize = rowPattern.data.size();
37     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
38
39     check_DB_integrity(rowPattern);
40 }
41 BOOST_AUTO_TEST_CASE(DBtestGlobal) {
42     DB::Row rowPattern = create_default_row();
43     rowPattern.data = RawBuffer(1024, 2);
44     rowPattern.dataSize = rowPattern.data.size();
45     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
46
47     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
48
49     DB::Row name_duplicate = rowPattern;
50     rowPattern.ownerLabel = rowPattern.ownerLabel + "1";
51 }
52 BOOST_AUTO_TEST_CASE(DBtestTransaction) {
53     DB::Row rowPattern = create_default_row();
54     rowPattern.data = RawBuffer(100, 20);
55     rowPattern.dataSize = rowPattern.data.size();
56     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
57     DB::Crypto::Transaction transaction(&m_db);
58
59     BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
60     BOOST_REQUIRE_NO_THROW(transaction.rollback());
61
62     DB::Crypto::RowOptional row_optional;
63     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name, m_default_label,
64                                                       DataType::BINARY_DATA));
65     BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback");
66 }
67
68 BOOST_AUTO_TEST_SUITE_END()
69
70
71
72 BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_PERF_TEST, DBFixture)
73
74 BOOST_AUTO_TEST_CASE(DBperfAddNames)
75 {
76     // actual test
77     performance_start("saveRow");
78     {
79         generate_perf_DB(c_num_names_add_test, c_names_per_label);
80     }
81     performance_stop(c_num_names_add_test);
82 }
83
84 BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner)
85 {
86     // prepare data
87     generate_perf_DB(c_num_names, c_names_per_label);
88
89     unsigned int num_labels = c_num_names/c_names_per_label;
90     Name name;
91     Label label;
92
93     // actual test - successful lookup
94     performance_start("getRow");
95     for(unsigned int t=0; t<c_test_retries; t++)
96     {
97         int label_num = rand() % num_labels;
98         generate_label(label_num, label);
99
100         unsigned int start_name = label_num*c_names_per_label;
101         for(unsigned int name_num=start_name; name_num<(start_name+c_names_per_label); name_num++)
102         {
103             generate_name(name_num, name);
104             read_row_expect_success(name, label);
105         }
106     }
107     performance_stop(c_test_retries * c_num_names);
108 }
109
110 BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions)
111 {
112     // prepare data
113     generate_perf_DB(c_num_names, c_names_per_label);
114
115     Name name;
116     Label owner_label;
117     Label smack_label;
118     unsigned int num_labels = c_num_names / c_names_per_label;
119
120     // actual test - random lookup
121     performance_start("getRow");
122     for(unsigned int t=0; t<c_test_retries; t++)
123     {
124         int name_idx = rand()%c_num_names;
125         generate_name(name_idx, name);
126         generate_label(name_idx/c_names_per_label, owner_label);
127         generate_label(rand()%num_labels, smack_label);
128
129         // do not care of result
130         m_db.getRow(name, owner_label, DataType::BINARY_DATA);
131     }
132     performance_stop(c_test_retries * c_num_names);
133 }
134
135 BOOST_AUTO_TEST_CASE(DBperfAddPermissions)
136 {
137     // prepare data
138     generate_perf_DB(c_num_names, c_names_per_label);
139
140     // actual test - add access rights
141     performance_start("setPermission");
142     long iterations = add_full_access_rights(c_num_names, c_names_per_label);
143     performance_stop(iterations);
144 }
145
146 BOOST_AUTO_TEST_CASE(DBperfAliasRemoval)
147 {
148     // prepare data
149     generate_perf_DB(c_num_names, c_names_per_label);
150     add_full_access_rights(c_num_names, c_names_per_label);
151
152     // actual test - random lookup
153     performance_start("deleteRow");
154     Name name;
155     Label label;
156     for(unsigned int t=0; t<c_num_names; t++)
157     {
158         generate_name(t, name);
159         generate_label(t/c_names_per_label, label);
160
161         BOOST_REQUIRE_NO_THROW(m_db.deleteRow(name, label));
162     }
163     performance_stop(c_num_names);
164
165     // verify everything has been removed
166     unsigned int num_labels = c_num_names / c_names_per_label;
167     for(unsigned int l=0; l<num_labels; l++)
168     {
169         generate_label(l, label);
170         LabelNameVector expect_no_data;
171         BOOST_REQUIRE_NO_THROW(m_db.listNames(label, expect_no_data, DataType::BINARY_DATA));
172         BOOST_REQUIRE(0 == expect_no_data.size());
173     }
174 }
175
176 BOOST_AUTO_TEST_CASE(DBperfGetAliasList)
177 {
178     // prepare data
179     generate_perf_DB(c_num_names, c_names_per_label);
180     add_full_access_rights(c_num_names, c_names_per_label);
181
182     unsigned int num_labels = c_num_names / c_names_per_label;
183     Label label;
184
185     // actual test - random lookup
186     performance_start("listNames");
187     for(unsigned int t=0; t<(c_test_retries/num_labels); t++)
188     {
189         LabelNameVector ret_list;
190         generate_label(rand()%num_labels, label);
191
192         BOOST_REQUIRE_NO_THROW(m_db.listNames(label, ret_list, DataType::BINARY_DATA));
193         BOOST_REQUIRE(c_num_names == ret_list.size());
194         ret_list.clear();
195     }
196     performance_stop(c_test_retries/num_labels);
197 }
198 BOOST_AUTO_TEST_SUITE_END()
199
200
201 BOOST_AUTO_TEST_SUITE(DBCRYPTO_MIGRATION_TEST)
202 namespace
203 {
204 const unsigned migration_names = 16107;
205 const unsigned migration_labels = 273;
206 const unsigned migration_reference_label_idx = 0;
207 const unsigned migration_accessed_element_idx = 7;
208
209 void verifyDBisValid(DBFixture & fixture)
210 {
211     /**
212      * there are (migration_labels), each having (migration_names)/(migration_labels) entries.
213      * reference label (migration_reference_label_idx) exists such that it has access to
214      * all others' label element with index (migration_accessed_element_idx).
215      *
216      * Example:
217      * - migration_label_63 has access to all items owned by migration_label_63,
218      *   which gives (migration_names)/(migration_labels) entries.
219      *
220      * - migration_label_0 (0 is the reference label) has access to all items
221      *   owned by migration_label_0 and all others' label element index 7,
222      *   which gives (migration_names)/(migration_labels)  + (migration_labels-1) entries.
223      *
224      */
225     Label reference_label;
226     fixture.generate_label(migration_reference_label_idx, reference_label);
227
228     // check number of elements accessible to the reference label
229     LabelNameVector ret_list;
230     BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(reference_label, ret_list, DataType::BINARY_DATA));
231     BOOST_REQUIRE((migration_names/migration_labels)/*own items*/ + (migration_labels-1)/*other labels'*/ == ret_list.size());
232     ret_list.clear();
233
234     // check number of elements accessible to the other labels
235     for(unsigned int l=0; l<migration_labels; l++)
236     {
237         // bypass the reference owner label
238         if(l == migration_reference_label_idx)
239             continue;
240
241         Label current_label;
242         fixture.generate_label(l, current_label);
243         BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(current_label, ret_list, DataType::BINARY_DATA));
244         BOOST_REQUIRE((migration_names/migration_labels) == ret_list.size());
245         for(auto it: ret_list)
246             BOOST_REQUIRE(it.first == current_label);
247         ret_list.clear();
248     }
249 }
250 struct DBVer1Migration : public DBFixture
251 {
252     DBVer1Migration() : DBFixture("/usr/share/ckm-db-test/testme_ver1.db")
253     {}
254 };
255
256 struct DBVer2Migration : public DBFixture
257 {
258     DBVer2Migration() : DBFixture("/usr/share/ckm-db-test/testme_ver2.db")
259     {}
260 };
261 }
262
263 BOOST_AUTO_TEST_CASE(DBMigrationDBVer1)
264 {
265     DBVer1Migration DBver1;
266     verifyDBisValid(DBver1);
267 }
268
269 BOOST_AUTO_TEST_CASE(DBMigrationDBVer2)
270 {
271     DBVer2Migration DBver2;
272     verifyDBisValid(DBver2);
273 }
274
275 BOOST_AUTO_TEST_CASE(DBMigrationDBCurrent)
276 {
277     DBFixture currentDB;
278
279     // prepare data using current DB mechanism
280     Label reference_label;
281     currentDB.generate_label(migration_reference_label_idx, reference_label);
282     {
283         currentDB.generate_perf_DB(migration_names, migration_names/migration_labels);
284
285         // only the reference label has access to the other labels element <migration_accessed_element_idx>
286         for(unsigned int l=0; l<migration_labels; l++)
287         {
288             // bypass the reference owner label
289             if(l == migration_reference_label_idx)
290                 continue;
291
292             unsigned element_index = migration_accessed_element_idx + l*migration_names/migration_labels;
293
294             // add permission
295             Name accessed_name;
296             currentDB.generate_name(element_index, accessed_name);
297             Label current_label;
298             currentDB.generate_label(l, current_label);
299             currentDB.add_permission(accessed_name, current_label, reference_label);
300         }
301     }
302
303     verifyDBisValid(currentDB);
304 }
305
306 BOOST_AUTO_TEST_SUITE_END()