Run key-manager test on onlycap
[platform/core/test/security-tests.git] / src / 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 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;
43
44 ckmc_cert_s* create_cert(TestData::certificateID idx) {
45
46     std::string cert_raw = TestData::getTestCertificateBase64(idx);
47
48     ckmc_cert_s* cert = NULL;
49     assert_positive(ckmc_cert_new,
50                     reinterpret_cast<unsigned char*>(const_cast<char*>(cert_raw.c_str())),
51                     cert_raw.size(),
52                     CKMC_FORM_PEM,
53                     &cert);
54
55     RUNNER_ASSERT_MSG(cert != NULL, "Cert is NULL");
56     return cert;
57 }
58
59 void save_cert(const ckmc_cert_s* cert, const char* alias) {
60     ckmc_policy_s policy;
61     policy.password = NULL;
62     policy.extractable = 1;
63
64     assert_positive(ckmc_save_cert, alias, *cert, policy);
65 }
66
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);
70
71     va_list ap;
72
73     va_start(ap, cert);
74     ckmc_cert_list_s* last = NULL;
75     for (ckmc_cert_s* c = cert; c!=NULL; c = va_arg(ap, ckmc_cert_s*)) {
76         if (!certList) {
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();
82         } else {
83             assert_positive(ckmc_cert_list_add, last, c, &last);
84             RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
85         }
86     }
87     va_end(ap);
88
89     return certList;
90 }
91
92 const ckmc_cert_s* NULL_CERT = NULL;
93 ckmc_cert_list_s** NULL_CHAIN = NULL;
94
95 /*
96  * Helper class for certificate verification
97  */
98 class ChainVerifierBase {
99 public:
100     ChainVerifierBase();
101     virtual ~ChainVerifierBase();
102
103     void addTrusted(TestData::certificateID idx);
104     void addUntrusted(TestData::certificateID idx);
105     void enableSystem(bool enable);
106
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;
109
110 protected:
111     void addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert);
112     void addAlias(ckmc_alias_list_s*& list, const char* alias);
113
114     ckmc_cert_list_s* m_trustedCerts;
115     ckmc_alias_list_s* m_trustedAliases;
116
117     ckmc_cert_list_s* m_untrustedCerts;
118     ckmc_alias_list_s* m_untrustedAliases;
119
120     bool m_system;
121 };
122
123
124 ChainVerifierBase::ChainVerifierBase() :
125         m_trustedCerts(NULL),
126         m_trustedAliases(NULL),
127         m_untrustedCerts(NULL),
128         m_untrustedAliases(NULL),
129         m_system(true)
130 {
131 }
132
133 ChainVerifierBase::~ChainVerifierBase()
134 {
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);
139 }
140
141 void ChainVerifierBase::addTrusted(TestData::certificateID idx)
142 {
143     size_t size = list_size(m_trustedCerts);
144     ckmc_cert_s* cert = create_cert(idx);
145     addCert(m_trustedCerts, cert);
146
147     std::stringstream ss;
148     ss << sharedDatabase("TRUSTED_CERT_ALIAS_") << size;
149     save_cert(cert, ss.str().c_str());
150     addAlias(m_trustedAliases, ss.str().c_str());
151 }
152
153 void ChainVerifierBase::addUntrusted(TestData::certificateID idx)
154 {
155     size_t size = list_size(m_untrustedCerts);
156     ckmc_cert_s* cert = create_cert(idx);
157     addCert(m_untrustedCerts, cert);
158
159     std::stringstream ss;
160     ss << sharedDatabase("UNTRUSTED_CERT_ALIAS_") << size;
161     save_cert(cert, ss.str().c_str());
162     addAlias(m_untrustedAliases, ss.str().c_str());
163 }
164
165 void ChainVerifierBase::enableSystem(bool enable)
166 {
167     m_system = enable;
168 }
169
170 void ChainVerifierBase::addCert(ckmc_cert_list_s*& list, ckmc_cert_s* cert)
171 {
172     if (!list) {
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");
176         list = tmp;
177     } else {
178         ckmc_cert_list_s* last = list;
179         while(last->next)
180             last = last->next;
181         assert_positive(ckmc_cert_list_add, last, cert, &last);
182         RUNNER_ASSERT_MSG(last != NULL, "Last cert on the list is NULL");
183     }
184 }
185
186 void ChainVerifierBase::addAlias(ckmc_alias_list_s*& list, const char* alias)
187 {
188     if (!list) {
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");
192         list = tmp;
193     } else {
194         ckmc_alias_list_s* last = list;
195         while(last->next)
196             last = last->next;
197         assert_positive(ckmc_alias_list_add, last, strdup(alias), &last);
198         RUNNER_ASSERT_MSG(last != NULL, "Last alias on the list is NULL");
199     }
200 }
201
202 class ChainVerifierOld : public ChainVerifierBase {
203 public:
204     virtual void verifyPositive(TestData::certificateID idx, size_t expected);
205     virtual void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
206 };
207
208 class ChainVerifier : public ChainVerifierBase {
209 public:
210     virtual void verifyPositive(TestData::certificateID idx, size_t expected);
211     virtual void verifyNegative(TestData::certificateID idx, int error = CKMC_ERROR_VERIFICATION_FAILED);
212 };
213
214 void ChainVerifierOld::verifyPositive(TestData::certificateID idx, size_t expected)
215 {
216     ckmc_cert_s* cert = create_cert(idx);
217
218     ckmc_cert_list_s* chain = NULL;
219
220     assert_positive(ckmc_get_cert_chain,
221                     cert,
222                     m_untrustedCerts,
223                     &chain);
224
225     size_t size = list_size(chain);
226     ckmc_cert_list_all_free(chain);
227     chain = NULL;
228     RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
229
230     assert_positive(ckmc_get_cert_chain_with_alias,
231                     cert,
232                     m_untrustedAliases,
233                     &chain);
234
235     size = list_size(chain);
236     ckmc_cert_list_all_free(chain);
237     chain = NULL;
238     RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
239
240     ckmc_cert_free(cert);
241 }
242
243 void ChainVerifier::verifyPositive(TestData::certificateID idx, size_t expected)
244 {
245     ckmc_cert_s* cert = create_cert(idx);
246
247     ckmc_cert_list_s* chain = NULL;
248
249     assert_positive(ckmc_get_cert_chain_with_trustedcert,
250                     cert,
251                     m_untrustedCerts,
252                     m_trustedCerts,
253                     m_system,
254                     &chain);
255
256     size_t size = list_size(chain);
257     ckmc_cert_list_all_free(chain);
258     chain = NULL;
259     RUNNER_ASSERT_MSG(size == expected, "Expected chain size: " << expected << " got: " << size);
260
261     ckmc_cert_free(cert);
262 }
263
264 void ChainVerifierOld::verifyNegative(TestData::certificateID idx, int error)
265 {
266     ckmc_cert_s* cert = create_cert(idx);
267
268     ckmc_cert_list_s* chain = NULL;
269
270     assert_result(error,
271                   ckmc_get_cert_chain,
272                   cert,
273                   m_untrustedCerts,
274                   &chain);
275     RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
276
277     assert_result(error,
278                   ckmc_get_cert_chain_with_alias,
279                   cert,
280                   m_untrustedAliases,
281                   &chain);
282
283     RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
284
285     ckmc_cert_free(cert);
286 }
287
288 void ChainVerifier::verifyNegative(TestData::certificateID idx, int error)
289 {
290     ckmc_cert_s* cert = create_cert(idx);
291
292     ckmc_cert_list_s* chain = NULL;
293
294     assert_result(error,
295                   ckmc_get_cert_chain_with_trustedcert,
296                   cert,
297                   m_untrustedCerts,
298                   m_trustedCerts,
299                   m_system,
300                   &chain);
301     RUNNER_ASSERT_MSG(chain == NULL, "Chain is not empty");
302
303     ckmc_cert_free(cert);
304 }
305 } // namespace anonymous
306
307 RUNNER_TEST_GROUP_INIT(T307_CKMC_CAPI_CERTIFICATE_CHAINS);
308
309 RUNNER_TEST(TCCH_0000_init)
310 {
311     remove_user_data(0);
312 }
313
314 // old API
315 RUNNER_TEST(TCCH_0010_get_chain_old_api)
316 {
317     remove_user_data(0);
318
319     ChainVerifierOld cv;
320     cv.verifyNegative(TestData::GOOGLE_COM);
321
322     cv.addUntrusted(TestData::GIAG2);
323     cv.verifyPositive(TestData::GOOGLE_COM, 3); // including system cert
324     cv.verifyNegative(TestData::TEST_LEAF);
325 }
326
327 // old API
328 RUNNER_TEST(TCCH_0020_get_chain_old_api_system_only)
329 {
330     remove_user_data(0);
331
332     ChainVerifierOld cv;
333     cv.verifyPositive(TestData::GIAG2, 2); // including system cert
334 }
335
336 // check invalid arguments
337 RUNNER_TEST(TCCH_0100_get_certificate_chain_invalid_param)
338 {
339     remove_user_data(0);
340
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;
344
345     // cert
346     CertListPtr untrusted_c = create_cert_list(ca1, NULL);
347     ca1 = NULL;
348
349     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
350                          NULL_CERT,
351                          untrusted_c.get(),
352                          untrusted_c.get(),
353                          true,
354                          &chain);
355
356     assert_invalid_param(ckmc_get_cert_chain_with_trustedcert,
357                          ca2,
358                          untrusted_c.get(),
359                          untrusted_c.get(),
360                          true,
361                          NULL_CHAIN);
362
363     ckmc_cert_free(ca2);
364 }
365
366 /*
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.
369  */
370 RUNNER_TEST(TCCH_0120_get_certificate_chain_root_ca_negative)
371 {
372     remove_user_data(0);
373
374     ChainVerifier cv;
375     cv.enableSystem(false);
376     cv.verifyNegative(TestData::EQUIFAX);
377
378     cv.addUntrusted(TestData::GIAG2);
379     cv.verifyNegative(TestData::GOOGLE_COM);
380 }
381
382 /*
383  * This test verifies that it's possible to build a chain of trust with single trusted certificate
384  * and no system certificates.
385  */
386 RUNNER_TEST(TCCH_0140_get_certificate_chain_trusted_only)
387 {
388     remove_user_data(0);
389
390     ChainVerifier cv;
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);
395 }
396
397 /*
398  * This test verifies that it's possible to build a chain of trust with system certificates only
399  */
400 RUNNER_TEST(TCCH_0150_get_certificate_chain_system_only)
401 {
402     remove_user_data(0);
403
404     ChainVerifier cv;
405     cv.verifyPositive(TestData::GIAG2, 2); // including system cert
406     cv.verifyNegative(TestData::GOOGLE_COM);
407 }
408
409 /*
410  * Verifies that chain of trust can be built without untrusted certificates.
411  */
412 RUNNER_TEST(TCCH_0160_get_certificate_chain_no_untrusted)
413 {
414     remove_user_data(0);
415
416     ChainVerifier cv;
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);
421 }
422
423 RUNNER_TEST(TCCH_0170_get_certificate_chain_no_trusted)
424 {
425     remove_user_data(0);
426
427     ChainVerifier cv;
428     cv.addUntrusted(TestData::GIAG2);
429     cv.verifyPositive(TestData::GOOGLE_COM,3); // including system cert
430     cv.verifyNegative(TestData::TEST_LEAF);
431 }
432
433 /*
434  * Check if its possible to build a chain of trust without system certs.
435  */
436 RUNNER_TEST(TCCH_0180_get_certificate_chain_no_system)
437 {
438     remove_user_data(0);
439
440     ChainVerifier cv;
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);
446 }
447
448 /*
449  * Check if its possible to build a chain of trust with intermediate ca cert in trusted list.
450  */
451 RUNNER_TEST(TCCH_0190_get_certificate_chain_im_ca_in_trusted)
452 {
453     remove_user_data(0);
454
455     ChainVerifier cv;
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);
461 }
462
463 RUNNER_TEST(TCCH_0200_get_certificate_chain_all)
464 {
465     remove_user_data(0);
466
467     ChainVerifier cv;
468     cv.enableSystem(true);
469     cv.addTrusted(TestData::TEST_ROOT_CA);
470     cv.addUntrusted(TestData::GEOTRUST);
471     cv.addUntrusted(TestData::GIAG2);
472     /*
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.
476      */
477     cv.verifyPositive(TestData::GOOGLE_COM,4);
478     cv.verifyNegative(TestData::TEST_LEAF);
479 }
480
481 RUNNER_TEST(TCCH_9999_deinit)
482 {
483     remove_user_data(0);
484 }