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