+static GTlsCertificateFlags
+g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
+ GSocketConnectable *identity,
+ GTlsCertificate *trusted_ca)
+{
+ GTlsCertificateGnutls *cert_gnutls;
+ int status;
+ guint gnutls_flags, num_certs, i, num_cas;
+ gnutls_x509_crt_t *chain, ca;
+ GTlsCertificateFlags gtls_flags;
+
+ cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (cert);
+ for (num_certs = 0; cert_gnutls; cert_gnutls = cert_gnutls->priv->issuer)
+ num_certs++;
+ chain = g_new (gnutls_x509_crt_t, num_certs);
+ cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (cert);
+ for (i = 0; cert_gnutls; cert_gnutls = cert_gnutls->priv->issuer, i++)
+ chain[i] = cert_gnutls->priv->cert;
+
+ if (trusted_ca)
+ {
+ cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (trusted_ca);
+ ca = cert_gnutls->priv->cert;
+ num_cas = 1;
+ }
+ else
+ {
+ ca = NULL;
+ num_cas = 0;
+ }
+
+ status = gnutls_x509_crt_list_verify (chain, num_certs,
+ &ca, num_cas,
+ NULL, 0,
+ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
+ &gnutls_flags);
+ g_free (chain);
+
+ if (status != 0)
+ return G_TLS_CERTIFICATE_GENERIC_ERROR;
+
+ gtls_flags = g_tls_certificate_gnutls_convert_flags (gnutls_flags);
+
+ if (identity)
+ gtls_flags |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (cert), identity);
+
+ return gtls_flags;
+}
+
+static void
+g_tls_certificate_gnutls_class_init (GTlsCertificateGnutlsClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GTlsCertificateGnutlsPrivate));
+
+ gobject_class->get_property = g_tls_certificate_gnutls_get_property;
+ gobject_class->set_property = g_tls_certificate_gnutls_set_property;
+ gobject_class->finalize = g_tls_certificate_gnutls_finalize;
+
+ certificate_class->verify = g_tls_certificate_gnutls_verify;
+
+ g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
+ g_object_class_override_property (gobject_class, PROP_CERTIFICATE_PEM, "certificate-pem");
+ g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY, "private-key");
+ g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY_PEM, "private-key-pem");
+ g_object_class_override_property (gobject_class, PROP_ISSUER, "issuer");
+}
+
+static void
+g_tls_certificate_gnutls_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = g_tls_certificate_gnutls_initable_init;
+}
+