Skip to content

Commit 02deaf7

Browse files
committed
Expose Pkcs11Impl and add new_unchecked
Signed-off-by: Wiktor Kwapisiewicz <wiktor@metacode.biz>
1 parent 4929849 commit 02deaf7

File tree

2 files changed

+73
-62
lines changed

2 files changed

+73
-62
lines changed

cryptoki/src/context/mod.rs

Lines changed: 72 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ enum FunctionList {
4949
V3_2(cryptoki_sys::CK_FUNCTION_LIST_3_2),
5050
}
5151

52-
// Implementation of Pkcs11 class that can be enclosed in a single Arc
53-
pub(crate) struct Pkcs11Impl {
52+
/// Implementation of Pkcs11 class that can be enclosed in a single [`std::sync::Arc`].
53+
///
54+
/// This object never finalizes the underlying PKCS#11 implementation.
55+
/// For most cases it is advisable to use [`Pkcs11`][`crate::context::Pkcs11`] object instead, which implements proper lifecycle functions.
56+
/// For advanced use cases, where the PKCS#11 lifecycle is managed externally use [`Pkcs11Impl::new_unchecked`].
57+
pub struct Pkcs11Impl {
5458
// Even if this field is never read, it is needed for the pointers in function_list to remain
5559
// valid.
5660
_pkcs11_lib: cryptoki_sys::Pkcs11,
@@ -74,9 +78,67 @@ impl Pkcs11Impl {
7478
FunctionList::V3_2(l) => l,
7579
}
7680
}
81+
82+
/// Initializes Pkcs11 using raw Pkcs11 object.
83+
///
84+
/// The caller is responsible for ensuring the validity of `pkcs11_lib` object and managing its lifecycle (e.g. calling `finalize`).
85+
/// For most use cases it is advisable to use [`crate::context::Pkcs11`] instead.
86+
///
87+
/// # Safety
88+
///
89+
/// `pkcs11_lib` must point to a valid Pkcs11 object.
90+
pub unsafe fn new_unchecked(pkcs11_lib: cryptoki_sys::Pkcs11) -> Result<Self> {
91+
/* First try the 3.* API to get default interface. It might have some more functions than
92+
* the 2.40 API */
93+
let mut interface: *mut cryptoki_sys::CK_INTERFACE = ptr::null_mut();
94+
if pkcs11_lib.C_GetInterface.is_ok() {
95+
Rv::from(pkcs11_lib.C_GetInterface(
96+
ptr::null_mut(),
97+
ptr::null_mut(),
98+
&mut interface,
99+
0,
100+
))
101+
.into_result(Function::GetInterface)?;
102+
if !interface.is_null() {
103+
let ifce: cryptoki_sys::CK_INTERFACE = *interface;
104+
105+
let list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST =
106+
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST;
107+
let list: cryptoki_sys::CK_FUNCTION_LIST = *list_ptr;
108+
if list.version.major >= 3 {
109+
if list.version.minor >= 2 {
110+
let list32_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_2 =
111+
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_2;
112+
return Ok(Pkcs11Impl {
113+
_pkcs11_lib: pkcs11_lib,
114+
function_list: FunctionList::V3_2(*list32_ptr),
115+
});
116+
}
117+
let list30_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_0 =
118+
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_0;
119+
return Ok(Pkcs11Impl {
120+
_pkcs11_lib: pkcs11_lib,
121+
function_list: FunctionList::V3_0(v30tov32(*list30_ptr)),
122+
});
123+
}
124+
/* fall back to the 2.* API */
125+
}
126+
}
127+
128+
let mut list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST = ptr::null_mut();
129+
Rv::from(pkcs11_lib.C_GetFunctionList(&mut list_ptr))
130+
.into_result(Function::GetFunctionList)?;
131+
132+
Ok(Pkcs11Impl {
133+
_pkcs11_lib: pkcs11_lib,
134+
function_list: FunctionList::V2(v2tov3(*list_ptr)),
135+
})
136+
}
77137
}
78138

