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