1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
5 * Copyright 2011 Collabora, Ltd.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see
19 * <http://www.gnu.org/licenses/>.
21 * In addition, when the library is used with OpenSSL, a special
22 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
24 * Author: Stef Walter <stefw@collabora.co.uk>
29 #include <sys/types.h>
33 tls_test_file_path (const char *name)
35 const gchar *const_path;
38 path = g_test_build_filename (G_TEST_DIST, "files", name, NULL);
39 if (!g_path_is_absolute (path))
43 cwd = g_get_current_dir ();
44 abs = g_build_filename (cwd, path, NULL);
50 const_path = g_intern_string (path);
59 gsize cert_pem_length;
67 setup_certificate (TestCertificate *test, gconstpointer data)
73 test->backend = g_tls_backend_get_default ();
74 test->cert_gtype = g_tls_backend_get_certificate_type (test->backend);
76 g_file_get_contents (tls_test_file_path ("server.pem"), &test->cert_pem,
77 &test->cert_pem_length, &error);
78 g_assert_no_error (error);
80 g_file_get_contents (tls_test_file_path ("server.der"),
81 &contents, &length, &error);
82 g_assert_no_error (error);
84 test->cert_der = g_byte_array_new ();
85 g_byte_array_append (test->cert_der, (guint8 *)contents, length);
88 g_file_get_contents (tls_test_file_path ("server-key.pem"), &test->key_pem,
89 &test->key_pem_length, &error);
90 g_assert_no_error (error);
92 g_file_get_contents (tls_test_file_path ("server-key.der"),
93 &contents, &length, &error);
94 g_assert_no_error (error);
96 test->key_der = g_byte_array_new ();
97 g_byte_array_append (test->key_der, (guint8 *)contents, length);
102 teardown_certificate (TestCertificate *test,
105 g_free (test->cert_pem);
106 g_byte_array_free (test->cert_der, TRUE);
108 g_free (test->key_pem);
109 g_byte_array_free (test->key_der, TRUE);
113 test_create_pem (TestCertificate *test,
116 GTlsCertificate *cert;
118 GError *error = NULL;
120 cert = g_tls_certificate_new_from_pem (test->cert_pem, test->cert_pem_length, &error);
121 g_assert_no_error (error);
122 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
124 g_object_get (cert, "certificate-pem", &pem, NULL);
125 g_assert_cmpstr (pem, ==, test->cert_pem);
128 g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
129 g_object_unref (cert);
130 g_assert_null (cert);
134 test_create_with_key_pem (TestCertificate *test,
137 GTlsCertificate *cert;
138 GError *error = NULL;
140 cert = g_initable_new (test->cert_gtype, NULL, &error,
141 "certificate-pem", test->cert_pem,
142 "private-key-pem", test->key_pem,
144 g_assert_no_error (error);
145 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
147 g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
148 g_object_unref (cert);
149 g_assert_null (cert);
153 test_create_der (TestCertificate *test,
156 GTlsCertificate *cert;
157 GByteArray *der = NULL;
158 GError *error = NULL;
160 cert = g_initable_new (test->cert_gtype, NULL, &error,
161 "certificate", test->cert_der,
163 g_assert_no_error (error);
164 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
166 g_object_get (cert, "certificate", &der, NULL);
167 g_assert_nonnull (der);
168 g_assert_cmpuint (der->len, ==, test->cert_der->len);
169 g_assert_cmpint (memcmp (der->data, test->cert_der->data, der->len), ==, 0);
171 g_byte_array_unref (der);
173 g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
174 g_object_unref (cert);
175 g_assert_null (cert);
179 test_create_with_key_der (TestCertificate *test,
182 GTlsCertificate *cert;
183 GError *error = NULL;
185 cert = g_initable_new (test->cert_gtype, NULL, &error,
186 "certificate", test->cert_der,
187 "private-key", test->key_der,
189 g_assert_no_error (error);
190 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
192 g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
193 g_object_unref (cert);
194 g_assert_null (cert);
198 test_create_certificate_with_issuer (TestCertificate *test,
201 GTlsCertificate *cert, *issuer, *check;
202 GError *error = NULL;
204 issuer = g_tls_certificate_new_from_file (tls_test_file_path ("ca.pem"), &error);
205 g_assert_no_error (error);
206 g_assert_true (G_IS_TLS_CERTIFICATE (issuer));
208 cert = g_initable_new (test->cert_gtype, NULL, &error,
209 "certificate-pem", test->cert_pem,
212 g_assert_no_error (error);
213 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
215 g_object_add_weak_pointer (G_OBJECT (issuer), (gpointer *)&issuer);
216 g_object_unref (issuer);
217 g_assert_nonnull (issuer);
219 check = g_tls_certificate_get_issuer (cert);
220 g_assert_true (check == issuer);
222 g_object_add_weak_pointer (G_OBJECT (cert), (gpointer *)&cert);
223 g_object_unref (cert);
224 g_assert_null (cert);
225 g_assert_null (issuer);
229 test_create_certificate_with_garbage_input (TestCertificate *test,
232 GTlsCertificate *cert;
233 GError *error = NULL;
235 cert = g_tls_certificate_new_from_file (tls_test_file_path ("garbage.pem"), &error);
236 g_assert_null (cert);
237 g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
238 g_clear_error (&error);
240 cert = g_tls_certificate_new_from_pem ("I am not a very good certificate.", -1, &error);
241 g_assert_null (cert);
242 g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
243 g_clear_error (&error);
247 test_create_certificate_chain (void)
249 GTlsCertificate *cert, *intermediate, *root;
250 GError *error = NULL;
252 cert = g_tls_certificate_new_from_file (tls_test_file_path ("chain.pem"), &error);
253 g_assert_no_error (error);
254 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
256 intermediate = g_tls_certificate_get_issuer (cert);
257 g_assert_true (G_IS_TLS_CERTIFICATE (intermediate));
259 root = g_tls_certificate_get_issuer (intermediate);
260 g_assert_true (G_IS_TLS_CERTIFICATE (root));
262 g_assert_null (g_tls_certificate_get_issuer (root));
264 g_object_unref (cert);
268 test_create_certificate_no_chain (void)
270 GTlsCertificate *cert, *issuer;
271 GError *error = NULL;
273 gsize cert_pem_length;
275 cert = g_tls_certificate_new_from_file (tls_test_file_path ("non-ca.pem"), &error);
276 g_assert_no_error (error);
277 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
279 issuer = g_tls_certificate_get_issuer (cert);
280 g_assert_null (issuer);
281 g_object_unref (cert);
283 /* Truncate a valid chain certificate file. We should only get the
286 g_file_get_contents (tls_test_file_path ("chain.pem"), &cert_pem,
287 &cert_pem_length, &error);
288 g_assert_no_error (error);
290 cert = g_tls_certificate_new_from_pem (cert_pem, cert_pem_length - 100, &error);
292 g_assert_no_error (error);
293 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
295 issuer = g_tls_certificate_get_issuer (cert);
296 g_assert_null (issuer);
297 g_object_unref (cert);
301 test_create_list (void)
304 GError *error = NULL;
306 list = g_tls_certificate_list_new_from_file (tls_test_file_path ("ca-roots.pem"), &error);
307 g_assert_no_error (error);
308 g_assert_cmpint (g_list_length (list), ==, 8);
310 g_list_free_full (list, g_object_unref);
314 test_create_list_bad (void)
317 GError *error = NULL;
319 list = g_tls_certificate_list_new_from_file (tls_test_file_path ("ca-roots-bad.pem"), &error);
320 g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
321 g_assert_null (list);
322 g_error_free (error);
325 /* -----------------------------------------------------------------------------
330 GTlsCertificate *cert;
331 GTlsCertificate *anchor;
332 GSocketConnectable *identity;
333 GTlsDatabase *database;
337 setup_verify (TestVerify *test,
340 GError *error = NULL;
342 test->cert = g_tls_certificate_new_from_file (tls_test_file_path ("server.pem"), &error);
343 g_assert_no_error (error);
344 g_assert_true (G_IS_TLS_CERTIFICATE (test->cert));
346 test->identity = g_network_address_new ("server.example.com", 80);
348 test->anchor = g_tls_certificate_new_from_file (tls_test_file_path ("ca.pem"), &error);
349 g_assert_no_error (error);
350 g_assert_true (G_IS_TLS_CERTIFICATE (test->anchor));
351 test->database = g_tls_file_database_new (tls_test_file_path ("ca.pem"), &error);
352 g_assert_no_error (error);
353 g_assert_true (G_IS_TLS_DATABASE (test->database));
357 teardown_verify (TestVerify *test,
360 g_assert_true (G_IS_TLS_CERTIFICATE (test->cert));
361 g_object_add_weak_pointer (G_OBJECT (test->cert),
362 (gpointer *)&test->cert);
363 g_object_unref (test->cert);
364 g_assert_null (test->cert);
366 g_assert_true (G_IS_TLS_CERTIFICATE (test->anchor));
367 g_object_add_weak_pointer (G_OBJECT (test->anchor),
368 (gpointer *)&test->anchor);
369 g_object_unref (test->anchor);
370 g_assert_null (test->anchor);
372 g_assert_true (G_IS_TLS_DATABASE (test->database));
373 g_object_add_weak_pointer (G_OBJECT (test->database),
374 (gpointer *)&test->database);
375 g_object_unref (test->database);
376 g_assert_null (test->database);
378 g_object_add_weak_pointer (G_OBJECT (test->identity),
379 (gpointer *)&test->identity);
380 g_object_unref (test->identity);
381 g_assert_null (test->identity);
385 test_verify_certificate_good (TestVerify *test,
388 GSocketConnectable *identity;
389 GSocketAddress *addr;
390 GTlsCertificateFlags errors;
392 errors = g_tls_certificate_verify (test->cert, test->identity, test->anchor);
393 g_assert_cmpuint (errors, ==, 0);
395 errors = g_tls_certificate_verify (test->cert, NULL, test->anchor);
396 g_assert_cmpuint (errors, ==, 0);
398 identity = g_network_address_new ("192.168.1.10", 80);
399 errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
400 g_assert_cmpuint (errors, ==, 0);
401 g_object_unref (identity);
403 addr = g_inet_socket_address_new_from_string ("192.168.1.10", 80);
404 errors = g_tls_certificate_verify (test->cert, G_SOCKET_CONNECTABLE (addr), test->anchor);
405 g_assert_cmpuint (errors, ==, 0);
406 g_object_unref (addr);
410 test_verify_certificate_bad_identity (TestVerify *test,
413 GSocketConnectable *identity;
414 GTlsCertificateFlags errors;
415 GSocketAddress *addr;
417 identity = g_network_address_new ("other.example.com", 80);
418 errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
419 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
420 g_object_unref (identity);
422 identity = g_network_address_new ("127.0.0.1", 80);
423 errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
424 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
425 g_object_unref (identity);
427 addr = g_inet_socket_address_new_from_string ("127.0.0.1", 80);
428 errors = g_tls_certificate_verify (test->cert, G_SOCKET_CONNECTABLE (addr), test->anchor);
429 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
430 g_object_unref (addr);
434 test_verify_certificate_bad_ca (TestVerify *test,
437 GTlsCertificateFlags errors;
438 GTlsCertificate *cert;
439 GError *error = NULL;
441 /* Use a client certificate as the CA, which is wrong */
442 cert = g_tls_certificate_new_from_file (tls_test_file_path ("client.pem"), &error);
443 g_assert_no_error (error);
444 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
446 errors = g_tls_certificate_verify (test->cert, test->identity, cert);
447 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
449 g_object_unref (cert);
453 test_verify_certificate_bad_before (TestVerify *test,
456 GTlsCertificateFlags errors;
457 GTlsCertificate *cert;
458 GError *error = NULL;
460 /* This is a certificate in the future */
461 cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-future.pem"), &error);
462 g_assert_no_error (error);
463 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
465 errors = g_tls_certificate_verify (cert, NULL, test->anchor);
466 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_NOT_ACTIVATED);
468 g_object_unref (cert);
472 test_verify_certificate_bad_expired (TestVerify *test,
475 GTlsCertificateFlags errors;
476 GTlsCertificate *cert;
477 GError *error = NULL;
479 /* This is a certificate in the future */
480 cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-past.pem"), &error);
481 g_assert_no_error (error);
482 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
484 errors = g_tls_certificate_verify (cert, NULL, test->anchor);
485 g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_EXPIRED);
487 g_object_unref (cert);
491 test_verify_certificate_bad_combo (TestVerify *test,
494 GTlsCertificate *cert;
495 GTlsCertificate *cacert;
496 GSocketConnectable *identity;
497 GTlsCertificateFlags errors;
498 GError *error = NULL;
500 cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-past.pem"), &error);
501 g_assert_no_error (error);
502 g_assert_true (G_IS_TLS_CERTIFICATE (cert));
504 /* Unrelated cert used as certificate authority */
505 cacert = g_tls_certificate_new_from_file (tls_test_file_path ("server-self.pem"), &error);
506 g_assert_no_error (error);
507 g_assert_true (G_IS_TLS_CERTIFICATE (cacert));
510 * - Use unrelated cert as CA
511 * - Use wrong identity.
512 * - Use expired certificate.
514 * Once upon a time, we might have asserted to see that all of these errors
515 * are set. But this is impossible to do correctly, so nowadays we only
516 * guarantee that at least one error will be set. See glib-networking#179 and
517 * glib!2214 for rationale.
520 identity = g_network_address_new ("other.example.com", 80);
522 errors = g_tls_certificate_verify (cert, identity, cacert);
523 g_assert_cmpuint (errors, !=, 0);
525 g_object_unref (cert);
526 g_object_unref (cacert);
527 g_object_unref (identity);
531 test_certificate_is_same (void)
533 GTlsCertificate *one;
534 GTlsCertificate *two;
535 GTlsCertificate *three;
536 GError *error = NULL;
538 one = g_tls_certificate_new_from_file (tls_test_file_path ("client.pem"), &error);
539 g_assert_no_error (error);
541 two = g_tls_certificate_new_from_file (tls_test_file_path ("client-and-key.pem"), &error);
542 g_assert_no_error (error);
544 three = g_tls_certificate_new_from_file (tls_test_file_path ("server.pem"), &error);
545 g_assert_no_error (error);
547 g_assert_true (g_tls_certificate_is_same (one, two));
548 g_assert_true (g_tls_certificate_is_same (two, one));
549 g_assert_false (g_tls_certificate_is_same (three, one));
550 g_assert_false (g_tls_certificate_is_same (one, three));
551 g_assert_false (g_tls_certificate_is_same (two, three));
552 g_assert_false (g_tls_certificate_is_same (three, two));
554 g_object_unref (one);
555 g_object_unref (two);
556 g_object_unref (three);
563 g_test_init (&argc, &argv, NULL);
565 g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
566 g_setenv ("GIO_USE_TLS", BACKEND, TRUE);
567 g_assert (g_ascii_strcasecmp (G_OBJECT_TYPE_NAME (g_tls_backend_get_default ()), "GTlsBackend" BACKEND) == 0);
569 g_test_add ("/tls/certificate/create-pem", TestCertificate, NULL,
570 setup_certificate, test_create_pem, teardown_certificate);
571 g_test_add ("/tls/certificate/create-der", TestCertificate, NULL,
572 setup_certificate, test_create_der, teardown_certificate);
573 g_test_add ("/tls/certificate/create-with-key-pem", TestCertificate, NULL,
574 setup_certificate, test_create_with_key_pem, teardown_certificate);
575 g_test_add ("/tls/certificate/create-with-key-der", TestCertificate, NULL,
576 setup_certificate, test_create_with_key_der, teardown_certificate);
577 g_test_add ("/tls/certificate/create-with-issuer", TestCertificate, NULL,
578 setup_certificate, test_create_certificate_with_issuer, teardown_certificate);
579 g_test_add ("/tls/certificate/create-with-garbage-input", TestCertificate, NULL,
580 setup_certificate, test_create_certificate_with_garbage_input, teardown_certificate);
582 g_test_add_func ("/tls/certificate/create-chain", test_create_certificate_chain);
583 g_test_add_func ("/tls/certificate/create-no-chain", test_create_certificate_no_chain);
584 g_test_add_func ("/tls/certificate/create-list", test_create_list);
585 g_test_add_func ("/tls/certificate/create-list-bad", test_create_list_bad);
587 g_test_add ("/tls/certificate/verify-good", TestVerify, NULL,
588 setup_verify, test_verify_certificate_good, teardown_verify);
589 g_test_add ("/tls/certificate/verify-bad-identity", TestVerify, NULL,
590 setup_verify, test_verify_certificate_bad_identity, teardown_verify);
591 g_test_add ("/tls/certificate/verify-bad-ca", TestVerify, NULL,
592 setup_verify, test_verify_certificate_bad_ca, teardown_verify);
593 g_test_add ("/tls/certificate/verify-bad-before", TestVerify, NULL,
594 setup_verify, test_verify_certificate_bad_before, teardown_verify);
595 g_test_add ("/tls/certificate/verify-bad-expired", TestVerify, NULL,
596 setup_verify, test_verify_certificate_bad_expired, teardown_verify);
597 g_test_add ("/tls/certificate/verify-bad-combo", TestVerify, NULL,
598 setup_verify, test_verify_certificate_bad_combo, teardown_verify);
600 g_test_add_func ("/tls/certificate/is-same", test_certificate_is_same);