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 takes ownership of provided certificates
68 CertListPtr create_cert_list(ckmc_cert_s* cert, ...) {
69 CertListPtr certList(NULL, ckmc_cert_list_all_free);
74 ckmc_cert_list_s* last = NULL;
75 for (ckmc_cert_s* c = cert; c!=NULL; c = va_arg(ap, ckmc_cert_s*)) {
77 ckmc_cert_list_s* tmp = NULL;
78 assert_positive(ckmc_cert_list_new, c, &tmp);
79 certList = CertListPtr(tmp, ckmc_cert_list_all_free);
80 RUNNER_ASSERT_MSG(!!certList, "Cert list is NULL");
81 last = certList.get();
83 assert_positive(ckmc_cert_list_add, last, c, &last);
84 RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
92 const ckmc_cert_s* NULL_CERT = NULL;
93 ckmc_cert_list_s** NULL_CHAIN = NULL;
96 * Helper class for certificate verification
98 class ChainVerifierBase {
101 virtual ~ChainVerifierBase();
103 void addTrusted(TestData::certificateID idx);
104 void addUntrusted(TestData::certificateID idx);
105 void enableSystem(bool enable);
107 virtual void verifyPositive(TestData::certificateID idx, size_t expected) = 0;
108 virtual void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED) = 0;
111 void addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert);
112 void addAlias(ckmc_alias_list_s*& list, const char* alias);
114 ckmc_cert_list_s* m_trustedCerts;
115 ckmc_alias_list_s* m_trustedAliases;
117 ckmc_cert_list_s* m_untrustedCerts;
118 ckmc_alias_list_s* m_untrustedAliases;
124 ChainVerifierBase::ChainVerifierBase() :
125 m_trustedCerts(NULL),
126 m_trustedAliases(NULL),
127 m_untrustedCerts(NULL),
128 m_untrustedAliases(NULL),
133 ChainVerifierBase::~ChainVerifierBase()
135 ckmc_cert_list_all_free(m_trustedCerts);
136 ckmc_cert_list_all_free(m_untrustedCerts);
137 ckmc_alias_list_all_free(m_trustedAliases);
138 ckmc_alias_list_all_free(m_untrustedAliases);
141 void ChainVerifierBase::addTrusted(TestData::certificateID idx)
143 size_t size = list_size(m_trustedCerts);
144 ckmc_cert_s* cert = create_cert(idx);
145 addCert(m_trustedCerts, cert);
147 std::stringstream ss;
148 ss << "TRUSTED_CERT_ALIAS_" << size;
149 save_cert(cert, ss.str().c_str());
150 addAlias(m_trustedAliases, ss.str().c_str());
153 void ChainVerifierBase::addUntrusted(TestData::certificateID idx)
155 size_t size = list_size(m_untrustedCerts);
156 ckmc_cert_s* cert = create_cert(idx);
157 addCert(m_untrustedCerts, cert);
159 std::stringstream ss;
160 ss << "UNTRUSTED_CERT_ALIAS_" << size;
161 save_cert(cert, ss.str().c_str());
162 addAlias(m_untrustedAliases, ss.str().c_str());
165 void ChainVerifierBase::enableSystem(bool enable)
170 void ChainVerifierBase::addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert)
173 ckmc_cert_list_s* tmp = NULL;
174 assert_positive(ckmc_cert_list_new, cert, &tmp);
175 RUNNER_ASSERT_MSG(!!tmp, "Cert list is NULL");
178 ckmc_cert_list_s* last = list;
181 assert_positive(ckmc_cert_list_add, last, cert, &last);
182 RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
186 void ChainVerifierBase::addAlias(ckmc_alias_list_s*& list, const char* alias)
189 ckmc_alias_list_s* tmp = NULL;
190 assert_positive(ckmc_alias_list_new, strdup(alias), &tmp);
191 RUNNER_ASSERT_MSG(!!tmp, "Alias list is NULL");
194 ckmc_alias_list_s* last = list;
197 assert_positive(ckmc_alias_list_add, last, strdup(alias), &last);
198 RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
202 class ChainVerifierOld : public ChainVerifierBase {
204 virtual void verifyPositive(TestData::certificateID idx, size_t expected);
205 virtual void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
208 class ChainVerifier : public ChainVerifierBase {
210 virtual void verifyPositive(TestData::certificateID idx, size_t expected);
211 virtual void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
214 void ChainVerifierOld::verifyPositive(TestData::certificateID idx, size_t expected)
216 ckmc_cert_s* cert = create_cert(idx);
218 ckmc_cert_list_s* chain = NULL;
220 assert_positive(ckmc_get_cert_chain,
225 size_t size = list_size(chain);
226 ckmc_cert_list_all_free(chain);
228 RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
230 assert_positive(ckmc_get_cert_chain_with_alias,
235 size = list_size(chain);
236 ckmc_cert_list_all_free(chain);
238 RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
240 ckmc_cert_free(cert);
243 void ChainVerifier::verifyPositive(TestData::certificateID idx, size_t expected)
245 ckmc_cert_s* cert = create_cert(idx);
247 ckmc_cert_list_s* chain = NULL;
249 assert_positive(ckmc_get_cert_chain_with_trustedcert,
256 size_t size = list_size(chain);
257 ckmc_cert_list_all_free(chain);
259 RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
261 ckmc_cert_free(cert);
264 void ChainVerifierOld::verifyNegative(TestData::certificateID idx, int error)
266 ckmc_cert_s* cert = create_cert(idx);
268 ckmc_cert_list_s* chain = NULL;
275 RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
278 ckmc_get_cert_chain_with_alias,
283 RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
285 ckmc_cert_free(cert);
288 void ChainVerifier::verifyNegative(TestData::certificateID idx, int error)
290 ckmc_cert_s* cert = create_cert(idx);
292 ckmc_cert_list_s* chain = NULL;
295 ckmc_get_cert_chain_with_trustedcert,
301 RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
303 ckmc_cert_free(cert);
305 } // namespace anonymous
307 RUNNER_TEST_GROUP_INIT(T307_CKMC_CAPI_CERTIFICATE_CHAINS);
309 RUNNER_TEST(TCCH_0000_init)
311 remove_user_data(APP_UID);
315 RUNNER_TEST(TCCH_0010_get_chain_old_api)
317 remove_user_data(APP_UID);
320 cv.verifyNegative(TestData::GOOGLE_COM);
322 cv.addUntrusted(TestData::GIAG2);
323 cv.verifyPositive(TestData::GOOGLE_COM, 3); // including system cert
324 cv.verifyNegative(TestData::TEST_LEAF);
328 RUNNER_TEST(TCCH_0020_get_chain_old_api_system_only)
330 remove_user_data(APP_UID);
333 cv.verifyPositive(TestData::GIAG2, 2); // including system cert
336 // check invalid arguments
337 RUNNER_TEST(TCCH_0100_get_certificate_chain_invalid_param)
339 remove_user_data(APP_UID);
341 ckmc_cert_s* ca2 = create_cert(TestData::GIAG2);
342 ckmc_cert_s* ca1 = create_cert(TestData::GEOTRUST);
343 ckmc_cert_list_s* chain = NULL;
346 CertListPtr untrusted_c = create_cert_list(ca1, NULL);
349 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
356 assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
367 * This test verifies that chain of trust won't be successfully built unless system or trusted
368 * certificates are used even if real trusted root ca certs are used as untrusted.
370 RUNNER_TEST(TCCH_0120_get_certificate_chain_root_ca_negative)
372 remove_user_data(APP_UID);
375 cv.enableSystem(false);
376 cv.verifyNegative(TestData::EQUIFAX);
378 cv.addUntrusted(TestData::GIAG2);
379 cv.verifyNegative(TestData::GOOGLE_COM);
383 * This test verifies that it's possible to build a chain of trust with single trusted certificate
384 * and no system certificates.
386 RUNNER_TEST(TCCH_0140_get_certificate_chain_trusted_only)
388 remove_user_data(APP_UID);
391 cv.enableSystem(false);
392 cv.addTrusted(TestData::TEST_ROOT_CA);
393 cv.verifyPositive(TestData::TEST_IM_CA, 2);
394 cv.verifyNegative(TestData::TEST_LEAF);
398 * This test verifies that it's possible to build a chain of trust with system certificates only
400 RUNNER_TEST(TCCH_0150_get_certificate_chain_system_only)
402 remove_user_data(APP_UID);
405 cv.verifyPositive(TestData::GIAG2, 2); // including system cert
406 cv.verifyNegative(TestData::GOOGLE_COM);
410 * Verifies that chain of trust can be built without untrusted certificates.
412 RUNNER_TEST(TCCH_0160_get_certificate_chain_no_untrusted)
414 remove_user_data(APP_UID);
417 cv.addTrusted(TestData::TEST_ROOT_CA);
418 cv.verifyPositive(TestData::TEST_IM_CA, 2);// signed by trusted cert (TEST_ROOT_CA)
419 cv.verifyPositive(TestData::GIAG2, 2); // signed by system cert (GEOTRUST)
420 cv.verifyNegative(TestData::GOOGLE_COM);
423 RUNNER_TEST(TCCH_0170_get_certificate_chain_no_trusted)
425 remove_user_data(APP_UID);
428 cv.addUntrusted(TestData::GIAG2);
429 cv.verifyPositive(TestData::GOOGLE_COM,3); // including system cert
430 cv.verifyNegative(TestData::TEST_LEAF);
434 * Check if its possible to build a chain of trust without system certs.
436 RUNNER_TEST(TCCH_0180_get_certificate_chain_no_system)
438 remove_user_data(APP_UID);
441 cv.enableSystem(false);
442 cv.addTrusted(TestData::TEST_ROOT_CA);
443 cv.addUntrusted(TestData::TEST_IM_CA);
444 cv.verifyPositive(TestData::TEST_LEAF, 3);
445 cv.verifyNegative(TestData::GOOGLE_COM);
449 * Check if its possible to build a chain of trust with intermediate ca cert in trusted list.
451 RUNNER_TEST(TCCH_0190_get_certificate_chain_im_ca_in_trusted)
453 remove_user_data(APP_UID);
456 cv.enableSystem(false);
457 cv.addTrusted(TestData::TEST_ROOT_CA);
458 cv.addTrusted(TestData::TEST_IM_CA);
459 cv.verifyPositive(TestData::TEST_LEAF, 3);
460 cv.verifyNegative(TestData::GOOGLE_COM);
463 RUNNER_TEST(TCCH_0200_get_certificate_chain_all)
465 remove_user_data(APP_UID);
468 cv.enableSystem(true);
469 cv.addTrusted(TestData::TEST_ROOT_CA);
470 cv.addUntrusted(TestData::GEOTRUST);
471 cv.addUntrusted(TestData::GIAG2);
473 * In combat conditions this may as well be 3. Because of 2 existing GeoTrust certificates with
474 * same Subject and Public key one being root ca and the other not there are 2 possible chains
475 * of trust for this certificate.
477 cv.verifyPositive(TestData::GOOGLE_COM,4);
478 cv.verifyNegative(TestData::TEST_LEAF);
481 RUNNER_TEST(TCCH_9999_deinit)
483 remove_user_data(APP_UID);