1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 * gtlscertificate-openssl.c
5 * Copyright (C) 2015 NICE s.r.l.
7 * This file 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.
12 * This file 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.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * In addition, when the library is used with OpenSSL, a special
21 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
23 * Authors: Ignacio Casal Quinteiro
29 #include "openssl-include.h"
31 #include "gtlscertificate-openssl.h"
32 #include <glib/gi18n-lib.h>
34 struct _GTlsCertificateOpenssl
36 GTlsCertificate parent_instance;
41 GTlsCertificateOpenssl *issuer;
43 GError *construct_error;
58 PROP_NOT_VALID_BEFORE,
66 static void g_tls_certificate_openssl_initable_iface_init (GInitableIface *iface);
68 G_DEFINE_TYPE_WITH_CODE (GTlsCertificateOpenssl, g_tls_certificate_openssl, G_TYPE_TLS_CERTIFICATE,
69 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
70 g_tls_certificate_openssl_initable_iface_init))
73 g_tls_certificate_openssl_finalize (GObject *object)
75 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
78 X509_free (openssl->cert);
80 EVP_PKEY_free (openssl->key);
82 g_clear_object (&openssl->issuer);
84 g_clear_error (&openssl->construct_error);
86 G_OBJECT_CLASS (g_tls_certificate_openssl_parent_class)->finalize (object);
90 get_subject_alt_names (GTlsCertificateOpenssl *cert,
93 GPtrArray *data = NULL;
94 STACK_OF (GENERAL_NAME) *sans;
95 const guint8 *san = NULL;
97 guint alt_occurrences;
100 if (type == GEN_IPADD)
101 data = g_ptr_array_new_with_free_func (g_object_unref);
103 data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
105 sans = X509_get_ext_d2i (cert->cert, NID_subject_alt_name, NULL, NULL);
108 alt_occurrences = sk_GENERAL_NAME_num (sans);
109 for (i = 0; i < alt_occurrences; i++)
111 const GENERAL_NAME *value = sk_GENERAL_NAME_value (sans, i);
112 if (value->type != type)
115 if (type == GEN_IPADD)
117 g_assert (value->type == GEN_IPADD);
118 san = ASN1_STRING_get0_data (value->d.ip);
119 san_size = ASN1_STRING_length (value->d.ip);
121 g_ptr_array_add (data, g_inet_address_new_from_bytes (san, G_SOCKET_FAMILY_IPV4));
122 else if (san_size == 16)
123 g_ptr_array_add (data, g_inet_address_new_from_bytes (san, G_SOCKET_FAMILY_IPV6));
127 g_assert (value->type == GEN_DNS);
128 san = ASN1_STRING_get0_data (value->d.ia5);
129 san_size = ASN1_STRING_length (value->d.ia5);
130 g_ptr_array_add (data, g_bytes_new (san, san_size));
134 for (i = 0; i < alt_occurrences; i++)
135 GENERAL_NAME_free (sk_GENERAL_NAME_value (sans, i));
136 sk_GENERAL_NAME_free (sans);
143 export_privkey_to_der (GTlsCertificateOpenssl *openssl,
144 guint8 **output_data,
147 PKCS8_PRIV_KEY_INFO *pkcs8 = NULL;
154 pkcs8 = EVP_PKEY2PKCS8 (openssl->key);
158 bio = BIO_new (BIO_s_mem ());
159 if (i2d_PKCS8_PRIV_KEY_INFO_bio (bio, pkcs8) == 0)
162 *output_size = BIO_get_mem_data (bio, (char **)&data);
163 if (*output_size <= 0)
166 *output_data = g_malloc (*output_size);
167 memcpy (*output_data, data, *output_size);
177 PKCS8_PRIV_KEY_INFO_free (pkcs8);
181 export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
185 const char *data = NULL;
191 bio = BIO_new (BIO_s_mem ());
192 ret = PEM_write_bio_PKCS8PrivateKey (bio, openssl->key, NULL, NULL, 0, NULL, NULL);
196 ret = BIO_write (bio, "\0", 1);
200 BIO_get_mem_data (bio, (char **)&data);
201 result = g_strdup (data);
209 g_tls_certificate_openssl_get_property (GObject *object,
214 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
215 GByteArray *certificate;
218 GByteArray *byte_array;
219 char *certificate_pem;
222 const ASN1_TIME *time_asn1;
227 const char *name_string;
231 case PROP_CERTIFICATE:
232 /* NOTE: we do the two calls to avoid openssl allocating the buffer for us */
233 size = i2d_X509 (openssl->cert, NULL);
238 certificate = g_byte_array_sized_new (size);
239 certificate->len = size;
240 data = certificate->data;
241 size = i2d_X509 (openssl->cert, &data);
244 g_byte_array_free (certificate, TRUE);
248 g_value_take_boxed (value, certificate);
251 case PROP_CERTIFICATE_PEM:
252 bio = BIO_new (BIO_s_mem ());
254 if (!PEM_write_bio_X509 (bio, openssl->cert) || !BIO_write (bio, "\0", 1))
255 certificate_pem = NULL;
258 BIO_get_mem_data (bio, &certificate_pem);
259 g_value_set_string (value, certificate_pem);
265 case PROP_PRIVATE_KEY:
266 export_privkey_to_der (openssl, &data, &size);
267 if (size > 0 && (gint64)size <= G_MAXUINT)
269 byte_array = g_byte_array_new_take (data, size);
270 g_value_take_boxed (value, byte_array);
274 case PROP_PRIVATE_KEY_PEM:
275 g_value_take_string (value, export_privkey_to_pem (openssl));
279 g_value_set_object (value, openssl->issuer);
282 case PROP_NOT_VALID_BEFORE:
283 time_asn1 = X509_get0_notBefore (openssl->cert);
284 ASN1_TIME_to_tm (time_asn1, &time_tm);
285 tz = g_time_zone_new_utc ();
286 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);
287 g_value_take_boxed (value, time);
288 g_time_zone_unref (tz);
291 case PROP_NOT_VALID_AFTER:
292 time_asn1 = X509_get0_notAfter (openssl->cert);
293 ASN1_TIME_to_tm (time_asn1, &time_tm);
294 tz = g_time_zone_new_utc ();
295 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);
296 g_value_take_boxed (value, time);
297 g_time_zone_unref (tz);
300 case PROP_SUBJECT_NAME:
301 bio = BIO_new (BIO_s_mem ());
302 name = X509_get_subject_name (openssl->cert);
303 X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
304 BIO_write (bio, "\0", 1);
305 BIO_get_mem_data (bio, (char **)&name_string);
306 g_value_set_string (value, name_string);
310 case PROP_ISSUER_NAME:
311 bio = BIO_new (BIO_s_mem ());
312 name = X509_get_issuer_name (openssl->cert);
313 X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
314 BIO_write (bio, "\0", 1);
315 BIO_get_mem_data (bio, &name_string);
316 g_value_set_string (value, name_string);
321 g_value_take_boxed (value, get_subject_alt_names (openssl, GEN_DNS));
324 case PROP_IP_ADDRESSES:
325 g_value_take_boxed (value, get_subject_alt_names (openssl, GEN_IPADD));
329 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
334 g_tls_certificate_openssl_set_property (GObject *object,
339 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (object);
344 char error_buffer[256];
348 case PROP_CERTIFICATE:
349 bytes = g_value_get_boxed (value);
352 g_return_if_fail (openssl->have_cert == FALSE);
353 /* see that we cannot use bytes->data directly since it will move the pointer */
355 openssl->cert = d2i_X509 (NULL, (const unsigned char **)&data, bytes->len);
357 openssl->have_cert = TRUE;
358 else if (!openssl->construct_error)
360 ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
361 openssl->construct_error =
362 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
363 _("Could not parse DER certificate: %s"),
369 case PROP_CERTIFICATE_PEM:
370 string = g_value_get_string (value);
373 g_return_if_fail (openssl->have_cert == FALSE);
374 bio = BIO_new_mem_buf ((gpointer)string, -1);
375 openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
378 openssl->have_cert = TRUE;
379 else if (!openssl->construct_error)
381 ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
382 openssl->construct_error =
383 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
384 _("Could not parse PEM certificate: %s"),
389 case PROP_PRIVATE_KEY:
390 bytes = g_value_get_boxed (value);
393 g_return_if_fail (openssl->have_key == FALSE);
394 bio = BIO_new_mem_buf (bytes->data, bytes->len);
395 openssl->key = d2i_PrivateKey_bio (bio, NULL);
398 openssl->have_key = TRUE;
399 else if (!openssl->construct_error)
401 ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
402 openssl->construct_error =
403 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
404 _("Could not parse DER private key: %s"),
409 case PROP_PRIVATE_KEY_PEM:
410 string = g_value_get_string (value);
413 g_return_if_fail (openssl->have_key == FALSE);
414 bio = BIO_new_mem_buf ((gpointer)string, -1);
415 openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
418 openssl->have_key = TRUE;
419 else if (!openssl->construct_error)
421 ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
422 openssl->construct_error =
423 g_error_new (G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
424 _("Could not parse PEM private key: %s"),
430 openssl->issuer = g_value_dup_object (value);
434 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
439 g_tls_certificate_openssl_init (GTlsCertificateOpenssl *openssl)
444 g_tls_certificate_openssl_initable_init (GInitable *initable,
445 GCancellable *cancellable,
448 GTlsCertificateOpenssl *openssl = G_TLS_CERTIFICATE_OPENSSL (initable);
450 if (openssl->construct_error)
452 g_propagate_error (error, openssl->construct_error);
453 openssl->construct_error = NULL;
456 else if (!openssl->have_cert)
458 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
459 _("No certificate data provided"));
466 static GTlsCertificateFlags
467 g_tls_certificate_openssl_verify (GTlsCertificate *cert,
468 GSocketConnectable *identity,
469 GTlsCertificate *trusted_ca)
471 GTlsCertificateOpenssl *cert_openssl;
472 GTlsCertificateFlags gtls_flags;
474 STACK_OF(X509) *untrusted;
476 cert_openssl = G_TLS_CERTIFICATE_OPENSSL (cert);
477 x = cert_openssl->cert;
479 untrusted = sk_X509_new_null ();
480 for (; cert_openssl; cert_openssl = cert_openssl->issuer)
481 sk_X509_push (untrusted, cert_openssl->cert);
489 STACK_OF(X509) *trusted;
491 store = X509_STORE_new ();
492 csc = X509_STORE_CTX_new ();
494 if (!X509_STORE_CTX_init (csc, store, x, untrusted))
496 sk_X509_free (untrusted);
497 X509_STORE_CTX_free (csc);
498 X509_STORE_free (store);
499 return G_TLS_CERTIFICATE_GENERIC_ERROR;
502 trusted = sk_X509_new_null ();
503 cert_openssl = G_TLS_CERTIFICATE_OPENSSL (trusted_ca);
504 for (; cert_openssl; cert_openssl = cert_openssl->issuer)
505 sk_X509_push (trusted, cert_openssl->cert);
507 X509_STORE_CTX_trusted_stack (csc, trusted);
508 if (X509_verify_cert (csc) <= 0)
509 gtls_flags |= g_tls_certificate_openssl_convert_error (X509_STORE_CTX_get_error (csc));
511 sk_X509_free (trusted);
512 X509_STORE_CTX_free (csc);
513 X509_STORE_free (store);
516 sk_X509_free (untrusted);
519 gtls_flags |= g_tls_certificate_openssl_verify_identity (G_TLS_CERTIFICATE_OPENSSL (cert), identity);
525 g_tls_certificate_openssl_class_init (GTlsCertificateOpensslClass *klass)
527 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
528 GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (klass);
530 gobject_class->get_property = g_tls_certificate_openssl_get_property;
531 gobject_class->set_property = g_tls_certificate_openssl_set_property;
532 gobject_class->finalize = g_tls_certificate_openssl_finalize;
534 certificate_class->verify = g_tls_certificate_openssl_verify;
536 g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
537 g_object_class_override_property (gobject_class, PROP_CERTIFICATE_PEM, "certificate-pem");
538 g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY, "private-key");
539 g_object_class_override_property (gobject_class, PROP_PRIVATE_KEY_PEM, "private-key-pem");
540 g_object_class_override_property (gobject_class, PROP_ISSUER, "issuer");
541 g_object_class_override_property (gobject_class, PROP_NOT_VALID_BEFORE, "not-valid-before");
542 g_object_class_override_property (gobject_class, PROP_NOT_VALID_AFTER, "not-valid-after");
543 g_object_class_override_property (gobject_class, PROP_SUBJECT_NAME, "subject-name");
544 g_object_class_override_property (gobject_class, PROP_ISSUER_NAME, "issuer-name");
545 g_object_class_override_property (gobject_class, PROP_DNS_NAMES, "dns-names");
546 g_object_class_override_property (gobject_class, PROP_IP_ADDRESSES, "ip-addresses");
550 g_tls_certificate_openssl_initable_iface_init (GInitableIface *iface)
552 iface->init = g_tls_certificate_openssl_initable_init;
556 g_tls_certificate_openssl_new (GBytes *bytes,
557 GTlsCertificate *issuer)
559 GTlsCertificateOpenssl *openssl;
561 openssl = g_object_new (G_TYPE_TLS_CERTIFICATE_OPENSSL,
564 g_tls_certificate_openssl_set_data (openssl, bytes);
566 return G_TLS_CERTIFICATE (openssl);
570 g_tls_certificate_openssl_new_from_x509 (X509 *x,
571 GTlsCertificate *issuer)
573 GTlsCertificateOpenssl *openssl;
575 openssl = g_object_new (G_TYPE_TLS_CERTIFICATE_OPENSSL,
579 openssl->cert = X509_dup (x);
580 openssl->have_cert = TRUE;
582 return G_TLS_CERTIFICATE (openssl);
586 g_tls_certificate_openssl_set_data (GTlsCertificateOpenssl *openssl,
589 const unsigned char *data;
591 g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
593 g_return_if_fail (!openssl->have_cert);
595 data = (const unsigned char *)g_bytes_get_data (bytes, NULL);
596 openssl->cert = d2i_X509 (NULL, &data, g_bytes_get_size (bytes));
599 openssl->have_cert = TRUE;
603 g_tls_certificate_openssl_get_bytes (GTlsCertificateOpenssl *openssl)
607 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), NULL);
609 g_object_get (openssl, "certificate", &array, NULL);
610 return g_byte_array_free_to_bytes (array);
614 g_tls_certificate_openssl_get_cert (GTlsCertificateOpenssl *openssl)
616 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
618 return openssl->cert;
622 g_tls_certificate_openssl_get_key (GTlsCertificateOpenssl *openssl)
624 g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl), FALSE);
630 g_tls_certificate_openssl_set_issuer (GTlsCertificateOpenssl *openssl,
631 GTlsCertificateOpenssl *issuer)
633 g_return_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (openssl));
634 g_return_if_fail (!issuer || G_IS_TLS_CERTIFICATE_OPENSSL (issuer));
636 if (g_set_object (&openssl->issuer, issuer))
637 g_object_notify (G_OBJECT (openssl), "issuer");
641 verify_identity_hostname (GTlsCertificateOpenssl *openssl,
642 GSocketConnectable *identity)
644 const char *hostname;
646 if (G_IS_NETWORK_ADDRESS (identity))
647 hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
648 else if (G_IS_NETWORK_SERVICE (identity))
649 hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
653 return X509_check_host (openssl->cert, hostname, strlen (hostname), 0, NULL) == 1;
657 verify_identity_ip (GTlsCertificateOpenssl *openssl,
658 GSocketConnectable *identity)
662 const guint8 *addr_bytes;
665 if (G_IS_INET_SOCKET_ADDRESS (identity))
666 addr = g_object_ref (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity)));
668 const char *hostname;
670 if (G_IS_NETWORK_ADDRESS (identity))
671 hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
672 else if (G_IS_NETWORK_SERVICE (identity))
673 hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
677 addr = g_inet_address_new_from_string (hostname);
682 addr_bytes = g_inet_address_to_bytes (addr);
683 addr_size = g_inet_address_get_native_size (addr);
685 ret = X509_check_ip (openssl->cert, addr_bytes, addr_size, 0) == 1;
687 g_object_unref (addr);
692 g_tls_certificate_openssl_verify_identity (GTlsCertificateOpenssl *openssl,
693 GSocketConnectable *identity)
695 if (verify_identity_hostname (openssl, identity))
697 else if (verify_identity_ip (openssl, identity))
700 /* FIXME: check sRVName and uniformResourceIdentifier
701 * subjectAltNames, if appropriate for @identity.
704 TIZEN_LOGE("SSL HandShake - Bad Identity");
705 return G_TLS_CERTIFICATE_BAD_IDENTITY;
709 g_tls_certificate_openssl_convert_error (guint openssl_error)
711 GTlsCertificateFlags gtls_flags;
715 /* FIXME: should we add more ? */
716 switch (openssl_error)
720 case X509_V_ERR_CERT_NOT_YET_VALID:
721 gtls_flags = G_TLS_CERTIFICATE_NOT_ACTIVATED;
723 case X509_V_ERR_CERT_HAS_EXPIRED:
724 gtls_flags = G_TLS_CERTIFICATE_EXPIRED;
726 case X509_V_ERR_CERT_REVOKED:
727 gtls_flags = G_TLS_CERTIFICATE_REVOKED;
729 case X509_V_ERR_AKID_SKID_MISMATCH:
730 gtls_flags = G_TLS_CERTIFICATE_BAD_IDENTITY;
732 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
733 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
735 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
737 gtls_flags = G_TLS_CERTIFICATE_UNKNOWN_CA;
740 gtls_flags = G_TLS_CERTIFICATE_GENERIC_ERROR;
747 is_issuer (GTlsCertificateOpenssl *cert,
748 GTlsCertificateOpenssl *issuer)
754 STACK_OF(X509) *trusted;
755 gboolean ret = FALSE;
758 x = g_tls_certificate_openssl_get_cert (cert);
759 issuer_x = g_tls_certificate_openssl_get_cert (issuer);
761 store = X509_STORE_new ();
762 csc = X509_STORE_CTX_new ();
764 if (!X509_STORE_CTX_init (csc, store, x, NULL))
767 trusted = sk_X509_new_null ();
768 sk_X509_push (trusted, issuer_x);
770 X509_STORE_CTX_trusted_stack (csc, trusted);
771 X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CB_ISSUER_CHECK);
773 /* FIXME: is this the right way to do it? */
774 if (X509_verify_cert (csc) <= 0)
776 err = X509_STORE_CTX_get_error (csc);
777 if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)
783 sk_X509_free (trusted);
786 X509_STORE_CTX_free (csc);
787 X509_STORE_free (store);
792 GTlsCertificateOpenssl *
793 g_tls_certificate_openssl_build_chain (X509 *x,
794 STACK_OF (X509) *chain)
796 GPtrArray *glib_certs;
797 GTlsCertificateOpenssl *issuer;
798 GTlsCertificateOpenssl *result;
801 g_return_val_if_fail (x, NULL);
802 g_return_val_if_fail (chain, NULL);
804 glib_certs = g_ptr_array_new_full (sk_X509_num (chain), g_object_unref);
805 g_ptr_array_add (glib_certs, g_tls_certificate_openssl_new_from_x509 (x, NULL));
806 for (i = 1; i < sk_X509_num (chain); i++)
807 g_ptr_array_add (glib_certs, g_tls_certificate_openssl_new_from_x509 (sk_X509_value (chain, i), NULL));
809 /* Some servers send certs out of order, or will send duplicate
810 * certs, so we need to be careful when assigning the issuer of
811 * our new GTlsCertificateOpenssl.
813 for (i = 0; i < glib_certs->len; i++)
817 /* Check if the cert issued itself */
818 if (is_issuer (glib_certs->pdata[i], glib_certs->pdata[i]))
821 if (i < glib_certs->len - 1 &&
822 is_issuer (glib_certs->pdata[i], glib_certs->pdata[i + 1]))
824 issuer = glib_certs->pdata[i + 1];
828 for (j = 0; j < glib_certs->len; j++)
831 is_issuer (glib_certs->pdata[i], glib_certs->pdata[j]))
833 issuer = glib_certs->pdata[j];
840 g_tls_certificate_openssl_set_issuer (glib_certs->pdata[i], issuer);
843 result = g_object_ref (glib_certs->pdata[0]);
844 g_ptr_array_unref (glib_certs);