69fb286a8f4b469b29d42bb6ace640335fb7a2b7
[platform/upstream/glib-networking.git] / tls / tests / connection.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * GIO TLS tests
4  *
5  * Copyright 2011 Collabora, Ltd.
6  *
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.
11  *
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.
16  *
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/>.
20  *
21  * In addition, when the library is used with OpenSSL, a special
22  * exception applies. Refer to the LICENSE_EXCEPTION file for details.
23  *
24  * Author: Stef Walter <stefw@collabora.co.uk>
25  */
26
27 #include "config.h"
28
29 #include "mock-interaction.h"
30
31 #include <gio/gio.h>
32
33 #include <sys/types.h>
34 #include <string.h>
35
36 #ifdef BACKEND_IS_GNUTLS
37 #include <gnutls/gnutls.h>
38 #endif
39
40 static const gchar *
41 tls_test_file_path (const char *name)
42 {
43   const gchar *const_path;
44   gchar *path;
45
46   path = g_test_build_filename (G_TEST_DIST, "files", name, NULL);
47   if (!g_path_is_absolute (path))
48     {
49       gchar *cwd, *abs;
50
51       cwd = g_get_current_dir ();
52       abs = g_build_filename (cwd, path, NULL);
53       g_free (cwd);
54       g_free (path);
55       path = abs;
56     }
57
58   const_path = g_intern_string (path);
59   g_free (path);
60   return const_path;
61 }
62
63 #define TEST_DATA "You win again, gravity!\n"
64 #define TEST_DATA_LENGTH 24
65
66 typedef struct {
67   GMainContext *context;
68   GMainLoop *loop;
69   GSocketService *service;
70   GTlsDatabase *database;
71   GIOStream *server_connection;
72   GIOStream *client_connection;
73   GSocketConnectable *identity;
74   GSocketAddress *address;
75   GTlsAuthenticationMode auth_mode;
76   gboolean rehandshake;
77   GTlsCertificateFlags accept_flags;
78   GError *expected_client_close_error;
79   GError *read_error;
80   GError *expected_server_error;
81   GError *server_error;
82   gboolean server_should_close;
83   gboolean server_running;
84   GTlsCertificate *server_certificate;
85 #if GLIB_CHECK_VERSION(2, 60, 0)
86   const gchar * const *server_protocols;
87 #endif
88
89   char buf[128];
90   gssize nread, nwrote;
91 } TestConnection;
92
93 static void
94 setup_connection (TestConnection *test, gconstpointer data)
95 {
96   test->context = g_main_context_default ();
97   test->loop = g_main_loop_new (test->context, FALSE);
98   test->auth_mode = G_TLS_AUTHENTICATION_NONE;
99 }
100
101 /* Waits about 10 seconds for @var to be NULL/FALSE */
102 #define WAIT_UNTIL_UNSET(var)                                \
103   if (var)                                                   \
104     {                                                        \
105       int i;                                                 \
106                                                              \
107       for (i = 0; i < 13 && (var); i++)                      \
108         {                                                    \
109           g_usleep (1000 * (1 << i));                        \
110           g_main_context_iteration (NULL, FALSE);            \
111         }                                                    \
112                                                              \
113       g_assert (!(var));                                     \
114     }
115
116 static void
117 teardown_connection (TestConnection *test, gconstpointer data)
118 {
119   if (test->service)
120     {
121       g_socket_service_stop (test->service);
122       /* The outstanding accept_async will hold a ref on test->service,
123        * which we want to wait for it to release if we're valgrinding.
124        */
125       g_object_add_weak_pointer (G_OBJECT (test->service), (gpointer *)&test->service);
126       g_object_unref (test->service);
127       WAIT_UNTIL_UNSET (test->service);
128     }
129
130   if (test->server_connection)
131     {
132       WAIT_UNTIL_UNSET (test->server_running);
133
134       g_object_add_weak_pointer (G_OBJECT (test->server_connection),
135                                  (gpointer *)&test->server_connection);
136       g_object_unref (test->server_connection);
137       WAIT_UNTIL_UNSET (test->server_connection);
138     }
139
140   if (test->client_connection)
141     {
142       g_object_add_weak_pointer (G_OBJECT (test->client_connection),
143                                  (gpointer *)&test->client_connection);
144       g_object_unref (test->client_connection);
145       WAIT_UNTIL_UNSET (test->client_connection);
146     }
147
148   if (test->database)
149     {
150       g_object_add_weak_pointer (G_OBJECT (test->database),
151                                  (gpointer *)&test->database);
152       g_object_unref (test->database);
153       WAIT_UNTIL_UNSET (test->database);
154     }
155
156   g_clear_object (&test->address);
157   g_clear_object (&test->identity);
158   g_clear_object (&test->server_certificate);
159
160   g_main_loop_unref (test->loop);
161
162   g_clear_error (&test->expected_client_close_error);
163   g_clear_error (&test->read_error);
164   g_clear_error (&test->server_error);
165   g_clear_error (&test->expected_server_error);
166 }
167
168 static void
169 start_server (TestConnection *test)
170 {
171   GInetAddress *inet;
172   GSocketAddress *addr;
173   GInetSocketAddress *iaddr;
174   GError *error = NULL;
175
176   inet = g_inet_address_new_from_string ("127.0.0.1");
177   addr = g_inet_socket_address_new (inet, 0);
178   g_object_unref (inet);
179
180   g_socket_listener_add_address (G_SOCKET_LISTENER (test->service), addr,
181                                  G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP,
182                                  NULL, &test->address, &error);
183   g_assert_no_error (error);
184
185   g_object_unref (addr);
186
187   /* The hostname in test->identity matches the server certificate. */
188   iaddr = G_INET_SOCKET_ADDRESS (test->address);
189   test->identity = g_network_address_new ("server.example.com",
190                                           g_inet_socket_address_get_port (iaddr));
191
192   test->server_running = TRUE;
193 }
194
195 static gboolean
196 on_accept_certificate (GTlsConnection       *conn,
197                        GTlsCertificate      *cert,
198                        GTlsCertificateFlags  errors,
199                        gpointer              user_data)
200 {
201   TestConnection *test = user_data;
202   return errors == test->accept_flags;
203 }
204
205 static void on_output_write_finish (GObject        *object,
206                                     GAsyncResult   *res,
207                                     gpointer        user_data);
208
209 static void
210 on_rehandshake_finish (GObject        *object,
211                        GAsyncResult   *res,
212                        gpointer        user_data)
213 {
214   TestConnection *test = user_data;
215   GError *error = NULL;
216   GOutputStream *stream;
217
218   g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), res, &error);
219   g_assert_no_error (error);
220
221   stream = g_io_stream_get_output_stream (test->server_connection);
222   g_output_stream_write_async (stream, TEST_DATA + TEST_DATA_LENGTH / 2,
223                                TEST_DATA_LENGTH / 2,
224                                G_PRIORITY_DEFAULT, NULL,
225                                on_output_write_finish, test);
226 }
227
228 static void
229 on_server_close_finish (GObject        *object,
230                         GAsyncResult   *res,
231                         gpointer        user_data)
232 {
233   TestConnection *test = user_data;
234   GError *expected_error = test->expected_server_error;
235   GError *error = NULL;
236
237   g_io_stream_close_finish (G_IO_STREAM (object), res, &error);
238   g_assert_no_error (error);
239
240   if (expected_error)
241     g_assert_error (test->server_error, expected_error->domain, expected_error->code);
242   else
243     g_assert_no_error (test->server_error);
244
245   test->server_running = FALSE;
246 }
247
248 static void
249 close_server_connection (TestConnection *test)
250 {
251   g_io_stream_close_async (test->server_connection, G_PRIORITY_DEFAULT, NULL,
252                            on_server_close_finish, test);
253 }
254
255 static void
256 on_output_write_finish (GObject        *object,
257                         GAsyncResult   *res,
258                         gpointer        user_data)
259 {
260   TestConnection *test = user_data;
261
262   g_assert_no_error (test->server_error);
263   g_output_stream_write_finish (G_OUTPUT_STREAM (object), res, &test->server_error);
264
265   if (!test->server_error && test->rehandshake)
266     {
267       test->rehandshake = FALSE;
268       g_tls_connection_handshake_async (G_TLS_CONNECTION (test->server_connection),
269                                         G_PRIORITY_DEFAULT, NULL,
270                                         on_rehandshake_finish, test);
271       return;
272     }
273
274   if (test->server_should_close)
275     close_server_connection (test);
276 }
277
278 static gboolean
279 on_incoming_connection (GSocketService     *service,
280                         GSocketConnection  *connection,
281                         GObject            *source_object,
282                         gpointer            user_data)
283 {
284   TestConnection *test = user_data;
285   GOutputStream *stream;
286   GTlsCertificate *cert;
287   GError *error = NULL;
288
289   g_assert_null (test->server_connection);
290   test->server_connection = g_tls_server_connection_new (G_IO_STREAM (connection),
291                                                          test->server_certificate, &error);
292   g_assert_no_error (error);
293
294   if (!test->server_certificate)
295     {
296       cert = g_tls_certificate_new_from_file (tls_test_file_path ("server-and-key.pem"), &error);
297       g_assert_no_error (error);
298       g_tls_connection_set_certificate ((GTlsConnection *)test->server_connection, cert);
299       g_object_unref (cert);
300     }
301
302   g_object_set (test->server_connection, "authentication-mode", test->auth_mode, NULL);
303   g_signal_connect (test->server_connection, "accept-certificate",
304                     G_CALLBACK (on_accept_certificate), test);
305
306   if (test->database)
307     g_tls_connection_set_database (G_TLS_CONNECTION (test->server_connection), test->database);
308
309 #if GLIB_CHECK_VERSION(2, 60, 0)
310   if (test->server_protocols)
311     {
312       g_tls_connection_set_advertised_protocols (G_TLS_CONNECTION (test->server_connection),
313                                                  test->server_protocols);
314     }
315 #endif
316
317   stream = g_io_stream_get_output_stream (test->server_connection);
318
319   g_output_stream_write_async (stream, TEST_DATA,
320                                test->rehandshake ? TEST_DATA_LENGTH / 2 : TEST_DATA_LENGTH,
321                                G_PRIORITY_DEFAULT, NULL,
322                                on_output_write_finish, test);
323   return FALSE;
324 }
325
326 static void
327 start_async_server_service (TestConnection         *test,
328                             GTlsAuthenticationMode  auth_mode,
329                             gboolean                should_close)
330 {
331   test->service = g_socket_service_new ();
332   start_server (test);
333
334   test->auth_mode = auth_mode;
335   g_signal_connect (test->service, "incoming", G_CALLBACK (on_incoming_connection), test);
336
337   test->server_should_close = should_close;
338 }
339
340 static GIOStream *
341 start_async_server_and_connect_to_it (TestConnection         *test,
342                                       GTlsAuthenticationMode  auth_mode)
343 {
344   GSocketClient *client;
345   GError *error = NULL;
346   GSocketConnection *connection;
347
348   start_async_server_service (test, auth_mode, TRUE);
349
350   client = g_socket_client_new ();
351   connection = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (test->address),
352                                         NULL, &error);
353   g_assert_no_error (error);
354   g_object_unref (client);
355
356   return G_IO_STREAM (connection);
357 }
358
359 static void
360 run_echo_server (GThreadedSocketService *service,
361                  GSocketConnection      *connection,
362                  GObject                *source_object,
363                  gpointer                user_data)
364 {
365   TestConnection *test = user_data;
366   GTlsConnection *tlsconn;
367   GTlsCertificate *cert;
368   GError *error = NULL;
369   GInputStream *istream;
370   GOutputStream *ostream;
371   gssize nread, nwrote, total;
372   gchar buf[128];
373
374   if (test->server_certificate)
375     {
376       cert = g_object_ref (test->server_certificate);
377     }
378   else
379     {
380       cert = g_tls_certificate_new_from_file (tls_test_file_path ("server-and-key.pem"), &error);
381       g_assert_no_error (error);
382     }
383
384   test->server_connection = g_tls_server_connection_new (G_IO_STREAM (connection),
385                                                          cert, &error);
386   g_assert_no_error (error);
387   g_object_unref (cert);
388
389   tlsconn = G_TLS_CONNECTION (test->server_connection);
390   g_tls_connection_handshake (tlsconn, NULL, &error);
391   g_assert_no_error (error);
392
393   istream = g_io_stream_get_input_stream (test->server_connection);
394   ostream = g_io_stream_get_output_stream (test->server_connection);
395
396   while (TRUE)
397     {
398       nread = g_input_stream_read (istream, buf, sizeof (buf), NULL, &error);
399       g_assert_no_error (error);
400       g_assert_cmpint (nread, >=, 0);
401
402       if (nread == 0)
403         break;
404
405       for (total = 0; total < nread; total += nwrote)
406         {
407           nwrote = g_output_stream_write (ostream, buf + total, nread - total, NULL, &error);
408           g_assert_no_error (error);
409         }
410
411       if (test->rehandshake)
412         {
413           test->rehandshake = FALSE;
414           g_tls_connection_handshake (tlsconn, NULL, &error);
415           g_assert_no_error (error);
416         }
417     }
418
419   g_io_stream_close (test->server_connection, NULL, &error);
420   g_assert_no_error (error);
421   test->server_running = FALSE;
422 }
423
424 static void
425 start_echo_server_service (TestConnection *test)
426 {
427   test->service = g_threaded_socket_service_new (5);
428   start_server (test);
429
430   g_signal_connect (test->service, "run", G_CALLBACK (run_echo_server), test);
431 }
432
433 static GIOStream *
434 start_echo_server_and_connect_to_it (TestConnection *test)
435 {
436   GSocketClient *client;
437   GError *error = NULL;
438   GSocketConnection *connection;
439
440   start_echo_server_service (test);
441
442   client = g_socket_client_new ();
443   connection = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (test->address),
444                                         NULL, &error);
445   g_assert_no_error (error);
446   g_object_unref (client);
447
448   return G_IO_STREAM (connection);
449 }
450
451 static void
452 on_client_connection_close_finish (GObject        *object,
453                                    GAsyncResult   *res,
454                                    gpointer        user_data)
455 {
456   TestConnection *test = user_data;
457   GError *error = NULL;
458
459   g_io_stream_close_finish (G_IO_STREAM (object), res, &error);
460
461   if (test->expected_client_close_error)
462     {
463       /* Although very rare, it's OK for broken pipe errors to not occur here if
464        * they have already occured earlier during a read. If so, there should be
465        * no error here at all.
466        */
467       if (error || !g_error_matches (test->expected_client_close_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE))
468         g_assert_error (error, test->expected_client_close_error->domain, test->expected_client_close_error->code);
469     }
470   else
471     {
472       g_assert_no_error (error);
473     }
474
475   g_main_loop_quit (test->loop);
476 }
477
478 static void
479 on_input_read_finish (GObject        *object,
480                       GAsyncResult   *res,
481                       gpointer        user_data)
482 {
483   TestConnection *test = user_data;
484   gchar *line, *check;
485
486   line = g_data_input_stream_read_line_finish (G_DATA_INPUT_STREAM (object), res,
487                                                NULL, &test->read_error);
488   if (!test->read_error)
489     {
490       g_assert_nonnull (line);
491
492       check = g_strdup (TEST_DATA);
493       g_strstrip (check);
494       g_assert_cmpstr (line, ==, check);
495       g_free (check);
496       g_free (line);
497     }
498
499   g_io_stream_close_async (test->client_connection, G_PRIORITY_DEFAULT,
500                            NULL, on_client_connection_close_finish, test);
501 }
502
503 static void
504 read_test_data_async (TestConnection *test)
505 {
506   GDataInputStream *stream;
507
508   stream = g_data_input_stream_new (g_io_stream_get_input_stream (test->client_connection));
509   g_assert_nonnull (stream);
510
511   g_data_input_stream_read_line_async (stream, G_PRIORITY_DEFAULT, NULL,
512                                        on_input_read_finish, test);
513   g_object_unref (stream);
514 }
515
516 static void
517 test_basic_connection (TestConnection *test,
518                        gconstpointer   data)
519 {
520   GIOStream *connection;
521   GError *error = NULL;
522
523   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
524   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
525   g_assert_no_error (error);
526   g_object_unref (connection);
527
528   /* No validation at all in this test */
529   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
530                                                 0);
531
532   read_test_data_async (test);
533   g_main_loop_run (test->loop);
534
535   g_assert_no_error (test->read_error);
536   g_assert_no_error (test->server_error);
537 }
538
539 static void
540 test_verified_connection (TestConnection *test,
541                           gconstpointer   data)
542 {
543   GIOStream *connection;
544   GError *error = NULL;
545
546   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
547   g_assert_no_error (error);
548   g_assert_nonnull (test->database);
549
550   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
551   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
552   g_assert_no_error (error);
553   g_assert_nonnull (test->client_connection);
554   g_object_unref (connection);
555
556   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
557
558   /* All validation in this test */
559   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
560                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
561
562   read_test_data_async (test);
563   g_main_loop_run (test->loop);
564
565   g_assert_no_error (test->read_error);
566   g_assert_no_error (test->server_error);
567 }
568
569 static void
570 test_verified_chain (TestConnection *test,
571                      gconstpointer   data)
572 {
573   GTlsBackend *backend;
574   GTlsCertificate *server_cert;
575   GTlsCertificate *intermediate_cert;
576   char *cert_data = NULL;
577   char *key_data = NULL;
578   GError *error = NULL;
579
580   backend = g_tls_backend_get_default ();
581
582   /* Prepare the intermediate cert. */
583   intermediate_cert = g_tls_certificate_new_from_file (tls_test_file_path ("intermediate-ca.pem"), &error);
584   g_assert_no_error (error);
585   g_assert_nonnull (intermediate_cert);
586
587   /* Prepare the server cert. */
588   g_clear_pointer (&cert_data, g_free);
589   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
590                        &cert_data, NULL, &error);
591   g_assert_no_error (error);
592   g_assert_nonnull (cert_data);
593
594   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
595                        &key_data, NULL, &error);
596   g_assert_no_error (error);
597   g_assert_nonnull (key_data);
598
599   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
600                                 NULL, &error,
601                                 "issuer", intermediate_cert,
602                                 "certificate-pem", cert_data,
603                                 "private-key-pem", key_data,
604                                 NULL);
605   g_assert_no_error (error);
606   g_assert_nonnull (server_cert);
607
608   g_object_unref (intermediate_cert);
609   g_free (cert_data);
610   g_free (key_data);
611
612   test->server_certificate = server_cert;
613   test_verified_connection (test, data);
614 }
615
616 static void
617 test_verified_chain_with_redundant_root_cert (TestConnection *test,
618                                               gconstpointer   data)
619 {
620   GTlsBackend *backend;
621   GTlsCertificate *server_cert;
622   GTlsCertificate *intermediate_cert;
623   GTlsCertificate *root_cert;
624   char *cert_data = NULL;
625   char *key_data = NULL;
626   GError *error = NULL;
627
628   backend = g_tls_backend_get_default ();
629
630   /* The root is redundant. It should not hurt anything. */
631   root_cert = g_tls_certificate_new_from_file (tls_test_file_path ("ca.pem"), &error);
632   g_assert_no_error (error);
633   g_assert_nonnull (root_cert);
634
635   /* Prepare the intermediate cert. */
636   g_file_get_contents (tls_test_file_path ("intermediate-ca.pem"),
637                        &cert_data, NULL, &error);
638   g_assert_no_error (error);
639   g_assert_nonnull (cert_data);
640
641   intermediate_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
642                                       NULL, &error,
643                                       "issuer", root_cert,
644                                       "certificate-pem", cert_data,
645                                       NULL);
646   g_assert_no_error (error);
647   g_assert_nonnull (intermediate_cert);
648
649   /* Prepare the server cert. */
650   g_clear_pointer (&cert_data, g_free);
651   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
652                        &cert_data, NULL, &error);
653   g_assert_no_error (error);
654   g_assert_nonnull (cert_data);
655
656   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
657                        &key_data, NULL, &error);
658   g_assert_no_error (error);
659   g_assert_nonnull (key_data);
660
661   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
662                                 NULL, &error,
663                                 "issuer", intermediate_cert,
664                                 "certificate-pem", cert_data,
665                                 "private-key-pem", key_data,
666                                 NULL);
667   g_assert_no_error (error);
668   g_assert_nonnull (server_cert);
669
670   g_object_unref (intermediate_cert);
671   g_object_unref (root_cert);
672   g_free (cert_data);
673   g_free (key_data);
674
675   test->server_certificate = server_cert;
676   test_verified_connection (test, data);
677 }
678
679 static void
680 test_verified_chain_with_duplicate_server_cert (TestConnection *test,
681                                                 gconstpointer   data)
682 {
683   /* This is another common server misconfiguration. Apache reads certificates
684    * from two configuration files: one for the server cert, and one for the rest
685    * of the chain. If the server cert is pasted into both files, it will be sent
686    * twice. We should be tolerant of this. */
687
688   GTlsBackend *backend;
689   GTlsCertificate *server_cert;
690   GTlsCertificate *extra_server_cert;
691   GTlsCertificate *intermediate_cert;
692   char *cert_data = NULL;
693   char *key_data = NULL;
694   GError *error = NULL;
695
696   backend = g_tls_backend_get_default ();
697
698   /* Prepare the intermediate cert. */
699   intermediate_cert = g_tls_certificate_new_from_file (tls_test_file_path ("intermediate-ca.pem"), &error);
700   g_assert_no_error (error);
701   g_assert_nonnull (intermediate_cert);
702
703   /* Prepare the server cert. */
704   g_clear_pointer (&cert_data, g_free);
705   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
706                        &cert_data, NULL, &error);
707   g_assert_no_error (error);
708   g_assert_nonnull (cert_data);
709
710   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
711                        &key_data, NULL, &error);
712   g_assert_no_error (error);
713   g_assert_nonnull (key_data);
714
715   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
716                                 NULL, &error,
717                                 "issuer", intermediate_cert,
718                                 "certificate-pem", cert_data,
719                                 NULL);
720   g_assert_no_error (error);
721   g_assert_nonnull (server_cert);
722
723   /* Prepare the server cert... again. Private key must go on this one. */
724   extra_server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
725                                       NULL, &error,
726                                       "issuer", server_cert,
727                                       "certificate-pem", cert_data,
728                                       "private-key-pem", key_data,
729                                       NULL);
730   g_assert_no_error (error);
731   g_assert_nonnull (extra_server_cert);
732
733   g_object_unref (intermediate_cert);
734   g_object_unref (server_cert);
735   g_free (cert_data);
736   g_free (key_data);
737
738   test->server_certificate = extra_server_cert;
739   test_verified_connection (test, data);
740 }
741
742 static void
743 test_verified_unordered_chain (TestConnection *test,
744                                gconstpointer   data)
745 {
746   GTlsBackend *backend;
747   GTlsCertificate *server_cert;
748   GTlsCertificate *intermediate_cert;
749   GTlsCertificate *root_cert;
750   char *cert_data = NULL;
751   char *key_data = NULL;
752   GError *error = NULL;
753
754   backend = g_tls_backend_get_default ();
755
756   /* Prepare the intermediate cert (to be sent last, out of order)! */
757   intermediate_cert = g_tls_certificate_new_from_file (tls_test_file_path ("intermediate-ca.pem"),
758                                                        &error);
759   g_assert_no_error (error);
760   g_assert_nonnull (intermediate_cert);
761
762   g_file_get_contents (tls_test_file_path ("ca.pem"), &cert_data, NULL, &error);
763   g_assert_no_error (error);
764   g_assert_nonnull (cert_data);
765
766   /* Prepare the root cert (to be sent in the middle of the chain). */
767   root_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
768                               NULL, &error,
769                               "issuer", intermediate_cert,
770                               "certificate-pem", cert_data,
771                               NULL);
772   g_assert_no_error (error);
773   g_assert_nonnull (root_cert);
774
775   g_clear_pointer (&cert_data, g_free);
776   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
777                        &cert_data, NULL, &error);
778   g_assert_no_error (error);
779   g_assert_nonnull (cert_data);
780
781   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
782                        &key_data, NULL, &error);
783   g_assert_no_error (error);
784   g_assert_nonnull (key_data);
785
786   /* Prepare the server cert. */
787   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
788                                 NULL, &error,
789                                 "issuer", root_cert,
790                                 "certificate-pem", cert_data,
791                                 "private-key-pem", key_data,
792                                 NULL);
793   g_assert_no_error (error);
794   g_assert_nonnull (server_cert);
795
796   g_object_unref (intermediate_cert);
797   g_object_unref (root_cert);
798   g_free (cert_data);
799   g_free (key_data);
800
801   test->server_certificate = server_cert;
802   test_verified_connection (test, data);
803 }
804
805 static void
806 test_verified_chain_with_alternative_ca_cert (TestConnection *test,
807                                               gconstpointer   data)
808 {
809   GTlsBackend *backend;
810   GTlsCertificate *server_cert;
811   GTlsCertificate *intermediate_cert;
812   GTlsCertificate *root_cert;
813   char *cert_data = NULL;
814   char *key_data = NULL;
815   GError *error = NULL;
816
817   backend = g_tls_backend_get_default ();
818
819   /* This "root" cert is issued by a CA that is not in the trust store. So it's
820    * not really a root, but it has the same public key as a cert in the trust
821    * store. If the client insists on a traditional chain of trust, this will
822    * fail, since the issuer is untrusted. */
823   root_cert = g_tls_certificate_new_from_file (tls_test_file_path ("ca-alternative.pem"), &error);
824   g_assert_no_error (error);
825   g_assert_nonnull (root_cert);
826
827   /* Prepare the intermediate cert. Modern TLS libraries are expected to notice
828    * that it is signed by the same public key as a certificate in the root
829    * store, and accept the certificate, ignoring the untrusted "root" sent next
830    * in the chain, which servers send for compatibility with clients that don't
831    * have the new CA cert in the trust store yet. (In this scenario, the old
832    * client still trusts the old CA cert.) */
833   g_file_get_contents (tls_test_file_path ("intermediate-ca.pem"),
834                        &cert_data, NULL, &error);
835   g_assert_no_error (error);
836   g_assert_nonnull (cert_data);
837
838   intermediate_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
839                                       NULL, &error,
840                                       "issuer", root_cert,
841                                       "certificate-pem", cert_data,
842                                       NULL);
843   g_assert_no_error (error);
844   g_assert_nonnull (intermediate_cert);
845
846   /* Prepare the server cert. */
847   g_clear_pointer (&cert_data, g_free);
848   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
849                        &cert_data, NULL, &error);
850   g_assert_no_error (error);
851   g_assert_nonnull (cert_data);
852
853   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
854                        &key_data, NULL, &error);
855   g_assert_no_error (error);
856   g_assert_nonnull (key_data);
857
858   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
859                                 NULL, &error,
860                                 "issuer", intermediate_cert,
861                                 "certificate-pem", cert_data,
862                                 "private-key-pem", key_data,
863                                 NULL);
864   g_assert_no_error (error);
865   g_assert_nonnull (server_cert);
866
867   g_object_unref (intermediate_cert);
868   g_object_unref (root_cert);
869   g_free (cert_data);
870   g_free (key_data);
871
872   test->server_certificate = server_cert;
873   test_verified_connection (test, data);
874 }
875
876 static void
877 test_invalid_chain_with_alternative_ca_cert (TestConnection *test,
878                                              gconstpointer   data)
879 {
880   GTlsBackend *backend;
881   GTlsCertificate *server_cert;
882   GTlsCertificate *root_cert;
883   GIOStream *connection;
884   char *cert_data = NULL;
885   char *key_data = NULL;
886   GError *error = NULL;
887
888   backend = g_tls_backend_get_default ();
889
890   /* This certificate has the same public key as a certificate in the root store. */
891   root_cert = g_tls_certificate_new_from_file (tls_test_file_path ("ca-alternative.pem"), &error);
892   g_assert_no_error (error);
893   g_assert_nonnull (root_cert);
894
895   /* The intermediate cert is not sent. The chain should be rejected, since without intermediate.pem
896    * there is no proof that ca-alternative.pem signed server-intermediate.pem. */
897   g_file_get_contents (tls_test_file_path ("server-intermediate.pem"),
898                        &cert_data, NULL, &error);
899   g_assert_no_error (error);
900   g_assert_nonnull (cert_data);
901
902   g_file_get_contents (tls_test_file_path ("server-intermediate-key.pem"),
903                        &key_data, NULL, &error);
904   g_assert_no_error (error);
905   g_assert_nonnull (key_data);
906
907   server_cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
908                                 NULL, &error,
909                                 "issuer", root_cert,
910                                 "certificate-pem", cert_data,
911                                 "private-key-pem", key_data,
912                                 NULL);
913   g_assert_no_error (error);
914   g_assert_nonnull (server_cert);
915
916   g_object_unref (root_cert);
917   g_free (cert_data);
918   g_free (key_data);
919
920   test->server_certificate = server_cert;
921   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
922   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
923   g_assert_no_error (error);
924   g_assert_nonnull (test->client_connection);
925   g_object_unref (connection);
926
927   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
928
929   /* Make sure this test doesn't expire. */
930   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
931                                                 G_TLS_CERTIFICATE_VALIDATE_ALL & ~G_TLS_CERTIFICATE_EXPIRED);
932
933   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS, "");
934
935   read_test_data_async (test);
936   g_main_loop_run (test->loop);
937
938   g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
939 }
940
941 static void
942 on_notify_accepted_cas (GObject *obj,
943                         GParamSpec *spec,
944                         gpointer user_data)
945 {
946   gboolean *changed = user_data;
947   g_assert_false (*changed);
948   *changed = TRUE;
949 }
950
951 static void
952 test_client_auth_connection (TestConnection *test,
953                              gconstpointer   data)
954 {
955   GIOStream *connection;
956   GError *error = NULL;
957   GTlsCertificate *cert;
958   GTlsCertificate *peer;
959   gboolean cas_changed;
960   GSocketClient *client;
961
962   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
963   g_assert_no_error (error);
964   g_assert_nonnull (test->database);
965
966   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUIRED);
967   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
968   g_assert_no_error (error);
969   g_assert_nonnull (test->client_connection);
970   g_object_unref (connection);
971
972   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
973
974   cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-and-key.pem"), &error);
975   g_assert_no_error (error);
976
977   g_tls_connection_set_certificate (G_TLS_CONNECTION (test->client_connection), cert);
978
979   /* All validation in this test */
980   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
981                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
982
983   cas_changed = FALSE;
984   g_signal_connect (test->client_connection, "notify::accepted-cas",
985                     G_CALLBACK (on_notify_accepted_cas), &cas_changed);
986
987   read_test_data_async (test);
988   g_main_loop_run (test->loop);
989
990   g_assert_no_error (test->read_error);
991   g_assert_no_error (test->server_error);
992
993   peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (test->server_connection));
994   g_assert_nonnull (peer);
995   g_assert_true (g_tls_certificate_is_same (peer, cert));
996   g_assert_true (cas_changed);
997
998   g_object_unref (cert);
999   g_object_unref (test->client_connection);
1000   g_clear_object (&test->server_connection);
1001
1002   /* Now start a new connection to the same server with a different client cert */
1003   client = g_socket_client_new ();
1004   connection = G_IO_STREAM (g_socket_client_connect (client, G_SOCKET_CONNECTABLE (test->address),
1005                                                      NULL, &error));
1006   g_assert_no_error (error);
1007   g_object_unref (client);
1008   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1009   g_assert_no_error (error);
1010   g_assert_nonnull (test->client_connection);
1011   g_object_unref (connection);
1012
1013   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1014                                                 0);
1015   cert = g_tls_certificate_new_from_file (tls_test_file_path ("client2-and-key.pem"), &error);
1016   g_assert_no_error (error);
1017   g_tls_connection_set_certificate (G_TLS_CONNECTION (test->client_connection), cert);
1018   g_object_unref (cert);
1019   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1020
1021   read_test_data_async (test);
1022   g_main_loop_run (test->loop);
1023
1024   g_assert_no_error (test->read_error);
1025   g_assert_no_error (test->server_error);
1026
1027   /* peer should see the second client cert */
1028   peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (test->server_connection));
1029   g_assert_nonnull (peer);
1030   g_assert_true (g_tls_certificate_is_same (peer, cert));
1031 }
1032
1033 static void
1034 test_client_auth_rehandshake (TestConnection *test,
1035                               gconstpointer   data)
1036 {
1037 #ifdef BACKEND_IS_OPENSSL
1038   g_test_skip ("the server avoids rehandshake to avoid the security problem CVE-2009-3555");
1039   return;
1040 #endif
1041
1042   test->rehandshake = TRUE;
1043   test_client_auth_connection (test, data);
1044 }
1045
1046 /* In TLS 1.3 the client handshake succeeds before the client has sent
1047  * its certificate to the server, so the client doesn't realize the
1048  * server has rejected its certificate until it tries performing I/O.
1049  * This results in different errors bubbling up to the API level. The
1050  * differences are unfortunate but difficult to avoid.
1051  *
1052  * FIXME: This isn't good to have different API behavior depending on
1053  * the version of GnuTLS in use. And how is OpenSSL supposed to deal
1054  * with this?
1055  */
1056 static gboolean
1057 client_can_receive_certificate_required_errors (TestConnection *test)
1058 {
1059 #ifdef BACKEND_IS_GNUTLS
1060   gnutls_priority_t priority_cache;
1061   int ret;
1062   int i;
1063   int nprotos;
1064   static int max_proto = 0;
1065   const guint *protos;
1066
1067   /* Determine whether GNUTLS_TLS1_3 is available at *runtime* (using
1068    * the default priority) so that these tests work in Fedora 28, which
1069    * has GnuTLS 3.6 (and therefore GNUTLS_TLS1_3) but with TLS 1.3
1070    * disabled.
1071    */
1072   if (max_proto == 0)
1073     {
1074       ret = gnutls_priority_init (&priority_cache, "NORMAL", NULL);
1075       g_assert_cmpint (ret, ==, GNUTLS_E_SUCCESS);
1076
1077       nprotos = gnutls_priority_protocol_list (priority_cache, &protos);
1078
1079       for (i = 0; i < nprotos && protos[i] <= GNUTLS_TLS_VERSION_MAX; i++)
1080         {
1081           if (protos[i] > max_proto)
1082             max_proto = protos[i];
1083         }
1084
1085       gnutls_priority_deinit (priority_cache);
1086     }
1087
1088   return max_proto <= GNUTLS_TLS1_2;
1089 #else
1090   return TRUE;
1091 #endif
1092 }
1093
1094 static void
1095 test_client_auth_failure (TestConnection *test,
1096                           gconstpointer   data)
1097 {
1098   GIOStream *connection;
1099   GError *error = NULL;
1100   gboolean accepted_changed;
1101   GSocketClient *client;
1102   GTlsCertificate *cert;
1103   GTlsCertificate *peer;
1104   GTlsInteraction *interaction;
1105
1106   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
1107   g_assert_no_error (error);
1108   g_assert_nonnull (test->database);
1109
1110   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUIRED);
1111   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1112   g_assert_no_error (error);
1113   g_assert_nonnull (test->client_connection);
1114   g_object_unref (connection);
1115
1116   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1117
1118   /* No Certificate set */
1119
1120   /* All validation in this test */
1121   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1122                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1123
1124   accepted_changed = FALSE;
1125   g_signal_connect (test->client_connection, "notify::accepted-cas",
1126                     G_CALLBACK (on_notify_accepted_cas), &accepted_changed);
1127
1128   if (!client_can_receive_certificate_required_errors (test))
1129     g_set_error_literal (&test->expected_client_close_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "");
1130   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED, "");
1131
1132   read_test_data_async (test);
1133   g_main_loop_run (test->loop);
1134
1135   /* In TLS 1.2 we'll notice that a server cert was requested. For TLS 1.3 we
1136    * just get dropped, usually G_TLS_ERROR_MISC but possibly also broken pipe.
1137    */
1138   if (client_can_receive_certificate_required_errors (test))
1139     g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
1140   else if (!g_error_matches (test->read_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE))
1141     g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_MISC);
1142   g_assert_error (test->server_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
1143
1144   g_assert_true (accepted_changed);
1145
1146   g_object_unref (test->client_connection);
1147   g_clear_object (&test->server_connection);
1148   g_clear_error (&test->expected_client_close_error);
1149   g_clear_error (&test->read_error);
1150   g_clear_error (&test->server_error);
1151   g_clear_error (&test->expected_server_error);
1152
1153   /* Now start a new connection to the same server with a valid client cert;
1154    * this should succeed, and not use the cached failed session from above */
1155   client = g_socket_client_new ();
1156   connection = G_IO_STREAM (g_socket_client_connect (client, G_SOCKET_CONNECTABLE (test->address),
1157                                                      NULL, &error));
1158   g_assert_no_error (error);
1159   g_object_unref (client);
1160   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1161   g_assert_no_error (error);
1162   g_assert_nonnull (test->client_connection);
1163   g_object_unref (connection);
1164
1165   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1166
1167   /* Have the interaction return a certificate */
1168   cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-and-key.pem"), &error);
1169   g_assert_no_error (error);
1170   interaction = mock_interaction_new_static_certificate (cert);
1171   g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
1172   g_object_unref (interaction);
1173
1174   /* All validation in this test */
1175   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1176                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1177
1178   accepted_changed = FALSE;
1179   g_signal_connect (test->client_connection, "notify::accepted-cas",
1180                     G_CALLBACK (on_notify_accepted_cas), &accepted_changed);
1181
1182   read_test_data_async (test);
1183   g_main_loop_run (test->loop);
1184
1185   g_assert_no_error (test->read_error);
1186   g_assert_no_error (test->server_error);
1187
1188   peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (test->server_connection));
1189   g_assert_nonnull (peer);
1190   g_assert_true (g_tls_certificate_is_same (peer, cert));
1191   g_assert_true (accepted_changed);
1192
1193   g_object_unref (cert);
1194 }
1195
1196 static void
1197 test_client_auth_fail_missing_client_private_key (TestConnection *test,
1198                                                   gconstpointer   data)
1199 {
1200   GTlsCertificate *cert;
1201   GIOStream *connection;
1202   GError *error = NULL;
1203
1204 #ifdef BACKEND_IS_OPENSSL
1205   g_test_skip("this new test does not work with openssl, more research needed");
1206   return;
1207 #endif
1208
1209   g_test_bug ("793712");
1210
1211   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
1212   g_assert_no_error (error);
1213   g_assert_nonnull (test->database);
1214
1215   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUIRED);
1216   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1217   g_assert_no_error (error);
1218   g_assert_nonnull (test->client_connection);
1219   g_object_unref (connection);
1220
1221   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1222
1223   /* Oops: we "accidentally" set client.pem rather than client-and-key.pem. The
1224    * connection will fail, but we should not crash.
1225    */
1226   cert = g_tls_certificate_new_from_file (tls_test_file_path ("client.pem"), &error);
1227   g_assert_no_error (error);
1228
1229   g_tls_connection_set_certificate (G_TLS_CONNECTION (test->client_connection), cert);
1230
1231   /* All validation in this test */
1232   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1233                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1234
1235   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS, "");
1236
1237   read_test_data_async (test);
1238   g_main_loop_run (test->loop);
1239
1240   g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
1241 }
1242
1243 static void
1244 test_client_auth_request_cert (TestConnection *test,
1245                                gconstpointer   data)
1246 {
1247   GIOStream *connection;
1248   GError *error = NULL;
1249   GTlsCertificate *cert;
1250   GTlsCertificate *peer;
1251   GTlsInteraction *interaction;
1252   gboolean cas_changed;
1253
1254   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
1255   g_assert_no_error (error);
1256   g_assert_nonnull (test->database);
1257
1258   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUIRED);
1259   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1260   g_assert_no_error (error);
1261   g_assert_nonnull (test->client_connection);
1262   g_object_unref (connection);
1263
1264   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1265
1266   /* Have the interaction return a certificate */
1267   cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-and-key.pem"), &error);
1268   g_assert_no_error (error);
1269   interaction = mock_interaction_new_static_certificate (cert);
1270   g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
1271   g_object_unref (interaction);
1272
1273   /* All validation in this test */
1274   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1275                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1276
1277   cas_changed = FALSE;
1278   g_signal_connect (test->client_connection, "notify::accepted-cas",
1279                     G_CALLBACK (on_notify_accepted_cas), &cas_changed);
1280
1281   read_test_data_async (test);
1282   g_main_loop_run (test->loop);
1283
1284   g_assert_no_error (test->read_error);
1285   g_assert_no_error (test->server_error);
1286
1287   peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (test->server_connection));
1288   g_assert_nonnull (peer);
1289   g_assert_true (g_tls_certificate_is_same (peer, cert));
1290   g_assert_true (cas_changed);
1291
1292   g_object_unref (cert);
1293 }
1294
1295 static void
1296 test_client_auth_request_fail (TestConnection *test,
1297                                gconstpointer   data)
1298 {
1299   GIOStream *connection;
1300   GError *error = NULL;
1301   GTlsInteraction *interaction;
1302
1303   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
1304   g_assert_no_error (error);
1305   g_assert_nonnull (test->database);
1306
1307   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUIRED);
1308   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1309   g_assert_no_error (error);
1310   g_assert_nonnull (test->client_connection);
1311   g_object_unref (connection);
1312
1313   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
1314
1315   /* Have the interaction return an error */
1316   interaction = mock_interaction_new_static_error (G_FILE_ERROR, G_FILE_ERROR_ACCES, "Request message");
1317   g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
1318   g_object_unref (interaction);
1319
1320   /* All validation in this test */
1321   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1322                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1323
1324   if (!client_can_receive_certificate_required_errors (test))
1325     g_set_error_literal (&test->expected_client_close_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "");
1326   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED, "");
1327
1328   read_test_data_async (test);
1329   g_main_loop_run (test->loop);
1330
1331   /* FIXME: G_FILE_ERROR_ACCES is not a very great error to get here. */
1332   if (client_can_receive_certificate_required_errors (test))
1333     g_assert_error (test->read_error, G_FILE_ERROR, G_FILE_ERROR_ACCES);
1334   else if (!g_error_matches (test->read_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE))
1335     g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_MISC);
1336
1337   g_io_stream_close (test->server_connection, NULL, NULL);
1338   g_io_stream_close (test->client_connection, NULL, NULL);
1339 }
1340
1341 static void
1342 test_connection_no_database (TestConnection *test,
1343                              gconstpointer   data)
1344 {
1345   GIOStream *connection;
1346   GError *error = NULL;
1347
1348   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
1349   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1350   g_assert_no_error (error);
1351   g_assert_nonnull (test->client_connection);
1352   g_object_unref (connection);
1353
1354   /* Overrides loading of the default database */
1355   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), NULL);
1356
1357   /* All validation in this test */
1358   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1359                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1360
1361   test->accept_flags = G_TLS_CERTIFICATE_UNKNOWN_CA;
1362   g_signal_connect (test->client_connection, "accept-certificate",
1363                     G_CALLBACK (on_accept_certificate), test);
1364
1365   read_test_data_async (test);
1366   g_main_loop_run (test->loop);
1367
1368   g_assert_no_error (test->read_error);
1369   g_assert_no_error (test->server_error);
1370 }
1371
1372 static void
1373 handshake_failed_cb (GObject      *source,
1374                      GAsyncResult *result,
1375                      gpointer      user_data)
1376 {
1377   TestConnection *test = user_data;
1378   GError *error = NULL;
1379
1380   g_tls_connection_handshake_finish (G_TLS_CONNECTION (test->client_connection),
1381                                      result, &error);
1382   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
1383   g_clear_error (&error);
1384
1385   g_main_loop_quit (test->loop);
1386 }
1387
1388 static void
1389 test_failed_connection (TestConnection *test,
1390                         gconstpointer   data)
1391 {
1392   GIOStream *connection;
1393   GError *error = NULL;
1394   GSocketConnectable *bad_addr;
1395
1396   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
1397
1398   bad_addr = g_network_address_new ("wrong.example.com", 80);
1399   test->client_connection = g_tls_client_connection_new (connection, bad_addr, &error);
1400   g_object_unref (bad_addr);
1401   g_assert_no_error (error);
1402   g_object_unref (connection);
1403
1404   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS, "");
1405
1406   g_tls_connection_handshake_async (G_TLS_CONNECTION (test->client_connection),
1407                                     G_PRIORITY_DEFAULT, NULL,
1408                                     handshake_failed_cb, test);
1409   g_main_loop_run (test->loop);
1410
1411   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1412                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
1413
1414   read_test_data_async (test);
1415   g_main_loop_run (test->loop);
1416
1417   g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
1418 }
1419
1420 static void
1421 socket_client_connected (GObject      *source,
1422                          GAsyncResult *result,
1423                          gpointer      user_data)
1424 {
1425   TestConnection *test = user_data;
1426   GSocketConnection *connection;
1427   GError *error = NULL;
1428
1429   connection = g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
1430                                                result, &error);
1431   g_assert_no_error (error);
1432   test->client_connection = G_IO_STREAM (connection);
1433
1434   g_main_loop_quit (test->loop);
1435 }
1436
1437 static void
1438 test_connection_socket_client (TestConnection *test,
1439                                gconstpointer   data)
1440 {
1441   GSocketClient *client;
1442   GTlsCertificateFlags flags;
1443   GSocketConnection *connection;
1444   GIOStream *base;
1445   GError *error = NULL;
1446
1447   start_async_server_service (test, G_TLS_AUTHENTICATION_NONE, TRUE);
1448   client = g_socket_client_new ();
1449   g_socket_client_set_tls (client, TRUE);
1450   flags = G_TLS_CERTIFICATE_VALIDATE_ALL & ~G_TLS_CERTIFICATE_UNKNOWN_CA;
1451   /* test->address doesn't match the server's cert */
1452   flags = flags & ~G_TLS_CERTIFICATE_BAD_IDENTITY;
1453   g_socket_client_set_tls_validation_flags (client, flags);
1454
1455   g_socket_client_connect_async (client, G_SOCKET_CONNECTABLE (test->address),
1456                                  NULL, socket_client_connected, test);
1457   g_main_loop_run (test->loop);
1458
1459   connection = (GSocketConnection *)test->client_connection;
1460   test->client_connection = NULL;
1461
1462   g_assert_true (G_IS_TCP_WRAPPER_CONNECTION (connection));
1463   base = g_tcp_wrapper_connection_get_base_io_stream (G_TCP_WRAPPER_CONNECTION (connection));
1464   g_assert_true (G_IS_TLS_CONNECTION (base));
1465
1466   g_io_stream_close (G_IO_STREAM (connection), NULL, &error);
1467   g_assert_no_error (error);
1468   g_object_unref (connection);
1469
1470   g_object_unref (client);
1471 }
1472
1473 static void
1474 socket_client_failed (GObject      *source,
1475                       GAsyncResult *result,
1476                       gpointer      user_data)
1477 {
1478   TestConnection *test = user_data;
1479   GError *error = NULL;
1480
1481   g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
1482                                   result, &error);
1483   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
1484   g_clear_error (&error);
1485
1486   g_main_loop_quit (test->loop);
1487 }
1488
1489 static void
1490 test_connection_socket_client_failed (TestConnection *test,
1491                                       gconstpointer   data)
1492 {
1493   GSocketClient *client;
1494
1495   start_async_server_service (test, G_TLS_AUTHENTICATION_NONE, TRUE);
1496   client = g_socket_client_new ();
1497   g_socket_client_set_tls (client, TRUE);
1498   /* this time we don't adjust the validation flags */
1499
1500   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS, "");
1501
1502   g_socket_client_connect_async (client, G_SOCKET_CONNECTABLE (test->address),
1503                                  NULL, socket_client_failed, test);
1504   g_main_loop_run (test->loop);
1505
1506   g_object_unref (client);
1507 }
1508
1509 static void
1510 socket_client_timed_out_write (GObject      *source,
1511                                GAsyncResult *result,
1512                                gpointer      user_data)
1513 {
1514   TestConnection *test = user_data;
1515   GSocketConnection *connection;
1516   GInputStream *input_stream;
1517   GOutputStream *output_stream;
1518   GError *error = NULL;
1519   gchar buffer[TEST_DATA_LENGTH];
1520   gssize size;
1521
1522   connection = g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
1523                                                result, &error);
1524   g_assert_no_error (error);
1525   test->client_connection = G_IO_STREAM (connection);
1526
1527   input_stream = g_io_stream_get_input_stream (test->client_connection);
1528   output_stream = g_io_stream_get_output_stream (test->client_connection);
1529
1530   /* read TEST_DATA_LENGTH once */
1531   size = g_input_stream_read (input_stream, &buffer, TEST_DATA_LENGTH,
1532                               NULL, &error);
1533   g_assert_no_error (error);
1534   g_assert_cmpint (size, ==, TEST_DATA_LENGTH);
1535
1536   /* read TEST_DATA_LENGTH again to cause the time out */
1537   size = g_input_stream_read (input_stream, &buffer, TEST_DATA_LENGTH,
1538                               NULL, &error);
1539   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
1540   g_assert_cmpint (size, ==, -1);
1541   g_clear_error (&error);
1542
1543   /* write after a timeout, session should still be valid */
1544   size = g_output_stream_write (output_stream, TEST_DATA, TEST_DATA_LENGTH,
1545                                 NULL, &error);
1546   g_assert_no_error (error);
1547   g_assert_cmpint (size, ==, TEST_DATA_LENGTH);
1548
1549   g_main_loop_quit (test->loop);
1550 }
1551
1552 static void
1553 test_connection_read_time_out_write (TestConnection *test,
1554                                      gconstpointer   data)
1555 {
1556   GSocketClient *client;
1557   GTlsCertificateFlags flags;
1558   GSocketConnection *connection;
1559   GIOStream *base;
1560   GError *error = NULL;
1561
1562   /* Don't close the server connection after writing TEST_DATA. */
1563   start_async_server_service (test, G_TLS_AUTHENTICATION_NONE, FALSE);
1564   client = g_socket_client_new ();
1565   /* Set a 1 second time out on the socket */
1566   g_socket_client_set_timeout (client, 1);
1567   g_socket_client_set_tls (client, TRUE);
1568   flags = G_TLS_CERTIFICATE_VALIDATE_ALL & ~G_TLS_CERTIFICATE_UNKNOWN_CA;
1569   /* test->address doesn't match the server's cert */
1570   flags = flags & ~G_TLS_CERTIFICATE_BAD_IDENTITY;
1571   g_socket_client_set_tls_validation_flags (client, flags);
1572
1573   g_socket_client_connect_async (client, G_SOCKET_CONNECTABLE (test->address),
1574                                  NULL, socket_client_timed_out_write, test);
1575
1576   g_main_loop_run (test->loop);
1577
1578   /* Close the server now */
1579   close_server_connection (test);
1580
1581   connection = (GSocketConnection *)test->client_connection;
1582   test->client_connection = NULL;
1583
1584   g_assert_true (G_IS_TCP_WRAPPER_CONNECTION (connection));
1585   base = g_tcp_wrapper_connection_get_base_io_stream (G_TCP_WRAPPER_CONNECTION (connection));
1586   g_assert_true (G_IS_TLS_CONNECTION (base));
1587
1588   g_io_stream_close (G_IO_STREAM (connection), NULL, &error);
1589   g_assert_no_error (error);
1590   g_object_unref (connection);
1591
1592   g_object_unref (client);
1593 }
1594
1595 static void
1596 simul_async_read_complete (GObject      *object,
1597                            GAsyncResult *result,
1598                            gpointer      user_data)
1599 {
1600   TestConnection *test = user_data;
1601   gssize nread;
1602   GError *error = NULL;
1603
1604   nread = g_input_stream_read_finish (G_INPUT_STREAM (object),
1605                                       result, &error);
1606   g_assert_no_error (error);
1607
1608   test->nread += nread;
1609   g_assert_cmpint (test->nread, <=, TEST_DATA_LENGTH);
1610
1611   if (test->nread == TEST_DATA_LENGTH)
1612     {
1613       g_io_stream_close (test->client_connection, NULL, &error);
1614       g_assert_no_error (error);
1615       g_main_loop_quit (test->loop);
1616     }
1617   else
1618     {
1619       g_input_stream_read_async (G_INPUT_STREAM (object),
1620                                  test->buf + test->nread,
1621                                  TEST_DATA_LENGTH / 2,
1622                                  G_PRIORITY_DEFAULT, NULL,
1623                                  simul_async_read_complete, test);
1624     }
1625 }
1626
1627 static void
1628 simul_async_write_complete (GObject      *object,
1629                             GAsyncResult *result,
1630                             gpointer      user_data)
1631 {
1632   TestConnection *test = user_data;
1633   gssize nwrote;
1634   GError *error = NULL;
1635
1636   nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (object),
1637                                          result, &error);
1638   g_assert_no_error (error);
1639
1640   test->nwrote += nwrote;
1641   if (test->nwrote < TEST_DATA_LENGTH)
1642     {
1643       g_output_stream_write_async (G_OUTPUT_STREAM (object),
1644                                    TEST_DATA + test->nwrote,
1645                                    TEST_DATA_LENGTH - test->nwrote,
1646                                    G_PRIORITY_DEFAULT, NULL,
1647                                    simul_async_write_complete, test);
1648     }
1649 }
1650
1651 static void
1652 test_simultaneous_async (TestConnection *test,
1653                          gconstpointer   data)
1654 {
1655   GIOStream *connection;
1656   GTlsCertificateFlags flags;
1657   GError *error = NULL;
1658
1659   connection = start_echo_server_and_connect_to_it (test);
1660   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1661   g_assert_no_error (error);
1662   g_object_unref (connection);
1663
1664   flags = G_TLS_CERTIFICATE_VALIDATE_ALL &
1665     ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
1666   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1667                                                 flags);
1668
1669   memset (test->buf, 0, sizeof (test->buf));
1670   test->nread = test->nwrote = 0;
1671
1672   g_input_stream_read_async (g_io_stream_get_input_stream (test->client_connection),
1673                              test->buf, TEST_DATA_LENGTH / 2,
1674                              G_PRIORITY_DEFAULT, NULL,
1675                              simul_async_read_complete, test);
1676   g_output_stream_write_async (g_io_stream_get_output_stream (test->client_connection),
1677                                TEST_DATA, TEST_DATA_LENGTH / 2,
1678                                G_PRIORITY_DEFAULT, NULL,
1679                                simul_async_write_complete, test);
1680
1681   g_main_loop_run (test->loop);
1682
1683   g_assert_cmpint (test->nread, ==, TEST_DATA_LENGTH);
1684   g_assert_cmpint (test->nwrote, ==, TEST_DATA_LENGTH);
1685   g_assert_cmpstr (test->buf, ==, TEST_DATA);
1686 }
1687
1688 #ifdef BACKEND_IS_GNUTLS
1689 static gboolean
1690 check_gnutls_has_rehandshaking_bug (void)
1691 {
1692   const char *version = gnutls_check_version (NULL);
1693
1694   return !strcmp (version, "3.6.1") ||
1695          !strcmp (version, "3.6.2");
1696 }
1697 #endif
1698
1699 static void
1700 test_simultaneous_async_rehandshake (TestConnection *test,
1701                                      gconstpointer   data)
1702 {
1703 #ifdef BACKEND_IS_OPENSSL
1704   g_test_skip ("this needs more research on openssl");
1705   return;
1706 #elif defined(BACKEND_IS_GNUTLS)
1707   if (check_gnutls_has_rehandshaking_bug ())
1708     {
1709       g_test_skip ("test would fail due to https://gitlab.com/gnutls/gnutls/issues/426");
1710       return;
1711     }
1712 #endif
1713
1714   test->rehandshake = TRUE;
1715   test_simultaneous_async (test, data);
1716 }
1717
1718 static gpointer
1719 simul_read_thread (gpointer user_data)
1720 {
1721   TestConnection *test = user_data;
1722   GInputStream *istream = g_io_stream_get_input_stream (test->client_connection);
1723   GError *error = NULL;
1724   gssize nread;
1725
1726   while (test->nread < TEST_DATA_LENGTH)
1727     {
1728       nread = g_input_stream_read (istream,
1729                                    test->buf + test->nread,
1730                                    MIN (TEST_DATA_LENGTH / 2, TEST_DATA_LENGTH - test->nread),
1731                                    NULL, &error);
1732       g_assert_no_error (error);
1733
1734       test->nread += nread;
1735     }
1736
1737   return NULL;
1738 }
1739
1740 static gpointer
1741 simul_write_thread (gpointer user_data)
1742 {
1743   TestConnection *test = user_data;
1744   GOutputStream *ostream = g_io_stream_get_output_stream (test->client_connection);
1745   GError *error = NULL;
1746   gssize nwrote;
1747
1748   while (test->nwrote < TEST_DATA_LENGTH)
1749     {
1750       nwrote = g_output_stream_write (ostream,
1751                                       TEST_DATA + test->nwrote,
1752                                       MIN (TEST_DATA_LENGTH / 2, TEST_DATA_LENGTH - test->nwrote),
1753                                       NULL, &error);
1754       g_assert_no_error (error);
1755
1756       test->nwrote += nwrote;
1757     }
1758
1759   return NULL;
1760 }
1761
1762 static void
1763 test_simultaneous_sync (TestConnection *test,
1764                         gconstpointer   data)
1765 {
1766   GIOStream *connection;
1767   GTlsCertificateFlags flags;
1768   GError *error = NULL;
1769   GThread *read_thread, *write_thread;
1770
1771   connection = start_echo_server_and_connect_to_it (test);
1772   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1773   g_assert_no_error (error);
1774   g_object_unref (connection);
1775
1776   flags = G_TLS_CERTIFICATE_VALIDATE_ALL &
1777     ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
1778   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1779                                                 flags);
1780
1781   memset (test->buf, 0, sizeof (test->buf));
1782   test->nread = test->nwrote = 0;
1783
1784   read_thread = g_thread_new ("reader", simul_read_thread, test);
1785   write_thread = g_thread_new ("writer", simul_write_thread, test);
1786
1787   /* We need to run the main loop to get the GThreadedSocketService to
1788    * receive the connection and spawn the server thread.
1789    */
1790   while (!test->server_connection)
1791     g_main_context_iteration (NULL, FALSE);
1792
1793   g_thread_join (write_thread);
1794   g_thread_join (read_thread);
1795
1796   g_assert_cmpint (test->nread, ==, TEST_DATA_LENGTH);
1797   g_assert_cmpint (test->nwrote, ==, TEST_DATA_LENGTH);
1798   g_assert_cmpstr (test->buf, ==, TEST_DATA);
1799
1800   g_io_stream_close (test->client_connection, NULL, &error);
1801   g_assert_no_error (error);
1802 }
1803
1804 static void
1805 test_simultaneous_sync_rehandshake (TestConnection *test,
1806                                     gconstpointer   data)
1807 {
1808 #ifdef BACKEND_IS_OPENSSL
1809   g_test_skip ("this needs more research on openssl");
1810   return;
1811 #elif defined(BACKEND_IS_GNUTLS)
1812   if (check_gnutls_has_rehandshaking_bug ())
1813     {
1814       g_test_skip ("test would fail due to https://gitlab.com/gnutls/gnutls/issues/426");
1815       return;
1816     }
1817 #endif
1818
1819   test->rehandshake = TRUE;
1820   test_simultaneous_sync (test, data);
1821 }
1822
1823 static void
1824 test_close_immediately (TestConnection *test,
1825                         gconstpointer   data)
1826 {
1827   GIOStream *connection;
1828   GError *error = NULL;
1829
1830   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
1831   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
1832   g_assert_no_error (error);
1833   g_object_unref (connection);
1834
1835   /*
1836    * At this point the server won't get a chance to run. But regardless
1837    * closing should not wait on the server, trying to handshake or something.
1838    */
1839   g_io_stream_close (test->client_connection, NULL, &error);
1840   g_assert_no_error (error);
1841 }
1842
1843 static gboolean
1844 async_implicit_handshake_dispatch (GPollableInputStream *stream,
1845                                    gpointer user_data)
1846 {
1847   TestConnection *test = user_data;
1848   GError *error = NULL;
1849   gchar buffer[TEST_DATA_LENGTH];
1850   gssize size;
1851   gboolean keep_running;
1852
1853   size = g_pollable_input_stream_read_nonblocking (stream, buffer,
1854                                                    TEST_DATA_LENGTH,
1855                                                    NULL, &error);
1856
1857   keep_running = (-1 == size);
1858
1859   if (keep_running)
1860     {
1861       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
1862       g_error_free (error);
1863     }
1864   else
1865     {
1866       g_assert_no_error (error);
1867       g_assert_cmpint (size, ==, TEST_DATA_LENGTH);
1868       g_main_loop_quit (test->loop);
1869     }
1870
1871   return keep_running;
1872 }
1873
1874 static void
1875 test_async_implicit_handshake (TestConnection *test, gconstpointer   data)
1876 {
1877   GTlsCertificateFlags flags;
1878   GIOStream *stream;
1879   GInputStream *input_stream;
1880   GSource *input_source;
1881   GError *error = NULL;
1882
1883   g_test_bug ("710691");
1884
1885   stream = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
1886   test->client_connection = g_tls_client_connection_new (stream, test->identity, &error);
1887   g_assert_no_error (error);
1888   g_object_unref (stream);
1889
1890   flags = G_TLS_CERTIFICATE_VALIDATE_ALL &
1891     ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
1892   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1893                                                 flags);
1894
1895   /**
1896    * Create a source from the client's input stream. The dispatch
1897    * callback will be called a first time, which will perform a
1898    * non-blocking read triggering the asynchronous implicit
1899    * handshaking.
1900    */
1901   input_stream = g_io_stream_get_input_stream (test->client_connection);
1902   input_source =
1903     g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (input_stream),
1904                                            NULL);
1905
1906   g_source_set_callback (input_source,
1907                          (GSourceFunc) async_implicit_handshake_dispatch,
1908                          test, NULL);
1909
1910   g_source_attach (input_source, NULL);
1911
1912   g_main_loop_run (test->loop);
1913
1914   g_io_stream_close (G_IO_STREAM (test->client_connection), NULL, &error);
1915   g_assert_no_error (error);
1916   g_object_unref (test->client_connection);
1917   test->client_connection = NULL;
1918 }
1919
1920 static void
1921 quit_on_handshake_complete (GObject      *object,
1922                             GAsyncResult *result,
1923                             gpointer      user_data)
1924 {
1925   TestConnection *test = user_data;
1926   GError *error = NULL;
1927
1928   g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), result, &error);
1929   g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS);
1930   g_error_free (error);
1931
1932   g_main_loop_quit (test->loop);
1933   return;
1934 }
1935
1936 static void
1937 test_fallback (TestConnection *test,
1938                gconstpointer   data)
1939 {
1940   GIOStream *connection;
1941   GTlsConnection *tlsconn;
1942   GError *error = NULL;
1943
1944 #ifdef BACKEND_IS_OPENSSL
1945   g_test_skip ("this needs more research on openssl");
1946   return;
1947 #endif
1948
1949   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
1950   test->client_connection = g_tls_client_connection_new (connection, NULL, &error);
1951   g_assert_no_error (error);
1952   tlsconn = G_TLS_CONNECTION (test->client_connection);
1953   g_object_unref (connection);
1954
1955   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
1956                                                 0);
1957 #if defined(__GNUC__)
1958 #pragma GCC diagnostic push
1959 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1960 #endif
1961   g_tls_client_connection_set_use_ssl3 (G_TLS_CLIENT_CONNECTION (test->client_connection),
1962                                         TRUE);
1963 #if defined(__GNUC__)
1964 #pragma GCC diagnostic pop
1965 #endif
1966
1967 #if GLIB_CHECK_VERSION(2, 60, 0)
1968   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_INAPPROPRIATE_FALLBACK, "");
1969 #else
1970   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_MISC, "");
1971 #endif
1972
1973   g_tls_connection_handshake_async (tlsconn, G_PRIORITY_DEFAULT, NULL,
1974                                     quit_on_handshake_complete, test);
1975   g_main_loop_run (test->loop);
1976
1977   /* The server should detect a protocol downgrade attack and terminate the connection.
1978    */
1979
1980   g_io_stream_close (test->client_connection, NULL, &error);
1981   g_assert_no_error (error);
1982 }
1983
1984 static void
1985 handshake_completed (GObject      *object,
1986                      GAsyncResult *result,
1987                      gpointer      user_data)
1988 {
1989   gboolean *complete = user_data;
1990
1991   *complete = TRUE;
1992   return;
1993 }
1994
1995 static void
1996 test_output_stream_close (TestConnection *test,
1997                           gconstpointer   data)
1998 {
1999   GIOStream *connection;
2000   GError *error = NULL;
2001   gboolean ret;
2002   gboolean handshake_complete = FALSE;
2003   gssize size;
2004
2005   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
2006   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
2007   g_assert_no_error (error);
2008   g_object_unref (connection);
2009
2010   /* No validation at all in this test */
2011   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
2012                                                 0);
2013
2014   g_tls_connection_handshake_async (G_TLS_CONNECTION (test->client_connection),
2015                                     G_PRIORITY_DEFAULT, NULL,
2016                                     handshake_completed, &handshake_complete);
2017
2018   while (!handshake_complete)
2019     g_main_context_iteration (NULL, TRUE);
2020
2021   ret = g_output_stream_close (g_io_stream_get_output_stream (test->client_connection),
2022                                NULL, &error);
2023   g_assert_no_error (error);
2024   g_assert_true (ret);
2025
2026   /* Verify that double close returns TRUE */
2027   ret = g_output_stream_close (g_io_stream_get_output_stream (test->client_connection),
2028                                NULL, &error);
2029   g_assert_no_error (error);
2030   g_assert_true (ret);
2031
2032   size = g_output_stream_write (g_io_stream_get_output_stream (test->client_connection),
2033                                 "data", 4, NULL, &error);
2034   g_assert_cmpint (size, ==, -1);
2035   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
2036   g_clear_error (&error);
2037
2038   /* We closed the output stream, but not the input stream, so receiving
2039    * data should still work.
2040    */
2041   read_test_data_async (test);
2042   g_main_loop_run (test->loop);
2043
2044   g_assert_no_error (test->read_error);
2045   g_assert_no_error (test->server_error);
2046
2047   ret = g_io_stream_close (test->client_connection, NULL, &error);
2048   g_assert_no_error (error);
2049   g_assert_true (ret);
2050 }
2051
2052 static void
2053 test_garbage_database (TestConnection *test,
2054                        gconstpointer   data)
2055 {
2056   GIOStream *connection;
2057   GError *error = NULL;
2058
2059   test->database = g_tls_file_database_new (tls_test_file_path ("garbage.pem"), &error);
2060   g_assert_no_error (error);
2061   g_assert_nonnull (test->database);
2062
2063   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
2064   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
2065   g_assert_no_error (error);
2066   g_assert_nonnull (test->client_connection);
2067   g_object_unref (connection);
2068
2069   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
2070
2071   /* All validation in this test */
2072   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
2073                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
2074
2075   g_set_error_literal (&test->expected_server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS, "");
2076
2077   read_test_data_async (test);
2078   g_main_loop_run (test->loop);
2079
2080   /* Should reject the server's certificate, because our TLS database contains
2081    * no valid certificates.
2082    */
2083   g_assert_error (test->read_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
2084 }
2085
2086 static void
2087 test_readwrite_after_connection_destroyed (TestConnection *test,
2088                                            gconstpointer   data)
2089 {
2090   GIOStream *connection;
2091   GOutputStream *ostream;
2092   GInputStream *istream;
2093   unsigned char buffer[1];
2094   GError *error = NULL;
2095
2096   g_test_bug ("792219");
2097
2098   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_REQUESTED);
2099   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
2100   g_assert_no_error (error);
2101   g_object_unref (connection);
2102
2103   istream = g_object_ref (g_io_stream_get_input_stream (test->client_connection));
2104   ostream = g_object_ref (g_io_stream_get_output_stream (test->client_connection));
2105   g_clear_object (&test->client_connection);
2106
2107   /* The GTlsConnection has been destroyed, but its underlying streams
2108    * live on, because we have reffed them. Verify that attempts to read
2109    * and write produce only nice GErrors.
2110    */
2111   g_input_stream_read (istream, buffer, sizeof (buffer), NULL, &error);
2112   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
2113   g_clear_error (&error);
2114
2115   g_output_stream_write (ostream, TEST_DATA, TEST_DATA_LENGTH,
2116                          G_PRIORITY_DEFAULT, &error);
2117   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
2118   g_clear_error (&error);
2119
2120   g_input_stream_close (istream, NULL, &error);
2121   g_assert_no_error (error);
2122
2123   g_output_stream_close (ostream, NULL, &error);
2124   g_assert_no_error (error);
2125
2126   g_object_unref (istream);
2127   g_object_unref (ostream);
2128 }
2129
2130 static void
2131 test_alpn (TestConnection *test,
2132            const char * const *client_protocols,
2133            const char * const *server_protocols,
2134            const char *negotiated_protocol)
2135 {
2136 #if GLIB_CHECK_VERSION(2, 60, 0)
2137   GIOStream *connection;
2138   GError *error = NULL;
2139
2140   test->server_protocols = server_protocols;
2141
2142   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
2143   g_assert_no_error (error);
2144   g_assert (test->database);
2145
2146   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
2147   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
2148   g_assert_no_error (error);
2149   g_object_unref (connection);
2150
2151   if (client_protocols)
2152     {
2153       g_tls_connection_set_advertised_protocols (G_TLS_CONNECTION (test->client_connection),
2154                                                  client_protocols);
2155     }
2156
2157   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
2158
2159   read_test_data_async (test);
2160   g_main_loop_run (test->loop);
2161
2162   g_assert_no_error (test->read_error);
2163   g_assert_no_error (test->server_error);
2164
2165   g_assert_cmpstr (g_tls_connection_get_negotiated_protocol (G_TLS_CONNECTION (test->server_connection)), ==, negotiated_protocol);
2166   g_assert_cmpstr (g_tls_connection_get_negotiated_protocol (G_TLS_CONNECTION (test->client_connection)), ==, negotiated_protocol);
2167 #else
2168   g_test_skip ("no support for ALPN in this GLib version");
2169 #endif
2170 }
2171
2172 static void
2173 test_alpn_match (TestConnection *test,
2174                  gconstpointer   data)
2175 {
2176   const char * const client_protocols[] = { "one", "two", "three", NULL };
2177   const char * const server_protocols[] = { "four", "seven", "nine", "two", NULL };
2178
2179   test_alpn (test, client_protocols, server_protocols, "two");
2180 }
2181
2182 static void
2183 test_alpn_no_match (TestConnection *test,
2184                     gconstpointer   data)
2185 {
2186   const char * const client_protocols[] = { "one", "two", "three", NULL };
2187   const char * const server_protocols[] = { "four", "seven", "nine", NULL };
2188
2189   test_alpn (test, client_protocols, server_protocols, NULL);
2190 }
2191
2192 static void
2193 test_alpn_client_only (TestConnection *test,
2194                        gconstpointer   data)
2195 {
2196   const char * const client_protocols[] = { "one", "two", "three", NULL };
2197
2198   test_alpn (test, client_protocols, NULL, NULL);
2199 }
2200
2201 static void
2202 test_alpn_server_only (TestConnection *test,
2203                        gconstpointer   data)
2204 {
2205   const char * const server_protocols[] = { "four", "seven", "nine", "two", NULL };
2206
2207   test_alpn (test, NULL, server_protocols, NULL);
2208 }
2209
2210 static gboolean
2211 on_accept_certificate_with_sync_close (GTlsClientConnection *conn,
2212                                        GTlsCertificate      *cert,
2213                                        GTlsCertificateFlags  errors,
2214                                        gpointer              user_data)
2215 {
2216   GError *error = NULL;
2217
2218   /* Attempting to perform a sync operation that would block the
2219    * handshake should fail, not deadlock.
2220    */
2221   g_io_stream_close (G_IO_STREAM (conn), NULL, &error);
2222   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
2223   g_error_free (error);
2224
2225   /* FIXME: When writing this test, I initially wanted to return FALSE
2226    * here to reject the connection. However, this surfaces a bug that I
2227    * have not fixed yet. The problem is the server is not seeing the end
2228    * of its g_output_stream_write() when the client fails the handshake.
2229    * No good. The server's implicit handshake failure should trigger a
2230    * write failure as well, instead of stalling. This needs to be fixed.
2231    *
2232    * Fixing this would allow us to guarantee that this callback is
2233    * actually executed by checking test->read_error at the bottom of
2234    * test_sync_op_during_handshake(). Currently, this test would still
2235    * pass even if this callback were to be improperly skipped.
2236    */
2237   return TRUE;
2238 }
2239
2240 static void
2241 test_sync_op_during_handshake (TestConnection *test,
2242                                gconstpointer   data)
2243 {
2244   GIOStream *connection;
2245   GError *error = NULL;
2246
2247   connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
2248   test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
2249   g_assert_no_error (error);
2250   g_object_unref (connection);
2251
2252   /* For this test, we need validation to fail to ensure that the
2253    * accept-certificate signal gets emitted.
2254    */
2255   g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
2256                                                 G_TLS_CERTIFICATE_VALIDATE_ALL);
2257
2258   g_signal_connect (test->client_connection, "accept-certificate",
2259                     G_CALLBACK (on_accept_certificate_with_sync_close), test);
2260
2261   read_test_data_async (test);
2262   g_main_loop_run (test->loop);
2263
2264   g_assert_no_error (test->read_error);
2265   g_assert_no_error (test->server_error);
2266 }
2267
2268 int
2269 main (int   argc,
2270       char *argv[])
2271 {
2272   int ret;
2273
2274   g_test_init (&argc, &argv, NULL);
2275   g_test_bug_base ("http://bugzilla.gnome.org/");
2276
2277   g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
2278   g_setenv ("GIO_USE_TLS", BACKEND, TRUE);
2279   g_assert (g_ascii_strcasecmp (G_OBJECT_TYPE_NAME (g_tls_backend_get_default ()), "GTlsBackend" BACKEND) == 0);
2280
2281   g_test_add ("/tls/connection/basic", TestConnection, NULL,
2282               setup_connection, test_basic_connection, teardown_connection);
2283   g_test_add ("/tls/connection/verified", TestConnection, NULL,
2284               setup_connection, test_verified_connection, teardown_connection);
2285   g_test_add ("/tls/connection/verified-chain", TestConnection, NULL,
2286               setup_connection, test_verified_chain, teardown_connection);
2287   g_test_add ("/tls/connection/verified-chain-with-redundant-root-cert", TestConnection, NULL,
2288               setup_connection, test_verified_chain_with_redundant_root_cert, teardown_connection);
2289   g_test_add ("/tls/connection/verified-chain-with-duplicate-server-cert", TestConnection, NULL,
2290               setup_connection, test_verified_chain_with_duplicate_server_cert, teardown_connection);
2291   g_test_add ("/tls/connection/verified-unordered-chain", TestConnection, NULL,
2292               setup_connection, test_verified_unordered_chain, teardown_connection);
2293   g_test_add ("/tls/connection/verified-chain-with-alternative-ca-cert", TestConnection, NULL,
2294               setup_connection, test_verified_chain_with_alternative_ca_cert, teardown_connection);
2295   g_test_add ("/tls/connection/invalid-chain-with-alternative-ca-cert", TestConnection, NULL,
2296               setup_connection, test_invalid_chain_with_alternative_ca_cert, teardown_connection);
2297   g_test_add ("/tls/connection/client-auth", TestConnection, NULL,
2298               setup_connection, test_client_auth_connection, teardown_connection);
2299   g_test_add ("/tls/connection/client-auth-rehandshake", TestConnection, NULL,
2300               setup_connection, test_client_auth_rehandshake, teardown_connection);
2301   g_test_add ("/tls/connection/client-auth-failure", TestConnection, NULL,
2302               setup_connection, test_client_auth_failure, teardown_connection);
2303   g_test_add ("/tls/connection/client-auth-fail-missing-client-private-key", TestConnection, NULL,
2304               setup_connection, test_client_auth_fail_missing_client_private_key, teardown_connection);
2305   g_test_add ("/tls/connection/client-auth-request-cert", TestConnection, NULL,
2306               setup_connection, test_client_auth_request_cert, teardown_connection);
2307   g_test_add ("/tls/connection/client-auth-request-fail", TestConnection, NULL,
2308               setup_connection, test_client_auth_request_fail, teardown_connection);
2309   g_test_add ("/tls/connection/no-database", TestConnection, NULL,
2310               setup_connection, test_connection_no_database, teardown_connection);
2311   g_test_add ("/tls/connection/failed", TestConnection, NULL,
2312               setup_connection, test_failed_connection, teardown_connection);
2313   g_test_add ("/tls/connection/socket-client", TestConnection, NULL,
2314               setup_connection, test_connection_socket_client, teardown_connection);
2315   g_test_add ("/tls/connection/socket-client-failed", TestConnection, NULL,
2316               setup_connection, test_connection_socket_client_failed, teardown_connection);
2317   g_test_add ("/tls/connection/read-time-out-then-write", TestConnection, NULL,
2318               setup_connection, test_connection_read_time_out_write, teardown_connection);
2319   g_test_add ("/tls/connection/simultaneous-async", TestConnection, NULL,
2320               setup_connection, test_simultaneous_async, teardown_connection);
2321   g_test_add ("/tls/connection/simultaneous-sync", TestConnection, NULL,
2322               setup_connection, test_simultaneous_sync, teardown_connection);
2323   g_test_add ("/tls/connection/simultaneous-async-rehandshake", TestConnection, NULL,
2324               setup_connection, test_simultaneous_async_rehandshake, teardown_connection);
2325   g_test_add ("/tls/connection/simultaneous-sync-rehandshake", TestConnection, NULL,
2326               setup_connection, test_simultaneous_sync_rehandshake, teardown_connection);
2327   g_test_add ("/tls/connection/close-immediately", TestConnection, NULL,
2328               setup_connection, test_close_immediately, teardown_connection);
2329   g_test_add ("/tls/connection/async-implicit-handshake", TestConnection, NULL,
2330               setup_connection, test_async_implicit_handshake, teardown_connection);
2331   g_test_add ("/tls/connection/output-stream-close", TestConnection, NULL,
2332               setup_connection, test_output_stream_close, teardown_connection);
2333   g_test_add ("/tls/connection/fallback", TestConnection, NULL,
2334               setup_connection, test_fallback, teardown_connection);
2335   g_test_add ("/tls/connection/garbage-database", TestConnection, NULL,
2336               setup_connection, test_garbage_database, teardown_connection);
2337   g_test_add ("/tls/connection/readwrite-after-connection-destroyed", TestConnection, NULL,
2338               setup_connection, test_readwrite_after_connection_destroyed, teardown_connection);
2339   g_test_add ("/tls/connection/alpn/match", TestConnection, NULL,
2340               setup_connection, test_alpn_match, teardown_connection);
2341   g_test_add ("/tls/connection/alpn/no-match", TestConnection, NULL,
2342               setup_connection, test_alpn_no_match, teardown_connection);
2343   g_test_add ("/tls/connection/alpn/client-only", TestConnection, NULL,
2344               setup_connection, test_alpn_client_only, teardown_connection);
2345   g_test_add ("/tls/connection/alpn/server-only", TestConnection, NULL,
2346               setup_connection, test_alpn_server_only, teardown_connection);
2347   g_test_add ("/tls/connection/sync-op-during-handshake", TestConnection, NULL,
2348               setup_connection, test_sync_op_during_handshake, teardown_connection);
2349
2350   ret = g_test_run ();
2351
2352   /* for valgrinding */
2353   g_main_context_unref (g_main_context_default ());
2354
2355   return ret;
2356 }