1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2011 Collabora Ltd.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "gtesttlsbackend.h"
20
21 #include <glib.h>
22
23 static GType _g_test_tls_certificate_get_type (void);
24 static GType _g_test_tls_connection_get_type (void);
25 static GTlsDatabase * _g_test_tls_backend_get_default_database (GTlsBackend * backend);
26 static GType _g_test_tls_database_get_type (void);
27
28 struct _GTestTlsBackend {
29 GObject parent_instance;
30 };
31
32 static void g_test_tls_backend_iface_init (GTlsBackendInterface *iface);
33
34 #define g_test_tls_backend_get_type _g_test_tls_backend_get_type
35 G_DEFINE_TYPE_WITH_CODE (GTestTlsBackend, g_test_tls_backend, G_TYPE_OBJECT,
36 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_BACKEND,
37 g_test_tls_backend_iface_init)
38 g_io_extension_point_set_required_type (
39 g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME),
40 G_TYPE_TLS_BACKEND);
41 g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME,
42 g_define_type_id,
43 "test",
44 999);)
45
46 static void
g_test_tls_backend_init(GTestTlsBackend * backend)47 g_test_tls_backend_init (GTestTlsBackend *backend)
48 {
49 }
50
51 static void
g_test_tls_backend_class_init(GTestTlsBackendClass * backend_class)52 g_test_tls_backend_class_init (GTestTlsBackendClass *backend_class)
53 {
54 }
55
56 static void
g_test_tls_backend_iface_init(GTlsBackendInterface * iface)57 g_test_tls_backend_iface_init (GTlsBackendInterface *iface)
58 {
59 iface->get_certificate_type = _g_test_tls_certificate_get_type;
60 iface->get_client_connection_type = _g_test_tls_connection_get_type;
61 iface->get_server_connection_type = _g_test_tls_connection_get_type;
62 iface->get_default_database = _g_test_tls_backend_get_default_database;
63 iface->get_file_database_type = _g_test_tls_database_get_type;
64 }
65
66 static GTlsDatabase *
_g_test_tls_backend_get_default_database(GTlsBackend * backend)67 _g_test_tls_backend_get_default_database (GTlsBackend * backend)
68 {
69 static GTlsDatabase *default_db;
70 GError *error = NULL;
71
72 if (!default_db)
73 {
74 default_db = g_initable_new (_g_test_tls_database_get_type (),
75 NULL,
76 &error,
77 NULL);
78 g_assert_no_error (error);
79 }
80
81 return default_db;
82 }
83
84 /* Test certificate type */
85
86 typedef struct _GTestTlsCertificate GTestTlsCertificate;
87 typedef struct _GTestTlsCertificateClass GTestTlsCertificateClass;
88
89 struct _GTestTlsCertificate {
90 GTlsCertificate parent_instance;
91 gchar *key_pem;
92 gchar *cert_pem;
93 GTlsCertificate *issuer;
94 };
95
96 struct _GTestTlsCertificateClass {
97 GTlsCertificateClass parent_class;
98 };
99
100 enum
101 {
102 PROP_CERT_CERTIFICATE = 1,
103 PROP_CERT_CERTIFICATE_PEM,
104 PROP_CERT_PRIVATE_KEY,
105 PROP_CERT_PRIVATE_KEY_PEM,
106 PROP_CERT_ISSUER
107 };
108
109 static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface);
110
111 #define g_test_tls_certificate_get_type _g_test_tls_certificate_get_type
G_DEFINE_TYPE_WITH_CODE(GTestTlsCertificate,g_test_tls_certificate,G_TYPE_TLS_CERTIFICATE,G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,g_test_tls_certificate_initable_iface_init))112 G_DEFINE_TYPE_WITH_CODE (GTestTlsCertificate, g_test_tls_certificate, G_TYPE_TLS_CERTIFICATE,
113 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
114 g_test_tls_certificate_initable_iface_init))
115
116 static GTlsCertificateFlags
117 g_test_tls_certificate_verify (GTlsCertificate *cert,
118 GSocketConnectable *identity,
119 GTlsCertificate *trusted_ca)
120 {
121 /* For now, all of the tests expect the certificate to verify */
122 return 0;
123 }
124
125 static void
g_test_tls_certificate_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)126 g_test_tls_certificate_get_property (GObject *object,
127 guint prop_id,
128 GValue *value,
129 GParamSpec *pspec)
130 {
131 GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
132
133 switch (prop_id)
134 {
135 case PROP_CERT_CERTIFICATE_PEM:
136 g_value_set_string (value, cert->cert_pem);
137 break;
138 case PROP_CERT_PRIVATE_KEY_PEM:
139 g_value_set_string (value, cert->key_pem);
140 break;
141 case PROP_CERT_ISSUER:
142 g_value_set_object (value, cert->issuer);
143 break;
144 default:
145 g_assert_not_reached ();
146 break;
147 }
148 }
149
150 static void
g_test_tls_certificate_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)151 g_test_tls_certificate_set_property (GObject *object,
152 guint prop_id,
153 const GValue *value,
154 GParamSpec *pspec)
155 {
156 GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
157
158 switch (prop_id)
159 {
160 case PROP_CERT_CERTIFICATE_PEM:
161 cert->cert_pem = g_value_dup_string (value);
162 break;
163 case PROP_CERT_PRIVATE_KEY_PEM:
164 cert->key_pem = g_value_dup_string (value);
165 break;
166 case PROP_CERT_ISSUER:
167 cert->issuer = g_value_dup_object (value);
168 break;
169 case PROP_CERT_CERTIFICATE:
170 case PROP_CERT_PRIVATE_KEY:
171 /* ignore */
172 break;
173 default:
174 g_assert_not_reached ();
175 break;
176 }
177 }
178
179 static void
g_test_tls_certificate_finalize(GObject * object)180 g_test_tls_certificate_finalize (GObject *object)
181 {
182 GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
183
184 g_free (cert->cert_pem);
185 g_free (cert->key_pem);
186 g_clear_object (&cert->issuer);
187
188 G_OBJECT_CLASS (g_test_tls_certificate_parent_class)->finalize (object);
189 }
190
191 static void
g_test_tls_certificate_class_init(GTestTlsCertificateClass * test_class)192 g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
193 {
194 GObjectClass *gobject_class = G_OBJECT_CLASS (test_class);
195 GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (test_class);
196
197 gobject_class->get_property = g_test_tls_certificate_get_property;
198 gobject_class->set_property = g_test_tls_certificate_set_property;
199 gobject_class->finalize = g_test_tls_certificate_finalize;
200
201 certificate_class->verify = g_test_tls_certificate_verify;
202
203 g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate");
204 g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem");
205 g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY, "private-key");
206 g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PEM, "private-key-pem");
207 g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer");
208 }
209
210 static void
g_test_tls_certificate_init(GTestTlsCertificate * certificate)211 g_test_tls_certificate_init (GTestTlsCertificate *certificate)
212 {
213 }
214
215 static gboolean
g_test_tls_certificate_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)216 g_test_tls_certificate_initable_init (GInitable *initable,
217 GCancellable *cancellable,
218 GError **error)
219 {
220 return TRUE;
221 }
222
223 static void
g_test_tls_certificate_initable_iface_init(GInitableIface * iface)224 g_test_tls_certificate_initable_iface_init (GInitableIface *iface)
225 {
226 iface->init = g_test_tls_certificate_initable_init;
227 }
228
229 /* Dummy connection type; since GTlsClientConnection and
230 * GTlsServerConnection are just interfaces, we can implement them
231 * both on a single object.
232 */
233
234 typedef struct _GTestTlsConnection GTestTlsConnection;
235 typedef struct _GTestTlsConnectionClass GTestTlsConnectionClass;
236
237 struct _GTestTlsConnection {
238 GTlsConnection parent_instance;
239 };
240
241 struct _GTestTlsConnectionClass {
242 GTlsConnectionClass parent_class;
243 };
244
245 enum
246 {
247 PROP_CONN_BASE_IO_STREAM = 1,
248 PROP_CONN_USE_SYSTEM_CERTDB,
249 PROP_CONN_REQUIRE_CLOSE_NOTIFY,
250 PROP_CONN_REHANDSHAKE_MODE,
251 PROP_CONN_CERTIFICATE,
252 PROP_CONN_PEER_CERTIFICATE,
253 PROP_CONN_PEER_CERTIFICATE_ERRORS,
254 PROP_CONN_VALIDATION_FLAGS,
255 PROP_CONN_SERVER_IDENTITY,
256 PROP_CONN_USE_SSL3,
257 PROP_CONN_ACCEPTED_CAS,
258 PROP_CONN_AUTHENTICATION_MODE
259 };
260
261 static void g_test_tls_connection_initable_iface_init (GInitableIface *iface);
262
263 #define g_test_tls_connection_get_type _g_test_tls_connection_get_type
G_DEFINE_TYPE_WITH_CODE(GTestTlsConnection,g_test_tls_connection,G_TYPE_TLS_CONNECTION,G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION,NULL)G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION,NULL)G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,g_test_tls_connection_initable_iface_init))264 G_DEFINE_TYPE_WITH_CODE (GTestTlsConnection, g_test_tls_connection, G_TYPE_TLS_CONNECTION,
265 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION, NULL)
266 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION, NULL)
267 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
268 g_test_tls_connection_initable_iface_init))
269
270 static void
271 g_test_tls_connection_get_property (GObject *object,
272 guint prop_id,
273 GValue *value,
274 GParamSpec *pspec)
275 {
276 }
277
278 static void
g_test_tls_connection_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)279 g_test_tls_connection_set_property (GObject *object,
280 guint prop_id,
281 const GValue *value,
282 GParamSpec *pspec)
283 {
284 }
285
286 static gboolean
g_test_tls_connection_close(GIOStream * stream,GCancellable * cancellable,GError ** error)287 g_test_tls_connection_close (GIOStream *stream,
288 GCancellable *cancellable,
289 GError **error)
290 {
291 return TRUE;
292 }
293
294 static void
g_test_tls_connection_class_init(GTestTlsConnectionClass * connection_class)295 g_test_tls_connection_class_init (GTestTlsConnectionClass *connection_class)
296 {
297 GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class);
298 GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (connection_class);
299
300 gobject_class->get_property = g_test_tls_connection_get_property;
301 gobject_class->set_property = g_test_tls_connection_set_property;
302
303 /* Need to override this because when initable_init fails it will
304 * dispose the connection, which will close it, which would
305 * otherwise try to close its input/output streams, which don't
306 * exist.
307 */
308 io_stream_class->close_fn = g_test_tls_connection_close;
309
310 g_object_class_override_property (gobject_class, PROP_CONN_BASE_IO_STREAM, "base-io-stream");
311 g_object_class_override_property (gobject_class, PROP_CONN_USE_SYSTEM_CERTDB, "use-system-certdb");
312 g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
313 g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
314 g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate");
315 g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate");
316 g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
317 g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags");
318 g_object_class_override_property (gobject_class, PROP_CONN_SERVER_IDENTITY, "server-identity");
319 g_object_class_override_property (gobject_class, PROP_CONN_USE_SSL3, "use-ssl3");
320 g_object_class_override_property (gobject_class, PROP_CONN_ACCEPTED_CAS, "accepted-cas");
321 g_object_class_override_property (gobject_class, PROP_CONN_AUTHENTICATION_MODE, "authentication-mode");
322 }
323
324 static void
g_test_tls_connection_init(GTestTlsConnection * connection)325 g_test_tls_connection_init (GTestTlsConnection *connection)
326 {
327 }
328
329 static gboolean
g_test_tls_connection_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)330 g_test_tls_connection_initable_init (GInitable *initable,
331 GCancellable *cancellable,
332 GError **error)
333 {
334 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
335 "TLS Connection support is not available");
336 return FALSE;
337 }
338
339 static void
g_test_tls_connection_initable_iface_init(GInitableIface * iface)340 g_test_tls_connection_initable_iface_init (GInitableIface *iface)
341 {
342 iface->init = g_test_tls_connection_initable_init;
343 }
344
345 const gchar *
g_test_tls_connection_get_private_key_pem(GTlsCertificate * cert)346 g_test_tls_connection_get_private_key_pem (GTlsCertificate *cert)
347 {
348 return ((GTestTlsCertificate *)cert)->key_pem;
349 }
350
351 /* Test database type */
352
353 typedef struct _GTestTlsDatabase GTestTlsDatabase;
354 typedef struct _GTestTlsDatabaseClass GTestTlsDatabaseClass;
355
356 struct _GTestTlsDatabase {
357 GTlsDatabase parent_instance;
358 gchar *anchors;
359 };
360
361 struct _GTestTlsDatabaseClass {
362 GTlsDatabaseClass parent_class;
363 };
364
365 enum
366 {
367 PROP_DATABASE_ANCHORS = 1,
368 };
369
370 static void g_test_tls_database_initable_iface_init (GInitableIface *iface);
371 static void g_test_tls_file_database_file_database_interface_init (GInitableIface *iface);
372
373 #define g_test_tls_database_get_type _g_test_tls_database_get_type
G_DEFINE_TYPE_WITH_CODE(GTestTlsDatabase,g_test_tls_database,G_TYPE_TLS_DATABASE,G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,g_test_tls_database_initable_iface_init);G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,g_test_tls_file_database_file_database_interface_init))374 G_DEFINE_TYPE_WITH_CODE (GTestTlsDatabase, g_test_tls_database, G_TYPE_TLS_DATABASE,
375 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
376 g_test_tls_database_initable_iface_init);
377 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
378 g_test_tls_file_database_file_database_interface_init))
379
380 static void
381 g_test_tls_database_get_property (GObject *object,
382 guint prop_id,
383 GValue *value,
384 GParamSpec *pspec)
385 {
386 GTestTlsDatabase *db = (GTestTlsDatabase *) object;
387
388 switch (prop_id)
389 {
390 case PROP_DATABASE_ANCHORS:
391 g_value_set_string (value, db->anchors);
392 break;
393 default:
394 g_assert_not_reached ();
395 break;
396 }
397 }
398
399 static void
g_test_tls_database_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)400 g_test_tls_database_set_property (GObject *object,
401 guint prop_id,
402 const GValue *value,
403 GParamSpec *pspec)
404 {
405 GTestTlsDatabase *db = (GTestTlsDatabase *) object;
406
407 switch (prop_id)
408 {
409 case PROP_DATABASE_ANCHORS:
410 g_free (db->anchors);
411 db->anchors = g_value_dup_string (value);
412 break;
413 default:
414 g_assert_not_reached ();
415 break;
416 }
417 }
418
419 static void
g_test_tls_database_finalize(GObject * object)420 g_test_tls_database_finalize (GObject *object)
421 {
422 GTestTlsDatabase *db = (GTestTlsDatabase *) object;
423
424 g_free (db->anchors);
425
426 G_OBJECT_CLASS (g_test_tls_database_parent_class)->finalize (object);
427 }
428
429 static void
g_test_tls_database_class_init(GTestTlsDatabaseClass * test_class)430 g_test_tls_database_class_init (GTestTlsDatabaseClass *test_class)
431 {
432 GObjectClass *gobject_class = G_OBJECT_CLASS (test_class);
433
434 gobject_class->get_property = g_test_tls_database_get_property;
435 gobject_class->set_property = g_test_tls_database_set_property;
436 gobject_class->finalize = g_test_tls_database_finalize;
437
438 g_object_class_override_property (gobject_class, PROP_DATABASE_ANCHORS, "anchors");
439 }
440
441 static void
g_test_tls_database_init(GTestTlsDatabase * database)442 g_test_tls_database_init (GTestTlsDatabase *database)
443 {
444 }
445
446 static gboolean
g_test_tls_database_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)447 g_test_tls_database_initable_init (GInitable *initable,
448 GCancellable *cancellable,
449 GError **error)
450 {
451 return TRUE;
452 }
453
454 static void
g_test_tls_file_database_file_database_interface_init(GInitableIface * iface)455 g_test_tls_file_database_file_database_interface_init (GInitableIface *iface)
456 {
457 }
458
459 static void
g_test_tls_database_initable_iface_init(GInitableIface * iface)460 g_test_tls_database_initable_iface_init (GInitableIface *iface)
461 {
462 iface->init = g_test_tls_database_initable_init;
463 }
464