2 * gtlscertificate-openssl.c
4 * Copyright (C) 2015 NICE s.r.l.
6 * This file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * In addition, when the library is used with OpenSSL, a special
20 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
22 * Authors: Ignacio Casal Quinteiro
28 #include "openssl-include.h"
30 #include "gtlscertificate-openssl.h"
31 #include "openssl-util.h"
32 #include <glib/gi18n-lib.h>
34 typedef struct _GTlsCertificateOpensslPrivate
39 GTlsCertificateOpenssl *issuer;
41 GError *construct_error;
45 } GTlsCertificateOpensslPrivate;
58 static void g_tls_certificate_openssl_initable_iface_init (GInitableIface *iface);
60 G_DEFINE_TYPE_WITH_CODE (GTlsCertificateOpenssl, g_tls_certificate_openssl, G_TYPE_TLS_CERTIFICATE,
61 G_ADD_PRIVATE (GTlsCertificateOpenssl)
62 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
63 g_tls_certificate_openssl_initable_iface_init))
66 g_tls_certificate_openssl_finalize (GObject *object)
68 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
69 GTlsCertificateOpensslPrivate *priv;
71 priv = g_tls_certificate_openssl_get_instance_private (openssl);
74 X509_free (priv->cert);
76 EVP_PKEY_free (priv->key);
78 g_clear_object (&priv->issuer);
80 g_clear_error (&priv->construct_error);
82 G_OBJECT_CLASS (g_tls_certificate_openssl_parent_class)->finalize (object);
86 g_tls_certificate_openssl_get_property (GObject *object,
91 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
92 GTlsCertificateOpensslPrivate *priv;
93 GByteArray *certificate;
96 char *certificate_pem;
99 priv = g_tls_certificate_openssl_get_instance_private (openssl);
103 case PROP_CERTIFICATE:
104 /* NOTE: we do the two calls to avoid openssl allocating the buffer for us */
105 size = i2d_X509 (priv->cert, NULL);
110 certificate = g_byte_array_sized_new (size);
111 certificate->len = size;
112 data = certificate->data;
113 size = i2d_X509 (priv->cert, &data);
116 g_byte_array_free (certificate, TRUE);
120 g_value_take_boxed (value, certificate);
123 case PROP_CERTIFICATE_PEM:
124 bio = BIO_new (BIO_s_mem ());
126 if (!PEM_write_bio_X509 (bio, priv->cert) || !BIO_write (bio, "\0", 1))
127 certificate_pem = NULL;
130 BIO_get_mem_data (bio, &certificate_pem);
131 g_value_set_string (value, certificate_pem);
138 g_value_set_object (value, priv->issuer);
142 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
147 g_tls_certificate_openssl_set_property (GObject *object,
152 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
153 GTlsCertificateOpensslPrivate *priv;
159 priv = g_tls_certificate_openssl_get_instance_private (openssl);
163 case PROP_CERTIFICATE:
164 bytes = g_value_get_boxed (value);
167 g_return_if_fail (priv->have_cert == FALSE);
168 /* see that we cannot use bytes->data directly since it will move the pointer */
170 priv->cert = d2i_X509 (NULL, (const unsigned char **)&data, bytes->len);
171 if (priv->cert != NULL)
172 priv->have_cert = TRUE;
173 else if (!priv->construct_error)
175 priv->construct_error =
176 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
177 _("Could not parse DER certificate: %s"),
178 ERR_error_string (ERR_get_error (), NULL));
183 case PROP_CERTIFICATE_PEM:
184 string = g_value_get_string (value);
187 g_return_if_fail (priv->have_cert == FALSE);
188 bio = BIO_new_mem_buf ((gpointer)string, -1);
189 priv->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
191 if (priv->cert != NULL)
192 priv->have_cert = TRUE;
193 else if (!priv->construct_error)
195 priv->construct_error =
196 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
197 _("Could not parse PEM certificate: %s"),
198 ERR_error_string (ERR_get_error (), NULL));
202 case PROP_PRIVATE_KEY:
203 bytes = g_value_get_boxed (value);
206 g_return_if_fail (priv->have_key == FALSE);
207 bio = BIO_new_mem_buf (bytes->data, bytes->len);
208 priv->key = d2i_PrivateKey_bio (bio, NULL);
210 if (priv->key != NULL)
211 priv->have_key = TRUE;
212 else if (!priv->construct_error)
214 priv->construct_error =
215 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
216 _("Could not parse DER private key: %s"),
217 ERR_error_string (ERR_get_error (), NULL));
221 case PROP_PRIVATE_KEY_PEM:
222 string = g_value_get_string (value);
225 g_return_if_fail (priv->have_key == FALSE);
226 bio = BIO_new_mem_buf ((gpointer)string, -1);
227 priv->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
229 if (priv->key != NULL)
230 priv->have_key = TRUE;
231 else if (!priv->construct_error)
233 priv->construct_error =
234 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
235 _("Could not parse PEM private key: %s"),
236 ERR_error_string (ERR_get_error (), NULL));
241 priv->issuer = g_value_dup_object (value);
245 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250 g_tls_certificate_openssl_init (GTlsCertificateOpenssl *openssl)
255 g_tls_certificate_openssl_initable_init (GInitable *initable,
256 GCancellable *cancellable,
259 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (initable);
260 GTlsCertificateOpensslPrivate *priv;
262 priv = g_tls_certificate_openssl_get_instance_private (openssl);
264 if (priv->construct_error)
266 g_propagate_error (error, priv->construct_error);
267 priv->construct_error = NULL;
270 else if (!priv->have_cert)
272 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
273 _("No certificate data provided"));
280 static GTlsCertificateFlags
281 g_tls_certificate_openssl_verify (GTlsCertificate *cert,
282 GSocketConnectable *identity,
283 GTlsCertificate *trusted_ca)
285 GTlsCertificateOpenssl *cert_openssl;
286 GTlsCertificateOpensslPrivate *priv;
287 GTlsCertificateFlags gtls_flags;
289 STACK_OF(X509) *untrusted;
292 cert_openssl = G_TLS_CERTIFICATE_OPENSSL (cert);
293 priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
296 untrusted = sk_X509_new_null ();
297 for (; cert_openssl; cert_openssl = priv->issuer)
299 priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
300 sk_X509_push (untrusted, priv->cert);
309 STACK_OF(X509) *trusted;
311 store = X509_STORE_new ();
312 csc = X509_STORE_CTX_new ();
314 if (!X509_STORE_CTX_init (csc, store, x, untrusted))
316 sk_X509_free (untrusted);
317 X509_STORE_CTX_free (csc);
318 X509_STORE_free (store);
319 return G_TLS_CERTIFICATE_GENERIC_ERROR;
322 trusted = sk_X509_new_null ();
323 cert_openssl = G_TLS_CERTIFICATE_OPENSSL (trusted_ca);
324 for (; cert_openssl; cert_openssl = priv->issuer)
326 priv = g_tls_certificate_openssl_get_instance_private (cert_openssl);
327 sk_X509_push (trusted, priv->cert);
330 X509_STORE_CTX_trusted_stack (csc, trusted);
331 if (X509_verify_cert (csc) <= 0)
332 gtls_flags |= g_tls_certificate_openssl_convert_error (X509_STORE_CTX_get_error (csc));
334 sk_X509_free (trusted);
335 X509_STORE_CTX_free (csc);
336 X509_STORE_free (store);
339 /* We have to check these ourselves since openssl
340 * does not give us flags and UNKNOWN_CA will take priority.
342 for (i = 0; i < sk_X509_num (untrusted); i++)
344 X509 *c = sk_X509_value (untrusted, i);
345 ASN1_TIME *not_before = X509_get_notBefore (c);
346 ASN1_TIME *not_after = X509_get_notAfter (c);
348 if (X509_cmp_current_time (not_before) > 0)
349 gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED;
351 if (X509_cmp_current_time (not_after) < 0)
352 gtls_flags |= G_TLS_CERTIFICATE_EXPIRED;
355 sk_X509_free (untrusted);
358 gtls_flags |= g_tls_certificate_openssl_verify_identity (G_TLS_CERTIFICATE_OPENSSL (cert), identity);
364 g_tls_certificate_openssl_class_init (GTlsCertificateOpensslClass *klass)
366 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
367 GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (klass);
369 gobject_class->get_property = g_tls_certificate_openssl_get_property;
370 gobject_class->set_property = g_tls_certificate_openssl_set_property;
371 gobject_class->finalize = g_tls_certificate_openssl_finalize;
373 certificate_class->verify = g_tls_certificate_openssl_verify;
375 g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
376 g_object_class_override_property (gobject_class, PROP_CERTIFICATE_PEM, "certificate-pem");
377 g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY, "private-key");
378 g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY_PEM, "private-key-pem");
379 g_object_class_override_property (gobject_class, PROP_ISSUER, "issuer");
383 g_tls_certificate_openssl_initable_iface_init (GInitableIface *iface)
385 iface->init = g_tls_certificate_openssl_initable_init;
389 g_tls_certificate_openssl_new (GBytes *bytes,
390 GTlsCertificate *issuer)
392 GTlsCertificateOpenssl *openssl;
394 openssl = g_object_new (G_TYPE_TLS_CERTIFICATE_OPENSSL,
397 g_tls_certificate_openssl_set_data (openssl, bytes);
399 return G_TLS_CERTIFICATE (openssl);
403 g_tls_certificate_openssl_new_from_x509 (X509 *x,
404 GTlsCertificate *issuer)
406 GTlsCertificateOpenssl *openssl;
407 GTlsCertificateOpensslPrivate *priv;
409 openssl = g_object_new (G_TYPE_TLS_CERTIFICATE_OPENSSL,
413 priv = g_tls_certificate_openssl_get_instance_private (openssl);
415 priv->cert = X509_dup (x);
416 priv->have_cert = TRUE;
418 return G_TLS_CERTIFICATE (openssl);
422 g_tls_certificate_openssl_set_data (GTlsCertificateOpenssl *openssl,
425 GTlsCertificateOpensslPrivate *priv;
426 const unsigned char *data;
428 g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
430 priv = g_tls_certificate_openssl_get_instance_private (openssl);
432 g_return_if_fail (!priv->have_cert);
434 data = (const unsigned char *)g_bytes_get_data (bytes, NULL);
435 priv->cert = d2i_X509 (NULL, &data, g_bytes_get_size (bytes));
437 if (priv->cert != NULL)
438 priv->have_cert = TRUE;
442 g_tls_certificate_openssl_get_bytes (GTlsCertificateOpenssl *openssl)
446 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), NULL);
448 g_object_get (openssl, "certificate", &array, NULL);
449 return g_byte_array_free_to_bytes (array);
453 g_tls_certificate_openssl_get_cert (GTlsCertificateOpenssl *openssl)
455 GTlsCertificateOpensslPrivate *priv;
457 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
459 priv = g_tls_certificate_openssl_get_instance_private (openssl);
465 g_tls_certificate_openssl_get_key (GTlsCertificateOpenssl *openssl)
467 GTlsCertificateOpensslPrivate *priv;
469 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
471 priv = g_tls_certificate_openssl_get_instance_private (openssl);
477 g_tls_certificate_openssl_set_issuer (GTlsCertificateOpenssl *openssl,
478 GTlsCertificateOpenssl *issuer)
480 GTlsCertificateOpensslPrivate *priv;
482 g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
483 g_return_if_fail (!issuer || G_IS_TLS_CERTIFICATE_OPENSSL (issuer));
485 priv = g_tls_certificate_openssl_get_instance_private (openssl);
487 if (g_set_object (&priv->issuer, issuer))
488 g_object_notify (G_OBJECT (openssl), "issuer");
492 verify_identity_hostname (GTlsCertificateOpenssl *openssl,
493 GSocketConnectable *identity)
495 GTlsCertificateOpensslPrivate *priv;
496 const char *hostname;
498 priv = g_tls_certificate_openssl_get_instance_private (openssl);
500 if (G_IS_NETWORK_ADDRESS (identity))
501 hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
502 else if (G_IS_NETWORK_SERVICE (identity))
503 hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
507 return g_tls_X509_check_host (priv->cert, hostname, strlen (hostname), 0, NULL) == 1;
511 verify_identity_ip (GTlsCertificateOpenssl *openssl,
512 GSocketConnectable *identity)
514 GTlsCertificateOpensslPrivate *priv;
517 const guint8 *addr_bytes;
520 priv = g_tls_certificate_openssl_get_instance_private (openssl);
522 if (G_IS_INET_SOCKET_ADDRESS (identity))
523 addr = g_object_ref (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity)));
525 const char *hostname;
527 if (G_IS_NETWORK_ADDRESS (identity))
528 hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
529 else if (G_IS_NETWORK_SERVICE (identity))
530 hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
534 addr = g_inet_address_new_from_string (hostname);
539 addr_bytes = g_inet_address_to_bytes (addr);
540 addr_size = g_inet_address_get_native_size (addr);
542 ret = g_tls_X509_check_ip (priv->cert, addr_bytes, addr_size, 0) == 1;
544 g_object_unref (addr);
549 g_tls_certificate_openssl_verify_identity (GTlsCertificateOpenssl *openssl,
550 GSocketConnectable *identity)
552 if (verify_identity_hostname (openssl, identity))
554 else if (verify_identity_ip (openssl, identity))
557 /* FIXME: check sRVName and uniformResourceIdentifier
558 * subjectAltNames, if appropriate for @identity.
560 TIZEN_LOGE("SSL HandShake - Bad Identity");
561 return G_TLS_CERTIFICATE_BAD_IDENTITY;
565 g_tls_certificate_openssl_convert_error (guint openssl_error)
567 GTlsCertificateFlags gtls_flags;
571 /* FIXME: should we add more ? */
572 switch (openssl_error)
576 case X509_V_ERR_CERT_NOT_YET_VALID:
577 gtls_flags = G_TLS_CERTIFICATE_NOT_ACTIVATED;
579 case X509_V_ERR_CERT_HAS_EXPIRED:
580 gtls_flags = G_TLS_CERTIFICATE_EXPIRED;
582 case X509_V_ERR_CERT_REVOKED:
583 gtls_flags = G_TLS_CERTIFICATE_REVOKED;
585 case X509_V_ERR_AKID_SKID_MISMATCH:
586 gtls_flags = G_TLS_CERTIFICATE_BAD_IDENTITY;
588 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
589 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
591 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
593 gtls_flags = G_TLS_CERTIFICATE_UNKNOWN_CA;
596 g_message ("certificate error: %s", X509_verify_cert_error_string (openssl_error));
597 gtls_flags = G_TLS_CERTIFICATE_GENERIC_ERROR;
604 is_issuer (GTlsCertificateOpenssl *cert,
605 GTlsCertificateOpenssl *issuer)
611 STACK_OF(X509) *trusted;
612 gboolean ret = FALSE;
615 x = g_tls_certificate_openssl_get_cert (cert);
616 issuer_x = g_tls_certificate_openssl_get_cert (issuer);
618 store = X509_STORE_new ();
619 csc = X509_STORE_CTX_new ();
621 if (!X509_STORE_CTX_init (csc, store, x, NULL))
624 trusted = sk_X509_new_null ();
625 sk_X509_push (trusted, issuer_x);
627 X509_STORE_CTX_trusted_stack (csc, trusted);
628 X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CB_ISSUER_CHECK);
630 /* FIXME: is this the right way to do it? */
631 if (X509_verify_cert (csc) <= 0)
633 err = X509_STORE_CTX_get_error (csc);
634 if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)
640 sk_X509_free (trusted);
643 X509_STORE_CTX_free (csc);
644 X509_STORE_free (store);
649 GTlsCertificateOpenssl *
650 g_tls_certificate_openssl_build_chain (X509 *x,
651 STACK_OF (X509) *chain)
653 GPtrArray *glib_certs;
654 GTlsCertificateOpenssl *issuer;
655 GTlsCertificateOpenssl *result;
658 g_return_val_if_fail (x != NULL, NULL);
659 g_return_val_if_fail (chain, NULL);
661 glib_certs = g_ptr_array_new_full (sk_X509_num (chain), g_object_unref);
662 g_ptr_array_add (glib_certs, g_tls_certificate_openssl_new_from_x509 (x, NULL));
663 for (i = 1; i < sk_X509_num (chain); i++)
664 g_ptr_array_add (glib_certs, g_tls_certificate_openssl_new_from_x509 (sk_X509_value (chain, i), NULL));
666 /* Some servers send certs out of order, or will send duplicate
667 * certs, so we need to be careful when assigning the issuer of
668 * our new GTlsCertificateOpenssl.
670 for (i = 0; i < glib_certs->len; i++)
674 /* Check if the cert issued itself */
675 if (is_issuer (glib_certs->pdata[i], glib_certs->pdata[i]))
678 if (i < glib_certs->len - 1 &&
679 is_issuer (glib_certs->pdata[i], glib_certs->pdata[i + 1]))
681 issuer = glib_certs->pdata[i + 1];
685 for (j = 0; j < glib_certs->len; j++)
688 is_issuer (glib_certs->pdata[i], glib_certs->pdata[j]))
690 issuer = glib_certs->pdata[j];
697 g_tls_certificate_openssl_set_issuer (glib_certs->pdata[i], issuer);
700 result = g_object_ref (glib_certs->pdata[0]);
701 g_ptr_array_unref (glib_certs);