Add log messages for debugging
[platform/upstream/glib-networking.git] / tls / openssl / gtlscertificate-openssl.c
index 83e6e28..f3afc3d 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
  * gtlscertificate-openssl.c
  *
 #include "openssl-include.h"
 
 #include "gtlscertificate-openssl.h"
-#include "openssl-util.h"
 #include <glib/gi18n-lib.h>
 
-typedef struct _GTlsCertificateOpensslPrivate
+struct _GTlsCertificateOpenssl
 {
+  GTlsCertificate parent_instance;
+
   X509 *cert;
   EVP_PKEY *key;
 
@@ -42,7 +44,7 @@ typedef struct _GTlsCertificateOpensslPrivate
 
   guint have_cert : 1;
   guint have_key  : 1;
-} GTlsCertificateOpensslPrivate;
+};
 
 enum
 {
@@ -52,13 +54,18 @@ enum
   PROP_CERTIFICATE_PEM,
   PROP_PRIVATE_KEY,
   PROP_PRIVATE_KEY_PEM,
-  PROP_ISSUER
+  PROP_ISSUER,
+  PROP_NOT_VALID_BEFORE,
+  PROP_NOT_VALID_AFTER,
+  PROP_SUBJECT_NAME,
+  PROP_ISSUER_NAME,
+  PROP_DNS_NAMES,
+  PROP_IP_ADDRESSES,
 };
 
 static void     g_tls_certificate_openssl_initable_iface_init (GInitableIface  *iface);
 
 G_DEFINE_TYPE_WITH_CODE (GTlsCertificateOpenssl, g_tls_certificate_openssl, G_TYPE_TLS_CERTIFICATE,
-                         G_ADD_PRIVATE (GTlsCertificateOpenssl)
                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                 g_tls_certificate_openssl_initable_iface_init))
 
@@ -66,22 +73,138 @@ static void
 g_tls_certificate_openssl_finalize (GObject *object)
 {
   GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
-  GTlsCertificateOpensslPrivate *priv;
-
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
 
-  if (priv->cert)
-    X509_free (priv->cert);
-  if (priv->key)
-    EVP_PKEY_free (priv->key);
+  if (openssl->cert)
+    X509_free (openssl->cert);
+  if (openssl->key)
+    EVP_PKEY_free (openssl->key);
 
-  g_clear_object (&priv->issuer);
+  g_clear_object (&openssl->issuer);
 
-  g_clear_error (&priv->construct_error);
+  g_clear_error (&openssl->construct_error);
 
   G_OBJECT_CLASS (g_tls_certificate_openssl_parent_class)->finalize (object);
 }
 
