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