Upgrade to 2.60.1 46/202846/2
authorSeonah Moon <seonah1.moon@samsung.com>
Fri, 5 Apr 2019 04:52:27 +0000 (13:52 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Fri, 5 Apr 2019 05:56:10 +0000 (14:56 +0900)
Change-Id: Id795b06ea4db9ea7e927dbe3a1bf20f17760ab8f

1  2 
COPYING
packaging/glib-networking.spec
tls/gnutls/gtlsbackend-gnutls.c
tls/gnutls/gtlscertificate-gnutls.c
tls/gnutls/gtlsconnection-gnutls.c
tls/gnutls/gtlsdatabase-gnutls.c
tls/gnutls/gtlsfiledatabase-gnutls.c

diff --cc COPYING
Simple merge
index 8490165,0000000..849c7fe
mode 100755,000000..100755
--- /dev/null
@@@ -1,82 -1,0 +1,82 @@@
- Version:        2.50.0
 +%bcond_with libproxy
 +Name:           glib-networking
- Source:         http://download.gnome.org/sources/glib-networking/2.50/%{name}-%{version}.tar.xz
++Version:        2.60.1
 +Release:        0
 +License:        LGPL-2.1+
 +Summary:        Network-related GIO modules for glib
 +Group:          System/Libraries
++Source:         http://download.gnome.org/sources/glib-networking/2.60/%{name}-%{version}.tar.xz
 +Source99:       baselibs.conf
 +Source1001:     glib-networking.manifest
 +Url:            http://www.gnome.org
 +BuildRequires:  intltool
 +BuildRequires:  which
 +BuildRequires:  libgcrypt-devel
 +BuildRequires:  pkgconfig(dbus-1)
 +BuildRequires:  pkgconfig(gio-2.0) >= 2.46.0
 +BuildRequires:  pkgconfig(gnutls) >= 3.0
 +BuildRequires:  pkgconfig(dlog)
 +BuildRequires:  pkgconfig(libtzplatform-config)
 +BuildRequires:  ca-certificates-devel
 +Requires: ca-certificates
 +%if %{with libproxy}
 +BuildRequires:  pkgconfig(libproxy-1.0)
 +%endif
 +
 +%description
 +This package contains network-related GIO modules for glib.
 +
 +Currently, there is only a proxy module based on libproxy.
 +
 +%lang_package
 +
 +%prep
 +%setup -q
 +cp %{SOURCE1001} .
 +
 +%build
 +export CFLAGS='-Wformat-nonliteral -fstack-protector-strong -Wl,-z,relro -D_FORTIFY_SOURCE=2 -fPIE -pie'
 +%autogen \
 +    --disable-static \
 +%if %{with libproxy}
 +    --with-libproxy  \
 +%endif
 +    --enable-tizen-dlog \
 +%if 0
 +    --enable-tizen-gnutls-debug \
 +%endif
 +%if "{tizen_profile_name}" == "tv"
 +    --enable-tizen-multiple-certificate=yes \
 +    --enable-tizen-tv-update-default-priority \
 +    --enable-tizen-performance-test-log \
 +%endif
 +%if "{tizen_profile_name}" == "tv"
 +    --with-ca-certificates=%{TZ_SYS_RO_CA_CERTS} \
 +%else
 +    --with-ca-certificates=%{TZ_SYS_RO_CA_BUNDLE} \
 +%endif
 +
 +%__make %{?_smp_mflags} V=1
 +
 +%install
 +%if "{tizen_profile_name}" == "tv"
 +rm -rf %{buildroot}
 +mkdir -p %{buildroot}%{TZ_SYS_SHARE}/ca-certificates/
 +cp wss.pem %{buildroot}%{TZ_SYS_SHARE}/ca-certificates/
 +%endif
 +%make_install
 +%find_lang %{name}
 +
 +%files
 +%manifest %{name}.manifest
 +%defattr(-, root, root)
 +%license COPYING
 +%{_libdir}/gio/modules/libgiognutls.so
 +%if "{tizen_profile_name}" == "tv"
 +%{TZ_SYS_SHARE}/ca-certificates/wss.pem
 +%endif
 +%if %{with libproxy}
 +%{_libdir}/gio/modules/libgiolibproxy.so
 +%{_libexecdir}/glib-pacrunner
 +%{_datadir}/dbus-1/services/org.gtk.GLib.PACRunner.service
 +%endif
  #include "gtlsfiledatabase-gnutls.h"
  #include "gtlsserverconnection-gnutls.h"
  
- struct _GTlsBackendGnutlsPrivate
 +#include "TIZEN.h"
 +
+ struct _GTlsBackendGnutls
  {
+   GObject parent_instance;
    GMutex mutex;
    GTlsDatabase *default_database;
  };
index 84b6ce0,ff18c46..62a774b
mode 100755,100644..100755
  
  #include "gtlscertificate-gnutls.h"
  #include <glib/gi18n-lib.h>
 +#include "TIZEN.h"
  
- static void     g_tls_certificate_gnutls_initable_iface_init (GInitableIface  *iface);
- G_DEFINE_TYPE_WITH_CODE (GTlsCertificateGnutls, g_tls_certificate_gnutls, G_TYPE_TLS_CERTIFICATE,
-                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                               g_tls_certificate_gnutls_initable_iface_init);)
  enum
  {
    PROP_0,
@@@ -284,14 -275,7 +286,10 @@@ correct_time_func(time_t *t
  static void
  g_tls_certificate_gnutls_init (GTlsCertificateGnutls *gnutls)
  {
-   gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls,
-                                             G_TYPE_TLS_CERTIFICATE_GNUTLS,
-                                             GTlsCertificateGnutlsPrivate);
-   gnutls_x509_crt_init (&gnutls->priv->cert);
+   gnutls_x509_crt_init (&gnutls->cert);
 +#if ENABLE(TIZEN_TV_ADJUST_TIME)
 +  gnutls_global_set_time_function(correct_time_func);
 +#endif
  }
  
  static gboolean
index 8e52cfb,27bbbcd..729c66c
mode 100755,100644..100755
  #endif
  
  #include <glib/gi18n-lib.h>
+ #include <glib/gprintf.h>
+ /*
+  * GTlsConnectionGnutls is the base abstract implementation of TLS and DTLS
+  * support, for both the client and server side of a connection. The choice
+  * between TLS and DTLS is made by setting the base-io-stream or
+  * base-socket properties — exactly one of them must be set at
+  * construction time.
+  *
+  * Client and server specific code is in the GTlsClientConnectionGnutls and
+  * GTlsServerConnectionGnutls concrete subclasses, although the line about where
+  * code is put is a little blurry, and there are various places in
+  * GTlsConnectionGnutls which check G_IS_TLS_CLIENT_CONNECTION(self) to switch
+  * to a client-only code path.
+  *
+  * This abstract class implements a lot of interfaces:
+  *  • Derived from GTlsConnection (itself from GIOStream), for TLS and streaming
+  *    communications.
+  *  • Implements GDtlsConnection and GDatagramBased, for DTLS and datagram
+  *    communications.
+  *  • Implements GInitable for failable GnuTLS initialisation.
+  *
+  * The GTlsClientConnectionGnutls and GTlsServerConnectionGnutls subclasses are
+  * both derived from GTlsConnectionGnutls (and hence GIOStream), and both
+  * implement the relevant TLS and DTLS interfaces:
+  *  • GTlsClientConnection
+  *  • GDtlsClientConnection
+  *  • GTlsServerConnection
+  *  • GDtlsServerConnection
+  */
  
 +#include "TIZEN.h"
 +
 +#if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
 +#include <sys/prctl.h>
 +#ifndef PR_TASK_PERF_USER_TRACE
 +#define PR_TASK_PERF_USER_TRACE 666
 +#endif
 +#define HWCLOCK_LOG(s)        {const char *str=s; prctl(PR_TASK_PERF_USER_TRACE, str, strlen(str));}
 +#endif
 +
  static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
-                                                 const void             *buf,
-                                                 size_t                  buflen);
+                                                   const void             *buf,
+                                                   size_t                  buflen);
+ static ssize_t g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_data,
+                                                       const giovec_t         *iov,
+                                                       int                     iovcnt);
  static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