+static GPtrArray *
+get_subject_alt_names (GTlsCertificateOpenssl *cert,
+                       guint                   type)
+{
+  GPtrArray *data = NULL;
+  STACK_OF (GENERAL_NAME) *sans;
+  const guint8 *san = NULL;
+  size_t san_size;
+  guint alt_occurrences;
+  guint i;
+
+  if (type == GEN_IPADD)
+    data = g_ptr_array_new_with_free_func (g_object_unref);
+  else
+    data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
+
+  sans = X509_get_ext_d2i (cert->cert, NID_subject_alt_name, NULL, NULL);
+  if (sans)
+    {
+      alt_occurrences = sk_GENERAL_NAME_num (sans);
+      for (i = 0; i < alt_occurrences; i++)
+        {
+          const GENERAL_NAME *value = sk_GENERAL_NAME_value (sans, i);
+          if (value->type != type)
+            continue;
+
+          if (type == GEN_IPADD)
+            {
+              g_assert (value->type == GEN_IPADD);
+              san = ASN1_STRING_get0_data (value->d.ip);
+              san_size = ASN1_STRING_length (value->d.ip);
+              if (san_size == 4)
+                g_ptr_array_add (data, g_inet_address_new_from_bytes (san, G_SOCKET_FAMILY_IPV4));
+              else if (san_size == 16)
+                g_ptr_array_add (data, g_inet_address_new_from_bytes (san, G_SOCKET_FAMILY_IPV6));
+            }
+          else
+            {
+              g_assert (value->type == GEN_DNS);
+              san = ASN1_STRING_get0_data (value->d.ia5);
+              san_size = ASN1_STRING_length (value->d.ia5);
+              g_ptr_array_add (data, g_bytes_new (san, san_size));
+            }
+          }
+
+      for (i = 0; i < alt_occurrences; i++)
+        GENERAL_NAME_free (sk_GENERAL_NAME_value (sans, i));
+      sk_GENERAL_NAME_free (sans);
+    }
+
+  return data;
+}
+
+static void
+export_privkey_to_der (GTlsCertificateOpenssl  *openssl,
+                       guint8                 **output_data,
+                       long                    *output_size)
+{
+  PKCS8_PRIV_KEY_INFO *pkcs8;
+  BIO *bio = NULL;
+  const guint8 *data;
+
+  if (!openssl->key)
+    goto err;
+
+  pkcs8 = EVP_PKEY2PKCS8 (openssl->key);
+  if (!pkcs8)
+    goto err;
+
+  bio = BIO_new (BIO_s_mem ());
+  if (i2d_PKCS8_PRIV_KEY_INFO_bio (bio, pkcs8) == 0)
+    goto err;
+
+  *output_size = BIO_get_mem_data (bio, (char **)&data);
+  if (*output_size <= 0)
+    goto err;
+
+  *output_data = g_malloc (*output_size);
+  memcpy (*output_data, data, *output_size);
+  goto out;
+
+err:
+  *output_data = NULL;
+  *output_size = 0;
+out:
+  if (bio)
+    BIO_free_all (bio);
+  if (pkcs8)
+    PKCS8_PRIV_KEY_INFO_free (pkcs8);
+}
+
+static char *
+export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
+{
+  int ret;
+  BIO *bio = NULL;
+  const char *data = NULL;
+  char *result = NULL;
+
+  if (!openssl->key)
+    return NULL;
+
+  bio = BIO_new (BIO_s_mem ());
+  ret = PEM_write_bio_PKCS8PrivateKey (bio, openssl->key, NULL, NULL, 0, NULL, NULL);
+  if (ret == 0)
+    goto out;
+
+  ret = BIO_write (bio, "\0", 1);
+  if (ret != 1)
+    goto out;
+
+  BIO_get_mem_data (bio, (char **)&data);
+  result = g_strdup (data);
+
+out:
+  BIO_free_all (bio);
+  return result;
+}
+
 static void
 g_tls_certificate_openssl_get_property (GObject    *object,
                                         guint       prop_id,
@@ -89,20 +212,25 @@ g_tls_certificate_openssl_get_property (GObject    *object,
                                         GParamSpec *pspec)
 {
   GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
-  GTlsCertificateOpensslPrivate *priv;
   GByteArray *certificate;
   guint8 *data;
   BIO *bio;
+  GByteArray *byte_array;
   char *certificate_pem;
-  int size;
+  long size;
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
+  const ASN1_TIME *time_asn1;
+  struct tm time_tm;
+  GDateTime *time;
+  GTimeZone *tz;
+  X509_NAME *name;
+  const char *name_string;
 
   switch (prop_id)
     {
     case PROP_CERTIFICATE:
       /* NOTE: we do the two calls to avoid openssl allocating the buffer for us */
-      size = i2d_X509 (priv->cert, NULL);
+      size = i2d_X509 (openssl->cert, NULL);
       if (size < 0)
         certificate = NULL;
       else
@@ -110,7 +238,7 @@ g_tls_certificate_openssl_get_property (GObject    *object,
           certificate = g_byte_array_sized_new (size);
           certificate->len = size;
           data = certificate->data;
-          size = i2d_X509 (priv->cert, &data);
+          size = i2d_X509 (openssl->cert, &data);
           if (size < 0)
             {
               g_byte_array_free (certificate, TRUE);
@@ -123,7 +251,7 @@ g_tls_certificate_openssl_get_property (GObject    *object,
     case PROP_CERTIFICATE_PEM:
       bio = BIO_new (BIO_s_mem ());
 
-      if (!PEM_write_bio_X509 (bio, priv->cert) || !BIO_write (bio, "\0", 1))
+      if (!PEM_write_bio_X509 (bio, openssl->cert) || !BIO_write (bio, "\0", 1))
         certificate_pem = NULL;
       else
         {
@@ -134,8 +262,67 @@ g_tls_certificate_openssl_get_property (GObject    *object,
         }
       break;
 
+    case PROP_PRIVATE_KEY:
+      export_privkey_to_der (openssl, &data, &size);
+      if (size > 0 && (gint64)size <= G_MAXUINT)
+        {
+          byte_array = g_byte_array_new_take (data, size);
+          g_value_take_boxed (value, byte_array);
+        }
+      break;
+
+    case PROP_PRIVATE_KEY_PEM:
+      g_value_take_string (value, export_privkey_to_pem (openssl));
+      break;
+
     case PROP_ISSUER:
-      g_value_set_object (value, priv->issuer);
+      g_value_set_object (value, openssl->issuer);
+      break;
+
+    case PROP_NOT_VALID_BEFORE:
+      time_asn1 = X509_get0_notBefore (openssl->cert);
+      ASN1_TIME_to_tm (time_asn1, &time_tm);
+      tz = g_time_zone_new_utc ();
+      time = g_date_time_new (tz, time_tm.tm_year + 1900, time_tm.tm_mon + 1, time_tm.tm_mday, time_tm.tm_hour, time_tm.tm_min, time_tm.tm_sec);
+      g_value_take_boxed (value, time);
+      g_time_zone_unref (tz);
+      break;
+
+    case PROP_NOT_VALID_AFTER:
+      time_asn1 = X509_get0_notAfter (openssl->cert);
+      ASN1_TIME_to_tm (time_asn1, &time_tm);
+      tz = g_time_zone_new_utc ();
+      time = g_date_time_new (tz, time_tm.tm_year + 1900, time_tm.tm_mon + 1, time_tm.tm_mday, time_tm.tm_hour, time_tm.tm_min, time_tm.tm_sec);
+      g_value_take_boxed (value, time);
+      g_time_zone_unref (tz);
+      break;
+
+    case PROP_SUBJECT_NAME:
+      bio = BIO_new (BIO_s_mem ());
+      name = X509_get_subject_name (openssl->cert);
+      X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
+      BIO_write (bio, "\0", 1);
+      BIO_get_mem_data (bio, (char **)&name_string);
+      g_value_set_string (value, name_string);
+      BIO_free_all (bio);
+      break;
+
+    case PROP_ISSUER_NAME:
+      bio = BIO_new (BIO_s_mem ());
+      name = X509_get_issuer_name (openssl->cert);
+      X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
+      BIO_write (bio, "\0", 1);
+      BIO_get_mem_data (bio, &name_string);
+      g_value_set_string (value, name_string);
+      BIO_free_all (bio);
+      break;
+
+    case PROP_DNS_NAMES:
+      g_value_take_boxed (value, get_subject_alt_names (openssl, GEN_DNS));
+      break;
+
+    case PROP_IP_ADDRESSES:
+      g_value_take_boxed (value, get_subject_alt_names (openssl, GEN_IPADD));
       break;
 
     default:
@@ -150,13 +337,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
                                        GParamSpec   *pspec)
 {
   GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
-  GTlsCertificateOpensslPrivate *priv;
   GByteArray *bytes;
   guint8 *data;
   BIO *bio;
   const char *string;
-
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
+  char error_buffer[256];
 
   switch (prop_id)
     {
@@ -164,18 +349,19 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       bytes = g_value_get_boxed (value);
       if (!bytes)
         break;
-      g_return_if_fail (priv->have_cert == FALSE);
+      g_return_if_fail (openssl->have_cert == FALSE);
       /* see that we cannot use bytes->data directly since it will move the pointer */
       data = bytes->data;
-      priv->cert = d2i_X509 (NULL, (const unsigned char **)&data, bytes->len);
-      if (priv->cert != NULL)
-        priv->have_cert = TRUE;
-      else if (!priv->construct_error)
+      openssl->cert = d2i_X509 (NULL, (const unsigned char **)&data, bytes->len);
+      if (openssl->cert)
+        openssl->have_cert = TRUE;
+      else if (!openssl->construct_error)
         {
-          priv->construct_error =
+          ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
+          openssl->construct_error =
             g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
                          _("Could not parse DER certificate: %s"),
-                         ERR_error_string (ERR_get_error (), NULL));
+                         error_buffer);
         }
 
       break;
@@ -184,18 +370,19 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       string = g_value_get_string (value);
       if (!string)
         break;
-      g_return_if_fail (priv->have_cert == FALSE);
+      g_return_if_fail (openssl->have_cert == FALSE);
       bio = BIO_new_mem_buf ((gpointer)string, -1);
-      priv->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
+      openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
       BIO_free (bio);
-      if (priv->cert != NULL)
-        priv->have_cert = TRUE;
-      else if (!priv->construct_error)
+      if (openssl->cert)
+        openssl->have_cert = TRUE;
+      else if (!openssl->construct_error)
         {
-          priv->construct_error =
+          ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
+          openssl->construct_error =
             g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
                          _("Could not parse PEM certificate: %s"),
-                         ERR_error_string (ERR_get_error (), NULL));
+                         error_buffer);
         }
       break;
 
@@ -203,18 +390,19 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       bytes = g_value_get_boxed (value);
       if (!bytes)
         break;
-      g_return_if_fail (priv->have_key == FALSE);
+      g_return_if_fail (openssl->have_key == FALSE);
       bio = BIO_new_mem_buf (bytes->data, bytes->len);
-      priv->key = d2i_PrivateKey_bio (bio, NULL);
+      openssl->key = d2i_PrivateKey_bio (bio, NULL);
       BIO_free (bio);
-      if (priv->key != NULL)
-        priv->have_key = TRUE;
-      else if (!priv->construct_error)
+      if (openssl->key)
+        openssl->have_key = TRUE;
+      else if (!openssl->construct_error)
         {
-          priv->construct_error =
+          ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
+          openssl->construct_error =
             g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
                          _("Could not parse DER private key: %s"),
-                         ERR_error_string (ERR_get_error (), NULL));
+                         error_buffer);
         }
       break;
 
@@ -222,23 +410,24 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       string = g_value_get_string (value);
       if (!string)
         break;
-      g_return_if_fail (priv->have_key == FALSE);
+      g_return_if_fail (openssl->have_key == FALSE);
       bio = BIO_new_mem_buf ((gpointer)string, -1);
-      priv->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
+      openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
       BIO_free (bio);
-      if (priv->key != NULL)
-        priv->have_key = TRUE;
-      else if (!priv->construct_error)
+      if (openssl->key)
+        openssl->have_key = TRUE;
+      else if (!openssl->construct_error)
         {
-          priv->construct_error =
+          ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
+          openssl->construct_error =
             g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
                          _("Could not parse PEM private key: %s"),
-                         ERR_error_string (ERR_get_error (), NULL));
+                         error_buffer);
         }
       break;
 
     case PROP_ISSUER:
