Skip to content

Commit 58114a4

Browse files
authored
Merge pull request #248 from Jakuje/pkcs11-3
Add support for PKCS#11 3.0
2 parents 359f2ff + 72cb497 commit 58114a4

File tree

13 files changed

+251
-51
lines changed

13 files changed

+251
-51
lines changed

.github/actions/ci_script/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ runs:
3131

3232
- name: Test script
3333
env:
34-
PKCS11_SOFTHSM2_MODULE: /usr/lib/softhsm/libsofthsm2.so
34+
TEST_PKCS11_MODULE: /usr/lib/softhsm/libsofthsm2.so
3535
SOFTHSM2_CONF: /tmp/softhsm2.conf
3636
run: ./ci.sh
3737
shell: bash

.github/workflows/ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ jobs:
4141
- name: "Installs SoftHSM and execute tests"
4242
uses: ./.github/actions/ci_script
4343

44+
tests-kryoptic:
45+
name: Run tests against Kryoptic
46+
runs-on: ubuntu-latest
47+
container: fedora:rawhide
48+
steps:
49+
- name: Install dependencies
50+
run: dnf -y install git cargo clang-devel kryoptic
51+
- uses: actions/checkout@v2
52+
- name: Test script
53+
env:
54+
KRYOPTIC_CONF: /tmp/kryoptic.sql
55+
TEST_PKCS11_MODULE: /usr/lib64/pkcs11/libkryoptic_pkcs11.so
56+
run: |
57+
RUST_BACKTRACE=1 cargo build &&
58+
RUST_BACKTRACE=1 cargo build --all-features &&
59+
RUST_BACKTRACE=1 cargo test
60+
61+
4462
build-msrv:
4563
name: MSRV - Execute CI script
4664
runs-on: ubuntu-latest

.github/workflows/nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
6464
- name: Test script
6565
env:
66-
PKCS11_SOFTHSM2_MODULE: /usr/lib/softhsm/libsofthsm2.so
66+
TEST_PKCS11_MODULE: /usr/lib/softhsm/libsofthsm2.so
6767
SOFTHSM2_CONF: /tmp/softhsm2.conf
6868
run: |
6969
rm Cargo.lock

