• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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