-      priv->issuer = g_value_dup_object (value);
+      openssl->issuer = g_value_dup_object (value);
       break;
 
     default:
@@ -257,17 +446,14 @@ g_tls_certificate_openssl_initable_init (GInitable       *initable,
                                          GError         **error)
 {
   GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (initable);
-  GTlsCertificateOpensslPrivate *priv;
-
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
 
-  if (priv->construct_error)
+  if (openssl->construct_error)
     {
-      g_propagate_error (error, priv->construct_error);
-      priv->construct_error = NULL;
+      g_propagate_error (error, openssl->construct_error);
+      openssl->construct_error = NULL;
       return FALSE;
     }
-  else if (!priv->have_cert)
+  else if (!openssl->have_cert)
     {
       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
                            _("No certificate data provided"));
@@ -283,22 +469,16 @@ g_tls_certificate_openssl_verify (GTlsCertificate     *cert,
                                   GTlsCertificate     *trusted_ca)
 {
   GTlsCertificateOpenssl *cert_openssl;
-  GTlsCertificateOpensslPrivate *priv;
   GTlsCertificateFlags gtls_flags;
   X509 *x;
   STACK_OF(X509) *untrusted;
-  gint i;
 
   cert_openssl = G_TLS_CERTIFICATE_OPENSSL (cert);
-  priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
-  x = priv->cert;
+  x = cert_openssl->cert;
 
   untrusted = sk_X509_new_null ();
-  for (; cert_openssl; cert_openssl = priv->issuer)
-    {
-      priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
-      sk_X509_push (untrusted, priv->cert);
-    }
+  for (; cert_openssl; cert_openssl = cert_openssl->issuer)
+    sk_X509_push (untrusted, cert_openssl->cert);
 
   gtls_flags = 0;
 
@@ -321,11 +501,8 @@ g_tls_certificate_openssl_verify (GTlsCertificate     *cert,
 
       trusted = sk_X509_new_null ();
       cert_openssl = G_TLS_CERTIFICATE_OPENSSL (trusted_ca);
-      for (; cert_openssl; cert_openssl = priv->issuer)
-        {
-          priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
-          sk_X509_push (trusted, priv->cert);
-        }
+      for (; cert_openssl; cert_openssl = cert_openssl->issuer)
+        sk_X509_push (trusted, cert_openssl->cert);
 
       X509_STORE_CTX_trusted_stack (csc, trusted);
       if (X509_verify_cert (csc) <= 0)
@@ -336,22 +513,6 @@ g_tls_certificate_openssl_verify (GTlsCertificate     *cert,
       X509_STORE_free (store);
     }
 
-  /* We have to check these ourselves since openssl
-   * does not give us flags and UNKNOWN_CA will take priority.
-   */
-  for (i = 0; i < sk_X509_num (untrusted); i++)
-    {
-      X509 *c = sk_X509_value (untrusted, i);
-      ASN1_TIME *not_before = X509_get_notBefore (c);
-      ASN1_TIME *not_after = X509_get_notAfter (c);
-
-      if (X509_cmp_current_time (not_before) > 0)
-        gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED;
-
-      if (X509_cmp_current_time (not_after) < 0)
-        gtls_flags |= G_TLS_CERTIFICATE_EXPIRED;
-    }
-
   sk_X509_free (untrusted);
 
   if (identity)
@@ -377,6 +538,12 @@ g_tls_certificate_openssl_class_init (GTlsCertificateOpensslClass *klass)
   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");
+  g_object_class_override_property (gobject_class, PROP_NOT_VALID_BEFORE, "not-valid-before");
+  g_object_class_override_property (gobject_class, PROP_NOT_VALID_AFTER, "not-valid-after");
+  g_object_class_override_property (gobject_class, PROP_SUBJECT_NAME, "subject-name");
+  g_object_class_override_property (gobject_class, PROP_ISSUER_NAME, "issuer-name");
+  g_object_class_override_property (gobject_class, PROP_DNS_NAMES, "dns-names");
+  g_object_class_override_property (gobject_class, PROP_IP_ADDRESSES, "ip-addresses");
 }
 
 static void
@@ -404,16 +571,13 @@ g_tls_certificate_openssl_new_from_x509 (X509            *x,
                                          GTlsCertificate *issuer)
 {
   GTlsCertificateOpenssl *openssl;
-  GTlsCertificateOpensslPrivate *priv;
 
   openssl = g_object_new (G_TYPE_TLS_CERTIFICATE_OPENSSL,
                           "issuer", issuer,
                           NULL);
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
-  priv->cert = X509_dup (x);
-  priv->have_cert = TRUE;
+  openssl->cert = X509_dup (x);
+  openssl->have_cert = TRUE;
 
   return G_TLS_CERTIFICATE (openssl);
 }
@@ -422,20 +586,17 @@ void
 g_tls_certificate_openssl_set_data (GTlsCertificateOpenssl *openssl,
                                     GBytes                 *bytes)
 {
-  GTlsCertificateOpensslPrivate *priv;
   const unsigned char *data;
 
   g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
-  g_return_if_fail (!priv->have_cert);
+  g_return_if_fail (!openssl->have_cert);
 
   data = (const unsigned char *)g_bytes_get_data (bytes, NULL);
-  priv->cert = d2i_X509 (NULL, &data, g_bytes_get_size (bytes));
+  openssl->cert = d2i_X509 (NULL, &data, g_bytes_get_size (bytes));
 
-  if (priv->cert != NULL)
-    priv->have_cert = TRUE;
+  if (openssl->cert)
+    openssl->have_cert = TRUE;
 }
 
 GBytes *
@@ -452,39 +613,27 @@ g_tls_certificate_openssl_get_bytes (GTlsCertificateOpenssl *openssl)
 X509 *
 g_tls_certificate_openssl_get_cert (GTlsCertificateOpenssl *openssl)
 {
-  GTlsCertificateOpensslPrivate *priv;
-
   g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
-  return priv->cert;
+  return openssl->cert;
 }
 
 EVP_PKEY *
 g_tls_certificate_openssl_get_key (GTlsCertificateOpenssl *openssl)
 {
-  GTlsCertificateOpensslPrivate *priv;
-
   g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
-  return priv->key;
+  return openssl->key;
 }
 
 void
 g_tls_certificate_openssl_set_issuer (GTlsCertificateOpenssl *openssl,
                                       GTlsCertificateOpenssl *issuer)
 {
-  GTlsCertificateOpensslPrivate *priv;
-
   g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
   g_return_if_fail (!issuer || G_IS_TLS_CERTIFICATE_OPENSSL (issuer));
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
-  if (g_set_object (&priv->issuer, issuer))
+  if (g_set_object (&openssl->issuer, issuer))
     g_object_notify (G_OBJECT (openssl), "issuer");
 }
 
@@ -492,11 +641,8 @@ static gboolean
 verify_identity_hostname (GTlsCertificateOpenssl *openssl,
                           GSocketConnectable     *identity)
 {
-  GTlsCertificateOpensslPrivate *priv;
   const char *hostname;
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
   if (G_IS_NETWORK_ADDRESS (identity))
     hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
   else if (G_IS_NETWORK_SERVICE (identity))
@@ -504,21 +650,18 @@ verify_identity_hostname (GTlsCertificateOpenssl *openssl,
   else
     return FALSE;
 
-  return g_tls_X509_check_host (priv->cert, hostname, strlen (hostname), 0, NULL) == 1;
+  return X509_check_host (openssl->cert, hostname, strlen (hostname), 0, NULL) == 1;
 }
 
 static gboolean
 verify_identity_ip (GTlsCertificateOpenssl *openssl,
                     GSocketConnectable     *identity)
 {
-  GTlsCertificateOpensslPrivate *priv;
   GInetAddress *addr;
   gsize addr_size;
   const guint8 *addr_bytes;
   gboolean ret;
 
-  priv = g_tls_certificate_openssl_get_instance_private (openssl);
-
   if (G_IS_INET_SOCKET_ADDRESS (identity))
     addr = g_object_ref (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity)));
   else {
@@ -539,7 +682,7 @@ verify_identity_ip (GTlsCertificateOpenssl *openssl,
   addr_bytes = g_inet_address_to_bytes (addr);
   addr_size = g_inet_address_get_native_size (addr);
 
-  ret = g_tls_X509_check_ip (priv->cert, addr_bytes, addr_size, 0) == 1;
+  ret = X509_check_ip (openssl->cert, addr_bytes, addr_size, 0) == 1;
 
   g_object_unref (addr);
   return ret;
@@ -558,6 +701,7 @@ g_tls_certificate_openssl_verify_identity (GTlsCertificateOpenssl *openssl,
    * subjectAltNames, if appropriate for @identity.
    */
 
+  TIZEN_LOGE("SSL HandShake - Bad Identity");
   return G_TLS_CERTIFICATE_BAD_IDENTITY;
 }
 
@@ -587,10 +731,12 @@ g_tls_certificate_openssl_convert_error (guint openssl_error)
       break;
     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+#ifdef TIZEN_EXT
+    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+#endif
       gtls_flags = G_TLS_CERTIFICATE_UNKNOWN_CA;
       break;
     default:
-      g_message ("certificate error: %s", X509_verify_cert_error_string (openssl_error));
       gtls_flags = G_TLS_CERTIFICATE_GENERIC_ERROR;
     }
 
@@ -652,7 +798,7 @@ g_tls_certificate_openssl_build_chain (X509            *x,
   GTlsCertificateOpenssl *result;
   guint i, j;
 
-  g_return_val_if_fail (x != NULL, NULL);
+  g_return_val_if_fail (x, NULL);
   g_return_val_if_fail (chain, NULL);
 
   glib_certs = g_ptr_array_new_full (sk_X509_num (chain), g_object_unref);