CKM:Add compilation flag for MDPP
[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 <ckm-common.h>
35 #include <ckm/ckm-manager.h>
36 #include <ckm/ckm-control.h>
37
38 using namespace CKM;
39 using namespace std;
40
41 #ifndef VCONFKEY_SECURITY_MDPP_STATE
42 #define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state"
43 #endif
44
45 namespace {
46
47 const useconds_t SLEEP = 100*1000;
48
49 const size_t MAX_RETRIES = 50;
50
51 const char* const ENABLED = "Enabled";
52 const char* const ENFORCING = "Enforcing";
53 const char* const DISABLED = "Disabled";
54 const char* const READY = "Ready";
55
56 const char* const CKM_LOCK = "/var/run/key-manager.pid";
57
58
59 // disable CC
60 int _unset_mdpp_key = vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
61
62 // Wrapper for mdpp state that restores the original value upon destruction
63 class MdppState
64 {
65 public:
66     MdppState();
67     ~MdppState();
68
69     // pass NULL to unset
70     void set(const char* const value);
71
72 private:
73     char* m_original;
74 };
75
76 MdppState::MdppState()
77 {
78     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
79 }
80
81 MdppState::~MdppState()
82 {
83     if (!m_original)
84         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
85     else {
86         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
87         free(m_original);
88     }
89 }
90
91 void MdppState::set(const char* const value)
92 {
93     if (value)
94         RUNNER_ASSERT_MSG(0 == vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value),
95                              "vconf_set() failed");
96     else
97         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
98 }
99
100 void remove_user_data()
101 {
102     auto control = Control::create();
103     int ret = control->removeUserData(0);
104     RUNNER_ASSERT_MSG(ret == CKM_API_SUCCESS,
105                          "Remove user data failed with error: " << ErrorToString(ret));
106 }
107
108 Alias rsa_pri_alias("rsa-private-T2002");
109 Alias rsa_pub_alias("rsa-public-T2002");
110 Alias ecdsa_pri_alias("ecdsa-private-T2002");
111 Alias ecdsa_pub_alias("ecdsa-public-T2002");
112
113 void save_keys()
114 {
115     int temp;
116     auto manager = Manager::create();
117
118     RUNNER_ASSERT_MSG(
119         CKM_API_SUCCESS == (temp = manager->createKeyPairRSA(
120                 1024,
121                 rsa_pri_alias,
122                 rsa_pub_alias,
123                 Policy(Password(), true),
124                 Policy(Password(), true))),
125             "Error=" << ErrorToString(temp));
126
127     RUNNER_ASSERT_MSG(
128         CKM_API_SUCCESS == (temp = manager->createKeyPairECDSA(
129                 ElipticCurve::prime192v1,
130                 ecdsa_pri_alias,
131                 ecdsa_pub_alias,
132                 Policy(Password(), true),
133                 Policy(Password(), true))),
134             "Error=" << ErrorToString(temp));
135 }
136
137 void read_key(ManagerShPtr& manager, const Alias& alias, int expected) {
138     KeyShPtr key;
139     int temp;
140     RUNNER_ASSERT_MSG(
141             expected == (temp = manager->getKey(alias, Password(), key)),
142             "Expected: " << expected << "/" << ErrorToString(expected) << " got: " << temp << "/" <<
143             ErrorToString(temp));
144 }
145
146 void read_keys(int expected)
147 {
148 // if mdpp is disabled at compilation time we expect that read_key always succeeds
149 #ifndef DSECURITY_MDFPP_STATE_ENABLE
150     expected = CKM_API_SUCCESS;
151 #endif
152     auto manager = Manager::create();
153
154     read_key(manager, rsa_pri_alias, expected);
155     read_key(manager, ecdsa_pri_alias, expected);
156 }
157
158 void update_cc_mode()
159 {
160     auto control = Control::create();
161     int ret;
162     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
163                          "Error=" << ErrorToString(ret));
164 }
165
166 void restart_ckm(const char* const mdpp_setting)
167 {
168     stop_service(MANAGER);
169     MdppState mdpp;
170     mdpp.set(mdpp_setting);
171     start_service(MANAGER);
172 }
173
174 } // namespace anonymous
175
176 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
177
178 RUNNER_TEST(TCC_0000_init)
179 {
180     remove_user_data();
181
182     int tmp;
183     auto control = Control::create();
184     RUNNER_ASSERT_MSG(
185         CKM_API_SUCCESS == (tmp = control->unlockUserKey(0, "t200-special-password")),
186         "Error=" << ErrorToString(tmp));
187 }
188
189 // updatedCCMode should succeed regardless of mdpp setting
190 RUNNER_TEST(TCC_0010_updateCCMode)
191 {
192     MdppState mdpp;
193
194     mdpp.set(NULL);
195     update_cc_mode();
196
197     mdpp.set(ENABLED);
198     update_cc_mode();
199
200     mdpp.set(ENFORCING);
201     update_cc_mode();
202
203     mdpp.set(DISABLED);
204     update_cc_mode();
205
206     mdpp.set(READY);
207     update_cc_mode();
208
209     mdpp.set("whatever");
210     update_cc_mode();
211 }
212
213 // tests without listener (ckm only)
214 RUNNER_TEST(TCC_0020_noListener)
215 {
216     stop_service(LISTENER);
217     MdppState mdpp;
218
219     remove_user_data();
220     save_keys();
221
222     mdpp.set(NULL);
223     update_cc_mode();
224     read_keys(CKM_API_SUCCESS);
225
226     mdpp.set(DISABLED);
227     update_cc_mode();
228     // MJK, it's counter-intuitive: Disabled does not mean
229     // that CC mode is disabled, but that device
230     // self-test failed "device DISABLED"
231     read_keys(CKM_API_ERROR_BAD_REQUEST);
232
233     mdpp.set("whatever");
234     update_cc_mode();
235     read_keys(CKM_API_SUCCESS);
236
237     mdpp.set(ENABLED);
238     update_cc_mode();
239     read_keys(CKM_API_ERROR_BAD_REQUEST);
240
241     mdpp.set(ENFORCING);
242     update_cc_mode();
243     read_keys(CKM_API_ERROR_BAD_REQUEST);
244
245     mdpp.set(READY);
246     update_cc_mode();
247     read_keys(CKM_API_SUCCESS);
248
249     mdpp.set("whatever");
250     update_cc_mode();
251     read_keys(CKM_API_SUCCESS);
252
253     mdpp.set(DISABLED);
254     update_cc_mode();
255     read_keys(CKM_API_ERROR_BAD_REQUEST);
256 }
257
258 // when listener is started with mdpp key unset it should not update mdpp status in ckm
259 RUNNER_TEST(TCC_0030_noCallbackRegistered)
260 {
261     // restart listener without vconf callback
262     stop_service(LISTENER);
263     remove_user_data();
264     MdppState mdpp;
265     mdpp.set(NULL);
266     update_cc_mode();
267     start_service(LISTENER);
268
269     // save and read
270     save_keys();
271     read_keys(CKM_API_SUCCESS);
272
273     mdpp.set(ENABLED);
274     usleep(SLEEP); // give some time for notification to reach ckm
275
276     read_keys(CKM_API_SUCCESS);
277 }
278
279 // when listener is started with mdpp key set it should update mdpp status in ckm
280 RUNNER_TEST(TCC_0040_callbackRegistered)
281 {
282     // restart listener with vconf callback
283     stop_service(LISTENER);
284     MdppState mdpp;
285     mdpp.set(DISABLED);
286     update_cc_mode();
287     start_service(LISTENER);
288
289     remove_user_data();
290     save_keys();
291     read_keys(CKM_API_ERROR_BAD_REQUEST);
292
293     mdpp.set("whatever");
294     usleep(SLEEP); // give some time for notification to reach ckm
295     read_keys(CKM_API_SUCCESS);
296
297     mdpp.set(ENABLED);
298     usleep(SLEEP); // give some time for notification to reach ckm
299     read_keys(CKM_API_ERROR_BAD_REQUEST);
300
301     mdpp.set(DISABLED);
302     usleep(SLEEP); // give some time for notification to reach ckm
303     read_keys(CKM_API_ERROR_BAD_REQUEST);
304
305     mdpp.set(READY);
306     usleep(SLEEP); // give some time for notification to reach ckm
307     read_keys(CKM_API_SUCCESS);
308
309     mdpp.set(ENFORCING);
310     usleep(SLEEP); // give some time for notification to reach ckm
311     read_keys(CKM_API_ERROR_BAD_REQUEST);
312
313     mdpp.set(NULL);
314     usleep(SLEEP); // give some time for notification to reach ckm
315     read_keys(CKM_API_SUCCESS);
316 }
317
318 // run ckm manually and see if it properly loads mdpp setting
319 RUNNER_TEST(TCC_0050_manualCkmDisabled)
320 {
321     restart_ckm(DISABLED);
322
323     remove_user_data();
324     save_keys();
325     read_keys(CKM_API_ERROR_BAD_REQUEST);
326 }
327
328 // run ckm manually and see if it properly loads mdpp setting
329 RUNNER_TEST(TCC_0060_manualCkmEnabled)
330 {
331     restart_ckm(ENABLED);
332
333     remove_user_data();
334     save_keys();
335     read_keys(CKM_API_ERROR_BAD_REQUEST);
336 }
337
338 // run ckm manually and see if it properly loads mdpp setting
339 RUNNER_TEST(TCC_0070_manualCkmEnforcing)
340 {
341     restart_ckm(ENFORCING);
342
343     remove_user_data();
344     save_keys();
345     read_keys(CKM_API_ERROR_BAD_REQUEST);
346 }
347
348 // run ckm manually and see if it properly loads mdpp setting
349 RUNNER_TEST(TCC_0075_manualCkmReady)
350 {
351     restart_ckm(READY);
352
353     remove_user_data();
354     save_keys();
355     read_keys(CKM_API_SUCCESS);
356 }
357
358 // run ckm manually and see if it properly loads mdpp setting
359 RUNNER_TEST(TCC_0080_manualCkmWhatever)
360 {
361     restart_ckm("whatever");
362
363     remove_user_data();
364     save_keys();
365     read_keys(CKM_API_SUCCESS);
366 }
367
368 // run ckm manually and see if it properly loads mdpp setting
369 RUNNER_TEST(TCC_0090_manualCkmUnset)
370 {
371     restart_ckm(NULL);
372
373     remove_user_data();
374     save_keys();
375     read_keys(CKM_API_SUCCESS);
376 }
377
378 // make sure listener won't activate ckm to update mdpp
379 RUNNER_TEST(TCC_0100_listenerDoesntStartCkm)
380 {
381     stop_service(MANAGER);
382     stop_service(LISTENER);
383
384     MdppState mdpp;
385     mdpp.set(ENABLED);
386
387     start_service(LISTENER);
388
389     usleep(1000*1000); // by that time ckm would be already started
390
391     int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
392     RUNNER_ASSERT_MSG(-1 != lock, "Error in opening lock file. Errno: " << strerror(errno));
393
394     int ret = lockf(lock, F_TEST, 0);
395     close(lock);
396     RUNNER_ASSERT_MSG(ret == 0, "CKM lock is occupied. CKM seems to be running.");
397 }
398
399 RUNNER_TEST(TCC_9999_deinit)
400 {
401     remove_user_data();
402
403     int tmp;
404     auto control = Control::create();
405     RUNNER_ASSERT_MSG(
406         CKM_API_SUCCESS == (tmp = control->lockUserKey(0)),
407         "Error=" << ErrorToString(tmp));
408 }