Add tests for storing PKCS12 files.
[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
55 const char* const CKM_LOCK = "/var/run/key-manager.pid";
56
57
58 // disable CC
59 int _unset_mdpp_key = vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
60
61 // Wrapper for mdpp state that restores the original value upon destruction
62 class MdppState
63 {
64 public:
65     MdppState();
66     ~MdppState();
67
68     // pass NULL to unset
69     void set(const char* const value);
70
71 private:
72     char* m_original;
73 };
74
75 MdppState::MdppState()
76 {
77     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
78 }
79
80 MdppState::~MdppState()
81 {
82     if (!m_original)
83         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
84     else {
85         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
86         free(m_original);
87     }
88 }
89
90 void MdppState::set(const char* const value)
91 {
92     if (value)
93         RUNNER_ASSERT_MSG(0 == vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value),
94                              "vconf_set() failed");
95     else
96         vconf_unset(VCONFKEY_SECURITY_MDPP_STATE);
97 }
98
99 void remove_user_data()
100 {
101     auto control = Control::create();
102     int ret = control->removeUserData(0);
103     RUNNER_ASSERT_MSG(ret == CKM_API_SUCCESS,
104                          "Remove user data failed with error: " << ErrorToString(ret));
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     auto manager = Manager::create();
148
149     read_key(manager, rsa_pri_alias, expected);
150     read_key(manager, ecdsa_pri_alias, expected);
151 }
152
153 void update_cc_mode()
154 {
155     auto control = Control::create();
156     int ret;
157     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
158                          "Error=" << ErrorToString(ret));
159 }
160
161 void restart_ckm(const char* const mdpp_setting)
162 {
163     stop_service(MANAGER);
164     MdppState mdpp;
165     mdpp.set(mdpp_setting);
166     start_service(MANAGER);
167 }
168
169 } // namespace anonymous
170
171 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
172
173 RUNNER_TEST(TCC_0000_init)
174 {
175     remove_user_data();
176
177     int tmp;
178     auto control = Control::create();
179     RUNNER_ASSERT_MSG(
180         CKM_API_SUCCESS == (tmp = control->unlockUserKey(0, "t200-special-password")),
181         "Error=" << ErrorToString(tmp));
182 }
183
184 // updatedCCMode should succeed regardless of mdpp setting
185 RUNNER_TEST(TCC_0010_updateCCMode)
186 {
187     MdppState mdpp;
188
189     mdpp.set(NULL);
190     update_cc_mode();
191
192     mdpp.set(ENABLED);
193     update_cc_mode();
194
195     mdpp.set(ENFORCING);
196     update_cc_mode();
197
198     mdpp.set(DISABLED);
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     remove_user_data();
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("whatever");
238     update_cc_mode();
239     read_keys(CKM_API_SUCCESS);
240
241     mdpp.set(DISABLED);
242     update_cc_mode();
243     read_keys(CKM_API_ERROR_BAD_REQUEST);
244 }
245
246 // when listener is started with mdpp key unset it should not update mdpp status in ckm
247 RUNNER_TEST(TCC_0030_noCallbackRegistered)
248 {
249     // restart listener without vconf callback
250     stop_service(LISTENER);
251     remove_user_data();
252     MdppState mdpp;
253     mdpp.set(NULL);
254     update_cc_mode();
255     start_service(LISTENER);
256
257     // save and read
258     save_keys();
259     read_keys(CKM_API_SUCCESS);
260
261     mdpp.set(ENABLED);
262     usleep(SLEEP); // give some time for notification to reach ckm
263
264     read_keys(CKM_API_SUCCESS);
265 }
266
267 // when listener is started with mdpp key set it should update mdpp status in ckm
268 RUNNER_TEST(TCC_0040_callbackRegistered)
269 {
270     // restart listener with vconf callback
271     stop_service(LISTENER);
272     MdppState mdpp;
273     mdpp.set(DISABLED);
274     update_cc_mode();
275     start_service(LISTENER);
276
277     remove_user_data();
278     save_keys();
279     read_keys(CKM_API_ERROR_BAD_REQUEST);
280
281     mdpp.set("whatever");
282     usleep(SLEEP); // give some time for notification to reach ckm
283     read_keys(CKM_API_SUCCESS);
284
285     mdpp.set(ENABLED);
286     usleep(SLEEP); // give some time for notification to reach ckm
287     read_keys(CKM_API_ERROR_BAD_REQUEST);
288
289     mdpp.set(DISABLED);
290     usleep(SLEEP); // give some time for notification to reach ckm
291     read_keys(CKM_API_ERROR_BAD_REQUEST);
292
293     mdpp.set(ENFORCING);
294     usleep(SLEEP); // give some time for notification to reach ckm
295     read_keys(CKM_API_ERROR_BAD_REQUEST);
296
297     mdpp.set(NULL);
298     usleep(SLEEP); // give some time for notification to reach ckm
299     read_keys(CKM_API_SUCCESS);
300 }
301
302 // run ckm manually and see if it properly loads mdpp setting
303 RUNNER_TEST(TCC_0050_manualCkmDisabled)
304 {
305     restart_ckm(DISABLED);
306
307     remove_user_data();
308     save_keys();
309     read_keys(CKM_API_ERROR_BAD_REQUEST);
310 }
311
312 // run ckm manually and see if it properly loads mdpp setting
313 RUNNER_TEST(TCC_0060_manualCkmEnabled)
314 {
315     restart_ckm(ENABLED);
316
317     remove_user_data();
318     save_keys();
319     read_keys(CKM_API_ERROR_BAD_REQUEST);
320 }
321
322 // run ckm manually and see if it properly loads mdpp setting
323 RUNNER_TEST(TCC_0070_manualCkmEnforcing)
324 {
325     restart_ckm(ENFORCING);
326
327     remove_user_data();
328     save_keys();
329     read_keys(CKM_API_ERROR_BAD_REQUEST);
330 }
331
332 // run ckm manually and see if it properly loads mdpp setting
333 RUNNER_TEST(TCC_0080_manualCkmWhatever)
334 {
335     restart_ckm("whatever");
336
337     remove_user_data();
338     save_keys();
339     read_keys(CKM_API_SUCCESS);
340 }
341
342 // run ckm manually and see if it properly loads mdpp setting
343 RUNNER_TEST(TCC_0090_manualCkmUnset)
344 {
345     restart_ckm(NULL);
346
347     remove_user_data();
348     save_keys();
349     read_keys(CKM_API_SUCCESS);
350 }
351
352 // make sure listener won't activate ckm to update mdpp
353 RUNNER_TEST(TCC_0100_listenerDoesntStartCkm)
354 {
355     stop_service(MANAGER);
356     stop_service(LISTENER);
357
358     MdppState mdpp;
359     mdpp.set(ENABLED);
360
361     start_service(LISTENER);
362
363     usleep(1000*1000); // by that time ckm would be already started
364
365     int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
366     RUNNER_ASSERT_MSG(-1 != lock, "Error in opening lock file. Errno: " << strerror(errno));
367
368     int ret = lockf(lock, F_TEST, 0);
369     close(lock);
370     RUNNER_ASSERT_MSG(ret == 0, "CKM lock is occupied. CKM seems to be running.");
371 }
372
373 RUNNER_TEST(TCC_9999_deinit)
374 {
375     remove_user_data();
376
377     int tmp;
378     auto control = Control::create();
379     RUNNER_ASSERT_MSG(
380         CKM_API_SUCCESS == (tmp = control->lockUserKey(0)),
381         "Error=" << ErrorToString(tmp));
382 }