CommonCriteria tests refactored and updated
[platform/core/test/security-tests.git] / tests / ckm / cc-mode.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file       cc-mode.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include <string>
29
30 #include <vconf/vconf.h>
31
32 #include <dpl/test/test_runner.h>
33 #include <tests_common.h>
34 #include <dbus_access.h>
35
36 #include <ckm/ckm-manager.h>
37 #include <ckm/ckm-control.h>
38
39 using namespace CKM;
40 using namespace std;
41
42 #ifndef VCONFKEY_SECURITY_MDPP_STATE
43 #define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state"
44 #endif
45
46 namespace {
47
48 const useconds_t SLEEP = 100*1000;
49
50 const size_t MAX_RETRIES = 50;
51
52 const char* const ENABLED = "Enabled";
53 const char* const ENFORCING = "Enforcing";
54 const char* const DISABLED = "Disabled";
55
56 const char* const CKM_LOCK = "/var/run/key-manager.pid";
57 const char* SERVICE[] = {
58         "/org/freedesktop/systemd1/unit/central_2dkey_2dmanager_2dlistener_2eservice",
59         "/org/freedesktop/systemd1/unit/central_2dkey_2dmanager_2eservice" };
60
61 enum ServiceIdx {
62     LISTENER,
63     MANAGER
64 };
65
66 // disable CC
67 int _unset_mdpp_key = vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
68
69 // Wrapper for mdpp state that restores the original value upon destruction
70 class MdppState
71 {
72 public:
73     MdppState();
74     ~MdppState();
75
76     // pass NULL to unset
77     void set(const char* const value);
78
79 private:
80     char* m_original;
81 };
82
83 MdppState::MdppState()
84 {
85     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
86 }
87
88 MdppState::~MdppState()
89 {
90     if (!m_original)
91         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
92     else {
93         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
94         free(m_original);
95     }
96 }
97
98 void MdppState::set(const char* const value)
99 {
100     if (value)
101         RUNNER_ASSERT_MSG(0 == vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value),
102                              "vconf_set() failed");
103     else
104         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
105 }
106
107 void start_service(ServiceIdx idx)
108 {
109     DBusAccess dbus(SERVICE[idx]);
110     dbus.start();
111 }
112
113 void stop_service(ServiceIdx idx)
114 {
115     DBusAccess dbus(SERVICE[idx]);
116     dbus.stop();
117 }
118
119 void remove_user_data()
120 {
121     auto control = Control::create();
122     int ret = control->removeUserData(0);
123     RUNNER_ASSERT_MSG(ret == CKM_API_SUCCESS,
124                          "Remove user data failed with error: " << ErrorToString(ret));
125 }
126
127 Alias rsa_pri_alias("rsa-private-T2002");
128 Alias rsa_pub_alias("rsa-public-T2002");
129 Alias ecdsa_pri_alias("ecdsa-private-T2002");
130 Alias ecdsa_pub_alias("ecdsa-public-T2002");
131
132 void save_keys()
133 {
134     int temp;
135     auto manager = Manager::create();
136
137     RUNNER_ASSERT_MSG(
138         CKM_API_SUCCESS == (temp = manager->createKeyPairRSA(
139                 1024,
140                 rsa_pri_alias,
141                 rsa_pub_alias,
142                 Policy(Password(), true),
143                 Policy(Password(), true))),
144             "Error=" << ErrorToString(temp));
145
146     RUNNER_ASSERT_MSG(
147         CKM_API_SUCCESS == (temp = manager->createKeyPairECDSA(
148                 ElipticCurve::prime192v1,
149                 ecdsa_pri_alias,
150                 ecdsa_pub_alias,
151                 Policy(Password(), true),
152                 Policy(Password(), true))),
153             "Error=" << ErrorToString(temp));
154 }
155
156 void read_key(ManagerShPtr& manager, const Alias& alias, int expected) {
157     KeyShPtr key;
158     int temp;
159     RUNNER_ASSERT_MSG(
160             expected == (temp = manager->getKey(alias, Password(), key)),
161             "Expected: " << expected << "/" << ErrorToString(expected) << " got: " << temp << "/" <<
162             ErrorToString(temp));
163 }
164
165 void read_keys(int expected)
166 {
167     auto manager = Manager::create();
168
169     read_key(manager, rsa_pri_alias, expected);
170     read_key(manager, ecdsa_pri_alias, expected);
171 }
172
173 void update_cc_mode()
174 {
175     auto control = Control::create();
176     int ret;
177     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
178                          "Error=" << ErrorToString(ret));
179 }
180
181 void restart_ckm(const char* const mdpp_setting)
182 {
183     stop_service(MANAGER);
184     MdppState mdpp;
185     mdpp.set(mdpp_setting);
186     start_service(MANAGER);
187 }
188
189 } // namespace anonymous
190
191 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
192
193 RUNNER_TEST(TCC_0000_init)
194 {
195     remove_user_data();
196
197     int tmp;
198     auto control = Control::create();
199     RUNNER_ASSERT_MSG(
200         CKM_API_SUCCESS == (tmp = control->unlockUserKey(0, "t200-special-password")),
201         "Error=" << ErrorToString(tmp));
202 }
203
204 // updatedCCMode should succeed regardless of mdpp setting
205 RUNNER_TEST(TCC_0010_updateCCMode)
206 {
207     MdppState mdpp;
208
209     mdpp.set(NULL);
210     update_cc_mode();
211
212     mdpp.set(ENABLED);
213     update_cc_mode();
214
215     mdpp.set(ENFORCING);
216     update_cc_mode();
217
218     mdpp.set(DISABLED);
219     update_cc_mode();
220
221     mdpp.set("whatever");
222     update_cc_mode();
223 }
224
225 // tests without listener (ckm only)
226 RUNNER_TEST(TCC_0020_noListener)
227 {
228     stop_service(LISTENER);
229     MdppState mdpp;
230
231     remove_user_data();
232     save_keys();
233
234     mdpp.set(NULL);
235     update_cc_mode();
236     read_keys(CKM_API_SUCCESS);
237
238     mdpp.set(DISABLED);
239     update_cc_mode();
240     read_keys(CKM_API_SUCCESS);
241
242     mdpp.set("whatever");
243     update_cc_mode();
244     read_keys(CKM_API_SUCCESS);
245
246     mdpp.set(ENABLED);
247     update_cc_mode();
248     read_keys(CKM_API_ERROR_BAD_REQUEST);
249
250     mdpp.set(ENFORCING);
251     update_cc_mode();
252     read_keys(CKM_API_ERROR_BAD_REQUEST);
253
254     mdpp.set(DISABLED);
255     update_cc_mode();
256     read_keys(CKM_API_SUCCESS);
257 }
258
259 // when listener is started with mdpp key unset it should not update mdpp status in ckm
260 RUNNER_TEST(TCC_0030_noCallbackRegistered)
261 {
262     // restart listener without vconf callback
263     stop_service(LISTENER);
264     remove_user_data();
265     MdppState mdpp;
266     mdpp.set(NULL);
267     update_cc_mode();
268     start_service(LISTENER);
269
270     // save and read
271     save_keys();
272     read_keys(CKM_API_SUCCESS);
273
274     mdpp.set(ENABLED);
275     usleep(SLEEP); // give some time for notification to reach ckm
276
277     read_keys(CKM_API_SUCCESS);
278 }
279
280 // when listener is started with mdpp key set it should update mdpp status in ckm
281 RUNNER_TEST(TCC_0040_callbackRegistered)
282 {
283     // restart listener with vconf callback
284     stop_service(LISTENER);
285     MdppState mdpp;
286     mdpp.set(DISABLED);
287     update_cc_mode();
288     start_service(LISTENER);
289
290     remove_user_data();
291     save_keys();
292     read_keys(CKM_API_SUCCESS);
293
294     mdpp.set("whatever");
295     usleep(SLEEP); // give some time for notification to reach ckm
296     read_keys(CKM_API_SUCCESS);
297
298     mdpp.set(ENABLED);
299     usleep(SLEEP); // give some time for notification to reach ckm
300     read_keys(CKM_API_ERROR_BAD_REQUEST);
301
302     mdpp.set(DISABLED);
303     usleep(SLEEP); // give some time for notification to reach ckm
304     read_keys(CKM_API_SUCCESS);
305
306     mdpp.set(ENFORCING);
307     usleep(SLEEP); // give some time for notification to reach ckm
308     read_keys(CKM_API_ERROR_BAD_REQUEST);
309
310     mdpp.set(NULL);
311     usleep(SLEEP); // give some time for notification to reach ckm
312     read_keys(CKM_API_SUCCESS);
313 }
314
315 // run ckm manually and see if it properly loads mdpp setting
316 RUNNER_TEST(TCC_0050_manualCkmDisabled)
317 {
318     restart_ckm(DISABLED);
319
320     remove_user_data();
321     save_keys();
322     read_keys(CKM_API_SUCCESS);
323 }
324
325 // run ckm manually and see if it properly loads mdpp setting
326 RUNNER_TEST(TCC_0060_manualCkmEnabled)
327 {
328     restart_ckm(ENABLED);
329
330     remove_user_data();
331     save_keys();
332     read_keys(CKM_API_ERROR_BAD_REQUEST);
333 }
334
335 // run ckm manually and see if it properly loads mdpp setting
336 RUNNER_TEST(TCC_0070_manualCkmEnforcing)
337 {
338     restart_ckm(ENFORCING);
339
340     remove_user_data();
341     save_keys();
342     read_keys(CKM_API_ERROR_BAD_REQUEST);
343 }
344
345 // run ckm manually and see if it properly loads mdpp setting
346 RUNNER_TEST(TCC_0080_manualCkmWhatever)
347 {
348     restart_ckm("whatever");
349
350     remove_user_data();
351     save_keys();
352     read_keys(CKM_API_SUCCESS);
353 }
354
355 // run ckm manually and see if it properly loads mdpp setting
356 RUNNER_TEST(TCC_0090_manualCkmUnset)
357 {
358     restart_ckm(NULL);
359
360     remove_user_data();
361     save_keys();
362     read_keys(CKM_API_SUCCESS);
363 }
364
365 // make sure listener won't activate ckm to update mdpp
366 RUNNER_TEST(TCC_0100_listenerDoesntStartCkm)
367 {
368     stop_service(MANAGER);
369     stop_service(LISTENER);
370
371     MdppState mdpp;
372     mdpp.set(ENABLED);
373
374     start_service(LISTENER);
375
376     usleep(1000*1000); // by that time ckm would be already started
377
378     int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
379     RUNNER_ASSERT_MSG(-1 != lock, "Error in opening lock file. Errno: " << strerror(errno));
380
381     int ret = lockf(lock, F_TEST, 0);
382     close(lock);
383     RUNNER_ASSERT_MSG(ret == 0, "CKM lock is occupied. CKM seems to be running.");
384 }
385
386 RUNNER_TEST(TCC_9999_deinit)
387 {
388     remove_user_data();
389
390     int tmp;
391     auto control = Control::create();
392     RUNNER_ASSERT_MSG(
393         CKM_API_SUCCESS == (tmp = control->lockUserKey(0)),
394         "Error=" << ErrorToString(tmp));
395 }