mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 06:56:14 +01:00
78411d0975
Move it to the struct docs. Signed-off-by: Philip Withnall <philip@tecnocode.co.uk> Helps: #3037
1027 lines
44 KiB
C
1027 lines
44 KiB
C
/* 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Stef Walter <stefw@collabora.co.uk>
|
|
*/
|
|
|
|
#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);
|
|
}
|