Imported Upstream version 2.73.3
[platform/upstream/glib.git] / gio / tests / gtesttlsbackend.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2011 Collabora Ltd.
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
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 <http://www.gnu.org/licenses/>.
19  */
20
21 #include "gtesttlsbackend.h"
22
23 #include <glib.h>
24
25 static GType _g_test_tls_certificate_get_type (void);
26 static GType _g_test_tls_connection_get_type (void);
27 static GTlsDatabase * _g_test_tls_backend_get_default_database (GTlsBackend * backend);
28 static GType _g_test_tls_database_get_type (void);
29
30 struct _GTestTlsBackend {
31   GObject parent_instance;
32 };
33
34 static void g_test_tls_backend_iface_init (GTlsBackendInterface *iface);
35
36 #define g_test_tls_backend_get_type _g_test_tls_backend_get_type
37 G_DEFINE_TYPE_WITH_CODE (GTestTlsBackend, g_test_tls_backend, G_TYPE_OBJECT,
38                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_BACKEND,
39                                                 g_test_tls_backend_iface_init)
40                          g_io_extension_point_set_required_type (
41                            g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME),
42                            G_TYPE_TLS_BACKEND);
43                          g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME,
44                                                          g_define_type_id,
45                                                          "test",
46                                                          999);)
47
48 static void
49 g_test_tls_backend_init (GTestTlsBackend *backend)
50 {
51 }
52
53 static void
54 g_test_tls_backend_class_init (GTestTlsBackendClass *backend_class)
55 {
56 }
57
58 static void
59 g_test_tls_backend_iface_init (GTlsBackendInterface *iface)
60 {
61   iface->get_certificate_type = _g_test_tls_certificate_get_type;
62   iface->get_client_connection_type = _g_test_tls_connection_get_type;
63   iface->get_server_connection_type = _g_test_tls_connection_get_type;
64   iface->get_dtls_client_connection_type = _g_test_tls_connection_get_type;
65   iface->get_dtls_server_connection_type = _g_test_tls_connection_get_type;
66   iface->get_default_database = _g_test_tls_backend_get_default_database;
67   iface->get_file_database_type = _g_test_tls_database_get_type;
68 }
69
70 static GTlsDatabase *
71 _g_test_tls_backend_get_default_database (GTlsBackend * backend)
72 {
73   static GTlsDatabase *default_db;
74   GError *error = NULL;
75
76   if (!default_db)
77     {
78       default_db = g_initable_new (_g_test_tls_database_get_type (),
79                                    NULL,
80                                    &error,
81                                    NULL);
82       g_assert_no_error (error);
83     }
84
85   return default_db;
86 }
87
88 /* Test certificate type */
89
90 typedef struct _GTestTlsCertificate      GTestTlsCertificate;
91 typedef struct _GTestTlsCertificateClass GTestTlsCertificateClass;
92
93 struct _GTestTlsCertificate {
94   GTlsCertificate parent_instance;
95   gchar *key_pem;
96   gchar *cert_pem;
97   GTlsCertificate *issuer;
98   gchar *pkcs11_uri;
99   gchar *private_key_pkcs11_uri;
100 };
101
102 struct _GTestTlsCertificateClass {
103   GTlsCertificateClass parent_class;
104 };
105
106 enum
107 {
108   PROP_CERT_CERTIFICATE = 1,
109   PROP_CERT_CERTIFICATE_PEM,
110   PROP_CERT_PRIVATE_KEY,
111   PROP_CERT_PRIVATE_KEY_PEM,
112   PROP_CERT_ISSUER,
113   PROP_CERT_PKCS11_URI,
114   PROP_CERT_PRIVATE_KEY_PKCS11_URI,
115   PROP_CERT_NOT_VALID_BEFORE,
116   PROP_CERT_NOT_VALID_AFTER,
117   PROP_CERT_SUBJECT_NAME,
118   PROP_CERT_ISSUER_NAME,
119   PROP_CERT_DNS_NAMES,
120   PROP_CERT_IP_ADDRESSES,
121 };
122
123 static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface);
124
125 #define g_test_tls_certificate_get_type _g_test_tls_certificate_get_type
126 G_DEFINE_TYPE_WITH_CODE (GTestTlsCertificate, g_test_tls_certificate, G_TYPE_TLS_CERTIFICATE,
127                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
128                                                 g_test_tls_certificate_initable_iface_init))
129
130 static GTlsCertificateFlags
131 g_test_tls_certificate_verify (GTlsCertificate     *cert,
132                                GSocketConnectable  *identity,
133                                GTlsCertificate     *trusted_ca)
134 {
135   /* For now, all of the tests expect the certificate to verify */
136   return 0;
137 }
138
139 static void
140 g_test_tls_certificate_get_property (GObject    *object,
141                                       guint       prop_id,
142                                       GValue     *value,
143                                       GParamSpec *pspec)
144 {
145   GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
146   GPtrArray *data = NULL;
147   const gchar *dns_name = "a.example.com";
148
149   switch (prop_id)
150     {
151     case PROP_CERT_CERTIFICATE_PEM:
152       g_value_set_string (value, cert->cert_pem);
153       break;
154     case PROP_CERT_PRIVATE_KEY_PEM:
155       g_value_set_string (value, cert->key_pem);
156       break;
157     case PROP_CERT_ISSUER:
158       g_value_set_object (value, cert->issuer);
159       break;
160     case PROP_CERT_PKCS11_URI:
161       /* This test value simulates a backend that ignores the value
162          because it is unsupported */
163       if (g_strcmp0 (cert->pkcs11_uri, "unsupported") != 0)
164         g_value_set_string (value, cert->pkcs11_uri);
165       break;
166     case PROP_CERT_PRIVATE_KEY_PKCS11_URI:
167       g_value_set_string (value, cert->private_key_pkcs11_uri);
168       break;
169     case PROP_CERT_NOT_VALID_BEFORE:
170       g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2020-10-12T17:49:44Z", NULL));
171       break;
172     case PROP_CERT_NOT_VALID_AFTER:
173       g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2045-10-06T17:49:44Z", NULL));
174       break;
175     case PROP_CERT_SUBJECT_NAME:
176       g_value_set_string (value, "DC=COM,DC=EXAMPLE,CN=server.example.com");
177       break;
178     case PROP_CERT_ISSUER_NAME:
179       g_value_set_string (value, "DC=COM,DC=EXAMPLE,OU=Certificate Authority,CN=ca.example.com,emailAddress=ca@example.com");
180       break;
181     case PROP_CERT_DNS_NAMES:
182       data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
183       g_ptr_array_add (data, g_bytes_new_static (dns_name, strlen (dns_name)));
184       g_value_take_boxed (value, data);
185       break;
186     case PROP_CERT_IP_ADDRESSES:
187       data = g_ptr_array_new_with_free_func (g_object_unref);
188       g_ptr_array_add (data, g_inet_address_new_from_string ("192.0.2.1"));
189       g_value_take_boxed (value, data);
190       break;
191     default:
192       g_assert_not_reached ();
193       break;
194     }
195 }
196
197 static void
198 g_test_tls_certificate_set_property (GObject      *object,
199                                       guint         prop_id,
200                                       const GValue *value,
201                                       GParamSpec   *pspec)
202 {
203   GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
204
205   switch (prop_id)
206     {
207     case PROP_CERT_CERTIFICATE_PEM:
208       cert->cert_pem = g_value_dup_string (value);
209       break;
210     case PROP_CERT_PRIVATE_KEY_PEM:
211       cert->key_pem = g_value_dup_string (value);
212       break;
213     case PROP_CERT_ISSUER:
214       cert->issuer = g_value_dup_object (value);
215       break;
216     case PROP_CERT_PKCS11_URI:
217       cert->pkcs11_uri = g_value_dup_string (value);
218       break;
219     case PROP_CERT_PRIVATE_KEY_PKCS11_URI:
220       cert->private_key_pkcs11_uri = g_value_dup_string (value);
221       break;
222     case PROP_CERT_CERTIFICATE:
223     case PROP_CERT_PRIVATE_KEY:
224       /* ignore */
225       break;
226     default:
227       g_assert_not_reached ();
228       break;
229     }
230 }
231
232 static void
233 g_test_tls_certificate_finalize (GObject *object)
234 {
235   GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
236
237   g_free (cert->cert_pem);
238   g_free (cert->key_pem);
239   g_free (cert->pkcs11_uri);
240   g_free (cert->private_key_pkcs11_uri);
241   g_clear_object (&cert->issuer);
242
243   G_OBJECT_CLASS (g_test_tls_certificate_parent_class)->finalize (object);
244 }
245
246 static void
247 g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
248 {
249   GObjectClass *gobject_class = G_OBJECT_CLASS (test_class);
250   GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (test_class);
251
252   gobject_class->get_property = g_test_tls_certificate_get_property;
253   gobject_class->set_property = g_test_tls_certificate_set_property;
254   gobject_class->finalize = g_test_tls_certificate_finalize;
255
256   certificate_class->verify = g_test_tls_certificate_verify;
257
258   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate");
259   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem");
260   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY, "private-key");
261   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PEM, "private-key-pem");
262   g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer");
263   g_object_class_override_property (gobject_class, PROP_CERT_PKCS11_URI, "pkcs11-uri");
264   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PKCS11_URI, "private-key-pkcs11-uri");
265   g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_BEFORE, "not-valid-before");
266   g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_AFTER, "not-valid-after");
267   g_object_class_override_property (gobject_class, PROP_CERT_SUBJECT_NAME, "subject-name");
268   g_object_class_override_property (gobject_class, PROP_CERT_ISSUER_NAME, "issuer-name");
269   g_object_class_override_property (gobject_class, PROP_CERT_DNS_NAMES, "dns-names");
270   g_object_class_override_property (gobject_class, PROP_CERT_IP_ADDRESSES, "ip-addresses");
271 }
272
273 static void
274 g_test_tls_certificate_init (GTestTlsCertificate *certificate)
275 {
276 }
277
278 static gboolean
279 g_test_tls_certificate_initable_init (GInitable       *initable,
280                                        GCancellable    *cancellable,
281                                        GError         **error)
282 {
283   return TRUE;
284 }
285
286 static void
287 g_test_tls_certificate_initable_iface_init (GInitableIface  *iface)
288 {
289   iface->init = g_test_tls_certificate_initable_init;
290 }
291
292 /* Dummy connection type; since GTlsClientConnection and
293  * GTlsServerConnection are just interfaces, we can implement them
294  * both on a single object.
295  */
296
297 typedef struct _GTestTlsConnection      GTestTlsConnection;
298 typedef struct _GTestTlsConnectionClass GTestTlsConnectionClass;
299
300 struct _GTestTlsConnection {
301   GTlsConnection parent_instance;
302 };
303
304 struct _GTestTlsConnectionClass {
305   GTlsConnectionClass parent_class;
306 };
307
308 enum
309 {
310   PROP_CONN_BASE_IO_STREAM = 1,
311   PROP_CONN_BASE_SOCKET,
312   PROP_CONN_USE_SYSTEM_CERTDB,
313   PROP_CONN_REQUIRE_CLOSE_NOTIFY,
314   PROP_CONN_REHANDSHAKE_MODE,
315   PROP_CONN_CERTIFICATE,
316   PROP_CONN_PEER_CERTIFICATE,
317   PROP_CONN_PEER_CERTIFICATE_ERRORS,
318   PROP_CONN_VALIDATION_FLAGS,
319   PROP_CONN_SERVER_IDENTITY,
320   PROP_CONN_USE_SSL3,
321   PROP_CONN_ACCEPTED_CAS,
322   PROP_CONN_AUTHENTICATION_MODE
323 };
324
325 static void g_test_tls_connection_initable_iface_init (GInitableIface *iface);
326
327 #define g_test_tls_connection_get_type _g_test_tls_connection_get_type
328 G_DEFINE_TYPE_WITH_CODE (GTestTlsConnection, g_test_tls_connection, G_TYPE_TLS_CONNECTION,
329                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION, NULL)
330                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION, NULL)
331                          G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED, NULL)
332                          G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION, NULL)
333                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
334                                                 g_test_tls_connection_initable_iface_init))
335
336 static void
337 g_test_tls_connection_get_property (GObject    *object,
338                                      guint       prop_id,
339                                      GValue     *value,
340                                      GParamSpec *pspec)
341 {
342 }
343
344 static void
345 g_test_tls_connection_set_property (GObject      *object,
346                                      guint         prop_id,
347                                      const GValue *value,
348                                      GParamSpec   *pspec)
349 {
350 }
351
352 static gboolean
353 g_test_tls_connection_close (GIOStream     *stream,
354                               GCancellable  *cancellable,
355                               GError       **error)
356 {
357   return TRUE;
358 }
359
360 static void
361 g_test_tls_connection_class_init (GTestTlsConnectionClass *connection_class)
362 {
363   GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class);
364   GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (connection_class);
365
366   gobject_class->get_property = g_test_tls_connection_get_property;
367   gobject_class->set_property = g_test_tls_connection_set_property;
368
369   /* Need to override this because when initable_init fails it will
370    * dispose the connection, which will close it, which would
371    * otherwise try to close its input/output streams, which don't
372    * exist.
373    */
374   io_stream_class->close_fn = g_test_tls_connection_close;
375
376   g_object_class_override_property (gobject_class, PROP_CONN_BASE_IO_STREAM, "base-io-stream");
377   g_object_class_override_property (gobject_class, PROP_CONN_BASE_SOCKET, "base-socket");
378   g_object_class_override_property (gobject_class, PROP_CONN_USE_SYSTEM_CERTDB, "use-system-certdb");
379   g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
380   g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
381   g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate");
382   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate");
383   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
384   g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags");
385   g_object_class_override_property (gobject_class, PROP_CONN_SERVER_IDENTITY, "server-identity");
386   g_object_class_override_property (gobject_class, PROP_CONN_USE_SSL3, "use-ssl3");
387   g_object_class_override_property (gobject_class, PROP_CONN_ACCEPTED_CAS, "accepted-cas");
388   g_object_class_override_property (gobject_class, PROP_CONN_AUTHENTICATION_MODE, "authentication-mode");
389 }
390
391 static void
392 g_test_tls_connection_init (GTestTlsConnection *connection)
393 {
394 }
395
396 static gboolean
397 g_test_tls_connection_initable_init (GInitable       *initable,
398                                       GCancellable    *cancellable,
399                                       GError         **error)
400 {
401   g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
402                        "TLS Connection support is not available");
403   return FALSE;
404 }
405
406 static void
407 g_test_tls_connection_initable_iface_init (GInitableIface  *iface)
408 {
409   iface->init = g_test_tls_connection_initable_init;
410 }
411
412 /* Test database type */
413
414 typedef struct _GTestTlsDatabase      GTestTlsDatabase;
415 typedef struct _GTestTlsDatabaseClass GTestTlsDatabaseClass;
416
417 struct _GTestTlsDatabase {
418   GTlsDatabase parent_instance;
419   gchar *anchors;
420 };
421
422 struct _GTestTlsDatabaseClass {
423   GTlsDatabaseClass parent_class;
424 };
425
426 enum
427 {
428   PROP_DATABASE_ANCHORS = 1,
429 };
430
431 static void g_test_tls_database_initable_iface_init (GInitableIface *iface);
432 static void g_test_tls_file_database_file_database_interface_init (GInitableIface *iface);
433
434 #define g_test_tls_database_get_type _g_test_tls_database_get_type
435 G_DEFINE_TYPE_WITH_CODE (GTestTlsDatabase, g_test_tls_database, G_TYPE_TLS_DATABASE,
436                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
437                                                 g_test_tls_database_initable_iface_init);
438                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
439                                                 g_test_tls_file_database_file_database_interface_init))
440
441 static void
442 g_test_tls_database_get_property (GObject    *object,
443                                   guint       prop_id,
444                                   GValue     *value,
445                                   GParamSpec *pspec)
446 {
447   GTestTlsDatabase *db = (GTestTlsDatabase *) object;
448
449   switch (prop_id)
450     {
451     case PROP_DATABASE_ANCHORS:
452       g_value_set_string (value, db->anchors);
453       break;
454     default:
455       g_assert_not_reached ();
456       break;
457     }
458 }
459
460 static void
461 g_test_tls_database_set_property (GObject      *object,
462                                   guint         prop_id,
463                                   const GValue *value,
464                                   GParamSpec   *pspec)
465 {
466   GTestTlsDatabase *db = (GTestTlsDatabase *) object;
467
468   switch (prop_id)
469     {
470     case PROP_DATABASE_ANCHORS:
471       g_free (db->anchors);
472       db->anchors = g_value_dup_string (value);
473       break;
474     default:
475       g_assert_not_reached ();
476       break;
477     }
478 }
479
480 static void
481 g_test_tls_database_finalize (GObject *object)
482 {
483   GTestTlsDatabase *db = (GTestTlsDatabase *) object;
484
485   g_free (db->anchors);
486
487   G_OBJECT_CLASS (g_test_tls_database_parent_class)->finalize (object);
488 }
489
490 static void
491 g_test_tls_database_class_init (GTestTlsDatabaseClass *test_class)
492 {
493   GObjectClass *gobject_class = G_OBJECT_CLASS (test_class);
494
495   gobject_class->get_property = g_test_tls_database_get_property;
496   gobject_class->set_property = g_test_tls_database_set_property;
497   gobject_class->finalize = g_test_tls_database_finalize;
498
499   g_object_class_override_property (gobject_class, PROP_DATABASE_ANCHORS, "anchors");
500 }
501
502 static void
503 g_test_tls_database_init (GTestTlsDatabase *database)
504 {
505 }
506
507 static gboolean
508 g_test_tls_database_initable_init (GInitable       *initable,
509                                    GCancellable    *cancellable,
510                                    GError         **error)
511 {
512   return TRUE;
513 }
514
515 static void
516 g_test_tls_file_database_file_database_interface_init (GInitableIface *iface)
517 {
518 }
519
520 static void
521 g_test_tls_database_initable_iface_init (GInitableIface  *iface)
522 {
523   iface->init = g_test_tls_database_initable_init;
524 }