Run key-manager test on onlycap
[platform/core/test/security-tests.git] / src / 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 const char* const UNSET = "Unset"; // Meaningless value for unset.
56
57 const char* const USER_LABEL = "User";
58 const char* const CKM_LOCK = "/var/run/key-manager.pid";
59
60 // Wrapper for mdpp state that restores the original value upon destruction
61 class MdppState
62 {
63 public:
64     MdppState();
65     ~MdppState();
66
67     // pass NULL to unset
68     void set(const char* const value);
69
70 private:
71     char* m_original;
72 };
73
74 MdppState::MdppState()
75 {
76     ScopedLabel sl(USER_LABEL);
77     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
78 }
79
80 MdppState::~MdppState()
81 {
82     ScopedLabel sl(USER_LABEL);
83     if (!m_original)
84         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
85     else {
86         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
87     }
88 }
89
90 void MdppState::set(const char* const value)
91 {
92     ScopedLabel sl(USER_LABEL);
93     if (value)
94     {
95         int ret = vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value);
96         RUNNER_ASSERT_MSG(0 == ret,
97                              "vconf_set() failed, ec: " << ret);
98     }
99     else
100         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
101 }
102
103
104
105 Alias rsa_pri_alias = sharedDatabase("rsa-private-T2002");
106 Alias rsa_pub_alias = sharedDatabase("rsa-public-T2002");
107 Alias ecdsa_pri_alias = sharedDatabase("ecdsa-private-T2002");
108 Alias ecdsa_pub_alias = sharedDatabase("ecdsa-public-T2002");
109 Alias aes_alias = sharedDatabase("aes-T2002");
110 size_t aes_length = 128;
111
112 void save_keys()
113 {
114     int temp;
115     auto manager = Manager::create();
116
117     RUNNER_ASSERT_MSG(
118         CKM_API_SUCCESS == (temp = manager->createKeyPairRSA(
119                 1024,
120                 rsa_pri_alias,
121                 rsa_pub_alias,
122                 Policy(Password(), true),
123                 Policy(Password(), true))),
124             "Error=" << CKMErrorToString(temp));
125
126     RUNNER_ASSERT_MSG(
127         CKM_API_SUCCESS == (temp = manager->createKeyPairECDSA(
128                 ElipticCurve::prime192v1,
129                 ecdsa_pri_alias,
130                 ecdsa_pub_alias,
131                 Policy(Password(), true),
132                 Policy(Password(), true))),
133             "Error=" << CKMErrorToString(temp));
134
135     RUNNER_ASSERT_MSG(
136         CKM_API_SUCCESS == (temp = manager->createKeyAES(
137                 aes_length,
138                 aes_alias,
139                 Policy(Password(), true))),
140             "Error=" << CKMErrorToString(temp));
141 }
142
143 void read_key(ManagerShPtr& manager, const Alias& alias, int expected) {
144     KeyShPtr key;
145     int temp;
146     RUNNER_ASSERT_MSG(
147             expected == (temp = manager->getKey(alias, Password(), key)),
148             "Expected: " << expected << "/" << CKMErrorToString(expected) << " got: " << temp << "/" <<
149             CKMErrorToString(temp));
150 }
151
152 void read_keys(int expected)
153 {
154 // if mdpp is disabled at compilation time we expect that read_key always succeeds
155 #ifndef DSECURITY_MDFPP_STATE_ENABLE
156     expected = CKM_API_SUCCESS;
157 #endif
158     auto manager = Manager::create();
159
160     read_key(manager, rsa_pri_alias, expected);
161     read_key(manager, ecdsa_pri_alias, expected);
162     read_key(manager, aes_alias, expected);
163 }
164
165 void update_cc_mode()
166 {
167     auto control = Control::create();
168     int ret;
169     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
170                          "Error=" << CKMErrorToString(ret));
171 }
172
173 void restart_ckm(const char* const mdpp_setting)
174 {
175     stop_service(MANAGER);
176     MdppState mdpp;
177     mdpp.set(mdpp_setting);
178     start_service(MANAGER);
179 }
180 } // namespace anonymous
181
182 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
183
184 RUNNER_TEST(TCC_0000_init)
185 {
186     remove_user_data(0);
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(0);
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(0);
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(0);
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(0);
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(0);
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(0);
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(0);
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(0);
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(0);
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(0);
402 }