-                                                 void                   *buf,
-                                                 size_t                  buflen);
+                                                   void                   *buf,
+                                                   size_t                  buflen);
+ static int     g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
+                                                           unsigned int           ms);
  
  static void     g_tls_connection_gnutls_initable_iface_init (GInitableIface  *iface);
  static gboolean g_tls_connection_gnutls_initable_init       (GInitable       *initable,
@@@ -223,11 -277,10 +287,14 @@@ g_tls_connection_gnutls_init (GTlsConne
  /* First field is "fallback", second is "allow unsafe rehandshaking" */
  static gnutls_priority_t priorities[2][2];
  
- #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT:%LATEST_RECORD_VERSION"
 +#if ENABLE(TIZEN_TV_UPDATE_DEFAULT_PRIORITY)
 +#define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT:!VERS-SSL3.0:%LATEST_RECORD_VERSION"
 +#else
+ /* TODO: Get rid of this in favor of gnutls_set_default_priority_append()
+  * when upgrading to GnuTLS 3.6.3.
+  */
+ #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT"
 +#endif
  
  static void
  g_tls_connection_gnutls_init_priorities (void)
@@@ -355,48 -440,52 +454,53 @@@ static voi
  g_tls_connection_gnutls_finalize (GObject *object)
  {
    GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
+   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
  
-   g_clear_object (&gnutls->priv->base_io_stream);
+   g_clear_object (&priv->base_io_stream);
+   g_clear_object (&priv->base_socket);
  
-   g_clear_object (&gnutls->priv->tls_istream);
-   g_clear_object (&gnutls->priv->tls_ostream);
+   g_clear_object (&priv->tls_istream);
+   g_clear_object (&priv->tls_ostream);
  
-   if (gnutls->priv->session)
-     gnutls_deinit (gnutls->priv->session);
-   if (gnutls->priv->creds)
-     gnutls_certificate_free_credentials (gnutls->priv->creds);
+   if (priv->session)
+     gnutls_deinit (priv->session);
+   if (priv->creds)
+     gnutls_certificate_free_credentials (priv->creds);
  
-   g_clear_object (&gnutls->priv->database);
-   g_clear_object (&gnutls->priv->certificate);
- #if ENABLE(TIZEN_EXT)
-   if (gnutls->priv->peer_certificate)
- #endif
-         g_clear_object (&gnutls->priv->peer_certificate);
-   g_clear_object (&gnutls->priv->peer_certificate_tmp);
+   g_clear_object (&priv->database);
+   g_clear_object (&priv->certificate);
+   g_clear_object (&priv->peer_certificate);
+   g_mutex_clear (&priv->verify_certificate_mutex);
+   g_cond_clear (&priv->verify_certificate_condition);
  
-   g_clear_pointer (&gnutls->priv->app_data_buf, g_byte_array_unref);
 +
- #ifdef HAVE_PKCS11
-   p11_kit_pin_unregister_callback (gnutls->priv->interaction_id,
-                                    on_pin_prompt_callback, gnutls);
+   g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
+   g_free (priv->interaction_id);
+   g_clear_object (&priv->interaction);
+ #if GLIB_CHECK_VERSION(2, 60, 0)
+   g_clear_pointer (&priv->advertised_protocols, g_strfreev);
+   g_clear_pointer (&priv->negotiated_protocol, g_free);
  #endif
-   g_free (gnutls->priv->interaction_id);
-   g_clear_object (&gnutls->priv->interaction);
  
-   g_clear_error (&gnutls->priv->handshake_error);
-   g_clear_error (&gnutls->priv->read_error);
-   g_clear_error (&gnutls->priv->write_error);
+   g_clear_error (&priv->handshake_error);
+   g_clear_error (&priv->read_error);
+   g_clear_error (&priv->write_error);
  
-   /* This must always be NULL at this, as it holds a referehce to @gnutls as
+   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
+   /* This must always be NULL here, as it holds a reference to @gnutls as
     * its source object. However, we clear it anyway just in case this changes
     * in future. */
-   g_clear_object (&gnutls->priv->implicit_handshake);
+   g_clear_object (&priv->implicit_handshake);
  
-   g_clear_object (&gnutls->priv->read_cancellable);
-   g_clear_object (&gnutls->priv->write_cancellable);
+   g_clear_object (&priv->read_cancellable);
+   g_clear_object (&priv->write_cancellable);
  
-   g_clear_object (&gnutls->priv->waiting_for_op);
-   g_mutex_clear (&gnutls->priv->op_mutex);
+   g_clear_object (&priv->waiting_for_op);
+   g_mutex_clear (&priv->op_mutex);
  
    G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
  }
@@@ -1329,45 -2080,58 +2100,66 @@@ handshake_thread (GTask        *task
      }
  }
  
- static gboolean
- accept_peer_certificate (GTlsConnectionGnutls *gnutls,
-                        GTlsCertificate      *peer_certificate,
-                        GTlsCertificateFlags  peer_certificate_errors)
+ static void
+ begin_handshake (GTlsConnectionGnutls *gnutls)
  {
-   gboolean accepted = FALSE;
+ #if GLIB_CHECK_VERSION(2, 60, 0)
+   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
  
-   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
 +#if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
 +  HWCLOCK_LOG("[BGN] gnutls_verify_peer");
 +#endif
 +
+   if (priv->advertised_protocols)
      {
-       GTlsCertificateFlags validation_flags =
-       g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
-       if ((peer_certificate_errors & validation_flags) == 0)
-       accepted = TRUE;
-     }
+       gnutls_datum_t *protocols;
+       int n_protos, i;
  
-   if (!accepted)
-     {
-       accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
-                                                          peer_certificate,
-                                                          peer_certificate_errors);
+       n_protos = g_strv_length (priv->advertised_protocols);
+       protocols = g_new (gnutls_datum_t, n_protos);
+       for (i = 0; priv->advertised_protocols[i]; i++)
+         {
+           protocols[i].size = strlen (priv->advertised_protocols[i]);
+           protocols[i].data = g_memdup (priv->advertised_protocols[i], protocols[i].size);
+         }
+       gnutls_alpn_set_protocols (priv->session, protocols, n_protos, 0);
+       g_free (protocols);
      }
+ #endif
  
-   return accepted;
 +#if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
 +  HWCLOCK_LOG("[END] gnutls_verify_peer");
 +#endif
 +
+   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
  }
  
