2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 * @file capi-certificate-chains.cpp
18 * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
27 #include <dpl/test/test_runner.h>
29 #include <tests_common.h>
30 #include <test-certs.h>
31 #include <ckm-common.h>
33 #include <ckmc/ckmc-manager.h>
34 #include <ckmc/ckmc-control.h>
35 #include <ckmc/ckmc-type.h>
36 #include <ckmc/ckmc-error.h>
40 typedef std::unique_ptr<ckmc_cert_s, void (*)(ckmc_cert_s*)> CertPtr;
41 typedef std::unique_ptr<ckmc_cert_list_s, void (*)(ckmc_cert_list_s*)> CertListPtr;
42 typedef std::unique_ptr<ckmc_alias_list_s, void (*)(ckmc_alias_list_s*)> AliasListPtr;
44 ckmc_cert_s* create_cert(TestData::certificateID idx) {
46 std::string cert_raw = TestData::getTestCertificateBase64(idx);
48 ckmc_cert_s* cert = NULL;
49 assert_positive(ckmc_cert_new,
50 reinterpret_cast<unsigned char*>(const_cast<char*>(cert_raw.c_str())),
55 RUNNER_ASSERT_MSG(cert != NULL, "Cert is NULL");
59 void save_cert(const ckmc_cert_s* cert, const char* alias) {
61 policy.password = NULL;
62 policy.extractable = 1;
64 assert_positive(ckmc_save_cert, alias, *cert, policy);
67 // list gets copies of aliases
68 AliasListPtr create_alias_list(const char* alias, ...) {
69 AliasListPtr aliasList(NULL, ckmc_alias_list_all_free);
74 ckmc_alias_list_s* last = NULL;
75 for (const char* a = alias; a != NULL; a = va_arg(ap, const char*)) {
76 if (aliasList == NULL) {
77 ckmc_alias_list_s* tmp = NULL;
78 assert_positive(ckmc_alias_list_new, strdup(a), &tmp);
79 aliasList = AliasListPtr(tmp, ckmc_alias_list_all_free);
80 RUNNER_ASSERT_MSG(!!aliasList, "Alias list is NULL");
81 last = aliasList.get();
83 assert_positive(ckmc_alias_list_add, last, strdup(a), &last);
84 RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
92 // list takes ownership of provided certificates
93 CertListPtr create_cert_list(ckmc_cert_s* cert, ...) {
94 CertListPtr certList(NULL, ckmc_cert_list_all_free);
99 ckmc_cert_list_s* last = NULL;
100 for (ckmc_cert_s* c = cert; c!=NULL; c = va_arg(ap, ckmc_cert_s*)) {
102 ckmc_cert_list_s* tmp = NULL;
103 assert_positive(ckmc_cert_list_new, c, &tmp);
104 certList = CertListPtr(tmp, ckmc_cert_list_all_free);
105 RUNNER_ASSERT_MSG(!!certList, "Cert list is NULL");
106 last = certList.get();
108 assert_positive(ckmc_cert_list_add, last, c, &last);
109 RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
117 const ckmc_alias_list_s* NULL_ALIASES = NULL;
118 const ckmc_cert_s* NULL_CERT = NULL;
119 ckmc_cert_list_s** NULL_CHAIN = NULL;
124 static int createChain(const ckmc_cert_s *cert,
125 const ckmc_cert_list_s *untrustedcerts,
126 const ckmc_cert_list_s* /*trustedcerts*/,
127 const bool /*use_trustedsystemcerts*/,
128 ckmc_cert_list_s **ppcert_chain_list)
130 return ckmc_get_cert_chain(cert, untrustedcerts, ppcert_chain_list);
133 static int createChainWithAlias(const ckmc_cert_s *cert,
134 const ckmc_alias_list_s *untrustedcerts,
135 const ckmc_alias_list_s* /*trustedcerts*/,
136 const bool /*use_trustedsystemcerts*/,
137 ckmc_cert_list_s **ppcert_chain_list)
139 return ckmc_get_cert_chain_with_alias(cert, untrustedcerts, ppcert_chain_list);
146 static int createChain(const ckmc_cert_s *cert,
147 const ckmc_cert_list_s *untrustedcerts,
148 const ckmc_cert_list_s *trustedcerts,
149 const bool use_trustedsystemcerts,
150 ckmc_cert_list_s **ppcert_chain_list)
152 return ckmc_get_cert_chain_with_trustedcert(cert,
155 use_trustedsystemcerts,
159 static int createChainWithAlias(const ckmc_cert_s *cert,
160 const ckmc_alias_list_s *untrustedcerts,
161 const ckmc_alias_list_s *trustedcerts,
162 const bool use_trustedsystemcerts,
163 ckmc_cert_list_s **ppcert_chain_list)
165 return ckmc_get_cert_chain_with_trustedcert_alias(cert,
168 use_trustedsystemcerts,
174 * Helper class for certificate verification
176 template <typename T=ChainApiNew>
183 void addTrusted(TestData::certificateID idx);
184 void addUntrusted(TestData::certificateID idx);
185 void enableSystem(bool enable);
187 void verifyPositive(TestData::certificateID idx, size_t expected);
188 void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
191 void addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert);
192 void addAlias(ckmc_alias_list_s*& list, const char* alias);
194 ckmc_cert_list_s* m_trustedCerts;
195 ckmc_alias_list_s* m_trustedAliases;
197 ckmc_cert_list_s* m_untrustedCerts;
198 ckmc_alias_list_s* m_untrustedAliases;
203 template <typename T>
204 ChainVerifier<T>::ChainVerifier() :
205 m_trustedCerts(NULL),
206 m_trustedAliases(NULL),
207 m_untrustedCerts(NULL),
208 m_untrustedAliases(NULL),
213 template <typename T>
214 ChainVerifier<T>::~ChainVerifier()
216 ckmc_cert_list_all_free(m_trustedCerts);
217 ckmc_cert_list_all_free(m_untrustedCerts);
218 ckmc_alias_list_all_free(m_trustedAliases);
219 ckmc_alias_list_all_free(m_untrustedAliases);
222 template <typename T>
223 void ChainVerifier<T>::addTrusted(TestData::certificateID idx)
225 size_t size = list_size(m_trustedCerts);
226 ckmc_cert_s* cert = create_cert(idx);
227 addCert(m_trustedCerts, cert);
229 std::stringstream ss;
230 ss << "TRUSTED_CERT_ALIAS_" << size;
231 save_cert(cert, ss.str().c_str());
232 addAlias(m_trustedAliases, ss.str().c_str());
235 template <typename T>
236 void ChainVerifier<T>::addUntrusted(TestData::certificateID idx)
238 size_t size = list_size(m_untrustedCerts);
239 ckmc_cert_s* cert = create_cert(idx);
240 addCert(m_untrustedCerts, cert);
242 std::stringstream ss;
243 ss << "UNTRUSTED_CERT_ALIAS_" << size;
244 save_cert(cert, ss.str().c_str());
245 addAlias(m_untrustedAliases, ss.str().c_str());
248 template <typename T>
249 void ChainVerifier<T>::enableSystem(bool enable)
254 template <typename T>
255 void ChainVerifier<T>::addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert)
258 ckmc_cert_list_s* tmp = NULL;
259 assert_positive(ckmc_cert_list_new, cert, &tmp);
260 RUNNER_ASSERT_MSG(!!tmp, "Cert list is NULL");
263 ckmc_cert_list_s* last = list;
266 assert_positive(ckmc_cert_list_add, last, cert, &last);
267 RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
271 template <typename T>
272 void ChainVerifier<T>::addAlias(ckmc_alias_list_s*& list, const char* alias)
275 ckmc_alias_list_s* tmp = NULL;
276 assert_positive(ckmc_alias_list_new, strdup(alias), &tmp);
277 RUNNER_ASSERT_MSG(!!tmp, "Alias list is NULL");
280 ckmc_alias_list_s* last = list;
283 assert_positive(ckmc_alias_list_add, last, strdup(alias), &last);
284 RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
288 template <typename T>
289 void ChainVerifier<T>::verifyPositive(TestData::certificateID idx, size_t expected)
291 ckmc_cert_s* cert = create_cert(idx);
293 ckmc_cert_list_s* chain = NULL;
295 assert_positive(T::createChain,
302 size_t size = list_size(chain);
303 ckmc_cert_list_all_free(chain);
305 RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
307 assert_positive(T::createChainWithAlias,
314 size = list_size(chain);
315 ckmc_cert_list_all_free(chain);
317 RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
318 ckmc_cert_free(cert);
321 template <typename T>
322 void ChainVerifier<T>::verifyNegative(TestData::certificateID idx, int error)
324 ckmc_cert_s* cert = create_cert(idx);
326 ckmc_cert_list_s* chain = NULL;
335 RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
338 T::createChainWithAlias,
345 RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
346 ckmc_cert_free(cert);
349 } // namespace anonymous
351 RUNNER_TEST_GROUP_INIT(T307_CKMC_CAPI_CERTIFICATE_CHAINS);
353 RUNNER_TEST(TCCH_0000_init)
355 assert_positive(ckmc_unlock_user_key, 0, "test-pass");
359 RUNNER_TEST(TCCH_0010_get_chain_old_api)
361 assert_positive(ckmc_remove_user_data,0);
363 ChainVerifier<ChainApiOld> cv;
364 cv.verifyNegative(TestData::GOOGLE_COM);
366 cv.addUntrusted(TestData::GIAG2);
367 cv.verifyPositive(TestData::GOOGLE_COM, 3); // including system cert
368 cv.verifyNegative(TestData::TEST_LEAF);
372 RUNNER_TEST(TCCH_0020_get_chain_old_api_system_only)
374 assert_positive(ckmc_remove_user_data,0);
376 ChainVerifier<ChainApiOld> cv;
377 cv.verifyPositive(TestData::GIAG2, 2); // including system cert
380 // check invalid arguments
381 RUNNER_TEST(TCCH_0100_get_certificate_chain_invalid_param)
383 assert_positive(ckmc_remove_user_data,0);
385 ckmc_cert_s* ca2 = create_cert(TestData::GIAG2);
386 ckmc_cert_s* ca1 = create_cert(TestData::GEOTRUST);
387 ckmc_cert_list_s* chain = NULL;
390 CertListPtr untrusted_c = create_cert_list(ca1, NULL);
393 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
400 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
408 ca1 = create_cert(TestData::GEOTRUST);
409 save_cert(ca1, "GEOTRUST");
410 AliasListPtr untrusted_a = create_alias_list("GEOTRUST", NULL);
412 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert_alias,
419 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert_alias,
429 // check invalid arguments
430 RUNNER_TEST(TCCH_0110_get_certificate_chain_alias_unknown)
432 assert_positive(ckmc_remove_user_data,0);
434 ckmc_cert_s* ca2 = create_cert(TestData::GIAG2);
435 ckmc_cert_list_s* chain = NULL;
437 AliasListPtr non_existing = create_alias_list("NON_EXISTING_ALIAS", NULL);
438 assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
439 ckmc_get_cert_chain_with_trustedcert_alias,
446 assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
447 ckmc_get_cert_chain_with_trustedcert_alias,
457 * This test verifies that chain of trust won't be successfully built unless system or trusted
458 * certificates are used even if real trusted root ca certs are used as untrusted.
460 RUNNER_TEST(TCCH_0120_get_certificate_chain_root_ca_negative)
462 assert_positive(ckmc_remove_user_data,0);
465 cv.enableSystem(false);
466 cv.verifyNegative(TestData::EQUIFAX);
468 cv.addUntrusted(TestData::GIAG2);
469 cv.verifyNegative(TestData::GOOGLE_COM);
473 * This test verifies that it's possible to build a chain of trust with single trusted certificate
474 * and no system certificates.
476 RUNNER_TEST(TCCH_0140_get_certificate_chain_trusted_only)
478 assert_positive(ckmc_remove_user_data,0);
481 cv.enableSystem(false);
482 cv.addTrusted(TestData::TEST_ROOT_CA);
483 cv.verifyPositive(TestData::TEST_IM_CA, 2);
484 cv.verifyNegative(TestData::TEST_LEAF);
488 * This test verifies that it's possible to build a chain of trust with system certificates only
490 RUNNER_TEST(TCCH_0150_get_certificate_chain_system_only)
492 assert_positive(ckmc_remove_user_data,0);
495 cv.verifyPositive(TestData::GIAG2, 2); // including system cert
496 cv.verifyNegative(TestData::GOOGLE_COM);
500 * Verifies that chain of trust can be built without untrusted certificates.
502 RUNNER_TEST(TCCH_0160_get_certificate_chain_no_untrusted)
504 assert_positive(ckmc_remove_user_data,0);
507 cv.addTrusted(TestData::TEST_ROOT_CA);
508 cv.verifyPositive(TestData::TEST_IM_CA, 2);// signed by trusted cert (TEST_ROOT_CA)
509 cv.verifyPositive(TestData::GIAG2, 2); // signed by system cert (GEOTRUST)
510 cv.verifyNegative(TestData::GOOGLE_COM);
513 RUNNER_TEST(TCCH_0170_get_certificate_chain_no_trusted)
515 assert_positive(ckmc_remove_user_data,0);
518 cv.addUntrusted(TestData::GIAG2);
519 cv.verifyPositive(TestData::GOOGLE_COM,3); // including system cert
520 cv.verifyNegative(TestData::TEST_LEAF);
524 * Check if its possible to build a chain of trust without system certs.
526 RUNNER_TEST(TCCH_0180_get_certificate_chain_no_system)
528 assert_positive(ckmc_remove_user_data,0);
531 cv.enableSystem(false);
532 cv.addTrusted(TestData::TEST_ROOT_CA);
533 cv.addUntrusted(TestData::TEST_IM_CA);
534 cv.verifyPositive(TestData::TEST_LEAF, 3);
535 cv.verifyNegative(TestData::GOOGLE_COM);
539 * Check if its possible to build a chain of trust with intermediate ca cert in trusted list.
541 RUNNER_TEST(TCCH_0190_get_certificate_chain_im_ca_in_trusted)
543 assert_positive(ckmc_remove_user_data,0);
546 cv.enableSystem(false);
547 cv.addTrusted(TestData::TEST_ROOT_CA);
548 cv.addTrusted(TestData::TEST_IM_CA);
549 cv.verifyPositive(TestData::TEST_LEAF, 3);
550 cv.verifyNegative(TestData::GOOGLE_COM);
553 RUNNER_TEST(TCCH_0200_get_certificate_chain_all)
555 assert_positive(ckmc_remove_user_data,0);
558 cv.enableSystem(true);
559 cv.addTrusted(TestData::TEST_ROOT_CA);
560 cv.addUntrusted(TestData::GEOTRUST);
561 cv.addUntrusted(TestData::GIAG2);
563 * In combat conditions this may as well be 3. Because of 2 existing GeoTrust certificates with
564 * same Subject and Public key one being root ca and the other not there are 2 possible chains
565 * of trust for this certificate.
567 cv.verifyPositive(TestData::GOOGLE_COM,4);
568 cv.verifyNegative(TestData::TEST_LEAF);
571 RUNNER_TEST(TCCH_9999_deinit)
573 assert_positive(ckmc_lock_user_key, 0);
574 assert_positive(ckmc_remove_user_data, 0);