CKM: no more "empty password for lockscreen" logics.
[platform/core/test/security-tests.git] / tests / ckm / capi-certificate-chains.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       capi-certificate-chains.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21
22 #include <stdarg.h>
23
24 #include <string>
25 #include <memory>
26
27 #include <dpl/test/test_runner.h>
28
29 #include <tests_common.h>
30 #include <test-certs.h>
31 #include <ckm-common.h>
32
33 #include <ckmc/ckmc-manager.h>
34 #include <ckmc/ckmc-control.h>
35 #include <ckmc/ckmc-type.h>
36 #include <ckmc/ckmc-error.h>
37
38 namespace {
39
40 const char *CHAINS_PASSWD = "chains-pass";
41
42 typedef std::unique_ptr<ckmc_cert_s, void (*)(ckmc_cert_s*)> CertPtr;
43 typedef std::unique_ptr<ckmc_cert_list_s, void (*)(ckmc_cert_list_s*)> CertListPtr;
44 typedef std::unique_ptr<ckmc_alias_list_s, void (*)(ckmc_alias_list_s*)> AliasListPtr;
45
46 ckmc_cert_s* create_cert(TestData::certificateID idx) {
47
48     std::string cert_raw = TestData::getTestCertificateBase64(idx);
49
50     ckmc_cert_s* cert = NULL;
51     assert_positive(ckmc_cert_new,
52                     reinterpret_cast<unsigned char*>(const_cast<char*>(cert_raw.c_str())),
53                     cert_raw.size(),
54                     CKMC_FORM_PEM,
55                     &cert);
56
57     RUNNER_ASSERT_MSG(cert != NULL, "Cert is NULL");
58     return cert;
59 }
60
61 void save_cert(const ckmc_cert_s* cert, const char* alias) {
62     ckmc_policy_s policy;
63     policy.password = NULL;
64     policy.extractable = 1;
65
66     assert_positive(ckmc_save_cert, alias, *cert, policy);
67 }
68
69 // list gets copies of aliases
70 AliasListPtr create_alias_list(const char* alias, ...) {
71     AliasListPtr aliasList(NULL, ckmc_alias_list_all_free);
72
73     va_list ap;
74
75     va_start(ap, alias);
76     ckmc_alias_list_s* last = NULL;
77     for (const char* a = alias; a != NULL; a = va_arg(ap, const char*)) {
78         if (aliasList == NULL) {
79             ckmc_alias_list_s* tmp = NULL;
80             assert_positive(ckmc_alias_list_new, strdup(a), &tmp);
81             aliasList = AliasListPtr(tmp, ckmc_alias_list_all_free);
82             RUNNER_ASSERT_MSG(!!aliasList, "Alias list is NULL");
83             last = aliasList.get();
84         } else {
85             assert_positive(ckmc_alias_list_add, last, strdup(a), &last);
86             RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
87         }
88     }
89     va_end(ap);
90
91     return aliasList;
92 }
93
94 // list takes ownership of provided certificates
95 CertListPtr create_cert_list(ckmc_cert_s* cert, ...) {
96     CertListPtr certList(NULL, ckmc_cert_list_all_free);
97
98     va_list ap;
99
100     va_start(ap, cert);
101     ckmc_cert_list_s* last = NULL;
102     for (ckmc_cert_s* c = cert; c!=NULL; c = va_arg(ap, ckmc_cert_s*)) {
103         if (!certList) {
104             ckmc_cert_list_s* tmp = NULL;
105             assert_positive(ckmc_cert_list_new, c, &tmp);
106             certList = CertListPtr(tmp, ckmc_cert_list_all_free);
107             RUNNER_ASSERT_MSG(!!certList, "Cert list is NULL");
108             last = certList.get();
109         } else {
110             assert_positive(ckmc_cert_list_add, last, c, &last);
111             RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
112         }
113     }
114     va_end(ap);
115
116     return certList;
117 }
118
119 const ckmc_alias_list_s* NULL_ALIASES = NULL;
120 const ckmc_cert_s* NULL_CERT = NULL;
121 ckmc_cert_list_s** NULL_CHAIN = NULL;
122
123 // old api wrapper
124 class ChainApiOld {
125 public:
126     static int createChain(const ckmc_cert_s *cert,
127                            const ckmc_cert_list_s *untrustedcerts,
128                            const ckmc_cert_list_s* /*trustedcerts*/,
129                            const bool /*use_trustedsystemcerts*/,
130                            ckmc_cert_list_s **ppcert_chain_list)
131     {
132         return ckmc_get_cert_chain(cert, untrustedcerts, ppcert_chain_list);
133     }
134
135     static int createChainWithAlias(const ckmc_cert_s *cert,
136                                     const ckmc_alias_list_s *untrustedcerts,
137                                     const ckmc_alias_list_s* /*trustedcerts*/,
138                                     const bool /*use_trustedsystemcerts*/,
139                                     ckmc_cert_list_s **ppcert_chain_list)
140     {
141         return ckmc_get_cert_chain_with_alias(cert, untrustedcerts, ppcert_chain_list);
142     }
143 };
144
145 // new api wrapper
146 class ChainApiNew {
147 public:
148     static int createChain(const ckmc_cert_s *cert,
149                            const ckmc_cert_list_s *untrustedcerts,
150                            const ckmc_cert_list_s *trustedcerts,
151                            const bool use_trustedsystemcerts,
152                            ckmc_cert_list_s **ppcert_chain_list)
153     {
154         return ckmc_get_cert_chain_with_trustedcert(cert,
155                                                     untrustedcerts,
156                                                     trustedcerts,
157                                                     use_trustedsystemcerts,
158                                                     ppcert_chain_list);
159     }
160
161     static int createChainWithAlias(const ckmc_cert_s *cert,
162                                     const ckmc_alias_list_s *untrustedcerts,
163                                     const ckmc_alias_list_s *trustedcerts,
164                                     const bool use_trustedsystemcerts,
165                                     ckmc_cert_list_s **ppcert_chain_list)
166     {
167         return ckmc_get_cert_chain_with_trustedcert_alias(cert,
168                                                           untrustedcerts,
169                                                           trustedcerts,
170                                                           use_trustedsystemcerts,
171                                                           ppcert_chain_list);
172     }
173 };
174
175 /*
176  * Helper class for certificate verification
177  */
178 template <typename T=ChainApiNew>
179 class ChainVerifier
180 {
181 public:
182     ChainVerifier();
183     ~ChainVerifier();
184
185     void addTrusted(TestData::certificateID idx);
186     void addUntrusted(TestData::certificateID idx);
187     void enableSystem(bool enable);
188
189     void verifyPositive(TestData::certificateID idx, size_t expected);
190     void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
191
192 private:
193     void addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert);
194     void addAlias(ckmc_alias_list_s*& list, const char* alias);
195
196     ckmc_cert_list_s* m_trustedCerts;
197     ckmc_alias_list_s* m_trustedAliases;
198
199     ckmc_cert_list_s* m_untrustedCerts;
200     ckmc_alias_list_s* m_untrustedAliases;
201
202     bool m_system;
203 };
204
205 template <typename T>
206 ChainVerifier<T>::ChainVerifier() :
207         m_trustedCerts(NULL),
208         m_trustedAliases(NULL),
209         m_untrustedCerts(NULL),
210         m_untrustedAliases(NULL),
211         m_system(true)
212 {
213 }
214
215 template <typename T>
216 ChainVerifier<T>::~ChainVerifier()
217 {
218     ckmc_cert_list_all_free(m_trustedCerts);
219     ckmc_cert_list_all_free(m_untrustedCerts);
220     ckmc_alias_list_all_free(m_trustedAliases);
221     ckmc_alias_list_all_free(m_untrustedAliases);
222 }
223
224 template <typename T>
225 void ChainVerifier<T>::addTrusted(TestData::certificateID idx)
226 {
227     size_t size = list_size(m_trustedCerts);
228     ckmc_cert_s* cert = create_cert(idx);
229     addCert(m_trustedCerts, cert);
230
231     std::stringstream ss;
232     ss << "TRUSTED_CERT_ALIAS_" << size;
233     save_cert(cert, ss.str().c_str());
234     addAlias(m_trustedAliases, ss.str().c_str());
235 }
236
237 template <typename T>
238 void ChainVerifier<T>::addUntrusted(TestData::certificateID idx)
239 {
240     size_t size = list_size(m_untrustedCerts);
241     ckmc_cert_s* cert = create_cert(idx);
242     addCert(m_untrustedCerts, cert);
243
244     std::stringstream ss;
245     ss << "UNTRUSTED_CERT_ALIAS_" << size;
246     save_cert(cert, ss.str().c_str());
247     addAlias(m_untrustedAliases, ss.str().c_str());
248 }
249
250 template <typename T>
251 void ChainVerifier<T>::enableSystem(bool enable)
252 {
253     m_system = enable;
254 }
255
256 template <typename T>
257 void ChainVerifier<T>::addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert)
258 {
259     if (!list) {
260         ckmc_cert_list_s* tmp = NULL;
261         assert_positive(ckmc_cert_list_new, cert, &tmp);
262         RUNNER_ASSERT_MSG(!!tmp, "Cert list is NULL");
263         list = tmp;
264     } else {
265         ckmc_cert_list_s* last = list;
266         while(last->next)
267             last = last->next;
268         assert_positive(ckmc_cert_list_add, last, cert, &last);
269         RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
270     }
271 }
272
273 template <typename T>
274 void ChainVerifier<T>::addAlias(ckmc_alias_list_s*& list, const char* alias)
275 {
276     if (!list) {
277         ckmc_alias_list_s* tmp = NULL;
278         assert_positive(ckmc_alias_list_new, strdup(alias), &tmp);
279         RUNNER_ASSERT_MSG(!!tmp, "Alias list is NULL");
280         list = tmp;
281     } else {
282         ckmc_alias_list_s* last = list;
283         while(last->next)
284             last = last->next;
285         assert_positive(ckmc_alias_list_add, last, strdup(alias), &last);
286         RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
287     }
288 }
289
290 template <typename T>
291 void ChainVerifier<T>::verifyPositive(TestData::certificateID idx, size_t expected)
292 {
293     ckmc_cert_s* cert = create_cert(idx);
294
295     ckmc_cert_list_s* chain = NULL;
296
297     assert_positive(T::createChain,
298                     cert,
299                     m_untrustedCerts,
300                     m_trustedCerts,
301                     m_system,
302                     &chain);
303
304     size_t size = list_size(chain);
305     ckmc_cert_list_all_free(chain);
306     chain = NULL;
307     RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
308
309     assert_positive(T::createChainWithAlias,
310                     cert,
311                     m_untrustedAliases,
312                     m_trustedAliases,
313                     m_system,
314                     &chain);
315
316     size = list_size(chain);
317     ckmc_cert_list_all_free(chain);
318     chain = NULL;
319     RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
320     ckmc_cert_free(cert);
321 }
322
323 template <typename T>
324 void ChainVerifier<T>::verifyNegative(TestData::certificateID idx, int error)
325 {
326     ckmc_cert_s* cert = create_cert(idx);
327
328     ckmc_cert_list_s* chain = NULL;
329
330     assert_result(error,
331                   T::createChain,
332                   cert,
333                   m_untrustedCerts,
334                   m_trustedCerts,
335                   m_system,
336                   &chain);
337     RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
338
339     assert_result(error,
340                   T::createChainWithAlias,
341                   cert,
342                   m_untrustedAliases,
343                   m_trustedAliases,
344                   m_system,
345                   &chain);
346
347     RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
348     ckmc_cert_free(cert);
349 }
350 } // namespace anonymous
351
352 RUNNER_TEST_GROUP_INIT(T307_CKMC_CAPI_CERTIFICATE_CHAINS);
353
354 RUNNER_TEST(TCCH_0000_init)
355 {
356     reset_user_data(0, CHAINS_PASSWD);
357 }
358
359 // old API
360 RUNNER_TEST(TCCH_0010_get_chain_old_api)
361 {
362     reset_user_data(0, CHAINS_PASSWD);
363
364     ChainVerifier<ChainApiOld> cv;
365     cv.verifyNegative(TestData::GOOGLE_COM);
366
367     cv.addUntrusted(TestData::GIAG2);
368     cv.verifyPositive(TestData::GOOGLE_COM, 3); // including system cert
369     cv.verifyNegative(TestData::TEST_LEAF);
370 }
371
372 // old API
373 RUNNER_TEST(TCCH_0020_get_chain_old_api_system_only)
374 {
375     reset_user_data(0, CHAINS_PASSWD);
376
377     ChainVerifier<ChainApiOld> cv;
378     cv.verifyPositive(TestData::GIAG2, 2); // including system cert
379 }
380
381 // check invalid arguments
382 RUNNER_TEST(TCCH_0100_get_certificate_chain_invalid_param)
383 {
384     reset_user_data(0, CHAINS_PASSWD);
385
386     ckmc_cert_s* ca2 = create_cert(TestData::GIAG2);
387     ckmc_cert_s* ca1 = create_cert(TestData::GEOTRUST);
388     ckmc_cert_list_s* chain = NULL;
389
390     // cert
391     CertListPtr untrusted_c = create_cert_list(ca1, NULL);
392     ca1 = NULL;
393
394     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
395                          NULL_CERT,
396                          untrusted_c.get(),
397                          untrusted_c.get(),
398                          true,
399                          &chain);
400
401     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
402                          ca2,
403                          untrusted_c.get(),
404                          untrusted_c.get(),
405                          true,
406                          NULL_CHAIN);
407
408     // alias
409     ca1 = create_cert(TestData::GEOTRUST);
410     save_cert(ca1, "GEOTRUST");
411     AliasListPtr untrusted_a = create_alias_list("GEOTRUST", NULL);
412
413     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert_alias,
414                          NULL_CERT,
415                          untrusted_a.get(),
416                          untrusted_a.get(),
417                          true,
418                          &chain);
419
420     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert_alias,
421                          ca2,
422                          untrusted_a.get(),
423                          untrusted_a.get(),
424                          true,
425                          NULL_CHAIN);
426
427     ckmc_cert_free(ca2);
428 }
429
430 // check invalid arguments
431 RUNNER_TEST(TCCH_0110_get_certificate_chain_alias_unknown)
432 {
433     reset_user_data(0, CHAINS_PASSWD);
434
435     ckmc_cert_s* ca2 = create_cert(TestData::GIAG2);
436     ckmc_cert_list_s* chain = NULL;
437
438     AliasListPtr non_existing = create_alias_list("NON_EXISTING_ALIAS", NULL);
439     assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
440                   ckmc_get_cert_chain_with_trustedcert_alias,
441                   ca2,
442                   non_existing.get(),
443                   NULL_ALIASES,
444                   true,
445                   &chain);
446
447     assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
448                   ckmc_get_cert_chain_with_trustedcert_alias,
449                   ca2,
450                   NULL_ALIASES,
451                   non_existing.get(),
452                   true,
453                   &chain);
454     ckmc_cert_free(ca2);
455 }
456
457 /*
458  * This test verifies that chain of trust won't be successfully built unless system or trusted
459  * certificates are used even if real trusted root ca certs are used as untrusted.
460  */
461 RUNNER_TEST(TCCH_0120_get_certificate_chain_root_ca_negative)
462 {
463     reset_user_data(0, CHAINS_PASSWD);
464
465     ChainVerifier<> cv;
466     cv.enableSystem(false);
467     cv.verifyNegative(TestData::EQUIFAX);
468
469     cv.addUntrusted(TestData::GIAG2);
470     cv.verifyNegative(TestData::GOOGLE_COM);
471 }
472
473 /*
474  * This test verifies that it's possible to build a chain of trust with single trusted certificate
475  * and no system certificates.
476  */
477 RUNNER_TEST(TCCH_0140_get_certificate_chain_trusted_only)
478 {
479     reset_user_data(0, CHAINS_PASSWD);
480
481     ChainVerifier<> cv;
482     cv.enableSystem(false);
483     cv.addTrusted(TestData::TEST_ROOT_CA);
484     cv.verifyPositive(TestData::TEST_IM_CA, 2);
485     cv.verifyNegative(TestData::TEST_LEAF);
486 }
487
488 /*
489  * This test verifies that it's possible to build a chain of trust with system certificates only
490  */
491 RUNNER_TEST(TCCH_0150_get_certificate_chain_system_only)
492 {
493     reset_user_data(0, CHAINS_PASSWD);
494
495     ChainVerifier<> cv;
496     cv.verifyPositive(TestData::GIAG2, 2); // including system cert
497     cv.verifyNegative(TestData::GOOGLE_COM);
498 }
499
500 /*
501  * Verifies that chain of trust can be built without untrusted certificates.
502  */
503 RUNNER_TEST(TCCH_0160_get_certificate_chain_no_untrusted)
504 {
505     reset_user_data(0, CHAINS_PASSWD);
506
507     ChainVerifier<> cv;
508     cv.addTrusted(TestData::TEST_ROOT_CA);
509     cv.verifyPositive(TestData::TEST_IM_CA, 2);// signed by trusted cert (TEST_ROOT_CA)
510     cv.verifyPositive(TestData::GIAG2, 2);    // signed by system cert (GEOTRUST)
511     cv.verifyNegative(TestData::GOOGLE_COM);
512 }
513
514 RUNNER_TEST(TCCH_0170_get_certificate_chain_no_trusted)
515 {
516     reset_user_data(0, CHAINS_PASSWD);
517
518     ChainVerifier<> cv;
519     cv.addUntrusted(TestData::GIAG2);
520     cv.verifyPositive(TestData::GOOGLE_COM,3); // including system cert
521     cv.verifyNegative(TestData::TEST_LEAF);
522 }
523
524 /*
525  * Check if its possible to build a chain of trust without system certs.
526  */
527 RUNNER_TEST(TCCH_0180_get_certificate_chain_no_system)
528 {
529     reset_user_data(0, CHAINS_PASSWD);
530
531     ChainVerifier<> cv;
532     cv.enableSystem(false);
533     cv.addTrusted(TestData::TEST_ROOT_CA);
534     cv.addUntrusted(TestData::TEST_IM_CA);
535     cv.verifyPositive(TestData::TEST_LEAF, 3);
536     cv.verifyNegative(TestData::GOOGLE_COM);
537 }
538
539 /*
540  * Check if its possible to build a chain of trust with intermediate ca cert in trusted list.
541  */
542 RUNNER_TEST(TCCH_0190_get_certificate_chain_im_ca_in_trusted)
543 {
544     reset_user_data(0, CHAINS_PASSWD);
545
546     ChainVerifier<> cv;
547     cv.enableSystem(false);
548     cv.addTrusted(TestData::TEST_ROOT_CA);
549     cv.addTrusted(TestData::TEST_IM_CA);
550     cv.verifyPositive(TestData::TEST_LEAF, 3);
551     cv.verifyNegative(TestData::GOOGLE_COM);
552 }
553
554 RUNNER_TEST(TCCH_0200_get_certificate_chain_all)
555 {
556     reset_user_data(0, CHAINS_PASSWD);
557
558     ChainVerifier<> cv;
559     cv.enableSystem(true);
560     cv.addTrusted(TestData::TEST_ROOT_CA);
561     cv.addUntrusted(TestData::GEOTRUST);
562     cv.addUntrusted(TestData::GIAG2);
563     /*
564      * In combat conditions this may as well be 3. Because of 2 existing GeoTrust certificates with
565      * same Subject and Public key one being root ca and the other not there are 2 possible chains
566      * of trust for this certificate.
567      */
568     cv.verifyPositive(TestData::GOOGLE_COM,4);
569     cv.verifyNegative(TestData::TEST_LEAF);
570 }
571
572 RUNNER_TEST(TCCH_9999_deinit)
573 {
574     remove_user_data(0);
575 }