/* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2010 Collabora, Ltd. * * SPDX-License-Identifier: LGPL-2.1-or-later * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, see . * * Author: Stef Walter */ #include "config.h" #include "gtlsdatabase.h" #include "gasyncresult.h" #include "gcancellable.h" #include "glibintl.h" #include "gsocketconnectable.h" #include "gtask.h" #include "gtlscertificate.h" #include "gtlsinteraction.h" /** * GTlsDatabase: * * `GTlsDatabase` is used to look up certificates and other information * from a certificate or key store. It is an abstract base class which * TLS library specific subtypes override. * * A `GTlsDatabase` may be accessed from multiple threads by the TLS backend. * All implementations are required to be fully thread-safe. * * Most common client applications will not directly interact with * `GTlsDatabase`. It is used internally by [class@Gio.TlsConnection]. * * Since: 2.30 */ /** * GTlsDatabaseClass: * @verify_chain: Virtual method implementing * g_tls_database_verify_chain(). * @verify_chain_async: Virtual method implementing * g_tls_database_verify_chain_async(). * @verify_chain_finish: Virtual method implementing * g_tls_database_verify_chain_finish(). * @create_certificate_handle: Virtual method implementing * g_tls_database_create_certificate_handle(). * @lookup_certificate_for_handle: Virtual method implementing * g_tls_database_lookup_certificate_for_handle(). * @lookup_certificate_for_handle_async: Virtual method implementing * g_tls_database_lookup_certificate_for_handle_async(). * @lookup_certificate_for_handle_finish: Virtual method implementing * g_tls_database_lookup_certificate_for_handle_finish(). * @lookup_certificate_issuer: Virtual method implementing * g_tls_database_lookup_certificate_issuer(). * @lookup_certificate_issuer_async: Virtual method implementing * g_tls_database_lookup_certificate_issuer_async(). * @lookup_certificate_issuer_finish: Virtual method implementing * g_tls_database_lookup_certificate_issuer_finish(). * @lookup_certificates_issued_by: Virtual method implementing * g_tls_database_lookup_certificates_issued_by(). * @lookup_certificates_issued_by_async: Virtual method implementing * g_tls_database_lookup_certificates_issued_by_async(). * @lookup_certificates_issued_by_finish: Virtual method implementing * g_tls_database_lookup_certificates_issued_by_finish(). * * The class for #GTlsDatabase. Derived classes should implement the various * virtual methods. _async and _finish methods have a default * implementation that runs the corresponding sync method in a thread. * * Since: 2.30 */ G_DEFINE_ABSTRACT_TYPE (GTlsDatabase, g_tls_database, G_TYPE_OBJECT) enum { UNLOCK_REQUIRED, LAST_SIGNAL }; /** * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER: * * The purpose used to verify the server certificate in a TLS connection. This * is the most common purpose in use. Used by TLS clients. */ /** * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT: * * The purpose used to verify the client certificate in a TLS connection. * Used by TLS servers. */ static void g_tls_database_init (GTlsDatabase *cert) { } typedef struct _AsyncVerifyChain { GTlsCertificate *chain; gchar *purpose; GSocketConnectable *identity; GTlsInteraction *interaction; GTlsDatabaseVerifyFlags flags; } AsyncVerifyChain; static void async_verify_chain_free (gpointer data) { AsyncVerifyChain *args = data; g_clear_object (&args->chain); g_free (args->purpose); g_clear_object (&args->identity); g_clear_object (&args->interaction); g_slice_free (AsyncVerifyChain, args); } static void async_verify_chain_thread (GTask *task, gpointer object, gpointer task_data, GCancellable *cancellable) { AsyncVerifyChain *args = task_data; GTlsCertificateFlags verify_result; GError *error = NULL; verify_result = g_tls_database_verify_chain (G_TLS_DATABASE (object), args->chain, args->purpose, args->identity, args->interaction, args->flags, cancellable, &error); if (error) g_task_return_error (task, error); else g_task_return_int (task, (gssize)verify_result); } static void g_tls_database_real_verify_chain_async (GTlsDatabase *self, GTlsCertificate *chain, const gchar *purpose, GSocketConnectable *identity, GTlsInteraction *interaction, GTlsDatabaseVerifyFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; AsyncVerifyChain *args; args = g_slice_new0 (AsyncVerifyChain); args->chain = g_object_ref (chain); args->purpose = g_strdup (purpose); args->identity = identity ? g_object_ref (identity) : NULL; args->interaction = interaction ? g_object_ref (interaction) : NULL; args->flags = flags; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, g_tls_database_real_verify_chain_async); g_task_set_name (task, "[gio] verify TLS chain"); g_task_set_task_data (task, args, async_verify_chain_free); g_task_run_in_thread (task, async_verify_chain_thread); g_object_unref (task); } static GTlsCertificateFlags g_tls_database_real_verify_chain_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { GTlsCertificateFlags ret; g_return_val_if_fail (g_task_is_valid (result, self), G_TLS_CERTIFICATE_GENERIC_ERROR); ret = (GTlsCertificateFlags)g_task_propagate_int (G_TASK (result), error); if (ret == (GTlsCertificateFlags)-1) return G_TLS_CERTIFICATE_GENERIC_ERROR; else return ret; } typedef struct { gchar *handle; GTlsInteraction *interaction; GTlsDatabaseLookupFlags flags; } AsyncLookupCertificateForHandle; static void async_lookup_certificate_for_handle_free (gpointer data) { AsyncLookupCertificateForHandle *args = data; g_free (args->handle); g_clear_object (&args->interaction); g_slice_free (AsyncLookupCertificateForHandle, args); } static void async_lookup_certificate_for_handle_thread (GTask *task, gpointer object, gpointer task_data, GCancellable *cancellable) { AsyncLookupCertificateForHandle *args = task_data; GTlsCertificate *result; GError *error = NULL; result = g_tls_database_lookup_certificate_for_handle (G_TLS_DATABASE (object), args->handle, args->interaction, args->flags, cancellable, &error); if (result) g_task_return_pointer (task, result, g_object_unref); else g_task_return_error (task, error); } static void g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase *self, const gchar *handle, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; AsyncLookupCertificateForHandle *args; args = g_slice_new0 (AsyncLookupCertificateForHandle); args->handle = g_strdup (handle); args->interaction = interaction ? g_object_ref (interaction) : NULL; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, g_tls_database_real_lookup_certificate_for_handle_async); g_task_set_name (task, "[gio] lookup TLS certificate"); g_task_set_task_data (task, args, async_lookup_certificate_for_handle_free); g_task_run_in_thread (task, async_lookup_certificate_for_handle_thread); g_object_unref (task); } static GTlsCertificate* g_tls_database_real_lookup_certificate_for_handle_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); } typedef struct { GTlsCertificate *certificate; GTlsInteraction *interaction; GTlsDatabaseLookupFlags flags; } AsyncLookupCertificateIssuer; static void async_lookup_certificate_issuer_free (gpointer data) { AsyncLookupCertificateIssuer *args = data; g_clear_object (&args->certificate); g_clear_object (&args->interaction); g_slice_free (AsyncLookupCertificateIssuer, args); } static void async_lookup_certificate_issuer_thread (GTask *task, gpointer object, gpointer task_data, GCancellable *cancellable) { AsyncLookupCertificateIssuer *args = task_data; GTlsCertificate *issuer; GError *error = NULL; issuer = g_tls_database_lookup_certificate_issuer (G_TLS_DATABASE (object), args->certificate, args->interaction, args->flags, cancellable, &error); if (issuer) g_task_return_pointer (task, issuer, g_object_unref); else g_task_return_error (task, error); } static void g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase *self, GTlsCertificate *certificate, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; AsyncLookupCertificateIssuer *args; args = g_slice_new0 (AsyncLookupCertificateIssuer); args->certificate = g_object_ref (certificate); args->flags = flags; args->interaction = interaction ? g_object_ref (interaction) : NULL; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, g_tls_database_real_lookup_certificate_issuer_async); g_task_set_name (task, "[gio] lookup certificate issuer"); g_task_set_task_data (task, args, async_lookup_certificate_issuer_free); g_task_run_in_thread (task, async_lookup_certificate_issuer_thread); g_object_unref (task); } static GTlsCertificate * g_tls_database_real_lookup_certificate_issuer_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); } typedef struct { GByteArray *issuer; GTlsInteraction *interaction; GTlsDatabaseLookupFlags flags; } AsyncLookupCertificatesIssuedBy; static void async_lookup_certificates_issued_by_free (gpointer data) { AsyncLookupCertificatesIssuedBy *args = data; g_byte_array_unref (args->issuer); g_clear_object (&args->interaction); g_slice_free (AsyncLookupCertificatesIssuedBy, args); } static void async_lookup_certificates_free_certificates (gpointer data) { GList *list = data; g_list_free_full (list, g_object_unref); } static void async_lookup_certificates_issued_by_thread (GTask *task, gpointer object, gpointer task_data, GCancellable *cancellable) { AsyncLookupCertificatesIssuedBy *args = task_data; GList *results; GError *error = NULL; results = g_tls_database_lookup_certificates_issued_by (G_TLS_DATABASE (object), args->issuer, args->interaction, args->flags, cancellable, &error); if (results) g_task_return_pointer (task, results, async_lookup_certificates_free_certificates); else g_task_return_error (task, error); } static void g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase *self, GByteArray *issuer, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; AsyncLookupCertificatesIssuedBy *args; args = g_slice_new0 (AsyncLookupCertificatesIssuedBy); args->issuer = g_byte_array_ref (issuer); args->flags = flags; args->interaction = interaction ? g_object_ref (interaction) : NULL; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, g_tls_database_real_lookup_certificates_issued_by_async); g_task_set_name (task, "[gio] lookup certificates issued by"); g_task_set_task_data (task, args, async_lookup_certificates_issued_by_free); g_task_run_in_thread (task, async_lookup_certificates_issued_by_thread); g_object_unref (task); } static GList * g_tls_database_real_lookup_certificates_issued_by_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); } static void g_tls_database_class_init (GTlsDatabaseClass *klass) { klass->verify_chain_async = g_tls_database_real_verify_chain_async; klass->verify_chain_finish = g_tls_database_real_verify_chain_finish; klass->lookup_certificate_for_handle_async = g_tls_database_real_lookup_certificate_for_handle_async; klass->lookup_certificate_for_handle_finish = g_tls_database_real_lookup_certificate_for_handle_finish; klass->lookup_certificate_issuer_async = g_tls_database_real_lookup_certificate_issuer_async; klass->lookup_certificate_issuer_finish = g_tls_database_real_lookup_certificate_issuer_finish; klass->lookup_certificates_issued_by_async = g_tls_database_real_lookup_certificates_issued_by_async; klass->lookup_certificates_issued_by_finish = g_tls_database_real_lookup_certificates_issued_by_finish; } /** * g_tls_database_verify_chain: * @self: a #GTlsDatabase * @chain: a #GTlsCertificate chain * @purpose: the purpose that this certificate chain will be used for. * @identity: (nullable): the expected peer identity * @interaction: (nullable): used to interact with the user if necessary * @flags: additional verify flags * @cancellable: (nullable): a #GCancellable, or %NULL * @error: (nullable): a #GError, or %NULL * * Determines the validity of a certificate chain, outside the context * of a TLS session. * * @chain is a chain of #GTlsCertificate objects each pointing to the next * certificate in the chain by its #GTlsCertificate:issuer property. * * @purpose describes the purpose (or usage) for which the certificate * is being used. Typically @purpose will be set to %G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER * which means that the certificate is being used to authenticate a server * (and we are acting as the client). * * The @identity is used to ensure the server certificate is valid for * the expected peer identity. If the identity does not match the * certificate, %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the * return value. If @identity is %NULL, that bit will never be set in * the return value. The peer identity may also be used to check for * pinned certificates (trust exceptions) in the database. These may * override the normal verification process on a host-by-host basis. * * Currently there are no @flags, and %G_TLS_DATABASE_VERIFY_NONE should be * used. * * If @chain is found to be valid, then the return value will be 0. If * @chain is found to be invalid, then the return value will indicate at * least one problem found. If the function is unable to determine * whether @chain is valid (for example, because @cancellable is * triggered before it completes) then the return value will be * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set accordingly. * @error is not set when @chain is successfully analyzed but found to * be invalid. * * GLib guarantees that if certificate verification fails, at least one * error will be set in the return value, but it does not guarantee * that all possible errors will be set. Accordingly, you may not safely * decide to ignore any particular type of error. For example, it would * be incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow * expired certificates, because this could potentially be the only * error flag set even if other problems exist with the certificate. * * Prior to GLib 2.48, GLib's default TLS backend modified @chain to * represent the certification path built by #GTlsDatabase during * certificate verification by adjusting the #GTlsCertificate:issuer * property of each certificate in @chain. Since GLib 2.48, this no * longer occurs, so you cannot rely on #GTlsCertificate:issuer to * represent the actual certification path used during certificate * verification. * * Because TLS session context is not used, #GTlsDatabase may not * perform as many checks on the certificates as #GTlsConnection would. * For example, certificate constraints may not be honored, and * revocation checks may not be performed. The best way to verify TLS * certificates used by a TLS connection is to let #GTlsConnection * handle the verification. * * The TLS backend may attempt to look up and add missing certificates * to the chain. This may involve HTTP requests to download missing * certificates. * * This function can block. Use g_tls_database_verify_chain_async() to * perform the verification operation asynchronously. * * Returns: the appropriate #GTlsCertificateFlags which represents the * result of verification. * * Since: 2.30 */ GTlsCertificateFlags g_tls_database_verify_chain (GTlsDatabase *self, GTlsCertificate *chain, const gchar *purpose, GSocketConnectable *identity, GTlsInteraction *interaction, GTlsDatabaseVerifyFlags flags, GCancellable *cancellable, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (G_IS_TLS_CERTIFICATE (chain), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (purpose, G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain, G_TLS_CERTIFICATE_GENERIC_ERROR); return G_TLS_DATABASE_GET_CLASS (self)->verify_chain (self, chain, purpose, identity, interaction, flags, cancellable, error); } /** * g_tls_database_verify_chain_async: * @self: a #GTlsDatabase * @chain: a #GTlsCertificate chain * @purpose: the purpose that this certificate chain will be used for. * @identity: (nullable): the expected peer identity * @interaction: (nullable): used to interact with the user if necessary * @flags: additional verify flags * @cancellable: (nullable): a #GCancellable, or %NULL * @callback: callback to call when the operation completes * @user_data: the data to pass to the callback function * * Asynchronously determines the validity of a certificate chain after * looking up and adding any missing certificates to the chain. See * g_tls_database_verify_chain() for more information. * * Since: 2.30 */ void g_tls_database_verify_chain_async (GTlsDatabase *self, GTlsCertificate *chain, const gchar *purpose, GSocketConnectable *identity, GTlsInteraction *interaction, GTlsDatabaseVerifyFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (G_IS_TLS_DATABASE (self)); g_return_if_fail (G_IS_TLS_CERTIFICATE (chain)); g_return_if_fail (purpose != NULL); g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity)); g_return_if_fail (callback != NULL); g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async); G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async (self, chain, purpose, identity, interaction, flags, cancellable, callback, user_data); } /** * g_tls_database_verify_chain_finish: * @self: a #GTlsDatabase * @result: a #GAsyncResult. * @error: a #GError pointer, or %NULL * * Finish an asynchronous verify chain operation. See * g_tls_database_verify_chain() for more information. * * If @chain is found to be valid, then the return value will be 0. If * @chain is found to be invalid, then the return value will indicate * the problems found. If the function is unable to determine whether * @chain is valid or not (eg, because @cancellable is triggered * before it completes) then the return value will be * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set * accordingly. @error is not set when @chain is successfully analyzed * but found to be invalid. * * Returns: the appropriate #GTlsCertificateFlags which represents the * result of verification. * * Since: 2.30 */ GTlsCertificateFlags g_tls_database_verify_chain_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish, G_TLS_CERTIFICATE_GENERIC_ERROR); return G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish (self, result, error); } /** * g_tls_database_create_certificate_handle: * @self: a #GTlsDatabase * @certificate: certificate for which to create a handle. * * Create a handle string for the certificate. The database will only be able * to create a handle for certificates that originate from the database. In * cases where the database cannot create a handle for a certificate, %NULL * will be returned. * * This handle should be stable across various instances of the application, * and between applications. If a certificate is modified in the database, * then it is not guaranteed that this handle will continue to point to it. * * Returns: (nullable): a newly allocated string containing the * handle. * * Since: 2.30 */ gchar* g_tls_database_create_certificate_handle (GTlsDatabase *self, GTlsCertificate *certificate) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle, NULL); return G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle (self, certificate); } /** * g_tls_database_lookup_certificate_for_handle: * @self: a #GTlsDatabase * @handle: a certificate handle * @interaction: (nullable): used to interact with the user if necessary * @flags: Flags which affect the lookup. * @cancellable: (nullable): a #GCancellable, or %NULL * @error: (nullable): a #GError, or %NULL * * Look up a certificate by its handle. * * The handle should have been created by calling * g_tls_database_create_certificate_handle() on a #GTlsDatabase object of * the same TLS backend. The handle is designed to remain valid across * instantiations of the database. * * If the handle is no longer valid, or does not point to a certificate in * this database, then %NULL will be returned. * * This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform * the lookup operation asynchronously. * * Returns: (transfer full) (nullable): a newly allocated * #GTlsCertificate, or %NULL. Use g_object_unref() to release the certificate. * * Since: 2.30 */ GTlsCertificate* g_tls_database_lookup_certificate_for_handle (GTlsDatabase *self, const gchar *handle, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (handle != NULL, NULL); g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle (self, handle, interaction, flags, cancellable, error); } /** * g_tls_database_lookup_certificate_for_handle_async: * @self: a #GTlsDatabase * @handle: a certificate handle * @interaction: (nullable): used to interact with the user if necessary * @flags: Flags which affect the lookup. * @cancellable: (nullable): a #GCancellable, or %NULL * @callback: callback to call when the operation completes * @user_data: the data to pass to the callback function * * Asynchronously look up a certificate by its handle in the database. See * g_tls_database_lookup_certificate_for_handle() for more information. * * Since: 2.30 */ void g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *self, const gchar *handle, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (G_IS_TLS_DATABASE (self)); g_return_if_fail (handle != NULL); g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async); G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async (self, handle, interaction, flags, cancellable, callback, user_data); } /** * g_tls_database_lookup_certificate_for_handle_finish: * @self: a #GTlsDatabase * @result: a #GAsyncResult. * @error: a #GError pointer, or %NULL * * Finish an asynchronous lookup of a certificate by its handle. See * g_tls_database_lookup_certificate_for_handle() for more information. * * If the handle is no longer valid, or does not point to a certificate in * this database, then %NULL will be returned. * * Returns: (transfer full): a newly allocated #GTlsCertificate object. * Use g_object_unref() to release the certificate. * * Since: 2.30 */ GTlsCertificate* g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish (self, result, error); } /** * g_tls_database_lookup_certificate_issuer: * @self: a #GTlsDatabase * @certificate: a #GTlsCertificate * @interaction: (nullable): used to interact with the user if necessary * @flags: flags which affect the lookup operation * @cancellable: (nullable): a #GCancellable, or %NULL * @error: (nullable): a #GError, or %NULL * * Look up the issuer of @certificate in the database. The * #GTlsCertificate:issuer property of @certificate is not modified, and * the two certificates are not hooked into a chain. * * This function can block. Use g_tls_database_lookup_certificate_issuer_async() * to perform the lookup operation asynchronously. * * Beware this function cannot be used to build certification paths. The * issuer certificate returned by this function may not be the same as * the certificate that would actually be used to construct a valid * certification path during certificate verification. * [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains * why an issuer certificate cannot be naively assumed to be part of the * the certification path (though GLib's TLS backends may not follow the * path building strategies outlined in this RFC). Due to the complexity * of certification path building, GLib does not provide any way to know * which certification path will actually be used when verifying a TLS * certificate. Accordingly, this function cannot be used to make * security-related decisions. Only GLib itself should make security * decisions about TLS certificates. * * Returns: (transfer full): a newly allocated issuer #GTlsCertificate, * or %NULL. Use g_object_unref() to release the certificate. * * Since: 2.30 */ GTlsCertificate* g_tls_database_lookup_certificate_issuer (GTlsDatabase *self, GTlsCertificate *certificate, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL); g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer (self, certificate, interaction, flags, cancellable, error); } /** * g_tls_database_lookup_certificate_issuer_async: * @self: a #GTlsDatabase * @certificate: a #GTlsCertificate * @interaction: (nullable): used to interact with the user if necessary * @flags: flags which affect the lookup operation * @cancellable: (nullable): a #GCancellable, or %NULL * @callback: callback to call when the operation completes * @user_data: the data to pass to the callback function * * Asynchronously look up the issuer of @certificate in the database. See * g_tls_database_lookup_certificate_issuer() for more information. * * Since: 2.30 */ void g_tls_database_lookup_certificate_issuer_async (GTlsDatabase *self, GTlsCertificate *certificate, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (G_IS_TLS_DATABASE (self)); g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate)); g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (callback != NULL); g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async); G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async (self, certificate, interaction, flags, cancellable, callback, user_data); } /** * g_tls_database_lookup_certificate_issuer_finish: * @self: a #GTlsDatabase * @result: a #GAsyncResult. * @error: a #GError pointer, or %NULL * * Finish an asynchronous lookup issuer operation. See * g_tls_database_lookup_certificate_issuer() for more information. * * Returns: (transfer full): a newly allocated issuer #GTlsCertificate, * or %NULL. Use g_object_unref() to release the certificate. * * Since: 2.30 */ GTlsCertificate* g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish (self, result, error); } /** * g_tls_database_lookup_certificates_issued_by: * @self: a #GTlsDatabase * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN. * @interaction: (nullable): used to interact with the user if necessary * @flags: Flags which affect the lookup operation. * @cancellable: (nullable): a #GCancellable, or %NULL * @error: (nullable): a #GError, or %NULL * * Look up certificates issued by this issuer in the database. * * This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform * the lookup operation asynchronously. * * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list. * * Since: 2.30 */ GList* g_tls_database_lookup_certificates_issued_by (GTlsDatabase *self, GByteArray *issuer_raw_dn, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (issuer_raw_dn, NULL); g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by (self, issuer_raw_dn, interaction, flags, cancellable, error); } /** * g_tls_database_lookup_certificates_issued_by_async: * @self: a #GTlsDatabase * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN. * @interaction: (nullable): used to interact with the user if necessary * @flags: Flags which affect the lookup operation. * @cancellable: (nullable): a #GCancellable, or %NULL * @callback: callback to call when the operation completes * @user_data: the data to pass to the callback function * * Asynchronously look up certificates issued by this issuer in the database. See * g_tls_database_lookup_certificates_issued_by() for more information. * * The database may choose to hold a reference to the issuer byte array for the duration * of this asynchronous operation. The byte array should not be modified during * this time. * * Since: 2.30 */ void g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase *self, GByteArray *issuer_raw_dn, GTlsInteraction *interaction, GTlsDatabaseLookupFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (G_IS_TLS_DATABASE (self)); g_return_if_fail (issuer_raw_dn != NULL); g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (callback != NULL); g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async); G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async (self, issuer_raw_dn, interaction, flags, cancellable, callback, user_data); } /** * g_tls_database_lookup_certificates_issued_by_finish: * @self: a #GTlsDatabase * @result: a #GAsyncResult. * @error: a #GError pointer, or %NULL * * Finish an asynchronous lookup of certificates. See * g_tls_database_lookup_certificates_issued_by() for more information. * * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list. * * Since: 2.30 */ GList* g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish, NULL); return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish (self, result, error); }