1 | use crate::error::ErrorStack; |
2 | use crate::lib_ctx::LibCtxRef; |
3 | use crate::{cvt, cvt_p}; |
4 | use foreign_types::{ForeignType, ForeignTypeRef}; |
5 | use openssl_macros::corresponds; |
6 | use std::ffi::CString; |
7 | use std::ptr; |
8 | |
9 | foreign_type_and_impl_send_sync! { |
10 | type CType = ffi::OSSL_PROVIDER; |
11 | fn drop = ossl_provider_free; |
12 | |
13 | pub struct Provider; |
14 | /// A reference to a [`Provider`]. |
15 | pub struct ProviderRef; |
16 | } |
17 | |
18 | #[inline ] |
19 | unsafe fn ossl_provider_free(p: *mut ffi::OSSL_PROVIDER) { |
20 | ffi::OSSL_PROVIDER_unload(prov:p); |
21 | } |
22 | |
23 | impl Provider { |
24 | /// Loads a new provider into the specified library context, disabling the fallback providers. |
25 | /// |
26 | /// If `ctx` is `None`, the provider will be loaded in to the default library context. |
27 | #[corresponds (OSSL_provider_load)] |
28 | pub fn load(ctx: Option<&LibCtxRef>, name: &str) -> Result<Self, ErrorStack> { |
29 | let name = CString::new(name).unwrap(); |
30 | unsafe { |
31 | let p = cvt_p(ffi::OSSL_PROVIDER_load( |
32 | ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), |
33 | name.as_ptr(), |
34 | ))?; |
35 | |
36 | Ok(Provider::from_ptr(p)) |
37 | } |
38 | } |
39 | |
40 | /// Loads a new provider into the specified library context, disabling the fallback providers if `retain_fallbacks` |
41 | /// is `false` and the load succeeds. |
42 | /// |
43 | /// If `ctx` is `None`, the provider will be loaded into the default library context. |
44 | #[corresponds (OSSL_provider_try_load)] |
45 | pub fn try_load( |
46 | ctx: Option<&LibCtxRef>, |
47 | name: &str, |
48 | retain_fallbacks: bool, |
49 | ) -> Result<Self, ErrorStack> { |
50 | let name = CString::new(name).unwrap(); |
51 | unsafe { |
52 | let p = cvt_p(ffi::OSSL_PROVIDER_try_load( |
53 | ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), |
54 | name.as_ptr(), |
55 | retain_fallbacks as _, |
56 | ))?; |
57 | |
58 | // OSSL_PROVIDER_try_load seems to leave errors on the stack, even |
59 | // when it succeeds. |
60 | let _ = ErrorStack::get(); |
61 | |
62 | Ok(Provider::from_ptr(p)) |
63 | } |
64 | } |
65 | |
66 | /// Specifies the default search path that is to be used for looking for providers in the specified library context. |
67 | /// If left unspecified, an environment variable and a fall back default value will be used instead |
68 | /// |
69 | /// If `ctx` is `None`, the provider will be loaded into the default library context. |
70 | #[corresponds (OSSL_PROVIDER_set_default_search_path)] |
71 | pub fn set_default_search_path(ctx: Option<&LibCtxRef>, path: &str) -> Result<(), ErrorStack> { |
72 | let path = CString::new(path).unwrap(); |
73 | unsafe { |
74 | cvt(ffi::OSSL_PROVIDER_set_default_search_path( |
75 | ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), |
76 | path.as_ptr(), |
77 | )) |
78 | .map(|_| ()) |
79 | } |
80 | } |
81 | } |
82 | |