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