• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2011 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
19  */
20 
21 #include "config.h"
22 
23 #include <gio/gio.h>
24 
25 #include "gtesttlsbackend.h"
26 
27 typedef struct
28 {
29   gchar *cert_pems[3];
30   gchar *cert_crlf_pem;
31   gchar *key_pem;
32   gchar *key_crlf_pem;
33   gchar *key8_pem;
34 } Reference;
35 
36 static void
pem_parser(const Reference * ref)37 pem_parser (const Reference *ref)
38 {
39   GTlsCertificate *cert;
40   gchar *pem;
41   gsize pem_len = 0;
42   gchar *parsed_cert_pem = NULL;
43   const gchar *parsed_key_pem = NULL;
44   GError *error = NULL;
45 
46   /* Check PEM parsing in certificate, private key order. */
47   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, &pem_len, &error);
48   g_assert_no_error (error);
49   g_assert_nonnull (pem);
50   g_assert_cmpuint (pem_len, >=, 10);
51 
52   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
53   g_assert_no_error (error);
54   g_assert_nonnull (cert);
55 
56   g_object_get (cert,
57       "certificate-pem", &parsed_cert_pem,
58       NULL);
59   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
60   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
61   g_free (parsed_cert_pem);
62   parsed_cert_pem = NULL;
63   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
64   parsed_key_pem = NULL;
65 
66   g_object_unref (cert);
67 
68   /* Make sure length is respected and parser detect invalid PEM
69    * when cert is truncated. */
70   cert = g_tls_certificate_new_from_pem (pem, 10, &error);
71   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
72   g_clear_error (&error);
73 
74   /* Make sure length is respected and parser detect invalid PEM
75    * when cert exists but key is truncated. */
76   cert = g_tls_certificate_new_from_pem (pem, pem_len - 10, &error);
77   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
78   g_clear_error (&error);
79   g_free (pem);
80 
81   /* Check PEM parsing in private key, certificate order */
82   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), &pem, NULL, &error);
83   g_assert_no_error (error);
84   g_assert_nonnull (pem);
85 
86   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
87   g_assert_no_error (error);
88   g_assert_nonnull (cert);
89 
90   g_object_get (cert,
91       "certificate-pem", &parsed_cert_pem,
92       NULL);
93   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
94   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
95   g_free (parsed_cert_pem);
96   parsed_cert_pem = NULL;
97   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
98   parsed_key_pem = NULL;
99 
100   g_free (pem);
101   g_object_unref (cert);
102 
103   /* Check certificate only PEM */
104   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), &pem, NULL, &error);
105   g_assert_no_error (error);
106   g_assert_nonnull (pem);
107 
108   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
109   g_assert_no_error (error);
110   g_assert_nonnull (cert);
111 
112   g_object_get (cert,
113       "certificate-pem", &parsed_cert_pem,
114       NULL);
115   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
116   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
117   g_free (parsed_cert_pem);
118   parsed_cert_pem = NULL;
119   g_assert_null (parsed_key_pem);
120 
121   g_free (pem);
122   g_object_unref (cert);
123 
124   /* Check error with private key only PEM */
125   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), &pem, NULL, &error);
126   g_assert_no_error (error);
127   g_assert_nonnull (pem);
128 
129   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
130   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
131   g_clear_error (&error);
132   g_assert_null (cert);
133   g_free (pem);
134 }
135 
136 static void
pem_parser_handles_chain(const Reference * ref)137 pem_parser_handles_chain (const Reference *ref)
138 {
139   GTlsCertificate *cert;
140   GTlsCertificate *issuer;
141   GTlsCertificate *original_cert;
142   gchar *pem;
143   gchar *parsed_cert_pem = NULL;
144   const gchar *parsed_key_pem = NULL;
145   GError *error = NULL;
146 
147   /* Check that a chain with exactly three certificates is returned */
148   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-list.pem", NULL), &pem, NULL, &error);
149   g_assert_no_error (error);
150   g_assert_nonnull (pem);
151 
152   cert = original_cert = g_tls_certificate_new_from_pem (pem, -1, &error);
153   g_free (pem);
154   g_assert_no_error (error);
155   g_assert_nonnull (cert);
156 
157   g_object_get (cert,
158       "certificate-pem", &parsed_cert_pem,
159       NULL);
160   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
161   g_clear_pointer (&parsed_cert_pem, g_free);
162 
163   /* Make sure the private key was parsed */
164   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
165   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
166   parsed_key_pem = NULL;
167 
168   /* Now test the second cert */
169   issuer = g_tls_certificate_get_issuer (cert);
170   g_assert_nonnull (issuer);
171 
172   cert = issuer;
173   issuer = g_tls_certificate_get_issuer (cert);
174   g_assert_nonnull (issuer);
175 
176   g_object_get (cert,
177       "certificate-pem", &parsed_cert_pem,
178       NULL);
179   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[1]);
180   g_clear_pointer (&parsed_cert_pem, g_free);
181 
182   /* Only the first cert should have a private key */
183   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
184   g_assert_null (parsed_key_pem);
185 
186   /* Now test the final cert */
187   cert = issuer;
188   issuer = g_tls_certificate_get_issuer (cert);
189   g_assert_null (issuer);
190 
191   g_object_get (cert,
192       "certificate-pem", &parsed_cert_pem,
193       NULL);
194   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[2]);
195   g_clear_pointer (&parsed_cert_pem, g_free);
196 
197   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
198   g_assert_null (parsed_key_pem);
199 
200   g_object_unref (original_cert);
201 }
202 
203 static void
from_file(const Reference * ref)204 from_file (const Reference *ref)
205 {
206   GTlsCertificate *cert;
207   gchar *parsed_cert_pem = NULL;
208   const gchar *parsed_key_pem = NULL;
209   GError *error = NULL;
210 
211   cert = g_tls_certificate_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
212                                           &error);
213   g_assert_no_error (error);
214   g_assert_nonnull (cert);
215 
216   g_object_get (cert,
217       "certificate-pem", &parsed_cert_pem,
218       NULL);
219   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
220   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
221   g_free (parsed_cert_pem);
222   parsed_cert_pem = NULL;
223   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
224   parsed_key_pem = NULL;
225 
226   g_object_unref (cert);
227 }
228 
229 static void
from_files(const Reference * ref)230 from_files (const Reference *ref)
231 {
232   GTlsCertificate *cert;
233   gchar *parsed_cert_pem = NULL;
234   const gchar *parsed_key_pem = NULL;
235   GError *error = NULL;
236 
237   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
238                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
239                                            &error);
240   g_assert_no_error (error);
241   g_assert_nonnull (cert);
242 
243   g_object_get (cert,
244       "certificate-pem", &parsed_cert_pem,
245       NULL);
246   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
247   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
248   g_free (parsed_cert_pem);
249   parsed_cert_pem = NULL;
250   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
251   parsed_key_pem = NULL;
252 
253   g_object_unref (cert);
254 
255   /* Missing private key */
256   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
257                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL),
258                                            &error);
259   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
260   g_clear_error (&error);
261   g_assert_null (cert);
262 
263   /* Missing header private key */
264   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
265                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-header.pem", NULL),
266                                            &error);
267   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
268   g_clear_error (&error);
269   g_assert_null (cert);
270 
271   /* Missing footer private key */
272   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
273                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-footer.pem", NULL),
274                                            &error);
275   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
276   g_clear_error (&error);
277   g_assert_null (cert);
278 
279   /* Missing certificate */
280   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
281                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
282                                            &error);
283   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
284   g_clear_error (&error);
285   g_assert_null (cert);
286 
287   /* Using this method twice with a file containing both private key and
288    * certificate as a way to enforce private key presence is a fair use
289    */
290   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
291                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
292                                            &error);
293   g_assert_no_error (error);
294   g_assert_nonnull (cert);
295   g_object_unref (cert);
296 }
297 
298 static void
from_files_crlf(const Reference * ref)299 from_files_crlf (const Reference *ref)
300 {
301   GTlsCertificate *cert;
302   gchar *parsed_cert_pem = NULL;
303   const gchar *parsed_key_pem = NULL;
304   GError *error = NULL;
305 
306   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-crlf.pem", NULL),
307                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key-crlf.pem", NULL),
308                                            &error);
309   g_assert_no_error (error);
310   g_assert_nonnull (cert);
311 
312   g_object_get (cert,
313       "certificate-pem", &parsed_cert_pem,
314       NULL);
315   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
316   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_crlf_pem);
317   g_free (parsed_cert_pem);
318   parsed_cert_pem = NULL;
319   g_assert_cmpstr (parsed_key_pem, ==, ref->key_crlf_pem);
320   parsed_key_pem = NULL;
321 
322   g_object_unref (cert);
323 }
324 
325 static void
from_files_pkcs8(const Reference * ref)326 from_files_pkcs8 (const Reference *ref)
327 {
328   GTlsCertificate *cert;
329   gchar *parsed_cert_pem = NULL;
330   const gchar *parsed_key_pem = NULL;
331   GError *error = NULL;
332 
333   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
334                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL),
335                                            &error);
336   g_assert_no_error (error);
337   g_assert_nonnull (cert);
338 
339   g_object_get (cert,
340       "certificate-pem", &parsed_cert_pem,
341       NULL);
342   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
343   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
344   g_free (parsed_cert_pem);
345   parsed_cert_pem = NULL;
346   g_assert_cmpstr (parsed_key_pem, ==, ref->key8_pem);
347   parsed_key_pem = NULL;
348 
349   g_object_unref (cert);
350 }
351 
352 static void
from_files_pkcs8enc(const Reference * ref)353 from_files_pkcs8enc (const Reference *ref)
354 {
355   GTlsCertificate *cert;
356   GError *error = NULL;
357 
358   /* Mare sure an error is returned for encrypted key */
359   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
360                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key8enc.pem", NULL),
361                                            &error);
362   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
363   g_clear_error (&error);
364   g_assert_null (cert);
365 }
366 
367 static void
list_from_file(const Reference * ref)368 list_from_file (const Reference *ref)
369 {
370   GList *list, *l;
371   GError *error = NULL;
372   int i;
373 
374   list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-list.pem", NULL),
375                                                &error);
376   g_assert_no_error (error);
377   g_assert_cmpint (g_list_length (list), ==, 3);
378 
379   l = list;
380   for (i = 0; i < 3; i++)
381     {
382       GTlsCertificate *cert = l->data;
383       gchar *parsed_cert_pem = NULL;
384       g_object_get (cert,
385           "certificate-pem", &parsed_cert_pem,
386           NULL);
387       g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[i]);
388       g_free (parsed_cert_pem);
389       l = g_list_next (l);
390     }
391 
392   g_list_free_full (list, g_object_unref);
393 
394   /* Empty list is not an error */
395   list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "nothing.pem", NULL),
396                                                &error);
397   g_assert_no_error (error);
398   g_assert_cmpint (g_list_length (list), ==, 0);
399 }
400 
401 static void
from_pkcs11_uri(void)402 from_pkcs11_uri (void)
403 {
404   GError *error = NULL;
405   GTlsCertificate *cert;
406   gchar *pkcs11_uri = NULL;
407 
408   cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
409   g_assert_no_error (error);
410   g_assert_nonnull (cert);
411 
412   g_object_get (cert, "pkcs11-uri", &pkcs11_uri, NULL);
413   g_assert_cmpstr ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", ==, pkcs11_uri);
414   g_free (pkcs11_uri);
415 
416   g_object_unref (cert);
417 }
418 
419 static void
from_unsupported_pkcs11_uri(void)420 from_unsupported_pkcs11_uri (void)
421 {
422   GError *error = NULL;
423   GTlsCertificate *cert;
424 
425   /* This is a magic value in gtesttlsbackend.c simulating an unsupported backend */
426   cert = g_tls_certificate_new_from_pkcs11_uris ("unsupported", NULL, &error);
427   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
428   g_assert_null (cert);
429 
430   g_clear_error (&error);
431 }
432 
433 int
main(int argc,char * argv[])434 main (int   argc,
435       char *argv[])
436 {
437   int rtv;
438   Reference ref;
439   GError *error = NULL;
440   gchar *path;
441 
442   g_test_init (&argc, &argv, NULL);
443 
444   _g_test_tls_backend_get_type ();
445 
446   /* Load reference PEM */
447   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL);
448   g_file_get_contents (path, &ref.cert_pems[0], NULL, &error);
449   g_assert_no_error (error);
450   g_assert_nonnull (ref.cert_pems[0]);
451   g_free (path);
452   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL);
453   g_file_get_contents (path, &ref.cert_pems[1], NULL, &error);
454   g_assert_no_error (error);
455   g_assert_nonnull (ref.cert_pems[1]);
456   g_free (path);
457   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert3.pem", NULL);
458   g_file_get_contents (path, &ref.cert_pems[2], NULL, &error);
459   g_assert_no_error (error);
460   g_assert_nonnull (ref.cert_pems[2]);
461   g_free (path);
462   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert-crlf.pem", NULL);
463   g_file_get_contents (path, &ref.cert_crlf_pem, NULL, &error);
464   g_assert_no_error (error);
465   g_assert_nonnull (ref.cert_crlf_pem);
466   g_free (path);
467   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL);
468   g_file_get_contents (path, &ref.key_pem, NULL, &error);
469   g_assert_no_error (error);
470   g_assert_nonnull (ref.key_pem);
471   g_free (path);
472   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key-crlf.pem", NULL);
473   g_file_get_contents (path, &ref.key_crlf_pem, NULL, &error);
474   g_assert_no_error (error);
475   g_assert_nonnull (ref.key_crlf_pem);
476   g_free (path);
477   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL);
478   g_file_get_contents (path, &ref.key8_pem, NULL, &error);
479   g_assert_no_error (error);
480   g_assert_nonnull (ref.key8_pem);
481   g_free (path);
482 
483   g_test_add_data_func ("/tls-certificate/pem-parser",
484                         &ref, (GTestDataFunc)pem_parser);
485   g_test_add_data_func ("/tls-certificate/pem-parser-handles-chain",
486                         &ref, (GTestDataFunc)pem_parser_handles_chain);
487   g_test_add_data_func ("/tls-certificate/from_file",
488                         &ref, (GTestDataFunc)from_file);
489   g_test_add_data_func ("/tls-certificate/from_files",
490                         &ref, (GTestDataFunc)from_files);
491   g_test_add_data_func ("/tls-certificate/from_files_crlf",
492                         &ref, (GTestDataFunc)from_files_crlf);
493   g_test_add_data_func ("/tls-certificate/from_files_pkcs8",
494                         &ref, (GTestDataFunc)from_files_pkcs8);
495   g_test_add_data_func ("/tls-certificate/from_files_pkcs8enc",
496                         &ref, (GTestDataFunc)from_files_pkcs8enc);
497   g_test_add_data_func ("/tls-certificate/list_from_file",
498                         &ref, (GTestDataFunc)list_from_file);
499   g_test_add_func ("/tls-certificate/pkcs11-uri",
500                    from_pkcs11_uri);
501   g_test_add_func ("/tls-certificate/pkcs11-uri-unsupported",
502                    from_unsupported_pkcs11_uri);
503 
504   rtv = g_test_run();
505 
506   g_free (ref.cert_pems[0]);
507   g_free (ref.cert_pems[1]);
508   g_free (ref.cert_pems[2]);
509   g_free (ref.cert_crlf_pem);
510   g_free (ref.key_pem);
511   g_free (ref.key_crlf_pem);
512   g_free (ref.key8_pem);
513 
514   return rtv;
515 }
516