Skip to content

Commit 050143a

Browse files
committed
context: Try PKCS #11 3.x API to get new interfaces first
Fixes: #209 Signed-off-by: Jakub Jelen <[email protected]>
1 parent 1265415 commit 050143a

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

cryptoki/src/context/general_purpose.rs

+59
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ macro_rules! check_fn {
4444
}};
4545
}
4646

47+
macro_rules! check_30_fn {
48+
($pkcs11:expr, $func_name:ident) => {{
49+
let func = paste! { $pkcs11
50+
.impl_
51+
.function_list_30
52+
.map(|f| f.[<C_ $func_name>])
53+
};
54+
func.is_some()
55+
}};
56+
}
57+
4758
#[allow(missing_docs)]
4859
#[derive(Debug, Copy, Clone)]
4960
/// Enumeration of all functions defined by the PKCS11 spec
@@ -116,6 +127,30 @@ pub enum Function {
116127
GetFunctionStatus,
117128
CancelFunction,
118129
WaitForSlotEvent,
130+
GetInterfaceList,
131+
GetInterface,
132+
LoginUser,
133+
SessionCancel,
134+
MessageEncryptInit,
135+
EncryptMessage,
136+
EncryptMessageBegin,
137+
EncryptMessageNext,
138+
MessageEncryptFinal,
139+
MessageDecryptInit,
140+
DecryptMessage,
141+
DecryptMessageBegin,
142+
DecryptMessageNext,
143+
MessageDecryptFinal,
144+
MessageSignInit,
145+
SignMessage,
146+
SignMessageBegin,
147+
SignMessageNext,
148+
MessageSignFinal,
149+
MessageVerifyInit,
150+
VerifyMessage,
151+
VerifyMessageBegin,
152+
VerifyMessageNext,
153+
MessageVerifyFinal,
119154
}
120155

121156
impl Display for Function {
@@ -195,5 +230,29 @@ pub(super) fn is_fn_supported(ctx: &Pkcs11, function: Function) -> bool {
195230
Function::GetFunctionStatus => check_fn!(ctx, GetFunctionStatus),
196231
Function::CancelFunction => check_fn!(ctx, CancelFunction),
197232
Function::WaitForSlotEvent => check_fn!(ctx, WaitForSlotEvent),
233+
Function::GetInterfaceList => check_30_fn!(ctx, GetInterfaceList),
234+
Function::GetInterface => check_30_fn!(ctx, GetInterface),
235+
Function::LoginUser => check_30_fn!(ctx, LoginUser),
236+
Function::SessionCancel => check_30_fn!(ctx, SessionCancel),
237+
Function::MessageEncryptInit => check_30_fn!(ctx, MessageEncryptInit),
238+
Function::EncryptMessage => check_30_fn!(ctx, EncryptMessage),
239+
Function::EncryptMessageBegin => check_30_fn!(ctx, EncryptMessageBegin),
240+
Function::EncryptMessageNext => check_30_fn!(ctx, EncryptMessageNext),
241+
Function::MessageEncryptFinal => check_30_fn!(ctx, MessageEncryptFinal),
242+
Function::MessageDecryptInit => check_30_fn!(ctx, MessageDecryptInit),
243+
Function::DecryptMessage => check_30_fn!(ctx, DecryptMessage),
244+
Function::DecryptMessageBegin => check_30_fn!(ctx, DecryptMessageBegin),
245+
Function::DecryptMessageNext => check_30_fn!(ctx, DecryptMessageNext),
246+
Function::MessageDecryptFinal => check_30_fn!(ctx, MessageDecryptFinal),
247+
Function::MessageSignInit => check_30_fn!(ctx, MessageSignInit),
248+
Function::SignMessage => check_30_fn!(ctx, SignMessage),
249+
Function::SignMessageBegin => check_30_fn!(ctx, SignMessageBegin),
250+
Function::SignMessageNext => check_30_fn!(ctx, SignMessageNext),
251+
Function::MessageSignFinal => check_30_fn!(ctx, MessageSignFinal),
252+
Function::MessageVerifyInit => check_30_fn!(ctx, MessageVerifyInit),
253+
Function::VerifyMessage => check_30_fn!(ctx, VerifyMessage),
254+
Function::VerifyMessageBegin => check_30_fn!(ctx, VerifyMessageBegin),
255+
Function::VerifyMessageNext => check_30_fn!(ctx, VerifyMessageNext),
256+
Function::MessageVerifyFinal => check_30_fn!(ctx, MessageVerifyFinal),
198257
}
199258
}

cryptoki/src/context/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ pub(crate) struct Pkcs11Impl {
4444
// valid.
4545
_pkcs11_lib: cryptoki_sys::Pkcs11,
4646
pub(crate) function_list: cryptoki_sys::CK_FUNCTION_LIST,
47+
pub(crate) function_list_30: Option<cryptoki_sys::CK_FUNCTION_LIST_3_0>,
4748
}
4849

4950
impl fmt::Debug for Pkcs11Impl {
5051
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5152
f.debug_struct("Pkcs11Impl")
5253
.field("function_list", &self.function_list)
54+
.field("function_list_30", &self.function_list_30)
5355
.finish()
5456
}
5557
}
@@ -111,6 +113,33 @@ impl Pkcs11 {
111113
}
112114

113115
unsafe fn _new(pkcs11_lib: cryptoki_sys::Pkcs11) -> Result<Self> {
116+
/* First try the 3.0 API to get default interface. It might have some more functions than
117+
* the 2.4 API */
118+
let mut interface = mem::MaybeUninit::uninit();
119+
if pkcs11_lib.C_GetInterface.is_ok() {
120+
Rv::from(pkcs11_lib.C_GetInterface(ptr::null_mut(), ptr::null_mut(), interface.as_mut_ptr(), 0))
121+
.into_result(Function::GetInterface)?;
122+
if !interface.as_ptr().is_null() {
123+
let ifce_ptr: *mut cryptoki_sys::CK_INTERFACE = *interface.as_ptr();
124+
let ifce: cryptoki_sys::CK_INTERFACE = *ifce_ptr;
125+
126+
let list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST = ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST;
127+
let list: cryptoki_sys::CK_FUNCTION_LIST = *list_ptr;
128+
if list.version.major >= 3 {
129+
let list30_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_0 = ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_0;
130+
return Ok(Pkcs11 {
131+
impl_: Arc::new(Pkcs11Impl {
132+
_pkcs11_lib: pkcs11_lib,
133+
function_list: *list_ptr, /* the function list aliases */
134+
function_list_30: Some(*list30_ptr),
135+
}),
136+
initialized: Arc::new(RwLock::new(false)),
137+
});
138+
}
139+
/* fall back to the 2.* API */
140+
}
141+
}
142+
114143
let mut list = mem::MaybeUninit::uninit();
115144

116145
Rv::from(pkcs11_lib.C_GetFunctionList(list.as_mut_ptr()))
@@ -122,6 +151,7 @@ impl Pkcs11 {
122151
impl_: Arc::new(Pkcs11Impl {
123152
_pkcs11_lib: pkcs11_lib,
124153
function_list: *list_ptr,
154+
function_list_30: None,
125155
}),
126156
initialized: Arc::new(RwLock::new(false)),
127157
})

0 commit comments

Comments
 (0)