Revert "gnutls: Implement certificate-bytes and private-key-bytes properties"
[platform/upstream/glib-networking.git] / tls / tests / certificate.c
1 /* GIO TLS tests
2  *
3  * Copyright 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, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * Author: Stef Walter <stefw@collabora.co.uk>
20  */
21
22 #include <gio/gio.h>
23
24 #include <sys/types.h>
25 #include <string.h>
26
27 #define TEST_FILE(name) (SRCDIR "/files/" name)
28
29 typedef struct {
30   GTlsBackend *backend;
31   GType cert_gtype;
32   gchar *cert_pem;
33   gsize cert_pem_length;
34   GByteArray *cert_der;
35   gchar *key_pem;
36   gsize key_pem_length;
37   GByteArray *key_der;
38 } TestCertificate;
39
40 static void
41 setup_certificate (TestCertificate *test, gconstpointer data)
42 {
43   GError *error = NULL;
44   gchar *contents;
45   gsize length;
46
47   test->backend = g_tls_backend_get_default ();
48   test->cert_gtype = g_tls_backend_get_certificate_type (test->backend);
49
50   g_file_get_contents (TEST_FILE ("server.pem"), &test->cert_pem,
51                        &test->cert_pem_length, &error);
52   g_assert_no_error (error);
53
54   g_file_get_contents (TEST_FILE ("server.der"),
55                        &contents, &length, &error);
56   g_assert_no_error (error);
57
58   test->cert_der = g_byte_array_new ();
59   g_byte_array_append (test->cert_der, (guint8 *)contents, length);
60   g_free (contents);
61
62   g_file_get_contents (TEST_FILE ("server-key.pem"), &test->key_pem,
63                        &test->key_pem_length, &error);
64   g_assert_no_error (error);
65
66   g_file_get_contents (TEST_FILE ("server-key.der"),
67                        &contents, &length, &error);
68   g_assert_no_error (error);
69
70   test->key_der = g_byte_array_new ();
71   g_byte_array_append (test->key_der, (guint8 *)contents, length);
72   g_free (contents);
73 }
74
75 static void
76 teardown_certificate (TestCertificate *test,
77                       gconstpointer data)
78 {
79   g_free (test->cert_pem);
80   g_byte_array_free (test->cert_der, TRUE);
81
82   g_free (test->key_pem);
83   g_byte_array_free (test->key_der, TRUE);
84 }
85
86 static void
87 test_create_pem (TestCertificate *test,
88                  gconstpointer data)
89 {
90   GTlsCertificate *cert;
91   gchar *pem = NULL;
92   GError *error = NULL;
93
94   cert = g_tls_certificate_new_from_pem (test->cert_pem, test->cert_pem_length, &error);
95   g_assert_no_error (error);
96   g_assert (G_IS_TLS_CERTIFICATE (cert));
97
98   g_object_get (cert, "certificate-pem", &pem, NULL);
99   g_assert_cmpstr (pem, ==, test->cert_pem);
100   g_free (pem);
101
102   g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
103   g_object_unref (cert);
104   g_assert (cert == NULL);
105 }
106
107 static void
108 test_create_with_key_pem (TestCertificate *test,
109                           gconstpointer data)
110 {
111   GTlsCertificate *cert;
112   GError *error = NULL;
113
114   cert = g_initable_new (test->cert_gtype, NULL, &error,
115                          "certificate-pem", test->cert_pem,
116                          "private-key-pem", test->key_pem,
117                          NULL);
118   g_assert_no_error (error);
119   g_assert (G_IS_TLS_CERTIFICATE (cert));
120
121   g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
122   g_object_unref (cert);
123   g_assert (cert == NULL);
124 }
125
126 static void
127 test_create_der (TestCertificate *test,
128                  gconstpointer data)
129 {
130   GTlsCertificate *cert;
131   GByteArray *der = NULL;
132   GError *error = NULL;
133
134   cert = g_initable_new (test->cert_gtype, NULL, &error,
135                          "certificate", test->cert_der,
136                          NULL);
137   g_assert_no_error (error);
138   g_assert (G_IS_TLS_CERTIFICATE (cert));
139
140   g_object_get (cert, "certificate", &der, NULL);
141   g_assert (der);
142   g_assert_cmpuint (der->len, ==, test->cert_der->len);
143   g_assert (memcmp (der->data, test->cert_der->data, der->len) == 0);
144
145   g_byte_array_unref (der);
146
147   g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
148   g_object_unref (cert);
149   g_assert (cert == NULL);
150 }
151
152 static void
153 test_create_with_key_der (TestCertificate *test,
154                           gconstpointer data)
155 {
156   GTlsCertificate *cert;
157   GError *error = NULL;
158
159   cert = g_initable_new (test->cert_gtype, NULL, &error,
160                          "certificate", test->cert_der,
161                          "private-key", test->key_der,
162                          NULL);
163   g_assert_no_error (error);
164   g_assert (G_IS_TLS_CERTIFICATE (cert));
165
166   g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
167   g_object_unref (cert);
168   g_assert (cert == NULL);
169 }
170
171 static void
172 test_create_certificate_with_issuer (TestCertificate   *test,
173                                      gconstpointer      data)
174 {
175   GTlsCertificate *cert, *issuer, *check;
176   GError *error = NULL;
177
178   issuer = g_tls_certificate_new_from_file (TEST_FILE ("ca.pem"), &error);
179   g_assert_no_error (error);
180   g_assert (G_IS_TLS_CERTIFICATE (issuer));
181
182   cert = g_initable_new (test->cert_gtype, NULL, &error,
183                          "certificate-pem", test->cert_pem,
184                          "issuer", issuer,
185                          NULL);
186   g_assert_no_error (error);
187   g_assert (G_IS_TLS_CERTIFICATE (cert));
188
189   g_object_add_weak_pointer (G_OBJECT (issuer), (gpointer *)&issuer);
190   g_object_unref (issuer);
191   g_assert (issuer != NULL);
192
193   check = g_tls_certificate_get_issuer (cert);
194   g_assert (check == issuer);
195
196   g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
197   g_object_unref (cert);
198   g_assert (cert == NULL);
199   g_assert (issuer == NULL);
200 }
201
202 /* -----------------------------------------------------------------------------
203  * CERTIFICATE VERIFY
204  */
205
206 typedef struct {
207   GTlsCertificate *cert;
208   GTlsCertificate *anchor;
209   GSocketConnectable *identity;
210   GTlsDatabase *database;
211 } TestVerify;
212
213 static void
214 setup_verify (TestVerify     *test,
215               gconstpointer   data)
216 {
217   GError *error = NULL;
218
219   test->cert = g_tls_certificate_new_from_file (TEST_FILE ("server.pem"), &error);
220   g_assert_no_error (error);
221   g_assert (G_IS_TLS_CERTIFICATE (test->cert));
222
223   test->identity = g_network_address_new ("server.example.com", 80);
224
225   test->anchor = g_tls_certificate_new_from_file (TEST_FILE ("ca.pem"), &error);
226   g_assert_no_error (error);
227   g_assert (G_IS_TLS_CERTIFICATE (test->anchor));
228   test->database = g_tls_file_database_new (TEST_FILE ("ca.pem"), &error);
229   g_assert_no_error (error);
230   g_assert (G_IS_TLS_DATABASE (test->database));
231 }
232
233 static void
234 teardown_verify (TestVerify      *test,
235                  gconstpointer    data)
236 {
237   g_assert (G_IS_TLS_CERTIFICATE (test->cert));
238   g_object_add_weak_pointer (G_OBJECT (test->cert),
239                              (gpointer *)&test->cert);
240   g_object_unref (test->cert);
241   g_assert (test->cert == NULL);
242
243   g_assert (G_IS_TLS_CERTIFICATE (test->anchor));
244   g_object_add_weak_pointer (G_OBJECT (test->anchor),
245                              (gpointer *)&test->anchor);
246   g_object_unref (test->anchor);
247   g_assert (test->anchor == NULL);
248
249   g_assert (G_IS_TLS_DATABASE (test->database));
250   g_object_add_weak_pointer (G_OBJECT (test->database),
251                              (gpointer *)&test->database);
252   g_object_unref (test->database);
253   g_assert (test->database == NULL);
254
255   g_object_add_weak_pointer (G_OBJECT (test->identity),
256                              (gpointer *)&test->identity);
257   g_object_unref (test->identity);
258   g_assert (test->identity == NULL);
259 }
260
261 static void
262 test_verify_certificate_good (TestVerify      *test,
263                               gconstpointer    data)
264 {
265   GTlsCertificateFlags errors;
266
267   errors = g_tls_certificate_verify (test->cert, test->identity, test->anchor);
268   g_assert_cmpuint (errors, ==, 0);
269
270   errors = g_tls_certificate_verify (test->cert, NULL, test->anchor);
271   g_assert_cmpuint (errors, ==, 0);
272 }
273
274 static void
275 test_verify_certificate_bad_identity (TestVerify      *test,
276                                       gconstpointer    data)
277 {
278   GSocketConnectable *identity;
279   GTlsCertificateFlags errors;
280
281   identity = g_network_address_new ("other.example.com", 80);
282
283   errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
284   g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
285
286   g_object_unref (identity);
287 }
288
289 static void
290 test_verify_certificate_bad_ca (TestVerify      *test,
291                                 gconstpointer    data)
292 {
293   GTlsCertificateFlags errors;
294   GTlsCertificate *cert;
295   GError *error = NULL;
296
297   /* Use a client certificate as the CA, which is wrong */
298   cert = g_tls_certificate_new_from_file (TEST_FILE ("client.pem"), &error);
299   g_assert_no_error (error);
300   g_assert (G_IS_TLS_CERTIFICATE (cert));
301
302   errors = g_tls_certificate_verify (test->cert, test->identity, cert);
303   g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
304
305   g_object_unref (cert);
306 }
307
308 static void
309 test_verify_certificate_bad_before (TestVerify      *test,
310                                     gconstpointer    data)
311 {
312   GTlsCertificateFlags errors;
313   GTlsCertificate *cert;
314   GError *error = NULL;
315
316   /* This is a certificate in the future */
317   cert = g_tls_certificate_new_from_file (TEST_FILE ("client-future.pem"), &error);
318   g_assert_no_error (error);
319   g_assert (G_IS_TLS_CERTIFICATE (cert));
320
321   errors = g_tls_certificate_verify (cert, NULL, test->anchor);
322   g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_NOT_ACTIVATED);
323
324   g_object_unref (cert);
325 }
326
327 static void
328 test_verify_certificate_bad_expired (TestVerify      *test,
329                                      gconstpointer    data)
330 {
331   GTlsCertificateFlags errors;
332   GTlsCertificate *cert;
333   GError *error = NULL;
334
335   /* This is a certificate in the future */
336   cert = g_tls_certificate_new_from_file (TEST_FILE ("client-past.pem"), &error);
337   g_assert_no_error (error);
338   g_assert (G_IS_TLS_CERTIFICATE (cert));
339
340   errors = g_tls_certificate_verify (cert, NULL, test->anchor);
341   g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_EXPIRED);
342
343   g_object_unref (cert);
344 }
345
346 static void
347 test_verify_certificate_bad_combo (TestVerify      *test,
348                                    gconstpointer    data)
349 {
350   GTlsCertificate *cert;
351   GTlsCertificate *cacert;
352   GSocketConnectable *identity;
353   GTlsCertificateFlags errors;
354   GError *error = NULL;
355
356   cert = g_tls_certificate_new_from_file (TEST_FILE ("client-past.pem"), &error);
357   g_assert_no_error (error);
358   g_assert (G_IS_TLS_CERTIFICATE (cert));
359
360   /* Unrelated cert used as certificate authority */
361   cacert = g_tls_certificate_new_from_file (TEST_FILE ("server-self.pem"), &error);
362   g_assert_no_error (error);
363   g_assert (G_IS_TLS_CERTIFICATE (cacert));
364
365   /*
366    * - Use unrelated cert as CA
367    * - Use wrong identity.
368    * - Use expired certificate.
369    */
370
371   identity = g_network_address_new ("other.example.com", 80);
372
373   errors = g_tls_certificate_verify (cert, identity, cacert);
374   g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA |
375                     G_TLS_CERTIFICATE_BAD_IDENTITY | G_TLS_CERTIFICATE_EXPIRED);
376
377   g_object_unref (cert);
378   g_object_unref (cacert);
379   g_object_unref (identity);
380 }
381
382 static void
383 test_certificate_is_same (void)
384 {
385   GTlsCertificate *one;
386   GTlsCertificate *two;
387   GTlsCertificate *three;
388   GError *error = NULL;
389
390   one = g_tls_certificate_new_from_file (TEST_FILE ("client.pem"), &error);
391   g_assert_no_error (error);
392
393   two = g_tls_certificate_new_from_file (TEST_FILE ("client-and-key.pem"), &error);
394   g_assert_no_error (error);
395
396   three = g_tls_certificate_new_from_file (TEST_FILE ("server.pem"), &error);
397   g_assert_no_error (error);
398
399   g_assert (g_tls_certificate_is_same (one, two) == TRUE);
400   g_assert (g_tls_certificate_is_same (two, one) == TRUE);
401   g_assert (g_tls_certificate_is_same (three, one) == FALSE);
402   g_assert (g_tls_certificate_is_same (one, three) == FALSE);
403   g_assert (g_tls_certificate_is_same (two, three) == FALSE);
404   g_assert (g_tls_certificate_is_same (three, two) == FALSE);
405
406   g_object_unref (one);
407   g_object_unref (two);
408   g_object_unref (three);
409 }
410
411 int
412 main (int   argc,
413       char *argv[])
414 {
415   g_type_init ();
416   g_test_init (&argc, &argv, NULL);
417
418   g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
419   g_setenv ("GIO_EXTRA_MODULES", TOP_BUILDDIR "/tls/gnutls/.libs", TRUE);
420   g_setenv ("GIO_USE_TLS", "gnutls", TRUE);
421
422   g_test_add ("/tls/certificate/create-pem", TestCertificate, NULL,
423               setup_certificate, test_create_pem, teardown_certificate);
424   g_test_add ("/tls/certificate/create-der", TestCertificate, NULL,
425               setup_certificate, test_create_der, teardown_certificate);
426   g_test_add ("/tls/certificate/create-with-key-pem", TestCertificate, NULL,
427               setup_certificate, test_create_with_key_pem, teardown_certificate);
428   g_test_add ("/tls/certificate/create-with-key-der", TestCertificate, NULL,
429               setup_certificate, test_create_with_key_der, teardown_certificate);
430   g_test_add ("/tls/certificate/create-with-issuer", TestCertificate, NULL,
431               setup_certificate, test_create_certificate_with_issuer, teardown_certificate);
432
433   g_test_add ("/tls/certificate/verify-good", TestVerify, NULL,
434               setup_verify, test_verify_certificate_good, teardown_verify);
435   g_test_add ("/tls/certificate/verify-bad-identity", TestVerify, NULL,
436               setup_verify, test_verify_certificate_bad_identity, teardown_verify);
437   g_test_add ("/tls/certificate/verify-bad-ca", TestVerify, NULL,
438               setup_verify, test_verify_certificate_bad_ca, teardown_verify);
439   g_test_add ("/tls/certificate/verify-bad-before", TestVerify, NULL,
440               setup_verify, test_verify_certificate_bad_before, teardown_verify);
441   g_test_add ("/tls/certificate/verify-bad-expired", TestVerify, NULL,
442               setup_verify, test_verify_certificate_bad_expired, teardown_verify);
443   g_test_add ("/tls/certificate/verify-bad-combo", TestVerify, NULL,
444               setup_verify, test_verify_certificate_bad_combo, teardown_verify);
445
446   g_test_add_func ("/tls/certificate/is-same", test_certificate_is_same);
447
448   return g_test_run();
449 }