+ #if GLIB_CHECK_VERSION(2, 60, 0)
  static void
begin_handshake (GTlsConnectionGnutls *gnutls)
update_negotiated_protocol (GTlsConnectionGnutls *gnutls)
  {
-   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
+   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+   gchar *orig_negotiated_protocol;
+   gnutls_datum_t protocol;
+   /*
+    * Preserve the prior negotiated protocol before clearing it
+    */
+   orig_negotiated_protocol = g_steal_pointer (&priv->negotiated_protocol);
+   if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 && protocol.size > 0)
+     priv->negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
+   /*
+    * Notify only if the negotiated protocol changed
+    */
+   if (g_strcmp0 (orig_negotiated_protocol, priv->negotiated_protocol) != 0)
+     g_object_notify (G_OBJECT (gnutls), "negotiated-protocol");
+   g_free (orig_negotiated_protocol);
  }
+ #endif
  
  static gboolean
  finish_handshake (GTlsConnectionGnutls  *gnutls,
index bc854d3,6ab18d9..19996d8
mode 100755,100644..100755
  
  #include "gtlscertificate-gnutls.h"
  
- static void g_tls_file_database_gnutls_file_database_interface_init (GTlsFileDatabaseInterface *iface);
- static void g_tls_file_database_gnutls_initable_interface_init (GInitableIface *iface);
- G_DEFINE_TYPE_WITH_CODE (GTlsFileDatabaseGnutls, g_tls_file_database_gnutls, G_TYPE_TLS_DATABASE_GNUTLS,
-                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
-                                                 g_tls_file_database_gnutls_file_database_interface_init);
-                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                                 g_tls_file_database_gnutls_initable_interface_init);
-                        );
 +#include <TIZEN.h>
 +
 +#if ENABLE(TIZEN_TV_MULTIPLE_CERTIFICATE)
 +#include <dirent.h>
 +#include <stdio.h>
 +#include <sys/stat.h>
 +#endif
 +
  enum
  {
    PROP_0,
    PROP_ANCHORS,
  };
  
