gio/auto/
tls_database.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{
6    ffi, AsyncResult, Cancellable, SocketConnectable, TlsCertificate, TlsCertificateFlags,
7    TlsDatabaseLookupFlags, TlsDatabaseVerifyFlags, TlsInteraction,
8};
9use glib::{prelude::*, translate::*};
10use std::{boxed::Box as Box_, pin::Pin};
11
12glib::wrapper! {
13    /// `GTlsDatabase` is used to look up certificates and other information
14    /// from a certificate or key store. It is an abstract base class which
15    /// TLS library specific subtypes override.
16    ///
17    /// A `GTlsDatabase` may be accessed from multiple threads by the TLS backend.
18    /// All implementations are required to be fully thread-safe.
19    ///
20    /// Most common client applications will not directly interact with
21    /// `GTlsDatabase`. It is used internally by [`TlsConnection`][crate::TlsConnection].
22    ///
23    /// This is an Abstract Base Class, you cannot instantiate it.
24    ///
25    /// # Implements
26    ///
27    /// [`TlsDatabaseExt`][trait@crate::prelude::TlsDatabaseExt], [`trait@glib::ObjectExt`]
28    #[doc(alias = "GTlsDatabase")]
29    pub struct TlsDatabase(Object<ffi::GTlsDatabase, ffi::GTlsDatabaseClass>);
30
31    match fn {
32        type_ => || ffi::g_tls_database_get_type(),
33    }
34}
35
36impl TlsDatabase {
37    pub const NONE: Option<&'static TlsDatabase> = None;
38}
39
40/// Trait containing all [`struct@TlsDatabase`] methods.
41///
42/// # Implementors
43///
44/// [`TlsDatabase`][struct@crate::TlsDatabase], [`TlsFileDatabase`][struct@crate::TlsFileDatabase]
45pub trait TlsDatabaseExt: IsA<TlsDatabase> + 'static {
46    /// Create a handle string for the certificate. The database will only be able
47    /// to create a handle for certificates that originate from the database. In
48    /// cases where the database cannot create a handle for a certificate, [`None`]
49    /// will be returned.
50    ///
51    /// This handle should be stable across various instances of the application,
52    /// and between applications. If a certificate is modified in the database,
53    /// then it is not guaranteed that this handle will continue to point to it.
54    /// ## `certificate`
55    /// certificate for which to create a handle.
56    ///
57    /// # Returns
58    ///
59    /// a newly allocated string containing the
60    /// handle.
61    #[doc(alias = "g_tls_database_create_certificate_handle")]
62    fn create_certificate_handle(
63        &self,
64        certificate: &impl IsA<TlsCertificate>,
65    ) -> Option<glib::GString> {
66        unsafe {
67            from_glib_full(ffi::g_tls_database_create_certificate_handle(
68                self.as_ref().to_glib_none().0,
69                certificate.as_ref().to_glib_none().0,
70            ))
71        }
72    }
73
74    /// Look up a certificate by its handle.
75    ///
76    /// The handle should have been created by calling
77    /// g_tls_database_create_certificate_handle() on a #GTlsDatabase object of
78    /// the same TLS backend. The handle is designed to remain valid across
79    /// instantiations of the database.
80    ///
81    /// If the handle is no longer valid, or does not point to a certificate in
82    /// this database, then [`None`] will be returned.
83    ///
84    /// This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform
85    /// the lookup operation asynchronously.
86    /// ## `handle`
87    /// a certificate handle
88    /// ## `interaction`
89    /// used to interact with the user if necessary
90    /// ## `flags`
91    /// Flags which affect the lookup.
92    /// ## `cancellable`
93    /// a #GCancellable, or [`None`]
94    ///
95    /// # Returns
96    ///
97    /// a newly allocated
98    /// #GTlsCertificate, or [`None`]. Use g_object_unref() to release the certificate.
99    #[doc(alias = "g_tls_database_lookup_certificate_for_handle")]
100    fn lookup_certificate_for_handle(
101        &self,
102        handle: &str,
103        interaction: Option<&impl IsA<TlsInteraction>>,
104        flags: TlsDatabaseLookupFlags,
105        cancellable: Option<&impl IsA<Cancellable>>,
106    ) -> Result<Option<TlsCertificate>, glib::Error> {
107        unsafe {
108            let mut error = std::ptr::null_mut();
109            let ret = ffi::g_tls_database_lookup_certificate_for_handle(
110                self.as_ref().to_glib_none().0,
111                handle.to_glib_none().0,
112                interaction.map(|p| p.as_ref()).to_glib_none().0,
113                flags.into_glib(),
114                cancellable.map(|p| p.as_ref()).to_glib_none().0,
115                &mut error,
116            );
117            if error.is_null() {
118                Ok(from_glib_full(ret))
119            } else {
120                Err(from_glib_full(error))
121            }
122        }
123    }
124
125    /// Asynchronously look up a certificate by its handle in the database. See
126    /// g_tls_database_lookup_certificate_for_handle() for more information.
127    /// ## `handle`
128    /// a certificate handle
129    /// ## `interaction`
130    /// used to interact with the user if necessary
131    /// ## `flags`
132    /// Flags which affect the lookup.
133    /// ## `cancellable`
134    /// a #GCancellable, or [`None`]
135    /// ## `callback`
136    /// callback to call when the operation completes
137    #[doc(alias = "g_tls_database_lookup_certificate_for_handle_async")]
138    fn lookup_certificate_for_handle_async<
139        P: FnOnce(Result<TlsCertificate, glib::Error>) + 'static,
140    >(
141        &self,
142        handle: &str,
143        interaction: Option<&impl IsA<TlsInteraction>>,
144        flags: TlsDatabaseLookupFlags,
145        cancellable: Option<&impl IsA<Cancellable>>,
146        callback: P,
147    ) {
148        let main_context = glib::MainContext::ref_thread_default();
149        let is_main_context_owner = main_context.is_owner();
150        let has_acquired_main_context = (!is_main_context_owner)
151            .then(|| main_context.acquire().ok())
152            .flatten();
153        assert!(
154            is_main_context_owner || has_acquired_main_context.is_some(),
155            "Async operations only allowed if the thread is owning the MainContext"
156        );
157
158        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
159            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
160        unsafe extern "C" fn lookup_certificate_for_handle_async_trampoline<
161            P: FnOnce(Result<TlsCertificate, glib::Error>) + 'static,
162        >(
163            _source_object: *mut glib::gobject_ffi::GObject,
164            res: *mut crate::ffi::GAsyncResult,
165            user_data: glib::ffi::gpointer,
166        ) {
167            let mut error = std::ptr::null_mut();
168            let ret = ffi::g_tls_database_lookup_certificate_for_handle_finish(
169                _source_object as *mut _,
170                res,
171                &mut error,
172            );
173            let result = if error.is_null() {
174                Ok(from_glib_full(ret))
175            } else {
176                Err(from_glib_full(error))
177            };
178            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
179                Box_::from_raw(user_data as *mut _);
180            let callback: P = callback.into_inner();
181            callback(result);
182        }
183        let callback = lookup_certificate_for_handle_async_trampoline::<P>;
184        unsafe {
185            ffi::g_tls_database_lookup_certificate_for_handle_async(
186                self.as_ref().to_glib_none().0,
187                handle.to_glib_none().0,
188                interaction.map(|p| p.as_ref()).to_glib_none().0,
189                flags.into_glib(),
190                cancellable.map(|p| p.as_ref()).to_glib_none().0,
191                Some(callback),
192                Box_::into_raw(user_data) as *mut _,
193            );
194        }
195    }
196
197    fn lookup_certificate_for_handle_future(
198        &self,
199        handle: &str,
200        interaction: Option<&(impl IsA<TlsInteraction> + Clone + 'static)>,
201        flags: TlsDatabaseLookupFlags,
202    ) -> Pin<Box_<dyn std::future::Future<Output = Result<TlsCertificate, glib::Error>> + 'static>>
203    {
204        let handle = String::from(handle);
205        let interaction = interaction.map(ToOwned::to_owned);
206        Box_::pin(crate::GioFuture::new(
207            self,
208            move |obj, cancellable, send| {
209                obj.lookup_certificate_for_handle_async(
210                    &handle,
211                    interaction.as_ref().map(::std::borrow::Borrow::borrow),
212                    flags,
213                    Some(cancellable),
214                    move |res| {
215                        send.resolve(res);
216                    },
217                );
218            },
219        ))
220    }
221
222    /// Look up the issuer of @certificate in the database. The
223    /// #GTlsCertificate:issuer property of @certificate is not modified, and
224    /// the two certificates are not hooked into a chain.
225    ///
226    /// This function can block. Use g_tls_database_lookup_certificate_issuer_async()
227    /// to perform the lookup operation asynchronously.
228    ///
229    /// Beware this function cannot be used to build certification paths. The
230    /// issuer certificate returned by this function may not be the same as
231    /// the certificate that would actually be used to construct a valid
232    /// certification path during certificate verification.
233    /// [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains
234    /// why an issuer certificate cannot be naively assumed to be part of the
235    /// the certification path (though GLib's TLS backends may not follow the
236    /// path building strategies outlined in this RFC). Due to the complexity
237    /// of certification path building, GLib does not provide any way to know
238    /// which certification path will actually be used when verifying a TLS
239    /// certificate. Accordingly, this function cannot be used to make
240    /// security-related decisions. Only GLib itself should make security
241    /// decisions about TLS certificates.
242    /// ## `certificate`
243    /// a #GTlsCertificate
244    /// ## `interaction`
245    /// used to interact with the user if necessary
246    /// ## `flags`
247    /// flags which affect the lookup operation
248    /// ## `cancellable`
249    /// a #GCancellable, or [`None`]
250    ///
251    /// # Returns
252    ///
253    /// a newly allocated issuer #GTlsCertificate,
254    /// or [`None`]. Use g_object_unref() to release the certificate.
255    #[doc(alias = "g_tls_database_lookup_certificate_issuer")]
256    fn lookup_certificate_issuer(
257        &self,
258        certificate: &impl IsA<TlsCertificate>,
259        interaction: Option<&impl IsA<TlsInteraction>>,
260        flags: TlsDatabaseLookupFlags,
261        cancellable: Option<&impl IsA<Cancellable>>,
262    ) -> Result<TlsCertificate, glib::Error> {
263        unsafe {
264            let mut error = std::ptr::null_mut();
265            let ret = ffi::g_tls_database_lookup_certificate_issuer(
266                self.as_ref().to_glib_none().0,
267                certificate.as_ref().to_glib_none().0,
268                interaction.map(|p| p.as_ref()).to_glib_none().0,
269                flags.into_glib(),
270                cancellable.map(|p| p.as_ref()).to_glib_none().0,
271                &mut error,
272            );
273            if error.is_null() {
274                Ok(from_glib_full(ret))
275            } else {
276                Err(from_glib_full(error))
277            }
278        }
279    }
280
281    /// Asynchronously look up the issuer of @certificate in the database. See
282    /// g_tls_database_lookup_certificate_issuer() for more information.
283    /// ## `certificate`
284    /// a #GTlsCertificate
285    /// ## `interaction`
286    /// used to interact with the user if necessary
287    /// ## `flags`
288    /// flags which affect the lookup operation
289    /// ## `cancellable`
290    /// a #GCancellable, or [`None`]
291    /// ## `callback`
292    /// callback to call when the operation completes
293    #[doc(alias = "g_tls_database_lookup_certificate_issuer_async")]
294    fn lookup_certificate_issuer_async<P: FnOnce(Result<TlsCertificate, glib::Error>) + 'static>(
295        &self,
296        certificate: &impl IsA<TlsCertificate>,
297        interaction: Option<&impl IsA<TlsInteraction>>,
298        flags: TlsDatabaseLookupFlags,
299        cancellable: Option<&impl IsA<Cancellable>>,
300        callback: P,
301    ) {
302        let main_context = glib::MainContext::ref_thread_default();
303        let is_main_context_owner = main_context.is_owner();
304        let has_acquired_main_context = (!is_main_context_owner)
305            .then(|| main_context.acquire().ok())
306            .flatten();
307        assert!(
308            is_main_context_owner || has_acquired_main_context.is_some(),
309            "Async operations only allowed if the thread is owning the MainContext"
310        );
311
312        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
313            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
314        unsafe extern "C" fn lookup_certificate_issuer_async_trampoline<
315            P: FnOnce(Result<TlsCertificate, glib::Error>) + 'static,
316        >(
317            _source_object: *mut glib::gobject_ffi::GObject,
318            res: *mut crate::ffi::GAsyncResult,
319            user_data: glib::ffi::gpointer,
320        ) {
321            let mut error = std::ptr::null_mut();
322            let ret = ffi::g_tls_database_lookup_certificate_issuer_finish(
323                _source_object as *mut _,
324                res,
325                &mut error,
326            );
327            let result = if error.is_null() {
328                Ok(from_glib_full(ret))
329            } else {
330                Err(from_glib_full(error))
331            };
332            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
333                Box_::from_raw(user_data as *mut _);
334            let callback: P = callback.into_inner();
335            callback(result);
336        }
337        let callback = lookup_certificate_issuer_async_trampoline::<P>;
338        unsafe {
339            ffi::g_tls_database_lookup_certificate_issuer_async(
340                self.as_ref().to_glib_none().0,
341                certificate.as_ref().to_glib_none().0,
342                interaction.map(|p| p.as_ref()).to_glib_none().0,
343                flags.into_glib(),
344                cancellable.map(|p| p.as_ref()).to_glib_none().0,
345                Some(callback),
346                Box_::into_raw(user_data) as *mut _,
347            );
348        }
349    }
350
351    fn lookup_certificate_issuer_future(
352        &self,
353        certificate: &(impl IsA<TlsCertificate> + Clone + 'static),
354        interaction: Option<&(impl IsA<TlsInteraction> + Clone + 'static)>,
355        flags: TlsDatabaseLookupFlags,
356    ) -> Pin<Box_<dyn std::future::Future<Output = Result<TlsCertificate, glib::Error>> + 'static>>
357    {
358        let certificate = certificate.clone();
359        let interaction = interaction.map(ToOwned::to_owned);
360        Box_::pin(crate::GioFuture::new(
361            self,
362            move |obj, cancellable, send| {
363                obj.lookup_certificate_issuer_async(
364                    &certificate,
365                    interaction.as_ref().map(::std::borrow::Borrow::borrow),
366                    flags,
367                    Some(cancellable),
368                    move |res| {
369                        send.resolve(res);
370                    },
371                );
372            },
373        ))
374    }
375
376    /// Look up certificates issued by this issuer in the database.
377    ///
378    /// This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform
379    /// the lookup operation asynchronously.
380    /// ## `issuer_raw_dn`
381    /// a #GByteArray which holds the DER encoded issuer DN.
382    /// ## `interaction`
383    /// used to interact with the user if necessary
384    /// ## `flags`
385    /// Flags which affect the lookup operation.
386    /// ## `cancellable`
387    /// a #GCancellable, or [`None`]
388    ///
389    /// # Returns
390    ///
391    /// a newly allocated list of #GTlsCertificate
392    /// objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list.
393    #[doc(alias = "g_tls_database_lookup_certificates_issued_by")]
394    fn lookup_certificates_issued_by(
395        &self,
396        issuer_raw_dn: &glib::ByteArray,
397        interaction: Option<&impl IsA<TlsInteraction>>,
398        flags: TlsDatabaseLookupFlags,
399        cancellable: Option<&impl IsA<Cancellable>>,
400    ) -> Result<Vec<TlsCertificate>, glib::Error> {
401        unsafe {
402            let mut error = std::ptr::null_mut();
403            let ret = ffi::g_tls_database_lookup_certificates_issued_by(
404                self.as_ref().to_glib_none().0,
405                issuer_raw_dn.to_glib_none().0,
406                interaction.map(|p| p.as_ref()).to_glib_none().0,
407                flags.into_glib(),
408                cancellable.map(|p| p.as_ref()).to_glib_none().0,
409                &mut error,
410            );
411            if error.is_null() {
412                Ok(FromGlibPtrContainer::from_glib_full(ret))
413            } else {
414                Err(from_glib_full(error))
415            }
416        }
417    }
418
419    /// Asynchronously look up certificates issued by this issuer in the database. See
420    /// g_tls_database_lookup_certificates_issued_by() for more information.
421    ///
422    /// The database may choose to hold a reference to the issuer byte array for the duration
423    /// of this asynchronous operation. The byte array should not be modified during
424    /// this time.
425    /// ## `issuer_raw_dn`
426    /// a #GByteArray which holds the DER encoded issuer DN.
427    /// ## `interaction`
428    /// used to interact with the user if necessary
429    /// ## `flags`
430    /// Flags which affect the lookup operation.
431    /// ## `cancellable`
432    /// a #GCancellable, or [`None`]
433    /// ## `callback`
434    /// callback to call when the operation completes
435    #[doc(alias = "g_tls_database_lookup_certificates_issued_by_async")]
436    fn lookup_certificates_issued_by_async<
437        P: FnOnce(Result<Vec<TlsCertificate>, glib::Error>) + 'static,
438    >(
439        &self,
440        issuer_raw_dn: &glib::ByteArray,
441        interaction: Option<&impl IsA<TlsInteraction>>,
442        flags: TlsDatabaseLookupFlags,
443        cancellable: Option<&impl IsA<Cancellable>>,
444        callback: P,
445    ) {
446        let main_context = glib::MainContext::ref_thread_default();
447        let is_main_context_owner = main_context.is_owner();
448        let has_acquired_main_context = (!is_main_context_owner)
449            .then(|| main_context.acquire().ok())
450            .flatten();
451        assert!(
452            is_main_context_owner || has_acquired_main_context.is_some(),
453            "Async operations only allowed if the thread is owning the MainContext"
454        );
455
456        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
457            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
458        unsafe extern "C" fn lookup_certificates_issued_by_async_trampoline<
459            P: FnOnce(Result<Vec<TlsCertificate>, glib::Error>) + 'static,
460        >(
461            _source_object: *mut glib::gobject_ffi::GObject,
462            res: *mut crate::ffi::GAsyncResult,
463            user_data: glib::ffi::gpointer,
464        ) {
465            let mut error = std::ptr::null_mut();
466            let ret = ffi::g_tls_database_lookup_certificates_issued_by_finish(
467                _source_object as *mut _,
468                res,
469                &mut error,
470            );
471            let result = if error.is_null() {
472                Ok(FromGlibPtrContainer::from_glib_full(ret))
473            } else {
474                Err(from_glib_full(error))
475            };
476            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
477                Box_::from_raw(user_data as *mut _);
478            let callback: P = callback.into_inner();
479            callback(result);
480        }
481        let callback = lookup_certificates_issued_by_async_trampoline::<P>;
482        unsafe {
483            ffi::g_tls_database_lookup_certificates_issued_by_async(
484                self.as_ref().to_glib_none().0,
485                issuer_raw_dn.to_glib_none().0,
486                interaction.map(|p| p.as_ref()).to_glib_none().0,
487                flags.into_glib(),
488                cancellable.map(|p| p.as_ref()).to_glib_none().0,
489                Some(callback),
490                Box_::into_raw(user_data) as *mut _,
491            );
492        }
493    }
494
495    fn lookup_certificates_issued_by_future(
496        &self,
497        issuer_raw_dn: &glib::ByteArray,
498        interaction: Option<&(impl IsA<TlsInteraction> + Clone + 'static)>,
499        flags: TlsDatabaseLookupFlags,
500    ) -> Pin<
501        Box_<dyn std::future::Future<Output = Result<Vec<TlsCertificate>, glib::Error>> + 'static>,
502    > {
503        let issuer_raw_dn = issuer_raw_dn.clone();
504        let interaction = interaction.map(ToOwned::to_owned);
505        Box_::pin(crate::GioFuture::new(
506            self,
507            move |obj, cancellable, send| {
508                obj.lookup_certificates_issued_by_async(
509                    &issuer_raw_dn,
510                    interaction.as_ref().map(::std::borrow::Borrow::borrow),
511                    flags,
512                    Some(cancellable),
513                    move |res| {
514                        send.resolve(res);
515                    },
516                );
517            },
518        ))
519    }
520
521    /// Determines the validity of a certificate chain, outside the context
522    /// of a TLS session.
523    ///
524    /// @chain is a chain of #GTlsCertificate objects each pointing to the next
525    /// certificate in the chain by its #GTlsCertificate:issuer property.
526    ///
527    /// @purpose describes the purpose (or usage) for which the certificate
528    /// is being used. Typically @purpose will be set to [`TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER`][crate::TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER]
529    /// which means that the certificate is being used to authenticate a server
530    /// (and we are acting as the client).
531    ///
532    /// The @identity is used to ensure the server certificate is valid for
533    /// the expected peer identity. If the identity does not match the
534    /// certificate, [`TlsCertificateFlags::BAD_IDENTITY`][crate::TlsCertificateFlags::BAD_IDENTITY] will be set in the
535    /// return value. If @identity is [`None`], that bit will never be set in
536    /// the return value. The peer identity may also be used to check for
537    /// pinned certificates (trust exceptions) in the database. These may
538    /// override the normal verification process on a host-by-host basis.
539    ///
540    /// Currently there are no @flags, and [`TlsDatabaseVerifyFlags::NONE`][crate::TlsDatabaseVerifyFlags::NONE] should be
541    /// used.
542    ///
543    /// If @chain is found to be valid, then the return value will be 0. If
544    /// @chain is found to be invalid, then the return value will indicate at
545    /// least one problem found. If the function is unable to determine
546    /// whether @chain is valid (for example, because @cancellable is
547    /// triggered before it completes) then the return value will be
548    /// [`TlsCertificateFlags::GENERIC_ERROR`][crate::TlsCertificateFlags::GENERIC_ERROR] and @error will be set accordingly.
549    /// @error is not set when @chain is successfully analyzed but found to
550    /// be invalid.
551    ///
552    /// GLib guarantees that if certificate verification fails, at least one
553    /// error will be set in the return value, but it does not guarantee
554    /// that all possible errors will be set. Accordingly, you may not safely
555    /// decide to ignore any particular type of error. For example, it would
556    /// be incorrect to mask [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow
557    /// expired certificates, because this could potentially be the only
558    /// error flag set even if other problems exist with the certificate.
559    ///
560    /// Prior to GLib 2.48, GLib's default TLS backend modified @chain to
561    /// represent the certification path built by #GTlsDatabase during
562    /// certificate verification by adjusting the #GTlsCertificate:issuer
563    /// property of each certificate in @chain. Since GLib 2.48, this no
564    /// longer occurs, so you cannot rely on #GTlsCertificate:issuer to
565    /// represent the actual certification path used during certificate
566    /// verification.
567    ///
568    /// Because TLS session context is not used, #GTlsDatabase may not
569    /// perform as many checks on the certificates as #GTlsConnection would.
570    /// For example, certificate constraints may not be honored, and
571    /// revocation checks may not be performed. The best way to verify TLS
572    /// certificates used by a TLS connection is to let #GTlsConnection
573    /// handle the verification.
574    ///
575    /// The TLS backend may attempt to look up and add missing certificates
576    /// to the chain. This may involve HTTP requests to download missing
577    /// certificates.
578    ///
579    /// This function can block. Use g_tls_database_verify_chain_async() to
580    /// perform the verification operation asynchronously.
581    /// ## `chain`
582    /// a #GTlsCertificate chain
583    /// ## `purpose`
584    /// the purpose that this certificate chain will be used for.
585    /// ## `identity`
586    /// the expected peer identity
587    /// ## `interaction`
588    /// used to interact with the user if necessary
589    /// ## `flags`
590    /// additional verify flags
591    /// ## `cancellable`
592    /// a #GCancellable, or [`None`]
593    ///
594    /// # Returns
595    ///
596    /// the appropriate #GTlsCertificateFlags which represents the
597    /// result of verification.
598    #[doc(alias = "g_tls_database_verify_chain")]
599    fn verify_chain(
600        &self,
601        chain: &impl IsA<TlsCertificate>,
602        purpose: &str,
603        identity: Option<&impl IsA<SocketConnectable>>,
604        interaction: Option<&impl IsA<TlsInteraction>>,
605        flags: TlsDatabaseVerifyFlags,
606        cancellable: Option<&impl IsA<Cancellable>>,
607    ) -> Result<TlsCertificateFlags, glib::Error> {
608        unsafe {
609            let mut error = std::ptr::null_mut();
610            let ret = ffi::g_tls_database_verify_chain(
611                self.as_ref().to_glib_none().0,
612                chain.as_ref().to_glib_none().0,
613                purpose.to_glib_none().0,
614                identity.map(|p| p.as_ref()).to_glib_none().0,
615                interaction.map(|p| p.as_ref()).to_glib_none().0,
616                flags.into_glib(),
617                cancellable.map(|p| p.as_ref()).to_glib_none().0,
618                &mut error,
619            );
620            if error.is_null() {
621                Ok(from_glib(ret))
622            } else {
623                Err(from_glib_full(error))
624            }
625        }
626    }
627
628    /// Asynchronously determines the validity of a certificate chain after
629    /// looking up and adding any missing certificates to the chain. See
630    /// g_tls_database_verify_chain() for more information.
631    /// ## `chain`
632    /// a #GTlsCertificate chain
633    /// ## `purpose`
634    /// the purpose that this certificate chain will be used for.
635    /// ## `identity`
636    /// the expected peer identity
637    /// ## `interaction`
638    /// used to interact with the user if necessary
639    /// ## `flags`
640    /// additional verify flags
641    /// ## `cancellable`
642    /// a #GCancellable, or [`None`]
643    /// ## `callback`
644    /// callback to call when the operation completes
645    #[doc(alias = "g_tls_database_verify_chain_async")]
646    fn verify_chain_async<P: FnOnce(Result<TlsCertificateFlags, glib::Error>) + 'static>(
647        &self,
648        chain: &impl IsA<TlsCertificate>,
649        purpose: &str,
650        identity: Option<&impl IsA<SocketConnectable>>,
651        interaction: Option<&impl IsA<TlsInteraction>>,
652        flags: TlsDatabaseVerifyFlags,
653        cancellable: Option<&impl IsA<Cancellable>>,
654        callback: P,
655    ) {
656        let main_context = glib::MainContext::ref_thread_default();
657        let is_main_context_owner = main_context.is_owner();
658        let has_acquired_main_context = (!is_main_context_owner)
659            .then(|| main_context.acquire().ok())
660            .flatten();
661        assert!(
662            is_main_context_owner || has_acquired_main_context.is_some(),
663            "Async operations only allowed if the thread is owning the MainContext"
664        );
665
666        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
667            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
668        unsafe extern "C" fn verify_chain_async_trampoline<
669            P: FnOnce(Result<TlsCertificateFlags, glib::Error>) + 'static,
670        >(
671            _source_object: *mut glib::gobject_ffi::GObject,
672            res: *mut crate::ffi::GAsyncResult,
673            user_data: glib::ffi::gpointer,
674        ) {
675            let mut error = std::ptr::null_mut();
676            let ret =
677                ffi::g_tls_database_verify_chain_finish(_source_object as *mut _, res, &mut error);
678            let result = if error.is_null() {
679                Ok(from_glib(ret))
680            } else {
681                Err(from_glib_full(error))
682            };
683            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
684                Box_::from_raw(user_data as *mut _);
685            let callback: P = callback.into_inner();
686            callback(result);
687        }
688        let callback = verify_chain_async_trampoline::<P>;
689        unsafe {
690            ffi::g_tls_database_verify_chain_async(
691                self.as_ref().to_glib_none().0,
692                chain.as_ref().to_glib_none().0,
693                purpose.to_glib_none().0,
694                identity.map(|p| p.as_ref()).to_glib_none().0,
695                interaction.map(|p| p.as_ref()).to_glib_none().0,
696                flags.into_glib(),
697                cancellable.map(|p| p.as_ref()).to_glib_none().0,
698                Some(callback),
699                Box_::into_raw(user_data) as *mut _,
700            );
701        }
702    }
703
704    fn verify_chain_future(
705        &self,
706        chain: &(impl IsA<TlsCertificate> + Clone + 'static),
707        purpose: &str,
708        identity: Option<&(impl IsA<SocketConnectable> + Clone + 'static)>,
709        interaction: Option<&(impl IsA<TlsInteraction> + Clone + 'static)>,
710        flags: TlsDatabaseVerifyFlags,
711    ) -> Pin<
712        Box_<dyn std::future::Future<Output = Result<TlsCertificateFlags, glib::Error>> + 'static>,
713    > {
714        let chain = chain.clone();
715        let purpose = String::from(purpose);
716        let identity = identity.map(ToOwned::to_owned);
717        let interaction = interaction.map(ToOwned::to_owned);
718        Box_::pin(crate::GioFuture::new(
719            self,
720            move |obj, cancellable, send| {
721                obj.verify_chain_async(
722                    &chain,
723                    &purpose,
724                    identity.as_ref().map(::std::borrow::Borrow::borrow),
725                    interaction.as_ref().map(::std::borrow::Borrow::borrow),
726                    flags,
727                    Some(cancellable),
728                    move |res| {
729                        send.resolve(res);
730                    },
731                );
732            },
733        ))
734    }
735}
736
737impl<O: IsA<TlsDatabase>> TlsDatabaseExt for O {}