1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2010 Collabora, Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author: Stef Walter <stefw@collabora.co.uk>
19  */
20 
21 #include "config.h"
22 
23 #include "gtlsdatabase.h"
24 
25 #include "gasyncresult.h"
26 #include "gcancellable.h"
27 #include "glibintl.h"
28 #include "gsocketconnectable.h"
29 #include "gtask.h"
30 #include "gtlscertificate.h"
31 #include "gtlsinteraction.h"
32 
33 /**
34  * SECTION:gtlsdatabase
35  * @short_description: TLS database type
36  * @include: gio/gio.h
37  *
38  * #GTlsDatabase is used to look up certificates and other information
39  * from a certificate or key store. It is an abstract base class which
40  * TLS library specific subtypes override.
41  *
42  * A #GTlsDatabase may be accessed from multiple threads by the TLS backend.
43  * All implementations are required to be fully thread-safe.
44  *
45  * Most common client applications will not directly interact with
46  * #GTlsDatabase. It is used internally by #GTlsConnection.
47  *
48  * Since: 2.30
49  */
50 
51 /**
52  * GTlsDatabase:
53  *
54  * Abstract base class for the backend-specific database types.
55  *
56  * Since: 2.30
57  */
58 
59 /**
60  * GTlsDatabaseClass:
61  * @verify_chain: Virtual method implementing
62  *  g_tls_database_verify_chain().
63  * @verify_chain_async: Virtual method implementing
64  *  g_tls_database_verify_chain_async().
65  * @verify_chain_finish: Virtual method implementing
66  *  g_tls_database_verify_chain_finish().
67  * @create_certificate_handle: Virtual method implementing
68  *  g_tls_database_create_certificate_handle().
69  * @lookup_certificate_for_handle: Virtual method implementing
70  *  g_tls_database_lookup_certificate_for_handle().
71  * @lookup_certificate_for_handle_async: Virtual method implementing
72  *  g_tls_database_lookup_certificate_for_handle_async().
73  * @lookup_certificate_for_handle_finish: Virtual method implementing
74  *  g_tls_database_lookup_certificate_for_handle_finish().
75  * @lookup_certificate_issuer: Virtual method implementing
76  *  g_tls_database_lookup_certificate_issuer().
77  * @lookup_certificate_issuer_async: Virtual method implementing
78  *  g_tls_database_lookup_certificate_issuer_async().
79  * @lookup_certificate_issuer_finish: Virtual method implementing
80  *  g_tls_database_lookup_certificate_issuer_finish().
81  * @lookup_certificates_issued_by: Virtual method implementing
82  *  g_tls_database_lookup_certificates_issued_by().
83  * @lookup_certificates_issued_by_async: Virtual method implementing
84  *  g_tls_database_lookup_certificates_issued_by_async().
85  * @lookup_certificates_issued_by_finish: Virtual method implementing
86  *  g_tls_database_lookup_certificates_issued_by_finish().
87  *
88  * The class for #GTlsDatabase. Derived classes should implement the various
89  * virtual methods. _async and _finish methods have a default
90  * implementation that runs the corresponding sync method in a thread.
91  *
92  * Since: 2.30
93  */
94 
95 G_DEFINE_ABSTRACT_TYPE (GTlsDatabase, g_tls_database, G_TYPE_OBJECT)
96 
97 enum {
98   UNLOCK_REQUIRED,
99 
100   LAST_SIGNAL
101 };
102 
103 /**
104  * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER:
105  *
106  * The purpose used to verify the server certificate in a TLS connection. This
107  * is the most common purpose in use. Used by TLS clients.
108  */
109 
110 /**
111  * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT:
112  *
113  * The purpose used to verify the client certificate in a TLS connection.
114  * Used by TLS servers.
115  */
116 
117 static void
g_tls_database_init(GTlsDatabase * cert)118 g_tls_database_init (GTlsDatabase *cert)
119 {
120 
121 }
122 
123 typedef struct _AsyncVerifyChain {
124   GTlsCertificate *chain;
125   gchar *purpose;
126   GSocketConnectable *identity;
127   GTlsInteraction *interaction;
128   GTlsDatabaseVerifyFlags flags;
129 } AsyncVerifyChain;
130 
131 static void
async_verify_chain_free(gpointer data)132 async_verify_chain_free (gpointer data)
133 {
134   AsyncVerifyChain *args = data;
135   g_clear_object (&args->chain);
136   g_free (args->purpose);
137   g_clear_object (&args->identity);
138   g_clear_object (&args->interaction);
139   g_slice_free (AsyncVerifyChain, args);
140 }
141 
142 static void
async_verify_chain_thread(GTask * task,gpointer object,gpointer task_data,GCancellable * cancellable)143 async_verify_chain_thread (GTask         *task,
144 			   gpointer       object,
145 			   gpointer       task_data,
146 			   GCancellable  *cancellable)
147 {
148   AsyncVerifyChain *args = task_data;
149   GTlsCertificateFlags verify_result;
150   GError *error = NULL;
151 
152   verify_result = g_tls_database_verify_chain (G_TLS_DATABASE (object),
153 					       args->chain,
154 					       args->purpose,
155 					       args->identity,
156 					       args->interaction,
157 					       args->flags,
158 					       cancellable,
159 					       &error);
160   if (error)
161     g_task_return_error (task, error);
162   else
163     g_task_return_int (task, (gssize)verify_result);
164 }
165 
166 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)167 g_tls_database_real_verify_chain_async (GTlsDatabase           *self,
168                                         GTlsCertificate        *chain,
169                                         const gchar            *purpose,
170                                         GSocketConnectable     *identity,
171                                         GTlsInteraction        *interaction,
172                                         GTlsDatabaseVerifyFlags flags,
173                                         GCancellable           *cancellable,
174                                         GAsyncReadyCallback     callback,
175                                         gpointer                user_data)
176 {
177   GTask *task;
178   AsyncVerifyChain *args;
179 
180   args = g_slice_new0 (AsyncVerifyChain);
181   args->chain = g_object_ref (chain);
182   args->purpose = g_strdup (purpose);
183   args->identity = identity ? g_object_ref (identity) : NULL;
184   args->interaction = interaction ? g_object_ref (interaction) : NULL;
185   args->flags = flags;
186 
187   task = g_task_new (self, cancellable, callback, user_data);
188   g_task_set_source_tag (task, g_tls_database_real_verify_chain_async);
189   g_task_set_name (task, "[gio] verify TLS chain");
190   g_task_set_task_data (task, args, async_verify_chain_free);
191   g_task_run_in_thread (task, async_verify_chain_thread);
192   g_object_unref (task);
193 }
194 
195 static GTlsCertificateFlags
g_tls_database_real_verify_chain_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)196 g_tls_database_real_verify_chain_finish (GTlsDatabase          *self,
197                                          GAsyncResult          *result,
198                                          GError               **error)
199 {
200   GTlsCertificateFlags ret;
201 
202   g_return_val_if_fail (g_task_is_valid (result, self), G_TLS_CERTIFICATE_GENERIC_ERROR);
203 
204   ret = (GTlsCertificateFlags)g_task_propagate_int (G_TASK (result), error);
205   if (ret == (GTlsCertificateFlags)-1)
206     return G_TLS_CERTIFICATE_GENERIC_ERROR;
207   else
208     return ret;
209 }
210 
211 typedef struct {
212   gchar *handle;
213   GTlsInteraction *interaction;
214   GTlsDatabaseLookupFlags flags;
215 } AsyncLookupCertificateForHandle;
216 
217 static void
async_lookup_certificate_for_handle_free(gpointer data)218 async_lookup_certificate_for_handle_free (gpointer data)
219 {
220   AsyncLookupCertificateForHandle *args = data;
221 
222   g_free (args->handle);
223   g_clear_object (&args->interaction);
224   g_slice_free (AsyncLookupCertificateForHandle, args);
225 }
226 
227 static void
async_lookup_certificate_for_handle_thread(GTask * task,gpointer object,gpointer task_data,GCancellable * cancellable)228 async_lookup_certificate_for_handle_thread (GTask         *task,
229 					    gpointer       object,
230 					    gpointer       task_data,
231 					    GCancellable  *cancellable)
232 {
233   AsyncLookupCertificateForHandle *args = task_data;
234   GTlsCertificate *result;
235   GError *error = NULL;
236 
237   result = g_tls_database_lookup_certificate_for_handle (G_TLS_DATABASE (object),
238 							 args->handle,
239 							 args->interaction,
240 							 args->flags,
241 							 cancellable,
242 							 &error);
243   if (result)
244     g_task_return_pointer (task, result, g_object_unref);
245   else
246     g_task_return_error (task, error);
247 }
248 
249 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)250 g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase           *self,
251                                                          const gchar            *handle,
252                                                          GTlsInteraction        *interaction,
253                                                          GTlsDatabaseLookupFlags flags,
254                                                          GCancellable           *cancellable,
255                                                          GAsyncReadyCallback     callback,
256                                                          gpointer                user_data)
257 {
258   GTask *task;
259   AsyncLookupCertificateForHandle *args;
260 
261   args = g_slice_new0 (AsyncLookupCertificateForHandle);
262   args->handle = g_strdup (handle);
263   args->interaction = interaction ? g_object_ref (interaction) : NULL;
264 
265   task = g_task_new (self, cancellable, callback, user_data);
266   g_task_set_source_tag (task,
267                          g_tls_database_real_lookup_certificate_for_handle_async);
268   g_task_set_name (task, "[gio] lookup TLS certificate");
269   g_task_set_task_data (task, args, async_lookup_certificate_for_handle_free);
270   g_task_run_in_thread (task, async_lookup_certificate_for_handle_thread);
271   g_object_unref (task);
272 }
273 
274 static GTlsCertificate*
g_tls_database_real_lookup_certificate_for_handle_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)275 g_tls_database_real_lookup_certificate_for_handle_finish (GTlsDatabase          *self,
276                                                           GAsyncResult          *result,
277                                                           GError               **error)
278 {
279   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
280 
281   return g_task_propagate_pointer (G_TASK (result), error);
282 }
283 
284 
285 typedef struct {
286   GTlsCertificate *certificate;
287   GTlsInteraction *interaction;
288   GTlsDatabaseLookupFlags flags;
289 } AsyncLookupCertificateIssuer;
290 
291 static void
async_lookup_certificate_issuer_free(gpointer data)292 async_lookup_certificate_issuer_free (gpointer data)
293 {
294   AsyncLookupCertificateIssuer *args = data;
295 
296   g_clear_object (&args->certificate);
297   g_clear_object (&args->interaction);
298   g_slice_free (AsyncLookupCertificateIssuer, args);
299 }
300 
301 static void
async_lookup_certificate_issuer_thread(GTask * task,gpointer object,gpointer task_data,GCancellable * cancellable)302 async_lookup_certificate_issuer_thread (GTask         *task,
303 					gpointer       object,
304 					gpointer       task_data,
305 					GCancellable  *cancellable)
306 {
307   AsyncLookupCertificateIssuer *args = task_data;
308   GTlsCertificate *issuer;
309   GError *error = NULL;
310 
311   issuer = g_tls_database_lookup_certificate_issuer (G_TLS_DATABASE (object),
312 						     args->certificate,
313 						     args->interaction,
314 						     args->flags,
315 						     cancellable,
316 						     &error);
317   if (issuer)
318     g_task_return_pointer (task, issuer, g_object_unref);
319   else
320     g_task_return_error (task, error);
321 }
322 
323 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)324 g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase           *self,
325                                                      GTlsCertificate        *certificate,
326                                                      GTlsInteraction        *interaction,
327                                                      GTlsDatabaseLookupFlags flags,
328                                                      GCancellable           *cancellable,
329                                                      GAsyncReadyCallback     callback,
330                                                      gpointer                user_data)
331 {
332   GTask *task;
333   AsyncLookupCertificateIssuer *args;
334 
335   args = g_slice_new0 (AsyncLookupCertificateIssuer);
336   args->certificate = g_object_ref (certificate);
337   args->flags = flags;
338   args->interaction = interaction ? g_object_ref (interaction) : NULL;
339 
340   task = g_task_new (self, cancellable, callback, user_data);
341   g_task_set_source_tag (task,
342                          g_tls_database_real_lookup_certificate_issuer_async);
343   g_task_set_name (task, "[gio] lookup certificate issuer");
344   g_task_set_task_data (task, args, async_lookup_certificate_issuer_free);
345   g_task_run_in_thread (task, async_lookup_certificate_issuer_thread);
346   g_object_unref (task);
347 }
348 
349 static GTlsCertificate *
g_tls_database_real_lookup_certificate_issuer_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)350 g_tls_database_real_lookup_certificate_issuer_finish (GTlsDatabase          *self,
351                                                       GAsyncResult          *result,
352                                                       GError               **error)
353 {
354   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
355 
356   return g_task_propagate_pointer (G_TASK (result), error);
357 }
358 
359 typedef struct {
360   GByteArray *issuer;
361   GTlsInteraction *interaction;
362   GTlsDatabaseLookupFlags flags;
363 } AsyncLookupCertificatesIssuedBy;
364 
365 static void
async_lookup_certificates_issued_by_free(gpointer data)366 async_lookup_certificates_issued_by_free (gpointer data)
367 {
368   AsyncLookupCertificatesIssuedBy *args = data;
369 
370   g_byte_array_unref (args->issuer);
371   g_clear_object (&args->interaction);
372   g_slice_free (AsyncLookupCertificatesIssuedBy, args);
373 }
374 
375 static void
async_lookup_certificates_free_certificates(gpointer data)376 async_lookup_certificates_free_certificates (gpointer data)
377 {
378   GList *list = data;
379 
380   g_list_free_full (list, g_object_unref);
381 }
382 
383 static void
async_lookup_certificates_issued_by_thread(GTask * task,gpointer object,gpointer task_data,GCancellable * cancellable)384 async_lookup_certificates_issued_by_thread (GTask         *task,
385 					    gpointer       object,
386 					    gpointer       task_data,
387                                             GCancellable  *cancellable)
388 {
389   AsyncLookupCertificatesIssuedBy *args = task_data;
390   GList *results;
391   GError *error = NULL;
392 
393   results = g_tls_database_lookup_certificates_issued_by (G_TLS_DATABASE (object),
394 							  args->issuer,
395 							  args->interaction,
396 							  args->flags,
397 							  cancellable,
398 							  &error);
399   if (results)
400     g_task_return_pointer (task, results, async_lookup_certificates_free_certificates);
401   else
402     g_task_return_error (task, error);
403 }
404 
405 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)406 g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase           *self,
407                                                          GByteArray             *issuer,
408                                                          GTlsInteraction        *interaction,
409                                                          GTlsDatabaseLookupFlags flags,
410                                                          GCancellable           *cancellable,
411                                                          GAsyncReadyCallback     callback,
412                                                          gpointer                user_data)
413 {
414   GTask *task;
415   AsyncLookupCertificatesIssuedBy *args;
416 
417   args = g_slice_new0 (AsyncLookupCertificatesIssuedBy);
418   args->issuer = g_byte_array_ref (issuer);
419   args->flags = flags;
420   args->interaction = interaction ? g_object_ref (interaction) : NULL;
421 
422   task = g_task_new (self, cancellable, callback, user_data);
423   g_task_set_source_tag (task,
424                          g_tls_database_real_lookup_certificates_issued_by_async);
425   g_task_set_name (task, "[gio] lookup certificates issued by");
426   g_task_set_task_data (task, args, async_lookup_certificates_issued_by_free);
427   g_task_run_in_thread (task, async_lookup_certificates_issued_by_thread);
428   g_object_unref (task);
429 }
430 
431 static GList *
g_tls_database_real_lookup_certificates_issued_by_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)432 g_tls_database_real_lookup_certificates_issued_by_finish (GTlsDatabase          *self,
433                                                           GAsyncResult          *result,
434                                                           GError               **error)
435 {
436   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
437 
438   return g_task_propagate_pointer (G_TASK (result), error);
439 }
440 
441 static void
g_tls_database_class_init(GTlsDatabaseClass * klass)442 g_tls_database_class_init (GTlsDatabaseClass *klass)
443 {
444   klass->verify_chain_async = g_tls_database_real_verify_chain_async;
445   klass->verify_chain_finish = g_tls_database_real_verify_chain_finish;
446   klass->lookup_certificate_for_handle_async = g_tls_database_real_lookup_certificate_for_handle_async;
447   klass->lookup_certificate_for_handle_finish = g_tls_database_real_lookup_certificate_for_handle_finish;
448   klass->lookup_certificate_issuer_async = g_tls_database_real_lookup_certificate_issuer_async;
449   klass->lookup_certificate_issuer_finish = g_tls_database_real_lookup_certificate_issuer_finish;
450   klass->lookup_certificates_issued_by_async = g_tls_database_real_lookup_certificates_issued_by_async;
451   klass->lookup_certificates_issued_by_finish = g_tls_database_real_lookup_certificates_issued_by_finish;
452 }
453 
454 /**
455  * g_tls_database_verify_chain:
456  * @self: a #GTlsDatabase
457  * @chain: a #GTlsCertificate chain
458  * @purpose: the purpose that this certificate chain will be used for.
459  * @identity: (nullable): the expected peer identity
460  * @interaction: (nullable): used to interact with the user if necessary
461  * @flags: additional verify flags
462  * @cancellable: (nullable): a #GCancellable, or %NULL
463  * @error: (nullable): a #GError, or %NULL
464  *
465  * Determines the validity of a certificate chain, outside the context
466  * of a TLS session.
467  *
468  * @chain is a chain of #GTlsCertificate objects each pointing to the next
469  * certificate in the chain by its #GTlsCertificate:issuer property.
470  *
471  * @purpose describes the purpose (or usage) for which the certificate
472  * is being used. Typically @purpose will be set to #G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
473  * which means that the certificate is being used to authenticate a server
474  * (and we are acting as the client).
475  *
476  * The @identity is used to ensure the server certificate is valid for
477  * the expected peer identity. If the identity does not match the
478  * certificate, %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the
479  * return value. If @identity is %NULL, that bit will never be set in
480  * the return value. The peer identity may also be used to check for
481  * pinned certificates (trust exceptions) in the database. These may
482  * override the normal verification process on a host-by-host basis.
483  *
484  * Currently there are no @flags, and %G_TLS_DATABASE_VERIFY_NONE should be
485  * used.
486  *
487  * If @chain is found to be valid, then the return value will be 0. If
488  * @chain is found to be invalid, then the return value will indicate
489  * the problems found. If the function is unable to determine whether
490  * @chain is valid or not (eg, because @cancellable is triggered
491  * before it completes) then the return value will be
492  * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set
493  * accordingly. @error is not set when @chain is successfully analyzed
494  * but found to be invalid.
495  *
496  * Prior to GLib 2.48, GLib's default TLS backend modified @chain to
497  * represent the certification path built by #GTlsDatabase during
498  * certificate verification by adjusting the #GTlsCertificate:issuer
499  * property of each certificate in @chain. Since GLib 2.48, this no
500  * longer occurs, so you cannot rely on #GTlsCertificate:issuer to
501  * represent the actual certification path used during certificate
502  * verification.
503  *
504  * Because TLS session context is not used, #GTlsDatabase may not
505  * perform as many checks on the certificates as #GTlsConnection would.
506  * For example, certificate constraints cannot be honored, and some
507  * revocation checks cannot be performed. The best way to verify TLS
508  * certificates used by a TLS connection is to let #GTlsConnection
509  * handle the verification.
510  *
511  * The TLS backend may attempt to look up and add missing certificates
512  * to the chain. Since GLib 2.70, this may involve HTTP requests to
513  * download missing certificates.
514  *
515  * This function can block. Use g_tls_database_verify_chain_async() to
516  * perform the verification operation asynchronously.
517  *
518  * Returns: the appropriate #GTlsCertificateFlags which represents the
519  * result of verification.
520  *
521  * Since: 2.30
522  */
523 GTlsCertificateFlags
g_tls_database_verify_chain(GTlsDatabase * self,GTlsCertificate * chain,const gchar * purpose,GSocketConnectable * identity,GTlsInteraction * interaction,GTlsDatabaseVerifyFlags flags,GCancellable * cancellable,GError ** error)524 g_tls_database_verify_chain (GTlsDatabase           *self,
525                              GTlsCertificate        *chain,
526                              const gchar            *purpose,
527                              GSocketConnectable     *identity,
528                              GTlsInteraction        *interaction,
529                              GTlsDatabaseVerifyFlags flags,
530                              GCancellable           *cancellable,
531                              GError                **error)
532 {
533   g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
534   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (chain),
535                         G_TLS_CERTIFICATE_GENERIC_ERROR);
536   g_return_val_if_fail (purpose, G_TLS_CERTIFICATE_GENERIC_ERROR);
537   g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction),
538                         G_TLS_CERTIFICATE_GENERIC_ERROR);
539   g_return_val_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity),
540                         G_TLS_CERTIFICATE_GENERIC_ERROR);
541   g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
542 
543   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain,
544                         G_TLS_CERTIFICATE_GENERIC_ERROR);
545 
546   return G_TLS_DATABASE_GET_CLASS (self)->verify_chain (self,
547                                                         chain,
548                                                         purpose,
549                                                         identity,
550                                                         interaction,
551                                                         flags,
552                                                         cancellable,
553                                                         error);
554 }
555 
556 /**
557  * g_tls_database_verify_chain_async:
558  * @self: a #GTlsDatabase
559  * @chain: a #GTlsCertificate chain
560  * @purpose: the purpose that this certificate chain will be used for.
561  * @identity: (nullable): the expected peer identity
562  * @interaction: (nullable): used to interact with the user if necessary
563  * @flags: additional verify flags
564  * @cancellable: (nullable): a #GCancellable, or %NULL
565  * @callback: callback to call when the operation completes
566  * @user_data: the data to pass to the callback function
567  *
568  * Asynchronously determines the validity of a certificate chain after
569  * looking up and adding any missing certificates to the chain. See
570  * g_tls_database_verify_chain() for more information.
571  *
572  * Since: 2.30
573  */
574 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)575 g_tls_database_verify_chain_async (GTlsDatabase           *self,
576                                    GTlsCertificate        *chain,
577                                    const gchar            *purpose,
578                                    GSocketConnectable     *identity,
579                                    GTlsInteraction        *interaction,
580                                    GTlsDatabaseVerifyFlags flags,
581                                    GCancellable           *cancellable,
582                                    GAsyncReadyCallback     callback,
583                                    gpointer                user_data)
584 {
585   g_return_if_fail (G_IS_TLS_DATABASE (self));
586   g_return_if_fail (G_IS_TLS_CERTIFICATE (chain));
587   g_return_if_fail (purpose != NULL);
588   g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
589   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
590   g_return_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity));
591   g_return_if_fail (callback != NULL);
592 
593   g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async);
594   G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async (self,
595                                                        chain,
596                                                        purpose,
597                                                        identity,
598                                                        interaction,
599                                                        flags,
600                                                        cancellable,
601                                                        callback,
602                                                        user_data);
603 }
604 
605 /**
606  * g_tls_database_verify_chain_finish:
607  * @self: a #GTlsDatabase
608  * @result: a #GAsyncResult.
609  * @error: a #GError pointer, or %NULL
610  *
611  * Finish an asynchronous verify chain operation. See
612  * g_tls_database_verify_chain() for more information.
613  *
614  * If @chain is found to be valid, then the return value will be 0. If
615  * @chain is found to be invalid, then the return value will indicate
616  * the problems found. If the function is unable to determine whether
617  * @chain is valid or not (eg, because @cancellable is triggered
618  * before it completes) then the return value will be
619  * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set
620  * accordingly. @error is not set when @chain is successfully analyzed
621  * but found to be invalid.
622  *
623  * Returns: the appropriate #GTlsCertificateFlags which represents the
624  * result of verification.
625  *
626  * Since: 2.30
627  */
628 GTlsCertificateFlags
g_tls_database_verify_chain_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)629 g_tls_database_verify_chain_finish (GTlsDatabase          *self,
630                                     GAsyncResult          *result,
631                                     GError               **error)
632 {
633   g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
634   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR);
635   g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
636   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish,
637                         G_TLS_CERTIFICATE_GENERIC_ERROR);
638   return G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish (self,
639                                                                result,
640                                                                error);
641 }
642 
643 /**
644  * g_tls_database_create_certificate_handle:
645  * @self: a #GTlsDatabase
646  * @certificate: certificate for which to create a handle.
647  *
648  * Create a handle string for the certificate. The database will only be able
649  * to create a handle for certificates that originate from the database. In
650  * cases where the database cannot create a handle for a certificate, %NULL
651  * will be returned.
652  *
653  * This handle should be stable across various instances of the application,
654  * and between applications. If a certificate is modified in the database,
655  * then it is not guaranteed that this handle will continue to point to it.
656  *
657  * Returns: (nullable): a newly allocated string containing the
658  * handle.
659  *
660  * Since: 2.30
661  */
662 gchar*
g_tls_database_create_certificate_handle(GTlsDatabase * self,GTlsCertificate * certificate)663 g_tls_database_create_certificate_handle (GTlsDatabase            *self,
664                                           GTlsCertificate         *certificate)
665 {
666   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
667   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
668   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle, NULL);
669   return G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle (self,
670                                                                      certificate);
671 }
672 
673 /**
674  * g_tls_database_lookup_certificate_for_handle:
675  * @self: a #GTlsDatabase
676  * @handle: a certificate handle
677  * @interaction: (nullable): used to interact with the user if necessary
678  * @flags: Flags which affect the lookup.
679  * @cancellable: (nullable): a #GCancellable, or %NULL
680  * @error: (nullable): a #GError, or %NULL
681  *
682  * Look up a certificate by its handle.
683  *
684  * The handle should have been created by calling
685  * g_tls_database_create_certificate_handle() on a #GTlsDatabase object of
686  * the same TLS backend. The handle is designed to remain valid across
687  * instantiations of the database.
688  *
689  * If the handle is no longer valid, or does not point to a certificate in
690  * this database, then %NULL will be returned.
691  *
692  * This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform
693  * the lookup operation asynchronously.
694  *
695  * Returns: (transfer full) (nullable): a newly allocated
696  * #GTlsCertificate, or %NULL. Use g_object_unref() to release the certificate.
697  *
698  * Since: 2.30
699  */
700 GTlsCertificate*
g_tls_database_lookup_certificate_for_handle(GTlsDatabase * self,const gchar * handle,GTlsInteraction * interaction,GTlsDatabaseLookupFlags flags,GCancellable * cancellable,GError ** error)701 g_tls_database_lookup_certificate_for_handle (GTlsDatabase            *self,
702                                               const gchar             *handle,
703                                               GTlsInteraction         *interaction,
704                                               GTlsDatabaseLookupFlags  flags,
705                                               GCancellable            *cancellable,
706                                               GError                 **error)
707 {
708   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
709   g_return_val_if_fail (handle != NULL, NULL);
710   g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
711   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
712   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
713   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle, NULL);
714   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle (self,
715                                                                          handle,
716                                                                          interaction,
717                                                                          flags,
718                                                                          cancellable,
719                                                                          error);
720 }
721 
722 
723 /**
724  * g_tls_database_lookup_certificate_for_handle_async:
725  * @self: a #GTlsDatabase
726  * @handle: a certificate handle
727  * @interaction: (nullable): used to interact with the user if necessary
728  * @flags: Flags which affect the lookup.
729  * @cancellable: (nullable): a #GCancellable, or %NULL
730  * @callback: callback to call when the operation completes
731  * @user_data: the data to pass to the callback function
732  *
733  * Asynchronously look up a certificate by its handle in the database. See
734  * g_tls_database_lookup_certificate_for_handle() for more information.
735  *
736  * Since: 2.30
737  */
738 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)739 g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase            *self,
740                                                     const gchar             *handle,
741                                                     GTlsInteraction         *interaction,
742                                                     GTlsDatabaseLookupFlags  flags,
743                                                     GCancellable            *cancellable,
744                                                     GAsyncReadyCallback      callback,
745                                                     gpointer                 user_data)
746 {
747   g_return_if_fail (G_IS_TLS_DATABASE (self));
748   g_return_if_fail (handle != NULL);
749   g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
750   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
751   g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async);
752   G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async (self,
753                                                                                handle,
754                                                                                interaction,
755                                                                                flags,
756                                                                                cancellable,
757                                                                                callback,
758                                                                                user_data);
759 }
760 
761 /**
762  * g_tls_database_lookup_certificate_for_handle_finish:
763  * @self: a #GTlsDatabase
764  * @result: a #GAsyncResult.
765  * @error: a #GError pointer, or %NULL
766  *
767  * Finish an asynchronous lookup of a certificate by its handle. See
768  * g_tls_database_lookup_certificate_for_handle() for more information.
769  *
770  * If the handle is no longer valid, or does not point to a certificate in
771  * this database, then %NULL will be returned.
772  *
773  * Returns: (transfer full): a newly allocated #GTlsCertificate object.
774  * Use g_object_unref() to release the certificate.
775  *
776  * Since: 2.30
777  */
778 GTlsCertificate*
g_tls_database_lookup_certificate_for_handle_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)779 g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase            *self,
780                                                      GAsyncResult            *result,
781                                                      GError                 **error)
782 {
783   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
784   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
785   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
786   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish, NULL);
787   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish (self,
788                                                                                 result,
789                                                                                 error);
790 }
791 
792 /**
793  * g_tls_database_lookup_certificate_issuer:
794  * @self: a #GTlsDatabase
795  * @certificate: a #GTlsCertificate
796  * @interaction: (nullable): used to interact with the user if necessary
797  * @flags: flags which affect the lookup operation
798  * @cancellable: (nullable): a #GCancellable, or %NULL
799  * @error: (nullable): a #GError, or %NULL
800  *
801  * Look up the issuer of @certificate in the database. The
802  * #GTlsCertificate:issuer property of @certificate is not modified, and
803  * the two certificates are not hooked into a chain.
804  *
805  * This function can block. Use g_tls_database_lookup_certificate_issuer_async()
806  * to perform the lookup operation asynchronously.
807  *
808  * Beware this function cannot be used to build certification paths. The
809  * issuer certificate returned by this function may not be the same as
810  * the certificate that would actually be used to construct a valid
811  * certification path during certificate verification.
812  * [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains
813  * why an issuer certificate cannot be naively assumed to be part of the
814  * the certification path (though GLib's TLS backends may not follow the
815  * path building strategies outlined in this RFC). Due to the complexity
816  * of certification path building, GLib does not provide any way to know
817  * which certification path will actually be used when verifying a TLS
818  * certificate. Accordingly, this function cannot be used to make
819  * security-related decisions. Only GLib itself should make security
820  * decisions about TLS certificates.
821  *
822  * Returns: (transfer full): a newly allocated issuer #GTlsCertificate,
823  * or %NULL. Use g_object_unref() to release the certificate.
824  *
825  * Since: 2.30
826  */
827 GTlsCertificate*
g_tls_database_lookup_certificate_issuer(GTlsDatabase * self,GTlsCertificate * certificate,GTlsInteraction * interaction,GTlsDatabaseLookupFlags flags,GCancellable * cancellable,GError ** error)828 g_tls_database_lookup_certificate_issuer (GTlsDatabase           *self,
829                                           GTlsCertificate        *certificate,
830                                           GTlsInteraction        *interaction,
831                                           GTlsDatabaseLookupFlags flags,
832                                           GCancellable           *cancellable,
833                                           GError                **error)
834 {
835   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
836   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
837   g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
838   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
839   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
840   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer, NULL);
841   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer (self,
842                                                                      certificate,
843                                                                      interaction,
844                                                                      flags,
845                                                                      cancellable,
846                                                                      error);
847 }
848 
849 /**
850  * g_tls_database_lookup_certificate_issuer_async:
851  * @self: a #GTlsDatabase
852  * @certificate: a #GTlsCertificate
853  * @interaction: (nullable): used to interact with the user if necessary
854  * @flags: flags which affect the lookup operation
855  * @cancellable: (nullable): a #GCancellable, or %NULL
856  * @callback: callback to call when the operation completes
857  * @user_data: the data to pass to the callback function
858  *
859  * Asynchronously look up the issuer of @certificate in the database. See
860  * g_tls_database_lookup_certificate_issuer() for more information.
861  *
862  * Since: 2.30
863  */
864 void
g_tls_database_lookup_certificate_issuer_async(GTlsDatabase * self,GTlsCertificate * certificate,GTlsInteraction * interaction,GTlsDatabaseLookupFlags flags,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)865 g_tls_database_lookup_certificate_issuer_async (GTlsDatabase           *self,
866                                                 GTlsCertificate        *certificate,
867                                                 GTlsInteraction        *interaction,
868                                                 GTlsDatabaseLookupFlags flags,
869                                                 GCancellable           *cancellable,
870                                                 GAsyncReadyCallback     callback,
871                                                 gpointer                user_data)
872 {
873   g_return_if_fail (G_IS_TLS_DATABASE (self));
874   g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
875   g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
876   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
877   g_return_if_fail (callback != NULL);
878   g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async);
879   G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async (self,
880                                                         certificate,
881                                                         interaction,
882                                                         flags,
883                                                         cancellable,
884                                                         callback,
885                                                         user_data);
886 }
887 
888 /**
889  * g_tls_database_lookup_certificate_issuer_finish:
890  * @self: a #GTlsDatabase
891  * @result: a #GAsyncResult.
892  * @error: a #GError pointer, or %NULL
893  *
894  * Finish an asynchronous lookup issuer operation. See
895  * g_tls_database_lookup_certificate_issuer() for more information.
896  *
897  * Returns: (transfer full): a newly allocated issuer #GTlsCertificate,
898  * or %NULL. Use g_object_unref() to release the certificate.
899  *
900  * Since: 2.30
901  */
902 GTlsCertificate*
g_tls_database_lookup_certificate_issuer_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)903 g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase          *self,
904                                                  GAsyncResult          *result,
905                                                  GError               **error)
906 {
907   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
908   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
909   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
910   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish, NULL);
911   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish (self,
912                                                                 result,
913                                                                 error);
914 }
915 
916 /**
917  * g_tls_database_lookup_certificates_issued_by:
918  * @self: a #GTlsDatabase
919  * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
920  * @interaction: (nullable): used to interact with the user if necessary
921  * @flags: Flags which affect the lookup operation.
922  * @cancellable: (nullable): a #GCancellable, or %NULL
923  * @error: (nullable): a #GError, or %NULL
924  *
925  * Look up certificates issued by this issuer in the database.
926  *
927  * This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform
928  * the lookup operation asynchronously.
929  *
930  * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate
931  * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list.
932  *
933  * Since: 2.30
934  */
935 GList*
g_tls_database_lookup_certificates_issued_by(GTlsDatabase * self,GByteArray * issuer_raw_dn,GTlsInteraction * interaction,GTlsDatabaseLookupFlags flags,GCancellable * cancellable,GError ** error)936 g_tls_database_lookup_certificates_issued_by (GTlsDatabase           *self,
937                                               GByteArray             *issuer_raw_dn,
938                                               GTlsInteraction        *interaction,
939                                               GTlsDatabaseLookupFlags flags,
940                                               GCancellable           *cancellable,
941                                               GError                **error)
942 {
943   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
944   g_return_val_if_fail (issuer_raw_dn, NULL);
945   g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
946   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
947   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
948   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by, NULL);
949   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by (self,
950                                                                          issuer_raw_dn,
951                                                                          interaction,
952                                                                          flags,
953                                                                          cancellable,
954                                                                          error);
955 }
956 
957 /**
958  * g_tls_database_lookup_certificates_issued_by_async:
959  * @self: a #GTlsDatabase
960  * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
961  * @interaction: (nullable): used to interact with the user if necessary
962  * @flags: Flags which affect the lookup operation.
963  * @cancellable: (nullable): a #GCancellable, or %NULL
964  * @callback: callback to call when the operation completes
965  * @user_data: the data to pass to the callback function
966  *
967  * Asynchronously look up certificates issued by this issuer in the database. See
968  * g_tls_database_lookup_certificates_issued_by() for more information.
969  *
970  * The database may choose to hold a reference to the issuer byte array for the duration
971  * of of this asynchronous operation. The byte array should not be modified during
972  * this time.
973  *
974  * Since: 2.30
975  */
976 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)977 g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase           *self,
978                                                     GByteArray             *issuer_raw_dn,
979                                                     GTlsInteraction        *interaction,
980                                                     GTlsDatabaseLookupFlags flags,
981                                                     GCancellable           *cancellable,
982                                                     GAsyncReadyCallback     callback,
983                                                     gpointer                user_data)
984 {
985   g_return_if_fail (G_IS_TLS_DATABASE (self));
986   g_return_if_fail (issuer_raw_dn != NULL);
987   g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
988   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
989   g_return_if_fail (callback != NULL);
990   g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async);
991   G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async (self,
992                                                                         issuer_raw_dn,
993                                                                         interaction,
994                                                                         flags,
995                                                                         cancellable,
996                                                                         callback,
997                                                                         user_data);
998 }
999 
1000 /**
1001  * g_tls_database_lookup_certificates_issued_by_finish:
1002  * @self: a #GTlsDatabase
1003  * @result: a #GAsyncResult.
1004  * @error: a #GError pointer, or %NULL
1005  *
1006  * Finish an asynchronous lookup of certificates. See
1007  * g_tls_database_lookup_certificates_issued_by() for more information.
1008  *
1009  * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate
1010  * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list.
1011  *
1012  * Since: 2.30
1013  */
1014 GList*
g_tls_database_lookup_certificates_issued_by_finish(GTlsDatabase * self,GAsyncResult * result,GError ** error)1015 g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase          *self,
1016                                                      GAsyncResult          *result,
1017                                                      GError               **error)
1018 {
1019   g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
1020   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
1021   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1022   g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish, NULL);
1023   return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish (self,
1024                                                                                 result,
1025                                                                                 error);
1026 }
1027