- struct _GTlsFileDatabaseGnutlsPrivate
+ struct _GTlsFileDatabaseGnutls
  {
+   GTlsDatabaseGnutls parent_instance;
    /* read-only after construct */
    gchar *anchor_filename;
-   gnutls_x509_trust_list_t trust_list;
-   /* protected by mutex */
-   GMutex mutex;
-   /*
-    * These are hash tables of GBytes -> GPtrArray<GBytes>. The values of
-    * the ptr array are full DER encoded certificate values. The keys are byte
-    * arrays containing either subject DNs, issuer DNs, or full DER encoded certs
-    */
-   GHashTable *subjects;
-   GHashTable *issuers;
-   /*
-    * This is a table of GBytes -> GBytes. The values and keys are
-    * DER encoded certificate values.
-    */
-   GHashTable *complete;
-   /*
-    * This is a table of gchar * -> GPtrArray<GBytes>. The values of
-    * the ptr array are full DER encoded certificate values. The keys are the
-    * string handles. This array is populated on demand.
-    */
-   GHashTable *handles;
  };
  
- static GHashTable *
- bytes_multi_table_new (void)
- {
-   return g_hash_table_new_full (g_bytes_hash, g_bytes_equal,
-                                 (GDestroyNotify)g_bytes_unref,
-                                 (GDestroyNotify)g_ptr_array_unref);
- }
- static void
- bytes_multi_table_insert (GHashTable *table,
-                           GBytes     *key,
-                           GBytes     *value)
- {
-   GPtrArray *multi;
-   multi = g_hash_table_lookup (table, key);
-   if (multi == NULL)
-     {
-       multi = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
-       g_hash_table_insert (table, g_bytes_ref (key), multi);
-     }
-   g_ptr_array_add (multi, g_bytes_ref (value));
- }
- static GBytes *
- bytes_multi_table_lookup_ref_one (GHashTable *table,
-                                   GBytes     *key)
- {
-   GPtrArray *multi;
-   multi = g_hash_table_lookup (table, key);
-   if (multi == NULL)
-     return NULL;
-   g_assert (multi->len > 0);
-   return g_bytes_ref (multi->pdata[0]);
- }
- static GList *
- bytes_multi_table_lookup_ref_all (GHashTable *table,
-                                   GBytes     *key)
- {
-   GPtrArray *multi;
-   GList *list = NULL;
-   guint i;
-   multi = g_hash_table_lookup (table, key);
-   if (multi == NULL)
-     return NULL;
-   for (i = 0; i < multi->len; i++)
-     list = g_list_prepend (list, g_bytes_ref (multi->pdata[i]));
-   return g_list_reverse (list);
- }
- static gchar *
- create_handle_for_certificate (const gchar *filename,
-                                GBytes      *der)
- {
-   gchar *bookmark;
-   gchar *uri_part;
-   gchar *uri;
-   /*
-    * Here we create a URI that looks like:
-    * file:///etc/ssl/certs/ca-certificates.crt#11b2641821252596420e468c275771f5e51022c121a17bd7a89a2f37b6336c8f
-    */
-   uri_part = g_filename_to_uri (filename, NULL, NULL);
-   if (!uri_part)
-     return NULL;
-   bookmark = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, der);
-   uri = g_strconcat (uri_part, "#", bookmark, NULL);
-   g_free (bookmark);
-   g_free (uri_part);
-   return uri;
- }
- static GHashTable *
- create_handles_array_unlocked (const gchar *filename,
-                                GHashTable  *complete)
- {
-   GHashTable *handles;
-   GHashTableIter iter;
-   GBytes *der;
-   gchar *handle;
-   handles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
-                                    (GDestroyNotify)g_bytes_unref);
-   g_hash_table_iter_init (&iter, complete);
-   while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&der))
-     {
-       handle = create_handle_for_certificate (filename, der);
-       if (handle != NULL)
-         g_hash_table_insert (handles, handle, g_bytes_ref (der));
-     }
-   return handles;
- }
- static gboolean
- load_anchor_file (const gchar  *filename,
-                   GHashTable   *subjects,
-                   GHashTable   *issuers,
-                   GHashTable   *complete,
-                   GError      **error)
- {
-   GList *list, *l;
-   gnutls_x509_crt_t cert;
-   gnutls_datum_t dn;
-   GBytes *der;
-   GBytes *subject;
-   GBytes *issuer;
-   gint gerr;
-   GError *my_error = NULL;
-   list = g_tls_certificate_list_new_from_file (filename, &my_error);
-   if (my_error)
-     {
-       g_propagate_error (error, my_error);
- #if ENABLE(TIZEN_TV_MULTIPLE_CERTIFICATE)
-       if ((error != NULL) && (*error != my_error))
-         g_clear_error (&my_error);
- #endif
-       return FALSE;
-     }
-   for (l = list; l; l = l->next)
-     {
-       cert = g_tls_certificate_gnutls_get_cert (l->data);
-       gerr = gnutls_x509_crt_get_raw_dn (cert, &dn);
-       if (gerr < 0)
-         {
-           g_warning ("failed to get subject of anchor certificate: %s",
-                      gnutls_strerror (gerr));
-           continue;
-         }
-       subject = g_bytes_new_with_free_func (dn.data, dn.size, gnutls_free, dn.data);
-       gerr = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn);
-       if (gerr < 0)
-         {
-           g_warning ("failed to get subject of anchor certificate: %s",
-                      gnutls_strerror (gerr));
-           continue;
-         }
-       issuer = g_bytes_new_with_free_func (dn.data, dn.size, gnutls_free, dn.data);
-       der = g_tls_certificate_gnutls_get_bytes (l->data);
-       g_return_val_if_fail (der != NULL, FALSE);
-       /* Three different ways of looking up same certificate */
-       bytes_multi_table_insert (subjects, subject, der);
-       bytes_multi_table_insert (issuers, issuer, der);
-       g_hash_table_insert (complete, g_bytes_ref (der),
-                            g_bytes_ref (der));
-       g_bytes_unref (der);
-       g_bytes_unref (subject);
-       g_bytes_unref (issuer);
-       g_object_unref (l->data);
-     }
-   g_list_free (list);
-   return TRUE;
- }
 +#if ENABLE(TIZEN_TV_MULTIPLE_CERTIFICATE)
 +static gboolean
 +traverse_load_anchor_file (const gchar *filename,
 +                           GHashTable  *subjects,
 +                           GHashTable  *issuers,
 +                           GHashTable  *complete,
 +                           GError     **error)
 +{
 +  struct stat buf;
 +  gboolean result = FALSE;
 +  if (!stat(filename, &buf))
 +    {
 +      if (S_ISREG(buf.st_mode))
 +          result = load_anchor_file (filename, subjects, issuers, complete, error);
 +      else if (S_ISDIR(buf.st_mode))
 +        {
 +          DIR *pDir = opendir(filename);
 +          if (pDir != NULL)
 +            {
 +              struct dirent *dp;
 +              char *stFileName;
 +              while ((dp = readdir(pDir)) != NULL)
 +                {
 +                  if (!g_ascii_strcasecmp(dp->d_name, ".") || !g_ascii_strcasecmp(dp->d_name, ".."))
 +                      continue;
 +
 +                  stFileName = g_strconcat (filename, "/", dp->d_name, NULL);
 +                  if (stFileName && !stat(stFileName, &buf) && S_ISREG(buf.st_mode))
 +                      result = load_anchor_file (stFileName, subjects, issuers, complete, error);
 +                  g_free (stFileName);
 +                }
 +              closedir(pDir);
 +            }
 +        }
 +    }
 +  return result;
 +}
 +#endif
+ static void g_tls_file_database_gnutls_file_database_interface_init (GTlsFileDatabaseInterface *iface);
+ G_DEFINE_TYPE_WITH_CODE (GTlsFileDatabaseGnutls, g_tls_file_database_gnutls, G_TYPE_TLS_DATABASE_GNUTLS,
+                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
+                                                 g_tls_file_database_gnutls_file_database_interface_init);
+                          );
  
  static void
  g_tls_file_database_gnutls_finalize (GObject *object)