Skip to content
Merged
2 changes: 1 addition & 1 deletion .github/actions/ci_script/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ runs:

- name: Test script
env:
PKCS11_SOFTHSM2_MODULE: /usr/lib/softhsm/libsofthsm2.so
TEST_PKCS11_MODULE: /usr/lib/softhsm/libsofthsm2.so
SOFTHSM2_CONF: /tmp/softhsm2.conf
run: ./ci.sh
shell: bash
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ jobs:
- name: "Installs SoftHSM and execute tests"
uses: ./.github/actions/ci_script

tests-kryoptic:
name: Run tests against Kryoptic
runs-on: ubuntu-latest
container: fedora:rawhide
steps:
- name: Install dependencies
run: dnf -y install git cargo clang-devel kryoptic
- uses: actions/checkout@v2
- name: Test script
env:
KRYOPTIC_CONF: /tmp/kryoptic.sql
TEST_PKCS11_MODULE: /usr/lib64/pkcs11/libkryoptic_pkcs11.so
run: |
RUST_BACKTRACE=1 cargo build &&
RUST_BACKTRACE=1 cargo build --all-features &&
RUST_BACKTRACE=1 cargo test


build-msrv:
name: MSRV - Execute CI script
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:

- name: Test script
env:
PKCS11_SOFTHSM2_MODULE: /usr/lib/softhsm/libsofthsm2.so
TEST_PKCS11_MODULE: /usr/lib/softhsm/libsofthsm2.so
SOFTHSM2_CONF: /tmp/softhsm2.conf
run: |
rm Cargo.lock
Expand Down
6 changes: 5 additions & 1 deletion cryptoki-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,12 @@ mod generate {
.dynamic_library_name("Pkcs11")
// The PKCS11 library works in a slightly different way to most shared libraries. We have
// to call `C_GetFunctionList`, which returns a list of pointers to the _actual_ library
// functions. This is the only function we need to create a binding for.
// functions (in PKCS #11 before 3.0). The PKCS #11 3.0 introduces the new functions
// `C_GetInterface` and `C_GetInterfaceList` to request the hew functions from 3.0 API.
// These are the only function we need to create a binding for.
.allowlist_function("C_GetFunctionList")
.allowlist_function("C_GetInterfaceList")
.allowlist_function("C_GetInterface")
// This is needed because no types will be generated if `allowlist_function` is used.
// Unsure if this is a bug.
.allowlist_type("*")
Expand Down
4 changes: 2 additions & 2 deletions cryptoki/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You can follow the installation steps directly in the repository's README but he
sudo apt install libsofthsm2
mkdir /tmp/tokens
echo "directories.tokendir = /tmp/tokens" > /tmp/softhsm2.conf
export PKCS11_SOFTHSM2_MODULE="/usr/lib/softhsm/libsofthsm2.so"
export TEST_PKCS11_MODULE="/usr/lib/softhsm/libsofthsm2.so"
export SOFTHSM2_CONF="/tmp/softhsm2.conf"
cargo run --example generate_key_pair
```
Expand All @@ -43,7 +43,7 @@ use std::env;

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

Expand Down
2 changes: 1 addition & 1 deletion cryptoki/examples/generate_key_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub static SO_PIN: &str = "abcdef";
fn main() -> testresult::TestResult {
// initialize a new Pkcs11 object using the module from the env variable
let pkcs11 = Pkcs11::new(
env::var("PKCS11_SOFTHSM2_MODULE")
env::var("TEST_PKCS11_MODULE")
.unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
)?;

Expand Down
61 changes: 61 additions & 0 deletions cryptoki/src/context/general_purpose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ macro_rules! check_fn {
}};
}

macro_rules! check_30_fn {
($pkcs11:expr, $func_name:ident) => {{
let func = paste! { $pkcs11
.impl_
.function_list_30
.map(|f| f.[<C_ $func_name>])
};
func.is_some()
}};
}

#[allow(missing_docs)]
#[derive(Debug, Copy, Clone)]
/// Enumeration of all functions defined by the PKCS11 spec
Expand Down Expand Up @@ -116,6 +127,31 @@ pub enum Function {
GetFunctionStatus,
CancelFunction,
WaitForSlotEvent,
/* PKCS #11 3.0 */
GetInterfaceList,
GetInterface,
LoginUser,
SessionCancel,
MessageEncryptInit,
EncryptMessage,
EncryptMessageBegin,
EncryptMessageNext,
MessageEncryptFinal,
MessageDecryptInit,
DecryptMessage,
DecryptMessageBegin,
DecryptMessageNext,
MessageDecryptFinal,
MessageSignInit,
SignMessage,
SignMessageBegin,
SignMessageNext,
MessageSignFinal,
MessageVerifyInit,
VerifyMessage,
VerifyMessageBegin,
VerifyMessageNext,
MessageVerifyFinal,
}

impl Display for Function {
Expand Down Expand Up @@ -195,5 +231,30 @@ pub(super) fn is_fn_supported(ctx: &Pkcs11, function: Function) -> bool {
Function::GetFunctionStatus => check_fn!(ctx, GetFunctionStatus),
Function::CancelFunction => check_fn!(ctx, CancelFunction),
Function::WaitForSlotEvent => check_fn!(ctx, WaitForSlotEvent),
/* PKCS #11 3.0 */
Function::GetInterfaceList => check_30_fn!(ctx, GetInterfaceList),
Function::GetInterface => check_30_fn!(ctx, GetInterface),
Function::LoginUser => check_30_fn!(ctx, LoginUser),
Function::SessionCancel => check_30_fn!(ctx, SessionCancel),
Function::MessageEncryptInit => check_30_fn!(ctx, MessageEncryptInit),
Function::EncryptMessage => check_30_fn!(ctx, EncryptMessage),
Function::EncryptMessageBegin => check_30_fn!(ctx, EncryptMessageBegin),
Function::EncryptMessageNext => check_30_fn!(ctx, EncryptMessageNext),
Function::MessageEncryptFinal => check_30_fn!(ctx, MessageEncryptFinal),
Function::MessageDecryptInit => check_30_fn!(ctx, MessageDecryptInit),
Function::DecryptMessage => check_30_fn!(ctx, DecryptMessage),
Function::DecryptMessageBegin => check_30_fn!(ctx, DecryptMessageBegin),
Function::DecryptMessageNext => check_30_fn!(ctx, DecryptMessageNext),
Function::MessageDecryptFinal => check_30_fn!(ctx, MessageDecryptFinal),
Function::MessageSignInit => check_30_fn!(ctx, MessageSignInit),
Function::SignMessage => check_30_fn!(ctx, SignMessage),
Function::SignMessageBegin => check_30_fn!(ctx, SignMessageBegin),
Function::SignMessageNext => check_30_fn!(ctx, SignMessageNext),
Function::MessageSignFinal => check_30_fn!(ctx, MessageSignFinal),
Function::MessageVerifyInit => check_30_fn!(ctx, MessageVerifyInit),
Function::VerifyMessage => check_30_fn!(ctx, VerifyMessage),
Function::VerifyMessageBegin => check_30_fn!(ctx, VerifyMessageBegin),
Function::VerifyMessageNext => check_30_fn!(ctx, VerifyMessageNext),
Function::MessageVerifyFinal => check_30_fn!(ctx, MessageVerifyFinal),
}
}
37 changes: 37 additions & 0 deletions cryptoki/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ pub(crate) struct Pkcs11Impl {
// valid.
_pkcs11_lib: cryptoki_sys::Pkcs11,
pub(crate) function_list: cryptoki_sys::CK_FUNCTION_LIST,
pub(crate) function_list_30: Option<cryptoki_sys::CK_FUNCTION_LIST_3_0>,
}

impl fmt::Debug for Pkcs11Impl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Pkcs11Impl")
.field("function_list", &self.function_list)
.field("function_list_30", &self.function_list_30)
.finish()
}
}
Expand Down Expand Up @@ -111,6 +113,40 @@ impl Pkcs11 {
}

unsafe fn _new(pkcs11_lib: cryptoki_sys::Pkcs11) -> Result<Self> {
/* First try the 3.0 API to get default interface. It might have some more functions than
* the 2.4 API */
let mut interface = mem::MaybeUninit::uninit();
if pkcs11_lib.C_GetInterface.is_ok() {
Rv::from(pkcs11_lib.C_GetInterface(
ptr::null_mut(),
ptr::null_mut(),
interface.as_mut_ptr(),
0,
))
.into_result(Function::GetInterface)?;
if !interface.as_ptr().is_null() {
let ifce_ptr: *mut cryptoki_sys::CK_INTERFACE = *interface.as_ptr();
let ifce: cryptoki_sys::CK_INTERFACE = *ifce_ptr;

let list_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST =
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST;
let list: cryptoki_sys::CK_FUNCTION_LIST = *list_ptr;
if list.version.major >= 3 {
let list30_ptr: *mut cryptoki_sys::CK_FUNCTION_LIST_3_0 =
ifce.pFunctionList as *mut cryptoki_sys::CK_FUNCTION_LIST_3_0;
return Ok(Pkcs11 {
impl_: Arc::new(Pkcs11Impl {
_pkcs11_lib: pkcs11_lib,
function_list: *list_ptr, /* the function list aliases */
function_list_30: Some(*list30_ptr),
}),
initialized: Arc::new(RwLock::new(false)),
});
}
/* fall back to the 2.* API */
}
}

let mut list = mem::MaybeUninit::uninit();

Rv::from(pkcs11_lib.C_GetFunctionList(list.as_mut_ptr()))
Expand All @@ -122,6 +158,7 @@ impl Pkcs11 {
impl_: Arc::new(Pkcs11Impl {
_pkcs11_lib: pkcs11_lib,
function_list: *list_ptr,
function_list_30: None,
}),
initialized: Arc::new(RwLock::new(false)),
})
Expand Down
2 changes: 1 addition & 1 deletion cryptoki/src/context/session_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl Pkcs11 {
/// use cryptoki::context::Pkcs11;
///
/// let mut client = Pkcs11::new(
/// std::env::var("PKCS11_SOFTHSM2_MODULE")
/// std::env::var("TEST_PKCS11_MODULE")
/// .unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
/// )?;
/// client.initialize(cryptoki::context::CInitializeArgs::OsThreads)?;
Expand Down
2 changes: 2 additions & 0 deletions cryptoki/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,8 @@ pub enum AttributeInfo {
Sensitive,
/// The attribute is available to get from the object and has the specified size in bytes.
Available(usize),
/// The attribute is not available.
Unavailable,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
Expand Down
12 changes: 8 additions & 4 deletions cryptoki/src/session/object_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const MAX_OBJECT_COUNT: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(10)
///
/// # fn main() -> testresult::TestResult {
/// # let pkcs11 = Pkcs11::new(
/// # env::var("PKCS11_SOFTHSM2_MODULE")
/// # env::var("TEST_PKCS11_MODULE")
/// # .unwrap_or_else(|_| "/usr/local/lib/libsofthsm2.so".to_string()),
/// # )?;
/// #
Expand Down Expand Up @@ -282,7 +282,7 @@ impl Session {
/// # use cryptoki::object::{Attribute, AttributeType, CertificateType, ObjectClass, ObjectHandle};
/// #
/// # let mut client = Pkcs11::new(
/// # std::env::var("PKCS11_SOFTHSM2_MODULE")
/// # std::env::var("TEST_PKCS11_MODULE")
/// # .unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
/// # )?;
/// # client.initialize(cryptoki::context::CInitializeArgs::OsThreads)?;
Expand Down Expand Up @@ -401,7 +401,7 @@ impl Session {
/// use std::env;
///
/// let mut pkcs11 = Pkcs11::new(
/// env::var("PKCS11_SOFTHSM2_MODULE")
/// env::var("TEST_PKCS11_MODULE")
/// .unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
/// )
/// .unwrap();
Expand Down Expand Up @@ -454,7 +454,11 @@ impl Session {
))
} {
Rv::Ok => {
results.push(AttributeInfo::Available(template[0].ulValueLen.try_into()?))
if template[0].ulValueLen == CK_UNAVAILABLE_INFORMATION {
results.push(AttributeInfo::Unavailable)
} else {
results.push(AttributeInfo::Available(template[0].ulValueLen.try_into()?))
}
}
Rv::Error(RvError::AttributeSensitive) => results.push(AttributeInfo::Sensitive),
Rv::Error(RvError::AttributeTypeInvalid) => {
Expand Down
Loading
Loading