Generic solution for onlycap issues
[platform/core/test/security-tests.git] / src / ckm / privileged / cc-mode.cpp
1 /*
2  *  Copyright (c) 2000 - 2019 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 #include <scoped_process_label.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 const char* const READY = "Ready";
56 const char* const UNSET = "Unset"; // Meaningless value for unset.
57
58 const char* const USER_LABEL = "User";
59 const char* const CKM_LOCK = "/var/run/key-manager.pid";
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     ScopedProcessLabel spl(USER_LABEL);
78     m_original = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
79 }
80
81 MdppState::~MdppState()
82 {
83     ScopedProcessLabel spl(USER_LABEL);
84     if (!m_original)
85         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
86     else {
87         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, m_original);
88     }
89 }
90
91 void MdppState::set(const char* const value)
92 {
93     ScopedProcessLabel spl(USER_LABEL);
94     if (value)
95     {
96         int ret = vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, value);
97         RUNNER_ASSERT_MSG(0 == ret,
98                              "vconf_set() failed, ec: " << ret);
99     }
100     else
101         vconf_set_str(VCONFKEY_SECURITY_MDPP_STATE, UNSET);
102 }
103
104
105
106 Alias rsa_pri_alias = sharedDatabase("rsa-private-T2002");
107 Alias rsa_pub_alias = sharedDatabase("rsa-public-T2002");
108 Alias ecdsa_pri_alias = sharedDatabase("ecdsa-private-T2002");
109 Alias ecdsa_pub_alias = sharedDatabase("ecdsa-public-T2002");
110 Alias aes_alias = sharedDatabase("aes-T2002");
111 size_t aes_length = 128;
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=" << APICodeToString(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=" << APICodeToString(temp));
135
136     RUNNER_ASSERT_MSG(
137         CKM_API_SUCCESS == (temp = manager->createKeyAES(
138                 aes_length,
139                 aes_alias,
140                 Policy(Password(), true))),
141             "Error=" << APICodeToString(temp));
142 }
143
144 void read_key(ManagerShPtr& manager, const Alias& alias, int expected) {
145     KeyShPtr key;
146     int temp;
147     RUNNER_ASSERT_MSG(
148             expected == (temp = manager->getKey(alias, Password(), key)),
149             "Expected: " << expected << "/" << APICodeToString(expected) << " got: " << temp << "/" <<
150             APICodeToString(temp));
151 }
152
153 void read_keys(int expected)
154 {
155 // if mdpp is disabled at compilation time we expect that read_key always succeeds
156 #ifndef DSECURITY_MDFPP_STATE_ENABLE
157     expected = CKM_API_SUCCESS;
158 #endif
159     auto manager = Manager::create();
160
161     read_key(manager, rsa_pri_alias, expected);
162     read_key(manager, ecdsa_pri_alias, expected);
163     read_key(manager, aes_alias, expected);
164 }
165
166 void update_cc_mode()
167 {
168     auto control = Control::create();
169     int ret;
170     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->updateCCMode()),
171                          "Error=" << APICodeToString(ret));
172 }
173
174 void restart_ckm(const char* const mdpp_setting)
175 {
176     stop_service(MANAGER);
177     MdppState mdpp;
178     mdpp.set(mdpp_setting);
179     start_service(MANAGER);
180 }
181 } // namespace anonymous
182
183 RUNNER_TEST_GROUP_INIT(CKM_CC_MODE);
184
185 RUNNER_TEST(TCC_0000_init)
186 {
187     remove_user_data(0);
188 }
189
190 // updatedCCMode should succeed regardless of mdpp setting
191 RUNNER_TEST(TCC_0010_updateCCMode)
192 {
193     MdppState mdpp;
194
195     mdpp.set(NULL);
196     update_cc_mode();
197
198     mdpp.set(ENABLED);
199     update_cc_mode();
200
201     mdpp.set(ENFORCING);
202     update_cc_mode();
203
204     mdpp.set(DISABLED);
205     update_cc_mode();
206
207     mdpp.set(READY);
208     update_cc_mode();
209
210     mdpp.set("whatever");
211     update_cc_mode();
212 }
213
214 // tests without listener (ckm only)
215 RUNNER_TEST(TCC_0020_noListener)
216 {
217     stop_service(LISTENER);
218     MdppState mdpp;
219
220     remove_user_data(0);
221     save_keys();
222
223     mdpp.set(NULL);
224     update_cc_mode();
225     read_keys(CKM_API_SUCCESS);
226
227     mdpp.set(DISABLED);
228     update_cc_mode();
229     // MJK, it's counter-intuitive: Disabled does not mean
230     // that CC mode is disabled, but that device
231     // self-test failed "device DISABLED"
232     read_keys(CKM_API_ERROR_BAD_REQUEST);
233
234     mdpp.set("whatever");
235     update_cc_mode();
236     read_keys(CKM_API_SUCCESS);
237
238     mdpp.set(ENABLED);
239     update_cc_mode();
240     read_keys(CKM_API_ERROR_BAD_REQUEST);
241
242     mdpp.set(ENFORCING);
243     update_cc_mode();
244     read_keys(CKM_API_ERROR_BAD_REQUEST);
245
246     mdpp.set(READY);
247     update_cc_mode();
248     read_keys(CKM_API_SUCCESS);
249
250     mdpp.set("whatever");
251     update_cc_mode();
252     read_keys(CKM_API_SUCCESS);
253
254     mdpp.set(DISABLED);
255     update_cc_mode();
256     read_keys(CKM_API_ERROR_BAD_REQUEST);
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(0);
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(0);
291     save_keys();
292     read_keys(CKM_API_ERROR_BAD_REQUEST);
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_ERROR_BAD_REQUEST);
305
306     mdpp.set(READY);
307     usleep(SLEEP); // give some time for notification to reach ckm
308     read_keys(CKM_API_SUCCESS);
309
310     mdpp.set(ENFORCING);
311     usleep(SLEEP); // give some time for notification to reach ckm
312     read_keys(CKM_API_ERROR_BAD_REQUEST);
313
314     mdpp.set(NULL);
315     usleep(SLEEP); // give some time for notification to reach ckm
316     read_keys(CKM_API_SUCCESS);
317 }
318
319 // run ckm manually and see if it properly loads mdpp setting
320 RUNNER_TEST(TCC_0050_manualCkmDisabled)
321 {
322     restart_ckm(DISABLED);
323
324     remove_user_data(0);
325     save_keys();
326     read_keys(CKM_API_ERROR_BAD_REQUEST);
327 }
328
329 // run ckm manually and see if it properly loads mdpp setting
330 RUNNER_TEST(TCC_0060_manualCkmEnabled)
331 {
332     restart_ckm(ENABLED);
333
334     remove_user_data(0);
335     save_keys();
336     read_keys(CKM_API_ERROR_BAD_REQUEST);
337 }
338
339 // run ckm manually and see if it properly loads mdpp setting
340 RUNNER_TEST(TCC_0070_manualCkmEnforcing)
341 {
342     restart_ckm(ENFORCING);
343
344     remove_user_data(0);
345     save_keys();
346     read_keys(CKM_API_ERROR_BAD_REQUEST);
347 }
348
349 // run ckm manually and see if it properly loads mdpp setting
350 RUNNER_TEST(TCC_0075_manualCkmReady)
351 {
352     restart_ckm(READY);
353
354     remove_user_data(0);
355     save_keys();
356     read_keys(CKM_API_SUCCESS);
357 }
358
359 // run ckm manually and see if it properly loads mdpp setting
360 RUNNER_TEST(TCC_0080_manualCkmWhatever)
361 {
362     restart_ckm("whatever");
363
364     remove_user_data(0);
365     save_keys();
366     read_keys(CKM_API_SUCCESS);
367 }
368
369 // run ckm manually and see if it properly loads mdpp setting
370 RUNNER_TEST(TCC_0090_manualCkmUnset)
371 {
372     restart_ckm(NULL);
373
374     remove_user_data(0);
375     save_keys();
376     read_keys(CKM_API_SUCCESS);
377 }
378
379 // make sure listener won't activate ckm to update mdpp
380 RUNNER_TEST(TCC_0100_listenerDoesntStartCkm)
381 {
382     stop_service(MANAGER);
383     stop_service(LISTENER);
384
385     MdppState mdpp;
386     mdpp.set(ENABLED);
387
388     start_service(LISTENER);
389
390     usleep(1000*1000); // by that time ckm would be already started
391
392     int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
393     RUNNER_ASSERT_MSG(-1 != lock, "Error in opening lock file. Errno: " << strerror(errno));
394
395     int ret = lockf(lock, F_TEST, 0);
396     close(lock);
397     RUNNER_ASSERT_MSG(ret == 0, "CKM lock is occupied. CKM seems to be running.");
398 }
399
400 RUNNER_TEST(TCC_9999_deinit)
401 {
402     remove_user_data(0);
403 }