More test coverage for settings backends
[platform/upstream/glib.git] / gio / tests / tls-certificate.c
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 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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
21  */
22
23 #include "config.h"
24
25 #include <gio/gio.h>
26
27 #include "gtesttlsbackend.h"
28
29 typedef struct
30 {
31   gchar *cert_pems[3];
32   gchar *key_pem;
33   gchar *key8_pem;
34 } Reference;
35
36 static void
37 pem_parser (const Reference *ref)
38 {
39   GTlsCertificate *cert;
40   gchar *pem;
41   gchar *parsed_cert_pem = NULL;
42   const gchar *parsed_key_pem = NULL;
43   GError *error = NULL;
44
45   /* Check PEM parsing in certificate, private key order. */
46   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, NULL, &error);
47   g_assert_no_error (error);
48   g_assert (pem);
49
50   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
51   g_assert_no_error (error);
52   g_assert (cert);
53
54   g_object_get (cert,
55       "certificate-pem", &parsed_cert_pem,
56       NULL);
57   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
58   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
59   g_free (parsed_cert_pem);
60   parsed_cert_pem = NULL;
61   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
62   parsed_key_pem = NULL;
63
64   g_object_unref (cert);
65
66   /* Make sure length is respected and parser detect invalid (truncated) PEM. */
67   cert = g_tls_certificate_new_from_pem (pem, 10, &error);
68   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
69   g_clear_error (&error);
70   g_free (pem);
71
72   /* Check PEM parsing in private key, certificate order */
73   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), &pem, NULL, &error);
74   g_assert_no_error (error);
75   g_assert (pem);
76
77   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
78   g_assert_no_error (error);
79   g_assert (cert);
80
81   g_object_get (cert,
82       "certificate-pem", &parsed_cert_pem,
83       NULL);
84   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
85   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
86   g_free (parsed_cert_pem);
87   parsed_cert_pem = NULL;
88   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
89   parsed_key_pem = NULL;
90
91   g_free (pem);
92   g_object_unref (cert);
93
94   /* Check certificate only PEM */
95   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), &pem, NULL, &error);
96   g_assert_no_error (error);
97   g_assert (pem);
98
99   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
100   g_assert_no_error (error);
101   g_assert (cert);
102
103   g_object_get (cert,
104       "certificate-pem", &parsed_cert_pem,
105       NULL);
106   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
107   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
108   g_free (parsed_cert_pem);
109   parsed_cert_pem = NULL;
110   g_assert (parsed_key_pem == NULL);
111
112   g_free (pem);
113   g_object_unref (cert);
114
115   /* Check error with private key only PEM */
116   g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), &pem, NULL, &error);
117   g_assert_no_error (error);
118   g_assert (pem);
119
120   cert = g_tls_certificate_new_from_pem (pem, -1, &error);
121   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
122   g_clear_error (&error);
123   g_assert (cert == NULL);
124   g_free (pem);
125 }
126
127 static void
128 from_file (const Reference *ref)
129 {
130   GTlsCertificate *cert;
131   gchar *parsed_cert_pem = NULL;
132   const gchar *parsed_key_pem = NULL;
133   GError *error = NULL;
134
135   cert = g_tls_certificate_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
136                                           &error);
137   g_assert_no_error (error);
138   g_assert (cert);
139
140   g_object_get (cert,
141       "certificate-pem", &parsed_cert_pem,
142       NULL);
143   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
144   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
145   g_free (parsed_cert_pem);
146   parsed_cert_pem = NULL;
147   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
148   parsed_key_pem = NULL;
149
150   g_object_unref (cert);
151 }
152
153 static void
154 from_files (const Reference *ref)
155 {
156   GTlsCertificate *cert;
157   gchar *parsed_cert_pem = NULL;
158   const gchar *parsed_key_pem = NULL;
159   GError *error = NULL;
160
161   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
162                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
163                                            &error);
164   g_assert_no_error (error);
165   g_assert (cert);
166
167   g_object_get (cert,
168       "certificate-pem", &parsed_cert_pem,
169       NULL);
170   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
171   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
172   g_free (parsed_cert_pem);
173   parsed_cert_pem = NULL;
174   g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem);
175   parsed_key_pem = NULL;
176
177   g_object_unref (cert);
178
179   /* Missing private key */
180   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
181                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL),
182                                            &error);
183   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
184   g_clear_error (&error);
185   g_assert (cert == NULL);
186
187   /* Missing certificate */
188   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
189                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
190                                            &error);
191   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
192   g_clear_error (&error);
193   g_assert (cert == NULL);
194
195   /* Using this method twice with a file containing both private key and
196    * certificate as a way to inforce private key presence is a fair use
197    */
198   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
199                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL),
200                                            &error);
201   g_assert_no_error (error);
202   g_assert (cert);
203   g_object_unref (cert);
204 }
205
206
207 static void
208 from_files_pkcs8 (const Reference *ref)
209 {
210   GTlsCertificate *cert;
211   gchar *parsed_cert_pem = NULL;
212   const gchar *parsed_key_pem = NULL;
213   GError *error = NULL;
214
215   cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL),
216                                            g_test_get_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL),
217                                            &error);
218   g_assert_no_error (error);
219   g_assert (cert);
220
221   g_object_get (cert,
222       "certificate-pem", &parsed_cert_pem,
223       NULL);
224   parsed_key_pem = g_test_tls_connection_get_private_key_pem (cert);
225   g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]);
226   g_free (parsed_cert_pem);
227   parsed_cert_pem = NULL;
228   g_assert_cmpstr (parsed_key_pem, ==, ref->key8_pem);
229   parsed_key_pem = NULL;
230
231   g_object_unref (cert);
232 }
233
234 static void
235 list_from_file (const Reference *ref)
236 {
237   GList *list, *l;
238   GError *error = NULL;
239   int i;
240
241   list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-list.pem", NULL),
242                                                &error);
243   g_assert_no_error (error);
244   g_assert_cmpint (g_list_length (list), ==, 3);
245
246   l = list;
247   for (i = 0; i < 3; i++)
248     {
249       GTlsCertificate *cert = l->data;
250       gchar *parsed_cert_pem = NULL;
251       g_object_get (cert,
252           "certificate-pem", &parsed_cert_pem,
253           NULL);
254       g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[i]);
255       g_free (parsed_cert_pem);
256       l = g_list_next (l);
257     }
258
259   g_list_free_full (list, g_object_unref);
260
261   /* Empty list is not an error */
262   list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "nothing.pem", NULL),
263                                                &error);
264   g_assert_no_error (error);
265   g_assert_cmpint (g_list_length (list), ==, 0);
266 }
267
268 int
269 main (int   argc,
270       char *argv[])
271 {
272   int rtv;
273   Reference ref;
274   GError *error = NULL;
275   gchar *path;
276
277   g_test_init (&argc, &argv, NULL);
278
279   _g_test_tls_backend_get_type ();
280
281   /* Load reference PEM */
282   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL);
283   g_file_get_contents (path, &ref.cert_pems[0], NULL, &error);
284   g_assert_no_error (error);
285   g_assert (ref.cert_pems[0]);
286   g_free (path);
287   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL);
288   g_file_get_contents (path, &ref.cert_pems[1], NULL, &error);
289   g_assert_no_error (error);
290   g_assert (ref.cert_pems[1]);
291   g_free (path);
292   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert3.pem", NULL);
293   g_file_get_contents (path, &ref.cert_pems[2], NULL, &error);
294   g_assert_no_error (error);
295   g_assert (ref.cert_pems[2]);
296   g_free (path);
297   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL);
298   g_file_get_contents (path, &ref.key_pem, NULL, &error);
299   g_assert_no_error (error);
300   g_assert (ref.key_pem);
301   g_free (path);
302   path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL);
303   g_file_get_contents (path, &ref.key8_pem, NULL, &error);
304   g_assert_no_error (error);
305   g_assert (ref.key8_pem);
306   g_free (path);
307
308   g_test_add_data_func ("/tls-certificate/pem-parser",
309                         &ref, (GTestDataFunc)pem_parser);
310   g_test_add_data_func ("/tls-certificate/from_file",
311                         &ref, (GTestDataFunc)from_file);
312   g_test_add_data_func ("/tls-certificate/from_files",
313                         &ref, (GTestDataFunc)from_files);
314   g_test_add_data_func ("/tls-certificate/from_files_pkcs8",
315                         &ref, (GTestDataFunc)from_files_pkcs8);
316   g_test_add_data_func ("/tls-certificate/list_from_file",
317                         &ref, (GTestDataFunc)list_from_file);
318
319   rtv = g_test_run();
320
321   g_free (ref.cert_pems[0]);
322   g_free (ref.cert_pems[1]);
323   g_free (ref.cert_pems[2]);
324   g_free (ref.key_pem);
325   g_free (ref.key8_pem);
326
327   return rtv;
328 }