Merge branch 'tizen' into cynara
[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 const char* const CC_PASSWD = "t200-special-password";
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     ScopedLabel sl(USER_LABEL);
79     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
80 }
81
82 MdppState::~MdppState()
83 {
84     ScopedLabel sl(USER_LABEL);
85     if (!m_original)
86         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
87     else {
88         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
89     }
90 }
91
92 void MdppState::set(const char* const value)
93 {
94     ScopedLabel sl(USER_LABEL);
95     if (value)
96     {
97         int ret = vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value);
98         RUNNER_ASSERT_MSG(0 == ret,
99                              "vconf_set() failed, ec: " << ret);
100     }
101     else
102         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
103 }
104
105
106
107 Alias rsa_pri_alias("rsa-private-T2002");
108 Alias rsa_pub_alias("rsa-public-T2002");
109 Alias ecdsa_pri_alias("ecdsa-private-T2002");
110 Alias ecdsa_pub_alias("ecdsa-public-T2002");
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=" << ErrorToString(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=" << ErrorToString(temp));
134 }
135
136 void read_key(ManagerShPtr& manager, const Alias& alias, int expected) {
137     KeyShPtr key;
138     int temp;
139     RUNNER_ASSERT_MSG(
140             expected == (temp = manager->getKey(alias, Password(), key)),
141             "Expected: " << expected << "/" << ErrorToString(expected) << " got: " << temp << "/" <<
142             ErrorToString(temp));
143 }
144
145 void read_keys(int expected)
146 {
147 // if mdpp is disabled at compilation time we expect that read_key always succeeds
148 #ifndef DSECURITY_MDFPP_STATE_ENABLE
149     expected = CKM_API_SUCCESS;
150 #endif
151     auto manager = Manager::create();
152
153     read_key(manager, rsa_pri_alias, expected);
154     read_key(manager, ecdsa_pri_alias, expected);
155 }
156
157 void update_cc_mode()
158 {
159     auto control = Control::create();
160     int ret;
161     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
162                          "Error=" << ErrorToString(ret));
163 }
164
165 void restart_ckm(const char* const mdpp_setting)
166 {
167     stop_service(MANAGER);
168     MdppState mdpp;
169     mdpp.set(mdpp_setting);
170     start_service(MANAGER);
171 }
172 } // namespace anonymous
173
174 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
175
176 RUNNER_TEST(TCC_0000_init)
177 {
178     reset_user_data(0, CC_PASSWD);
179 }
180
181 // updatedCCMode should succeed regardless of mdpp setting
182 RUNNER_TEST(TCC_0010_updateCCMode)
183 {
184     MdppState mdpp;
185
186     mdpp.set(NULL);
187     update_cc_mode();
188
189     mdpp.set(ENABLED);
190     update_cc_mode();
191
192     mdpp.set(ENFORCING);
193     update_cc_mode();
194
195     mdpp.set(DISABLED);
196     update_cc_mode();
197
198     mdpp.set(READY);
199     update_cc_mode();
200
201     mdpp.set("whatever");
202     update_cc_mode();
203 }
204
205 // tests without listener (ckm only)
206 RUNNER_TEST(TCC_0020_noListener)
207 {
208     stop_service(LISTENER);
209     MdppState mdpp;
210
211     reset_user_data(0, CC_PASSWD);
212     save_keys();
213
214     mdpp.set(NULL);
215     update_cc_mode();
216     read_keys(CKM_API_SUCCESS);
217
218     mdpp.set(DISABLED);
219     update_cc_mode();
220     // MJK, it's counter-intuitive: Disabled does not mean
221     // that CC mode is disabled, but that device
222     // self-test failed "device DISABLED"
223     read_keys(CKM_API_ERROR_BAD_REQUEST);
224
225     mdpp.set("whatever");
226     update_cc_mode();
227     read_keys(CKM_API_SUCCESS);
228
229     mdpp.set(ENABLED);
230     update_cc_mode();
231     read_keys(CKM_API_ERROR_BAD_REQUEST);
232
233     mdpp.set(ENFORCING);
234     update_cc_mode();
235     read_keys(CKM_API_ERROR_BAD_REQUEST);
236
237     mdpp.set(READY);
238     update_cc_mode();
239     read_keys(CKM_API_SUCCESS);
240
241     mdpp.set("whatever");
242     update_cc_mode();
243     read_keys(CKM_API_SUCCESS);
244
245     mdpp.set(DISABLED);
246     update_cc_mode();
247     read_keys(CKM_API_ERROR_BAD_REQUEST);
248 }
249
250 // when listener is started with mdpp key unset it should not update mdpp status in ckm
251 RUNNER_TEST(TCC_0030_noCallbackRegistered)
252 {
253     // restart listener without vconf callback
254     stop_service(LISTENER);
255     reset_user_data(0, CC_PASSWD);
256     MdppState mdpp;
257     mdpp.set(NULL);
258     update_cc_mode();
259     start_service(LISTENER);
260
261     // save and read
262     save_keys();
263     read_keys(CKM_API_SUCCESS);
264
265     mdpp.set(ENABLED);
266     usleep(SLEEP); // give some time for notification to reach ckm
267
268     read_keys(CKM_API_SUCCESS);
269 }
270
271 // when listener is started with mdpp key set it should update mdpp status in ckm
272 RUNNER_TEST(TCC_0040_callbackRegistered)
273 {
274     // restart listener with vconf callback
275     stop_service(LISTENER);
276     MdppState mdpp;
277     mdpp.set(DISABLED);
278     update_cc_mode();
279     start_service(LISTENER);
280
281     reset_user_data(0, CC_PASSWD);
282     save_keys();
283     read_keys(CKM_API_ERROR_BAD_REQUEST);
284
285     mdpp.set("whatever");
286     usleep(SLEEP); // give some time for notification to reach ckm
287     read_keys(CKM_API_SUCCESS);
288
289     mdpp.set(ENABLED);
290     usleep(SLEEP); // give some time for notification to reach ckm
291     read_keys(CKM_API_ERROR_BAD_REQUEST);
292
293     mdpp.set(DISABLED);
294     usleep(SLEEP); // give some time for notification to reach ckm
295     read_keys(CKM_API_ERROR_BAD_REQUEST);
296
297     mdpp.set(READY);
298     usleep(SLEEP); // give some time for notification to reach ckm
299     read_keys(CKM_API_SUCCESS);
300
301     mdpp.set(ENFORCING);
302     usleep(SLEEP); // give some time for notification to reach ckm
303     read_keys(CKM_API_ERROR_BAD_REQUEST);
304
305     mdpp.set(NULL);
306     usleep(SLEEP); // give some time for notification to reach ckm
307     read_keys(CKM_API_SUCCESS);
308 }
309
310 // run ckm manually and see if it properly loads mdpp setting
311 RUNNER_TEST(TCC_0050_manualCkmDisabled)
312 {
313     restart_ckm(DISABLED);
314
315     reset_user_data(0, CC_PASSWD);
316     save_keys();
317     read_keys(CKM_API_ERROR_BAD_REQUEST);
318 }
319
320 // run ckm manually and see if it properly loads mdpp setting
321 RUNNER_TEST(TCC_0060_manualCkmEnabled)
322 {
323     restart_ckm(ENABLED);
324
325     reset_user_data(0, CC_PASSWD);
326     save_keys();
327     read_keys(CKM_API_ERROR_BAD_REQUEST);
328 }
329
330 // run ckm manually and see if it properly loads mdpp setting
331 RUNNER_TEST(TCC_0070_manualCkmEnforcing)
332 {
333     restart_ckm(ENFORCING);
334
335     reset_user_data(0, CC_PASSWD);
336     save_keys();
337     read_keys(CKM_API_ERROR_BAD_REQUEST);
338 }
339
340 // run ckm manually and see if it properly loads mdpp setting
341 RUNNER_TEST(TCC_0075_manualCkmReady)
342 {
343     restart_ckm(READY);
344
345     reset_user_data(0, CC_PASSWD);
346     save_keys();
347     read_keys(CKM_API_SUCCESS);
348 }
349
350 // run ckm manually and see if it properly loads mdpp setting
351 RUNNER_TEST(TCC_0080_manualCkmWhatever)
352 {
353     restart_ckm("whatever");
354
355     reset_user_data(0, CC_PASSWD);
356     save_keys();
357     read_keys(CKM_API_SUCCESS);
358 }
359
360 // run ckm manually and see if it properly loads mdpp setting
361 RUNNER_TEST(TCC_0090_manualCkmUnset)
362 {
363     restart_ckm(NULL);
364
365     reset_user_data(0, CC_PASSWD);
366     save_keys();
367     read_keys(CKM_API_SUCCESS);
368 }
369
370 // make sure listener won't activate ckm to update mdpp
371 RUNNER_TEST(TCC_0100_listenerDoesntStartCkm)
372 {
373     stop_service(MANAGER);
374     stop_service(LISTENER);
375
376     MdppState mdpp;
377     mdpp.set(ENABLED);
378
379     start_service(LISTENER);
380
381     usleep(1000*1000); // by that time ckm would be already started
382
383     int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
384     RUNNER_ASSERT_MSG(-1 != lock, "Error in opening lock file. Errno: " << strerror(errno));
385
386     int ret = lockf(lock, F_TEST, 0);
387     close(lock);
388     RUNNER_ASSERT_MSG(ret == 0, "CKM lock is occupied. CKM seems to be running.");
389 }
390
391 RUNNER_TEST(TCC_9999_deinit)
392 {
393     remove_user_data(0);
394 }