79139
/// Main PKCS11 context. Should usually be unique per application.
140+
///
141+
/// After this object goes out of scope the `Finalize` function of the PKCS#11 implementation will be called.
80142
#[derive(Debug)]
81143
pub struct Pkcs11 {
82144
pub(crate) impl_: Pkcs11Impl,
@@ -117,7 +179,10 @@ impl Pkcs11 {
117179
unsafe {
118180
let pkcs11_lib =
119181
cryptoki_sys::Pkcs11::new(filename.as_ref()).map_err(Error::LibraryLoading)?;
120-
Self::_new(pkcs11_lib)
182+
Ok(Self {
183+
impl_: Pkcs11Impl::new_unchecked(pkcs11_lib)?,
184+
initialized: RwLock::new(false),
185+
})
121186
}
122187
}
123188

@@ -129,67 +194,13 @@ impl Pkcs11 {
129194
#[cfg(windows)]
130195
let this_lib = libloading::os::windows::Library::this()?;
131196
let pkcs11_lib = cryptoki_sys::Pkcs11::from_library(this_lib)?;
132-
Self::_new(pkcs11_lib)
197+
Ok(Self {
198+
impl_: Pkcs11Impl::new_unchecked(pkcs11_lib)?,
199+
initialized: RwLock::new(false),
200+
})
133201
}
134202
}
135203

136-
unsafe fn _new(pkcs11_lib: cryptoki_sys::Pkcs11) -> Result<Self> {
137-
/* First try the 3.* API to get default interface. It might have some more functions than
138-
* the 2.40 API */
139-
let mut interface: *mut cryptoki_sys::CK_INTERFACE = ptr::null_mut();
140-
if pkcs11_lib.C_GetInterface.is_ok() {
141-
Rv::from(pkcs11_lib.C_GetInterface(
142-
ptr::null_mut(),
143-
ptr::null_mut(),
144-
&mut interface,
145-
0,
146-
))
147-
.into_result(Function::GetInterface)?;
148-
if !interface.is_null() {
149-
let ifce: cryptoki_sys::CK_INTERFACE = *interface;
150-
151-
let list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST =
152-
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST;
153-
let list: cryptoki_sys::CK_FUNCTION_LIST = *list_ptr;
154-
if list.version.major >= 3 {
155-
if list.version.minor >= 2 {
156-
let list32_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_2 =
157-
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_2;
158-
return Ok(Pkcs11 {
159-
impl_: Pkcs11Impl {
160-
_pkcs11_lib: pkcs11_lib,
161-
function_list: FunctionList::V3_2(*list32_ptr),
162-
},
163-
initialized: RwLock::new(false),
164-
});
165-
}
166-
let list30_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_0 =
167-
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_0;
168-
return Ok(Pkcs11 {
169-
impl_: Pkcs11Impl {
170-
_pkcs11_lib: pkcs11_lib,
171-
function_list: FunctionList::V3_0(v30tov32(*list30_ptr)),
172-
},
173-
initialized: RwLock::new(false),
174-
});
175-
}
176-
/* fall back to the 2.* API */
177-
}
178-
}
179-
180-
let mut list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST = ptr::null_mut();
181-
Rv::from(pkcs11_lib.C_GetFunctionList(&mut list_ptr))
182-
.into_result(Function::GetFunctionList)?;
183-
184-
Ok(Pkcs11 {
185-
impl_: Pkcs11Impl {
186-
_pkcs11_lib: pkcs11_lib,
187-
function_list: FunctionList::V2(v2tov3(*list_ptr)),
188-
},
189-
initialized: RwLock::new(false),
190-
})
191-
}
192-
193204
/// Initialize the PKCS11 library
194205
pub fn initialize(&self, init_args: CInitializeArgs) -> Result<()> {
195206
let mut init_lock = self.initialized.write().expect("lock not to be poisoned");

cryptoki/src/session/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<'a> Session<'a> {
8080
}
8181

8282
pub(crate) fn client(&self) -> &Pkcs11 {
83-
&self.client
83+
self.client
8484
}
8585
}
8686

0 commit comments

Comments
 (0)