1use crate::error::ErrorStack; 2use crate::lib_ctx::LibCtxRef; 3use crate::{cvt, cvt_p}; 4use foreign_types::{ForeignType, ForeignTypeRef}; 5use openssl_macros::corresponds; 6use std::ffi::CString; 7use std::ptr; 8 9foreign_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] 19unsafe fn ossl_provider_free(p: *mut ffi::OSSL_PROVIDER) { 20 ffi::OSSL_PROVIDER_unload(p); 21} 22 23impl 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 Ok(Provider::from_ptr(p)) 59 } 60 } 61 62 /// Specifies the default search path that is to be used for looking for providers in the specified library context. 63 /// If left unspecified, an environment variable and a fall back default value will be used instead 64 /// 65 /// If `ctx` is `None`, the provider will be loaded into the default library context. 66 #[corresponds(OSSL_PROVIDER_set_default_search_path)] 67 pub fn set_default_search_path(ctx: Option<&LibCtxRef>, path: &str) -> Result<(), ErrorStack> { 68 let path = CString::new(path).unwrap(); 69 unsafe { 70 cvt(ffi::OSSL_PROVIDER_set_default_search_path( 71 ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), 72 path.as_ptr(), 73 )) 74 .map(|_| ()) 75 } 76 } 77} 78