e952e532782fd6be338116ae0e27b1b1a2eb4642
[platform/upstream/p11-kit.git] / tools / tests / test-x509.c
1 /*
2  * Copyright (c) 2011, Collabora Ltd.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *     * Redistributions of source code must retain the above
9  *       copyright notice, this list of conditions and the
10  *       following disclaimer.
11  *     * Redistributions in binary form must reproduce the
12  *       above copyright notice, this list of conditions and
13  *       the following disclaimer in the documentation and/or
14  *       other materials provided with the distribution.
15  *     * The names of contributors to this software may not be
16  *       used to endorse or promote products derived from this
17  *       software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
30  * DAMAGE.
31  *
32  * Author: Stef Walter <stefw@collabora.co.uk>
33  */
34
35 #include "config.h"
36 #include "CuTest.h"
37
38 #include "attrs.h"
39 #include "compat.h"
40 #include "debug.h"
41 #include "dict.h"
42 #include "extract.h"
43 #include "message.h"
44 #include "mock.h"
45 #include "path.h"
46 #include "pkcs11.h"
47 #include "pkcs11x.h"
48 #include "oid.h"
49 #include "test.h"
50
51 #include <assert.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <unistd.h>
56
57 struct {
58         CK_FUNCTION_LIST module;
59         P11KitIter *iter;
60         p11_extract_info ex;
61         char *directory;
62 } test;
63
64 static void
65 setup (CuTest *tc)
66 {
67         CK_RV rv;
68
69         memcpy (&test.module, &mock_module, sizeof (CK_FUNCTION_LIST));
70         rv = p11_kit_initialize_module (&test.module);
71         CuAssertIntEquals (tc, CKR_OK, rv);
72
73         mock_module_reset_objects (MOCK_SLOT_ONE_ID);
74
75         test.iter = p11_kit_iter_new (NULL);
76
77         p11_extract_info_init (&test.ex);
78
79         test.directory = p11_path_expand ("$TEMP/test-extract.XXXXXX");
80         if (!mkdtemp (test.directory))
81                 CuFail (tc, "mkdtemp() failed");
82 }
83
84 static void
85 teardown (CuTest *tc)
86 {
87         CK_RV rv;
88
89         if (rmdir (test.directory) < 0)
90                 CuFail (tc, "rmdir() failed");
91         free (test.directory);
92
93         p11_extract_info_cleanup (&test.ex);
94         p11_kit_iter_free (test.iter);
95
96         rv = p11_kit_finalize_module (&test.module);
97         CuAssertIntEquals (tc, CKR_OK, rv);
98 }
99
100 static CK_OBJECT_CLASS certificate_class = CKO_CERTIFICATE;
101 static CK_CERTIFICATE_TYPE x509_type = CKC_X_509;
102
103 static CK_ATTRIBUTE cacert3_authority_attrs[] = {
104         { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
105         { CKA_CLASS, &certificate_class, sizeof (certificate_class) },
106         { CKA_CERTIFICATE_TYPE, &x509_type, sizeof (x509_type) },
107         { CKA_LABEL, "Cacert3 Here", 12 },
108         { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) },
109         { CKA_ID, "ID1", 3 },
110         { CKA_INVALID },
111 };
112
113 static CK_ATTRIBUTE certificate_filter[] = {
114         { CKA_CLASS, &certificate_class, sizeof (certificate_class) },
115         { CKA_INVALID },
116 };
117
118 static void
119 test_file (CuTest *tc)
120 {
121         bool ret;
122
123         setup (tc);
124
125         mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs);
126
127         p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL);
128         p11_kit_iter_add_filter (test.iter, certificate_filter, 1);
129         p11_kit_iter_begin_with (test.iter, &test.module, 0, 0);
130
131         if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0)
132                 assert_not_reached ();
133
134         ret = p11_extract_x509_file (test.iter, &test.ex);
135         CuAssertIntEquals (tc, true, ret);
136
137         test_check_file (tc, test.directory, "extract.cer", SRCDIR "/files/cacert3.der");
138
139         free (test.ex.destination);
140         teardown (tc);
141 }
142
143 static void
144 test_file_multiple (CuTest *tc)
145 {
146         bool ret;
147
148         setup (tc);
149
150         mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs);
151         mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs);
152
153         p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL);
154         p11_kit_iter_add_filter (test.iter, certificate_filter, 1);
155         p11_kit_iter_begin_with (test.iter, &test.module, 0, 0);
156
157         if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0)
158                 assert_not_reached ();
159
160         p11_message_quiet ();
161
162         ret = p11_extract_x509_file (test.iter, &test.ex);
163         CuAssertIntEquals (tc, true, ret);
164
165         CuAssertTrue (tc, strstr (p11_message_last (), "multiple certificates") != NULL);
166
167         p11_message_loud ();
168
169         test_check_file (tc, test.directory, "extract.cer", SRCDIR "/files/cacert3.der");
170
171         free (test.ex.destination);
172         teardown (tc);
173 }
174
175 static void
176 test_file_without (CuTest *tc)
177 {
178         bool ret;
179
180         setup (tc);
181
182         p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL);
183         p11_kit_iter_add_filter (test.iter, certificate_filter, 1);
184         p11_kit_iter_begin_with (test.iter, &test.module, 0, 0);
185
186         if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0)
187                 assert_not_reached ();
188
189         p11_message_quiet ();
190
191         ret = p11_extract_x509_file (test.iter, &test.ex);
192         CuAssertIntEquals (tc, false, ret);
193
194         CuAssertTrue (tc, strstr (p11_message_last (), "no certificate") != NULL);
195
196         p11_message_loud ();
197
198         free (test.ex.destination);
199         teardown (tc);
200 }
201
202 static void
203 test_directory (CuTest *tc)
204 {
205         bool ret;
206
207         setup (tc);
208
209         mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs);
210         mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs);
211
212         p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL);
213         p11_kit_iter_add_filter (test.iter, certificate_filter, 1);
214         p11_kit_iter_begin_with (test.iter, &test.module, 0, 0);
215
216         /* Yes, this is a race, and why you shouldn't build software as root */
217         if (rmdir (test.directory) < 0)
218                 assert_not_reached ();
219         test.ex.destination = test.directory;
220
221         ret = p11_extract_x509_directory (test.iter, &test.ex);
222         CuAssertIntEquals (tc, true, ret);
223
224         test_check_directory (tc, test.directory, ("Cacert3_Here.cer", "Cacert3_Here.1.cer", NULL));
225         test_check_file (tc, test.directory, "Cacert3_Here.cer", SRCDIR "/files/cacert3.der");
226         test_check_file (tc, test.directory, "Cacert3_Here.1.cer", SRCDIR "/files/cacert3.der");
227
228         teardown (tc);
229 }
230
231 static void
232 test_directory_empty (CuTest *tc)
233 {
234         bool ret;
235
236         setup (tc);
237
238         p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL);
239         p11_kit_iter_add_filter (test.iter, certificate_filter, 1);
240         p11_kit_iter_begin_with (test.iter, &test.module, 0, 0);
241
242         /* Yes, this is a race, and why you shouldn't build software as root */
243         if (rmdir (test.directory) < 0)
244                 assert_not_reached ();
245         test.ex.destination = test.directory;
246
247         ret = p11_extract_x509_directory (test.iter, &test.ex);
248         CuAssertIntEquals (tc, true, ret);
249
250         test_check_directory (tc, test.directory, (NULL, NULL));
251
252         teardown (tc);
253 }
254
255 int
256 main (void)
257 {
258         CuString *output = CuStringNew ();
259         CuSuite* suite = CuSuiteNew ();
260         int ret;
261
262         putenv ("P11_KIT_STRICT=1");
263         mock_module_init ();
264         p11_debug_init ();
265
266         SUITE_ADD_TEST (suite, test_file);
267         SUITE_ADD_TEST (suite, test_file_multiple);
268         SUITE_ADD_TEST (suite, test_file_without);
269         SUITE_ADD_TEST (suite, test_directory);
270         SUITE_ADD_TEST (suite, test_directory_empty);
271
272         CuSuiteRun (suite);
273         CuSuiteSummary (suite, output);
274         CuSuiteDetails (suite, output);
275         printf ("%s\n", output->buffer);
276         ret = suite->failCount;
277         CuSuiteDelete (suite);
278         CuStringDelete (output);
279
280         return ret;
281 }