cryptoki-sys/build.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,12 @@ mod generate {
9191
.dynamic_library_name("Pkcs11")
9292
// The PKCS11 library works in a slightly different way to most shared libraries. We have
9393
// to call `C_GetFunctionList`, which returns a list of pointers to the _actual_ library
94-
// functions. This is the only function we need to create a binding for.
94+
// functions (in PKCS #11 before 3.0). The PKCS #11 3.0 introduces the new functions
95+
// `C_GetInterface` and `C_GetInterfaceList` to request the hew functions from 3.0 API.
96+
// These are the only function we need to create a binding for.
9597
.allowlist_function("C_GetFunctionList")
98+
.allowlist_function("C_GetInterfaceList")
99+
.allowlist_function("C_GetInterface")
96100
// This is needed because no types will be generated if `allowlist_function` is used.
97101
// Unsure if this is a bug.
98102
.allowlist_type("*")

cryptoki/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ You can follow the installation steps directly in the repository's README but he
2222
sudo apt install libsofthsm2
2323
mkdir /tmp/tokens
2424
echo "directories.tokendir = /tmp/tokens" > /tmp/softhsm2.conf
25-
export PKCS11_SOFTHSM2_MODULE="/usr/lib/softhsm/libsofthsm2.so"
25+
export TEST_PKCS11_MODULE="/usr/lib/softhsm/libsofthsm2.so"
2626
export SOFTHSM2_CONF="/tmp/softhsm2.conf"
2727
cargo run --example generate_key_pair
2828
```
@@ -43,7 +43,7 @@ use std::env;
4343

4444
// initialize a new Pkcs11 object using the module from the env variable
4545
let pkcs11 = Pkcs11::new(
46-
env::var("PKCS11_SOFTHSM2_MODULE")
46+
env::var("TEST_PKCS11_MODULE")
4747
.unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
4848
)?;
4949

cryptoki/examples/generate_key_pair.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub static SO_PIN: &str = "abcdef";
1515
fn main() -> testresult::TestResult {
1616
// initialize a new Pkcs11 object using the module from the env variable
1717
let pkcs11 = Pkcs11::new(
18-
env::var("PKCS11_SOFTHSM2_MODULE")
18+
env::var("TEST_PKCS11_MODULE")
1919
.unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
2020
)?;
2121

cryptoki/src/context/general_purpose.rs

Lines changed: 61 additions & 0 deletions
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,31 @@ pub enum Function {
116127
GetFunctionStatus,
117128
CancelFunction,
118129
WaitForSlotEvent,
130+
/* PKCS #11 3.0 */
131+
GetInterfaceList,
132+
GetInterface,
133+
LoginUser,
134+
SessionCancel,
135+
MessageEncryptInit,
136+
EncryptMessage,
137+
EncryptMessageBegin,
138+
EncryptMessageNext,
139+
MessageEncryptFinal,
140+
MessageDecryptInit,
141+
DecryptMessage,
142+
DecryptMessageBegin,
143+
DecryptMessageNext,
144+
MessageDecryptFinal,
145+
MessageSignInit,
146+
SignMessage,
147+
SignMessageBegin,
148+
SignMessageNext,
149+
MessageSignFinal,
150+
MessageVerifyInit,
151+
VerifyMessage,
152+
VerifyMessageBegin,
153+
VerifyMessageNext,
154+
MessageVerifyFinal,
119155
}
120156

121157
impl Display for Function {
@@ -195,5 +231,30 @@ pub(super) fn is_fn_supported(ctx: &Pkcs11, function: Function) -> bool {
195231
Function::GetFunctionStatus => check_fn!(ctx, GetFunctionStatus),
196232
Function::CancelFunction => check_fn!(ctx, CancelFunction),
197233
Function::WaitForSlotEvent => check_fn!(ctx, WaitForSlotEvent),
234+
/* PKCS #11 3.0 */
235+
Function::GetInterfaceList => check_30_fn!(ctx, GetInterfaceList),
236+
Function::GetInterface => check_30_fn!(ctx, GetInterface),
237+
Function::LoginUser => check_30_fn!(ctx, LoginUser),
238+
Function::SessionCancel => check_30_fn!(ctx, SessionCancel),
239+
Function::MessageEncryptInit => check_30_fn!(ctx, MessageEncryptInit),
240+
Function::EncryptMessage => check_30_fn!(ctx, EncryptMessage),
241+
Function::EncryptMessageBegin => check_30_fn!(ctx, EncryptMessageBegin),
242+
Function::EncryptMessageNext => check_30_fn!(ctx, EncryptMessageNext),
243+
Function::MessageEncryptFinal => check_30_fn!(ctx, MessageEncryptFinal),
244+
Function::MessageDecryptInit => check_30_fn!(ctx, MessageDecryptInit),
245+
Function::DecryptMessage => check_30_fn!(ctx, DecryptMessage),
246+
Function::DecryptMessageBegin => check_30_fn!(ctx, DecryptMessageBegin),
247+
Function::DecryptMessageNext => check_30_fn!(ctx, DecryptMessageNext),
248+
Function::MessageDecryptFinal => check_30_fn!(ctx, MessageDecryptFinal),
249+
Function::MessageSignInit => check_30_fn!(ctx, MessageSignInit),
250+
Function::SignMessage => check_30_fn!(ctx, SignMessage),
251+
Function::SignMessageBegin => check_30_fn!(ctx, SignMessageBegin),
252+
Function::SignMessageNext => check_30_fn!(ctx, SignMessageNext),
253+
Function::MessageSignFinal => check_30_fn!(ctx, MessageSignFinal),
254+
Function::MessageVerifyInit => check_30_fn!(ctx, MessageVerifyInit),
255+
Function::VerifyMessage => check_30_fn!(ctx, VerifyMessage),
256+
Function::VerifyMessageBegin => check_30_fn!(ctx, VerifyMessageBegin),
257+
Function::VerifyMessageNext => check_30_fn!(ctx, VerifyMessageNext),
258+
Function::MessageVerifyFinal => check_30_fn!(ctx, MessageVerifyFinal),
198259
}
199260
}

cryptoki/src/context/mod.rs

Lines changed: 37 additions & 0 deletions
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,40 @@ 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(
121+
ptr::null_mut(),
122+
ptr::null_mut(),
123+
interface.as_mut_ptr(),
124+
0,
125+
))
126+
.into_result(Function::GetInterface)?;
127+
if !interface.as_ptr().is_null() {
128+
let ifce_ptr: *mut cryptoki_sys::CK_INTERFACE = *interface.as_ptr();
129+
let ifce: cryptoki_sys::CK_INTERFACE = *ifce_ptr;
130+
131+
let list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST =
132+
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST;
133+
let list: cryptoki_sys::CK_FUNCTION_LIST = *list_ptr;
134+
if list.version.major >= 3 {
135+
let list30_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_0 =
136+
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_0;
137+
return Ok(Pkcs11 {
138+
impl_: Arc::new(Pkcs11Impl {
139+
_pkcs11_lib: pkcs11_lib,
140+
function_list: *list_ptr, /* the function list aliases */
141+
function_list_30: Some(*list30_ptr),
142+
}),
143+
initialized: Arc::new(RwLock::new(false)),
144+
});
145+
}
146+
/* fall back to the 2.* API */
147+
}
148+
}
149+
114150
let mut list = mem::MaybeUninit::uninit();
115151

116152
Rv::from(pkcs11_lib.C_GetFunctionList(list.as_mut_ptr()))
@@ -122,6 +158,7 @@ impl Pkcs11 {
122158
impl_: Arc::new(Pkcs11Impl {
123159
_pkcs11_lib: pkcs11_lib,
124160
function_list: *list_ptr,
161+
function_list_30: None,
125162
}),
126163
initialized: Arc::new(RwLock::new(false)),
127164
})

cryptoki/src/context/session_management.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl Pkcs11 {
5050
/// use cryptoki::context::Pkcs11;
5151
///
5252
/// let mut client = Pkcs11::new(
53-
/// std::env::var("PKCS11_SOFTHSM2_MODULE")
53+
/// std::env::var("TEST_PKCS11_MODULE")
5454
/// .unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
5555
/// )?;
5656
/// client.initialize(cryptoki::context::CInitializeArgs::OsThreads)?;

cryptoki/src/object.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,8 @@ pub enum AttributeInfo {
13781378
Sensitive,
13791379
/// The attribute is available to get from the object and has the specified size in bytes.
13801380
Available(usize),
1381+
/// The attribute is not available.
1382+
Unavailable,
13811383
}
13821384

13831385
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)