(root)/
glib-2.79.0/
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  }