CAPI cleanup: control "owner" removal, set_permission replaces allow_access.
[platform/core/security/key-manager.git] / tests / DBFixture.cpp
1 #include <boost/test/unit_test.hpp>
2 #include <db-crypto.h>
3 #include <ckm/ckm-error.h>
4 #include <DBFixture.h>
5
6 using namespace CKM;
7 using namespace std::chrono;
8
9
10 DBFixture::DBFixture()
11 {
12     high_resolution_clock::time_point srand_feed = high_resolution_clock::now();
13     srand(srand_feed.time_since_epoch().count());
14
15     BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT);
16     BOOST_REQUIRE_NO_THROW(m_db = DBCrypto(m_crypto_db_fname, defaultPass));
17 }
18
19 double DBFixture::performance_get_time_elapsed_ms()
20 {
21     return duration_cast<milliseconds>(m_end_time - m_start_time).count();
22 }
23
24 void DBFixture::performance_start(const char *operation_name)
25 {
26     m_operation = std::string(operation_name?operation_name:"unknown");
27     BOOST_TEST_MESSAGE("\t<performance> running " << m_operation << " performance test...");
28     m_start_time = high_resolution_clock::now();
29 }
30
31 void DBFixture::performance_stop(long num_operations_performed)
32 {
33     m_end_time = high_resolution_clock::now();
34     double time_elapsed_ms = performance_get_time_elapsed_ms();
35     BOOST_TEST_MESSAGE("\t<performance> time elapsed: " << time_elapsed_ms << "[ms], number of " << m_operation << ": " << num_operations_performed);
36     if(num_operations_performed>0)
37         BOOST_TEST_MESSAGE("\t<performance> average time per " << m_operation << ": " << time_elapsed_ms/num_operations_performed << "[ms]");
38 }
39
40 void DBFixture::generate_name(unsigned int id, Name & output)
41 {
42     std::stringstream ss;
43     ss << "name_no_" << id;
44     output = ss.str();
45 }
46
47 void DBFixture::generate_label(unsigned int id, Label & output)
48 {
49     std::stringstream ss;
50     ss << "label_no_" << id;
51     output = ss.str();
52 }
53
54 void DBFixture::generate_perf_DB(unsigned int num_name, unsigned int num_label)
55 {
56     // to speed up data creation - cache the row
57     DBRow rowPattern = create_default_row(DBDataType::BINARY_DATA);
58     rowPattern.data = RawBuffer(100, 20);
59     rowPattern.dataSize = rowPattern.data.size();
60     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
61
62     for(unsigned int i=0; i<num_name; i++)
63     {
64         generate_name(i, rowPattern.name);
65         generate_label(i/num_label, rowPattern.ownerLabel);
66
67         BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
68     }
69 }
70
71 long DBFixture::add_full_access_rights(unsigned int num_name, unsigned int num_name_per_label)
72 {
73     long iterations = 0;
74     unsigned int num_labels = num_name / num_name_per_label;
75     Name name;
76     Label owner_label, accessor_label;
77     for(unsigned int a=0; a<num_name; a++)
78     {
79         generate_name(a, name);
80         generate_label(a/num_name_per_label, owner_label);
81         for(unsigned int l=0; l<num_labels; l++)
82         {
83             // bypass the owner label
84             if(l == (a/num_name_per_label))
85                 continue;
86
87             // add permission
88             generate_label(l, accessor_label);
89             add_permission(name, owner_label, accessor_label);
90             iterations ++;
91         }
92     }
93
94     return iterations;
95 }
96
97 DBRow DBFixture::create_default_row(DBDataType type)
98 {
99     return create_default_row(m_default_name, m_default_label, type);
100 }
101
102 DBRow DBFixture::create_default_row(const Name &name,
103                                     const Label &label,
104                                     DBDataType type)
105 {
106     DBRow row;
107     row.name = name;
108     row.ownerLabel = label;
109     row.exportable = 1;
110     row.algorithmType = DBCMAlgType::AES_GCM_256;
111     row.dataType = type;
112     row.iv = createDefaultPass();
113     row.encryptionScheme = 0;
114     row.dataSize = 0;
115
116     return row;
117 }
118
119 void DBFixture::compare_row(const DBRow &lhs, const DBRow &rhs)
120 {
121     BOOST_CHECK_MESSAGE(lhs.name == rhs.name,
122             "namees didn't match! Got: " << rhs.name
123                 << " , expected : " << lhs.name);
124
125     BOOST_CHECK_MESSAGE(lhs.ownerLabel == rhs.ownerLabel,
126             "smackLabel didn't match! Got: " << rhs.ownerLabel
127                 << " , expected : " << lhs.ownerLabel);
128
129     BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable,
130             "exportable didn't match! Got: " << rhs.exportable
131                 << " , expected : " << lhs.exportable);
132
133     BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv,
134             "iv didn't match! Got: " << rhs.iv.size()
135                 << " , expected : " << lhs.iv.size());
136
137     BOOST_CHECK_MESSAGE(lhs.data == rhs.data,
138             "data didn't match! Got: " << rhs.data.size()
139                 << " , expected : " << lhs.data.size());
140 }
141
142 void DBFixture::check_DB_integrity(const DBRow &rowPattern)
143 {
144     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
145     DBRow selectRow = rowPattern;
146
147     DBCrypto::DBRowOptional optional_row;
148     BOOST_REQUIRE_NO_THROW(optional_row = m_db.getDBRow("name", "label", DBDataType::BINARY_DATA));
149     BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row");
150
151     compare_row(selectRow, rowPattern);
152     DBRow name_duplicate = rowPattern;
153     name_duplicate.data = createDefaultPass();
154     name_duplicate.dataSize = name_duplicate.data.size();
155
156     unsigned int erased;
157     BOOST_REQUIRE_NO_THROW(erased = m_db.deleteDBRow("name", "label"));
158     BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db");
159
160     DBCrypto::DBRowOptional row_optional;
161     BOOST_REQUIRE_NO_THROW(row_optional = m_db.getDBRow("name", "label", DBDataType::BINARY_DATA));
162     BOOST_REQUIRE_MESSAGE(!row_optional, "Select should not return row after deletion");
163 }
164
165 void DBFixture::insert_row()
166 {
167     insert_row(m_default_name, m_default_label);
168 }
169
170 void DBFixture::insert_row(const Name &name, const Label &owner_label)
171 {
172     DBRow rowPattern = create_default_row(name, owner_label, DBDataType::BINARY_DATA);
173     rowPattern.data = RawBuffer(100, 20);
174     rowPattern.dataSize = rowPattern.data.size();
175     rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
176     BOOST_REQUIRE_NO_THROW(m_db.saveDBRow(rowPattern));
177 }
178
179 void DBFixture::delete_row(const Name &name, const Label &owner_label)
180 {
181     bool exit_flag;
182     BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteDBRow(name, owner_label));
183     BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed");
184 }
185
186 void DBFixture::add_permission(const Name &name, const Label &owner_label, const Label &accessor_label)
187 {
188     BOOST_REQUIRE_NO_THROW(m_db.setPermission(name,
189                                               owner_label,
190                                               accessor_label,
191                                               CKM::Permission::READ | CKM::Permission::REMOVE));
192 }
193
194 void DBFixture::read_row_expect_success(const Name &name, const Label &owner_label)
195 {
196     DBCrypto::DBRowOptional row;
197     BOOST_REQUIRE_NO_THROW(row = m_db.getDBRow(name, owner_label, DBDataType::BINARY_DATA));
198     BOOST_REQUIRE_MESSAGE(row, "row is empty");
199     BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid");
200 }