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 {}