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