From e60dd7daba8ec43d8006d7effdf6cc707995e804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 4 Jan 2024 11:13:49 +0100 Subject: [PATCH 1/6] Fix panics on failed initialization This patch adds a `Result` version of the `Device` static so that any call can first check that the initialization was successful. --- pkcs11/src/api/decrypt.rs | 9 +++++++++ pkcs11/src/api/digest.rs | 15 +++++++++++++++ pkcs11/src/api/encrypt.rs | 4 ++++ pkcs11/src/api/generation.rs | 11 +++++++++++ pkcs11/src/api/mod.rs | 23 ++++++++++++++++++++++- pkcs11/src/api/object.rs | 11 +++++++++++ pkcs11/src/api/pin.rs | 4 ++++ pkcs11/src/api/session.rs | 12 ++++++++++++ pkcs11/src/api/sign.rs | 10 ++++++++++ pkcs11/src/api/token.rs | 10 ++++++++++ pkcs11/src/api/verify.rs | 13 +++++++++++++ pkcs11/src/data.rs | 17 ++++++++++++++++- 12 files changed, 137 insertions(+), 2 deletions(-) diff --git a/pkcs11/src/api/decrypt.rs b/pkcs11/src/api/decrypt.rs index 2575a882..6054d8f4 100644 --- a/pkcs11/src/api/decrypt.rs +++ b/pkcs11/src/api/decrypt.rs @@ -13,6 +13,8 @@ pub extern "C" fn C_DecryptInit( ) -> cryptoki_sys::CK_RV { trace!("C_DecryptInit() called"); + ensure_init!(); + let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, None => { @@ -45,6 +47,8 @@ pub extern "C" fn C_Decrypt( ) -> cryptoki_sys::CK_RV { trace!("C_Decrypt() called"); + ensure_init!(); + lock_session!(hSession, session); if pulDataLen.is_null() || pEncryptedData.is_null() { @@ -134,6 +138,8 @@ pub extern "C" fn C_DecryptFinal( ) -> cryptoki_sys::CK_RV { trace!("C_DecryptFinal() called"); + ensure_init!(); + lock_session!(hSession, session); if pulLastPartLen.is_null() { @@ -197,6 +203,9 @@ pub extern "C" fn C_DecryptVerifyUpdate( pulPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DecryptVerifyUpdate() called"); + + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } diff --git a/pkcs11/src/api/digest.rs b/pkcs11/src/api/digest.rs index 130fc2df..783cff96 100644 --- a/pkcs11/src/api/digest.rs +++ b/pkcs11/src/api/digest.rs @@ -10,6 +10,8 @@ pub extern "C" fn C_DigestInit( ) -> cryptoki_sys::CK_RV { trace!("C_DigestInit() called"); + ensure_init!(); + if pMechanism.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -26,6 +28,8 @@ pub extern "C" fn C_Digest( ) -> cryptoki_sys::CK_RV { trace!("C_Digest() called"); + ensure_init!(); + if pData.is_null() || pDigest.is_null() || pulDigestLen.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -40,6 +44,8 @@ pub extern "C" fn C_DigestUpdate( ) -> cryptoki_sys::CK_RV { trace!("C_DigestUpdate() called"); + ensure_init!(); + if pPart.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -54,6 +60,8 @@ pub extern "C" fn C_DigestFinal( ) -> cryptoki_sys::CK_RV { trace!("C_DigestFinal() called"); + ensure_init!(); + if pDigest.is_null() || pulDigestLen.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -66,6 +74,9 @@ pub extern "C" fn C_DigestKey( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_DigestKey() called"); + + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -77,6 +88,8 @@ pub extern "C" fn C_DigestEncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DigestEncryptUpdate() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -88,6 +101,8 @@ pub extern "C" fn C_DecryptDigestUpdate( pulPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DecryptDigestUpdate() called "); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } diff --git a/pkcs11/src/api/encrypt.rs b/pkcs11/src/api/encrypt.rs index b8494142..f6c5698b 100644 --- a/pkcs11/src/api/encrypt.rs +++ b/pkcs11/src/api/encrypt.rs @@ -15,6 +15,7 @@ pub extern "C" fn C_EncryptInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptInit() called"); + ensure_init!(); let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, @@ -47,6 +48,7 @@ pub extern "C" fn C_Encrypt( pulEncryptedDataLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_Encrypt() called"); + ensure_init!(); lock_session!(hSession, session); @@ -115,6 +117,7 @@ pub extern "C" fn C_EncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptUpdate() called"); + ensure_init!(); lock_session!(hSession, session); @@ -177,6 +180,7 @@ pub extern "C" fn C_EncryptFinal( pulLastEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptFinal() called"); + ensure_init!(); lock_session!(hSession, session); diff --git a/pkcs11/src/api/generation.rs b/pkcs11/src/api/generation.rs index 19b336f4..8c00944f 100644 --- a/pkcs11/src/api/generation.rs +++ b/pkcs11/src/api/generation.rs @@ -19,6 +19,7 @@ pub extern "C" fn C_GenerateKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateKey() called"); + ensure_init!(); // pTemplate and pMechanism are checked for null with `from_raw_ptr` @@ -86,6 +87,7 @@ pub extern "C" fn C_GenerateKeyPair( phPrivateKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateKeyPair() called"); + ensure_init!(); // pMechanism, pPrivateKeyTemplate, pPublicKeyTemplate checked for null with `from_raw_ptr` @@ -166,6 +168,8 @@ pub extern "C" fn C_WrapKey( pulWrappedKeyLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_WrapKey() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -180,6 +184,8 @@ pub extern "C" fn C_UnwrapKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_UnwrapKey() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -192,6 +198,8 @@ pub extern "C" fn C_DeriveKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DeriveKey() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -202,6 +210,8 @@ pub extern "C" fn C_SeedRandom( ulSeedLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SeedRandom() called"); + ensure_init!(); + cryptoki_sys::CKR_OK } @@ -211,6 +221,7 @@ pub extern "C" fn C_GenerateRandom( ulRandomLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateRandom() called"); + ensure_init!(); if RandomData.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; diff --git a/pkcs11/src/api/mod.rs b/pkcs11/src/api/mod.rs index 18f90fd8..f47a5cb6 100644 --- a/pkcs11/src/api/mod.rs +++ b/pkcs11/src/api/mod.rs @@ -2,6 +2,16 @@ // for now we allow unused variables, but we should remove this when we have implemented all the functions we need #![allow(unused_variables)] +/// Immediately return an error if the module failed to initialize +/// This is preferable to panicking +macro_rules! ensure_init { + () => { + if *crate::data::DEVICE_ERROR { + return cryptoki_sys::CKR_GENERAL_ERROR; + } + }; +} + pub mod decrypt; pub mod digest; pub mod encrypt; @@ -27,6 +37,8 @@ pub extern "C" fn C_GetFunctionList( pp_fn_list: *mut *mut cryptoki_sys::CK_FUNCTION_LIST, ) -> cryptoki_sys::CK_RV { trace!("C_GetFunctionList() called"); + ensure_init!(); + if pp_fn_list.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -38,12 +50,15 @@ pub extern "C" fn C_GetFunctionList( } pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { + trace!("C_Initialize() called with args: {:?}", pInitArgs); + + ensure_init!(); + // we force the initialization of the lazy static here if DEVICE.slots.is_empty() { debug!("No slots configured"); } - trace!("C_Initialize() called with args: {:?}", pInitArgs); if defs::CRYPTOKI_VERSION.major == 2 && defs::CRYPTOKI_VERSION.minor == 40 && !pInitArgs.is_null() @@ -84,6 +99,9 @@ pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { pub extern "C" fn C_Finalize(pReserved: CK_VOID_PTR) -> CK_RV { trace!("C_Finalize() called"); + + ensure_init!(); + if !pReserved.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -94,6 +112,9 @@ pub extern "C" fn C_Finalize(pReserved: CK_VOID_PTR) -> CK_RV { pub extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV { trace!("C_GetInfo() called"); + + ensure_init!(); + if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } diff --git a/pkcs11/src/api/object.rs b/pkcs11/src/api/object.rs index adf5e753..656c8cf0 100644 --- a/pkcs11/src/api/object.rs +++ b/pkcs11/src/api/object.rs @@ -13,6 +13,7 @@ pub extern "C" fn C_FindObjectsInit( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjectsInit() called with session {}", hSession); + ensure_init!(); if ulCount > 0 && pTemplate.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -35,6 +36,7 @@ pub extern "C" fn C_FindObjects( pulObjectCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjects() called"); + ensure_init!(); if phObject.is_null() || pulObjectCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -64,6 +66,8 @@ pub extern "C" fn C_FindObjectsFinal( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjectsFinal() called"); + ensure_init!(); + lock_session!(hSession, session); session.enum_final(); @@ -77,6 +81,7 @@ pub extern "C" fn C_GetAttributeValue( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_GetAttributeValue() called for object {}.", hObject); + ensure_init!(); if pTemplate.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -117,6 +122,7 @@ pub extern "C" fn C_GetObjectSize( pulSize: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetObjectSize() called"); + ensure_init!(); if pulSize.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -146,6 +152,7 @@ pub extern "C" fn C_CreateObject( phObject: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_CreateObject() called "); + ensure_init!(); // pTemplate checked with from_raw_ptr @@ -189,6 +196,8 @@ pub extern "C" fn C_CopyObject( phNewObject: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_CopyObject() called"); + ensure_init!(); + cryptoki_sys::CKR_ACTION_PROHIBITED } @@ -197,6 +206,7 @@ pub extern "C" fn C_DestroyObject( hObject: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_DestroyObject() called : {}", hObject); + ensure_init!(); lock_session!(hSession, session); @@ -213,6 +223,7 @@ pub extern "C" fn C_SetAttributeValue( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SetAttributeValue() called"); + ensure_init!(); let template = match unsafe { CkRawAttrTemplate::from_raw_ptr(pTemplate, ulCount as usize) } { Some(template) => template, diff --git a/pkcs11/src/api/pin.rs b/pkcs11/src/api/pin.rs index 16c103e6..5fafe37b 100644 --- a/pkcs11/src/api/pin.rs +++ b/pkcs11/src/api/pin.rs @@ -12,6 +12,8 @@ pub extern "C" fn C_InitPIN( ulPinLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_InitPIN() called "); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -23,6 +25,8 @@ pub extern "C" fn C_SetPIN( ulNewLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SetPIN() called "); + ensure_init!(); + lock_session!(hSession, session); if pOldPin.is_null() || pNewPin.is_null() { diff --git a/pkcs11/src/api/session.rs b/pkcs11/src/api/session.rs index 62a1c382..68f076dd 100644 --- a/pkcs11/src/api/session.rs +++ b/pkcs11/src/api/session.rs @@ -16,6 +16,7 @@ pub extern "C" fn C_OpenSession( slotID, flags ); + ensure_init!(); if phSession.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -48,6 +49,7 @@ pub extern "C" fn C_OpenSession( pub extern "C" fn C_CloseSession(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> cryptoki_sys::CK_RV { trace!("C_CloseSession() called with session handle {}.", hSession); + ensure_init!(); let mut manager = SESSION_MANAGER.lock().unwrap(); let result = manager.delete_session(hSession); @@ -65,6 +67,7 @@ pub extern "C" fn C_CloseSession(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> c pub extern "C" fn C_CloseAllSessions(slotID: cryptoki_sys::CK_SLOT_ID) -> cryptoki_sys::CK_RV { trace!("C_CloseAllSessions() called"); + ensure_init!(); if get_slot(slotID as usize).is_err() { error!( @@ -89,6 +92,7 @@ pub extern "C" fn C_GetSessionInfo( "C_GetSessionInfo() called with session handle {}.", hSession ); + ensure_init!(); if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -109,6 +113,8 @@ pub extern "C" fn C_GetOperationState( pulOperationStateLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetOperationState() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -120,6 +126,8 @@ pub extern "C" fn C_SetOperationState( hAuthenticationKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_SetOperationState() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -127,6 +135,8 @@ pub extern "C" fn C_GetFunctionStatus( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_GetFunctionStatus() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL } @@ -134,6 +144,8 @@ pub extern "C" fn C_CancelFunction( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_CancelFunction() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL } diff --git a/pkcs11/src/api/sign.rs b/pkcs11/src/api/sign.rs index eeb6e9b7..48b6a432 100644 --- a/pkcs11/src/api/sign.rs +++ b/pkcs11/src/api/sign.rs @@ -16,6 +16,7 @@ pub extern "C" fn C_SignInit( hKey, hSession ); + ensure_init!(); let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, @@ -48,6 +49,7 @@ pub extern "C" fn C_Sign( pulSignatureLen: *mut cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Sign() called"); + ensure_init!(); lock_session!(hSession, session); @@ -119,6 +121,7 @@ pub extern "C" fn C_SignUpdate( ulPartLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SignUpdate() called"); + ensure_init!(); lock_session!(hSession, session); @@ -144,6 +147,7 @@ pub extern "C" fn C_SignFinal( pulSignatureLen: *mut cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SignFinal() called"); + ensure_init!(); lock_session!(hSession, session); @@ -207,6 +211,8 @@ pub extern "C" fn C_SignRecoverInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_SignRecoverInit() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -218,6 +224,8 @@ pub extern "C" fn C_SignRecover( pulSignatureLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_SignRecover() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -229,6 +237,8 @@ pub extern "C" fn C_SignEncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_SignEncryptUpdate() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } diff --git a/pkcs11/src/api/token.rs b/pkcs11/src/api/token.rs index bc343506..21bc4f37 100644 --- a/pkcs11/src/api/token.rs +++ b/pkcs11/src/api/token.rs @@ -26,6 +26,7 @@ pub extern "C" fn C_GetSlotList( pulCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetSlotList() called"); + ensure_init!(); if pulCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -71,6 +72,7 @@ pub extern "C" fn C_GetSlotInfo( pInfo: cryptoki_sys::CK_SLOT_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetSlotInfo() called with slotID: {}", slotID); + ensure_init!(); if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -148,6 +150,8 @@ pub extern "C" fn C_GetTokenInfo( pInfo: cryptoki_sys::CK_TOKEN_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetTokenInfo() called with slotID: {}", slotID); + ensure_init!(); + // get the slot let slot = match get_slot(slotID as usize) { Ok(slot) => slot, @@ -235,6 +239,7 @@ pub extern "C" fn C_InitToken( pLabel: cryptoki_sys::CK_UTF8CHAR_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_InitToken() called"); + ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -245,6 +250,7 @@ pub extern "C" fn C_GetMechanismList( pulCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetMechanismList() called"); + ensure_init!(); if pulCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -295,6 +301,7 @@ pub extern "C" fn C_GetMechanismInfo( pInfo: cryptoki_sys::CK_MECHANISM_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetMechanismInfo() called"); + ensure_init!(); if let Err(e) = get_slot(slotID as usize) { return e; @@ -325,6 +332,7 @@ pub extern "C" fn C_Login( ulPinLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Login() called"); + ensure_init!(); if pPin.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -348,6 +356,7 @@ pub extern "C" fn C_Login( } pub extern "C" fn C_Logout(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> cryptoki_sys::CK_RV { trace!("C_Logout() called"); + ensure_init!(); lock_session!(hSession, session); @@ -363,6 +372,7 @@ pub extern "C" fn C_WaitForSlotEvent( pReserved: cryptoki_sys::CK_VOID_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_WaitForSlotEvent() called"); + ensure_init!(); if pSlot.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; diff --git a/pkcs11/src/api/verify.rs b/pkcs11/src/api/verify.rs index d6abb168..5b652b20 100644 --- a/pkcs11/src/api/verify.rs +++ b/pkcs11/src/api/verify.rs @@ -9,6 +9,9 @@ pub extern "C" fn C_VerifyInit( pMechanism: cryptoki_sys::CK_MECHANISM_PTR, hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { + trace!("C_VerifyInit() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -20,6 +23,8 @@ pub extern "C" fn C_Verify( ulSignatureLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Verify() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -29,6 +34,8 @@ pub extern "C" fn C_VerifyUpdate( ulPartLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyUpdate() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -38,6 +45,8 @@ pub extern "C" fn C_VerifyFinal( ulSignatureLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyFinal() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -47,6 +56,8 @@ pub extern "C" fn C_VerifyRecoverInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyRecoverInit() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -58,6 +69,8 @@ pub extern "C" fn C_VerifyRecover( pulDataLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyRecover() called"); + ensure_init!(); + cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } diff --git a/pkcs11/src/data.rs b/pkcs11/src/data.rs index b8d08e21..a69ee68d 100644 --- a/pkcs11/src/data.rs +++ b/pkcs11/src/data.rs @@ -2,6 +2,7 @@ use std::sync::{Arc, Mutex, RwLock}; use crate::backend::events::EventsManager; +use crate::config::initialization::InitializationError; use crate::{ api, backend::session::SessionManager, @@ -9,18 +10,31 @@ use crate::{ }; use cryptoki_sys::{CK_FUNCTION_LIST, CK_SLOT_ID, CK_VERSION}; use lazy_static::lazy_static; +use log::error; + pub const DEVICE_VERSION: CK_VERSION = CK_VERSION { major: 2, minor: 40, }; lazy_static! { - pub static ref DEVICE: Device = match config::initialization::initialize_configuration() { + pub static ref DEVICE_RESULT: Result = config::initialization::initialize_configuration(); + + pub static ref DEVICE: &'static Device = match &*DEVICE_RESULT { Ok(config) => config, Err(e) => { panic!("Error initializing configuration: {:?}", e); } }; + + pub static ref DEVICE_ERROR: bool = match &*DEVICE_RESULT { + Ok(_) => false, + Err(e) => { + error!("Error initializing configuration: {:?}", e); + true + } + }; + pub static ref SESSION_MANAGER : Arc> = Arc::new(Mutex::new(SessionManager::new())); // Aliases for the keys, used when enable_set_attribute_value is set. @@ -34,6 +48,7 @@ lazy_static! { // If the calling application allows threads to be used pub static ref THREADS_ALLOWED : Arc> = Arc::new(Mutex::new(true)); } + pub static mut FN_LIST: CK_FUNCTION_LIST = CK_FUNCTION_LIST { version: DEVICE_VERSION, C_Initialize: Some(api::C_Initialize), From ebd9233a5491f2a3b51ce215262518546856c766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 4 Jan 2024 13:47:45 +0100 Subject: [PATCH 2/6] Improve deserialization of fingerprints and certificates This removes panic paths in the initialization of the device. --- pkcs11/src/config/config_file.rs | 47 ++++++++++++++++++++++++++++- pkcs11/src/config/initialization.rs | 30 +++++++++++------- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/pkcs11/src/config/config_file.rs b/pkcs11/src/config/config_file.rs index 3aa013fe..ae9a9011 100644 --- a/pkcs11/src/config/config_file.rs +++ b/pkcs11/src/config/config_file.rs @@ -93,13 +93,58 @@ pub struct RetryConfig { pub delay_seconds: u64, } +#[derive(Debug, Clone)] +pub struct HexFingerprint { + pub value: Vec, +} + +impl Serialize for HexFingerprint { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&hex::encode(&self.value)) + } +} + +impl<'de> Deserialize<'de> for HexFingerprint { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct HexFingerprintVisitor; + impl<'de> serde::de::Visitor<'de> for HexFingerprintVisitor { + type Value = HexFingerprint; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("An hexadecimal value, possibly separated with ':'") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Ok(HexFingerprint { + value: hex::decode(v.replace(':', "")).map_err(|err| { + E::custom(format_args!( + "Failed to parse hexadecimal fingerprint: {err}" + )) + })?, + }) + } + } + + deserializer.deserialize_str(HexFingerprintVisitor) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InstanceConfig { pub url: String, #[serde(default)] pub danger_insecure_cert: bool, #[serde(default)] - pub sha256_fingerprints: Vec, + pub sha256_fingerprints: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/pkcs11/src/config/initialization.rs b/pkcs11/src/config/initialization.rs index b64f53e7..84cfbf23 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -7,7 +7,7 @@ use super::{ config_file::SlotConfig, device::{Device, Slot}, }; -use log::trace; +use log::{debug, error, trace}; use nethsm_sdk_rs::ureq; use rustls::client::ServerCertVerifier; use sha2::Digest; @@ -17,6 +17,7 @@ const DEFAULT_USER_AGENT: &str = "pkcs11-rs/0.1.0"; #[derive(Debug)] pub enum InitializationError { Config(crate::config::config_file::ConfigError), + NoCerts, NoUser(String), } @@ -100,21 +101,28 @@ fn slot_from_config(slot: &SlotConfig) -> Result { .with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier {})) .with_no_client_auth() } else if !instance.sha256_fingerprints.is_empty() { - let mut fingerprints = vec![]; - - for fingerprint in instance.sha256_fingerprints.iter() { - fingerprints.push(hex::decode(fingerprint.replace(':', "")).unwrap()); - } - + let fingerprints = instance + .sha256_fingerprints + .iter() + .map(|f| f.value.clone()) + .collect(); tls_conf .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { fingerprints })) .with_no_client_auth() } else { let mut roots = rustls::RootCertStore::empty(); - for cert in - rustls_native_certs::load_native_certs().expect("could not load platform certs") - { - roots.add(&rustls::Certificate(cert.0)).unwrap(); + let native_certs = rustls_native_certs::load_native_certs().map_err(|err| { + error!("Failed to load certificates: {err}"); + InitializationError::NoCerts + })?; + + let (added, failed) = roots.add_parsable_certificates(&native_certs); + // panic!("{:?}", (added, failed)); + debug!("Added {added} certifcates and failed to parse {failed} certificates"); + + if added == 0 { + error!("Added no native certificates"); + return Err(InitializationError::NoCerts); } tls_conf.with_root_certificates(roots).with_no_client_auth() From 11293a88cf9886f80dc24fd4fd06aea5bcdf1122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 4 Jan 2024 14:02:46 +0100 Subject: [PATCH 3/6] Fix tests --- pkcs11/src/api/decrypt.rs | 18 +++++++++++++++++- pkcs11/src/api/digest.rs | 9 +++++++++ pkcs11/src/api/encrypt.rs | 21 ++++++++++++++++++++- pkcs11/src/api/generation.rs | 19 +++++++++++++++++++ pkcs11/src/api/object.rs | 19 +++++++++++++++++++ pkcs11/src/api/pin.rs | 9 ++++++++- pkcs11/src/api/session.rs | 9 +++++++++ pkcs11/src/api/sign.rs | 19 ++++++++++++++++++- pkcs11/src/api/token.rs | 7 +++++++ pkcs11/src/api/verify.rs | 8 ++++++++ 10 files changed, 134 insertions(+), 4 deletions(-) diff --git a/pkcs11/src/api/decrypt.rs b/pkcs11/src/api/decrypt.rs index 6054d8f4..a5239b21 100644 --- a/pkcs11/src/api/decrypt.rs +++ b/pkcs11/src/api/decrypt.rs @@ -213,7 +213,7 @@ pub extern "C" fn C_DecryptVerifyUpdate( mod tests { use super::*; - use crate::data::SESSION_MANAGER; + use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; fn setup_session() -> cryptoki_sys::CK_SESSION_HANDLE { SESSION_MANAGER.lock().unwrap().setup_dummy_session() @@ -221,12 +221,14 @@ mod tests { #[test] fn test_decrypt_init_null_mech() { + set_test_config_env(); let rv = C_DecryptInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_decrypt_init_unknown_mech() { + set_test_config_env(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: 15000, // doesn't exist pParameter: std::ptr::null_mut(), @@ -239,6 +241,7 @@ mod tests { #[test] fn test_decrypt_init_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut mech = cryptoki_sys::CK_MECHANISM { @@ -253,6 +256,7 @@ mod tests { #[test] fn test_decrypt_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_Decrypt( @@ -267,6 +271,7 @@ mod tests { #[test] fn test_decrypt_null_data_len() { + set_test_config_env(); let mut pEncryptedData = [0u8; 32]; let session_handle = setup_session(); @@ -283,6 +288,7 @@ mod tests { #[test] fn test_decrypt_null_encrypted_data() { + set_test_config_env(); let mut pulDataLen = 0; let session_handle = setup_session(); @@ -299,6 +305,7 @@ mod tests { #[test] fn test_decrypt_null_data() { + set_test_config_env(); let mut pulDataLen = 0; let session_handle = setup_session(); @@ -317,6 +324,7 @@ mod tests { #[test] fn test_decrypt_update_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_DecryptUpdate( @@ -331,6 +339,7 @@ mod tests { #[test] fn test_decrypt_update_null_encrypted_part() { + set_test_config_env(); let session_handle = setup_session(); let mut pulPartLen = 0; @@ -348,6 +357,7 @@ mod tests { #[test] fn test_decrypt_update_null_part_len() { + set_test_config_env(); let session_handle = setup_session(); let mut pEncryptedPart = [0u8; 32]; @@ -365,6 +375,7 @@ mod tests { #[test] fn test_decrypt_update_operation_not_initialized() { + set_test_config_env(); let session_handle = setup_session(); let mut pEncryptedPart = [0u8; 32]; @@ -383,6 +394,7 @@ mod tests { #[test] fn test_decrypt_final_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pulLastPartLen = 0; @@ -393,6 +405,7 @@ mod tests { #[test] fn test_decrypt_final_null_last_part_len() { + set_test_config_env(); let session_handle = setup_session(); let mut lastPart = [0u8; 32]; @@ -403,6 +416,7 @@ mod tests { #[test] fn test_decrypt_final_operation_not_initialized() { + set_test_config_env(); let session_handle = setup_session(); let mut lastPart = [0u8; 32]; @@ -414,6 +428,7 @@ mod tests { // #[test] // fn test_decrypt_final_null_last_part() { + // set_test_config_env(); // let session_handle = setup_session(); // let mut pulLastPartLen = 0; @@ -425,6 +440,7 @@ mod tests { // unsupported function #[test] fn test_decrypt_verify_update() { + set_test_config_env(); let rv = C_DecryptVerifyUpdate( 0, std::ptr::null_mut(), diff --git a/pkcs11/src/api/digest.rs b/pkcs11/src/api/digest.rs index 783cff96..fb0fff6f 100644 --- a/pkcs11/src/api/digest.rs +++ b/pkcs11/src/api/digest.rs @@ -110,9 +110,12 @@ pub extern "C" fn C_DecryptDigestUpdate( mod tests { use cryptoki_sys::CK_ULONG; + use crate::backend::slot::set_test_config_env; + use super::*; #[test] fn test_digest_init() { + set_test_config_env(); let rv = C_DigestInit(0, std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -128,6 +131,7 @@ mod tests { #[test] fn test_digest() { + set_test_config_env(); let rv = C_Digest( 0, std::ptr::null_mut(), @@ -153,6 +157,7 @@ mod tests { #[test] fn test_digest_update() { + set_test_config_env(); let rv = C_DigestUpdate(0, std::ptr::null_mut(), 0 as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -164,6 +169,7 @@ mod tests { #[test] fn test_digest_final() { + set_test_config_env(); let rv = C_DigestFinal(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -176,12 +182,14 @@ mod tests { #[test] fn test_digest_key() { + set_test_config_env(); let rv = C_DigestKey(0, 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_digest_encrypt_update() { + set_test_config_env(); let mut encrypted_part_len: CK_ULONG = 0; let mut encrypted_part: Vec = Vec::new(); let mut part: Vec = Vec::new(); @@ -198,6 +206,7 @@ mod tests { #[test] fn test_decrypt_digest_update() { + set_test_config_env(); let mut encrypted_part_len: CK_ULONG = 0; let mut encrypted_part: Vec = Vec::new(); let mut part: Vec = Vec::new(); diff --git a/pkcs11/src/api/encrypt.rs b/pkcs11/src/api/encrypt.rs index f6c5698b..14f6725b 100644 --- a/pkcs11/src/api/encrypt.rs +++ b/pkcs11/src/api/encrypt.rs @@ -245,18 +245,20 @@ pub extern "C" fn C_EncryptFinal( #[cfg(test)] mod tests { - use crate::data::SESSION_MANAGER; + use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; use super::*; #[test] fn test_encrypt_init_null_mechanism() { + set_test_config_env(); let rv = C_EncryptInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_encrypt_init_invalid_mechanism() { + set_test_config_env(); let mut mechanism = cryptoki_sys::CK_MECHANISM { mechanism: 15000, pParameter: std::ptr::null_mut(), @@ -269,6 +271,7 @@ mod tests { #[test] fn test_encrypt_init_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -283,6 +286,7 @@ mod tests { #[test] fn test_encrypt_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut data: Vec = Vec::new(); @@ -301,6 +305,7 @@ mod tests { #[test] fn test_encrypt_update_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut data: Vec = Vec::new(); @@ -319,6 +324,7 @@ mod tests { #[test] fn test_encrypt_final_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut encrypted_data: Vec = Vec::new(); @@ -330,6 +336,7 @@ mod tests { #[test] fn test_encrypt_null_data() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedDataLen: CK_ULONG = 0; @@ -347,6 +354,7 @@ mod tests { #[test] fn test_encrypt_null_encrypted_data_len() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -364,6 +372,7 @@ mod tests { #[test] fn test_encrypt_null_encrypted_data() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -381,6 +390,7 @@ mod tests { #[test] fn test_encrypt_operation_not_initialized() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -399,6 +409,7 @@ mod tests { #[test] fn test_encrypt_update_null_part() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPartLen: CK_ULONG = 0; @@ -416,6 +427,7 @@ mod tests { #[test] fn test_encrypt_update_null_encrypted_part_len() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -433,6 +445,7 @@ mod tests { #[test] fn test_encrypt_update_null_encrypted_part() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -450,6 +463,7 @@ mod tests { #[test] fn test_encrypt_update_buffer_too_small() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = vec![0; 100]; @@ -468,6 +482,7 @@ mod tests { #[test] fn test_encrypt_update_operation_not_initialized() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = vec![0; 100]; @@ -486,6 +501,7 @@ mod tests { #[test] fn test_encrypt_final_null_encrypted_part() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPartLen: CK_ULONG = 0; @@ -496,6 +512,7 @@ mod tests { #[test] fn test_encrypt_final_null_encrypted_part_len() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPart: Vec = Vec::new(); @@ -510,6 +527,7 @@ mod tests { // #[test] // fn test_encrypt_final_buffer_too_small() { + // set_test_config_env(); // let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // let mut pEncryptedPart: Vec = Vec::new(); @@ -525,6 +543,7 @@ mod tests { #[test] fn test_encrypt_final_operation_not_initialized() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPart: Vec = Vec::new(); diff --git a/pkcs11/src/api/generation.rs b/pkcs11/src/api/generation.rs index 8c00944f..bf2c408f 100644 --- a/pkcs11/src/api/generation.rs +++ b/pkcs11/src/api/generation.rs @@ -289,10 +289,13 @@ pub extern "C" fn C_GenerateRandom( #[cfg(test)] mod tests { + use crate::backend::slot::set_test_config_env; + use super::*; #[test] fn test_generate_key_null_mech() { + set_test_config_env(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -313,6 +316,7 @@ mod tests { #[test] fn test_generate_key_null_template() { + set_test_config_env(); let mut phKey = 0; let mut mech = cryptoki_sys::CK_MECHANISM { @@ -327,6 +331,7 @@ mod tests { #[test] fn test_generate_key_null_phkey() { + set_test_config_env(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -345,6 +350,7 @@ mod tests { #[test] fn test_generate_key_unknown_mech() { + set_test_config_env(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -365,6 +371,7 @@ mod tests { #[test] fn test_generate_key_pair_null_mech() { + set_test_config_env(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -389,6 +396,7 @@ mod tests { #[test] fn test_generate_key_pair_null_public_template() { + set_test_config_env(); let mut phPublicKey = 0; let mut phPrivateKey = 0; @@ -419,6 +427,7 @@ mod tests { #[test] fn test_generate_key_pair_null_private_template() { + set_test_config_env(); let mut phPublicKey = 0; let mut phPrivateKey = 0; @@ -449,6 +458,7 @@ mod tests { #[test] fn test_generate_key_pair_null_ph_public_key() { + set_test_config_env(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: cryptoki_sys::CKM_RSA_PKCS_KEY_PAIR_GEN, pParameter: std::ptr::null_mut(), @@ -482,6 +492,7 @@ mod tests { #[test] fn test_generate_key_pair_null_ph_private_key() { + set_test_config_env(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: cryptoki_sys::CKM_RSA_PKCS_KEY_PAIR_GEN, pParameter: std::ptr::null_mut(), @@ -515,6 +526,7 @@ mod tests { #[test] fn test_generate_key_pair_unknown_mech() { + set_test_config_env(); let mut public_template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -549,12 +561,14 @@ mod tests { #[test] fn test_generate_random_null_data() { + set_test_config_env(); let rv = C_GenerateRandom(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_generate_random_invalid_length() { + set_test_config_env(); let mut random_data = vec![0; 1500]; let rv = C_GenerateRandom(0, random_data.as_mut_ptr(), 1500); @@ -563,6 +577,7 @@ mod tests { #[test] fn test_generate_random_zero_length() { + set_test_config_env(); let mut random_data = vec![0; 1500]; let rv = C_GenerateRandom(0, random_data.as_mut_ptr(), 0); @@ -571,6 +586,7 @@ mod tests { #[test] fn test_wrap_key() { + set_test_config_env(); let rv = C_WrapKey( 0, std::ptr::null_mut(), @@ -584,6 +600,7 @@ mod tests { #[test] fn test_unwrap_key() { + set_test_config_env(); let rv = C_UnwrapKey( 0, std::ptr::null_mut(), @@ -599,6 +616,7 @@ mod tests { #[test] fn test_derive_key() { + set_test_config_env(); let rv = C_DeriveKey( 0, std::ptr::null_mut(), @@ -612,6 +630,7 @@ mod tests { #[test] fn test_seed_random() { + set_test_config_env(); let rv = C_SeedRandom(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_OK); } diff --git a/pkcs11/src/api/object.rs b/pkcs11/src/api/object.rs index 656c8cf0..9e196673 100644 --- a/pkcs11/src/api/object.rs +++ b/pkcs11/src/api/object.rs @@ -280,6 +280,7 @@ mod tests { db::{Db, Object}, login::LoginCtx, session::Session, + slot::set_test_config_env, }, config::config_file::RetryConfig, data::SESSION_MANAGER, @@ -289,12 +290,14 @@ mod tests { #[test] fn test_find_objects_init_bad_arguments() { + set_test_config_env(); let rv = C_FindObjectsInit(0, std::ptr::null_mut(), 1); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_find_objects_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -306,6 +309,7 @@ mod tests { #[test] fn test_find_objects_null_object() { + set_test_config_env(); let mut pulObjectCount: cryptoki_sys::CK_ULONG = 0; let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); @@ -316,6 +320,7 @@ mod tests { #[test] fn test_find_objects_null_object_count() { + set_test_config_env(); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); @@ -326,6 +331,7 @@ mod tests { #[test] fn test_find_objects_final_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_FindObjectsFinal(0); @@ -334,6 +340,7 @@ mod tests { #[test] fn test_get_attribute_value_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut template = vec![]; @@ -344,6 +351,7 @@ mod tests { #[test] fn test_get_attribute_value_null_template() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetAttributeValue(session, 0, std::ptr::null_mut(), 0); @@ -352,6 +360,7 @@ mod tests { #[test] fn test_get_attribute_value_invalid_object() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut template = vec![]; @@ -362,6 +371,7 @@ mod tests { #[test] fn test_get_object_size_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pulSize: cryptoki_sys::CK_ULONG = 0; @@ -372,6 +382,7 @@ mod tests { #[test] fn test_get_object_size_null_size() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetObjectSize(session, 0, std::ptr::null_mut()); @@ -380,6 +391,7 @@ mod tests { #[test] fn test_get_object_size_invalid_object() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pulSize: cryptoki_sys::CK_ULONG = 0; @@ -390,6 +402,7 @@ mod tests { #[test] fn test_get_object_size() { + set_test_config_env(); let size = 32; let mut db = Db::new(); let mut object = Object::default(); @@ -431,6 +444,7 @@ mod tests { #[test] fn test_create_object_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut template = vec![]; let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -441,6 +455,7 @@ mod tests { #[test] fn test_create_object_null_object() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut template = vec![]; @@ -451,6 +466,7 @@ mod tests { #[test] fn test_create_object_null_template() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -461,6 +477,7 @@ mod tests { #[test] fn test_destroy_object_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_DestroyObject(0, 0); @@ -469,6 +486,7 @@ mod tests { #[test] fn test_set_attribute_null_template() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SetAttributeValue(session, 0, std::ptr::null_mut(), 0); @@ -477,6 +495,7 @@ mod tests { #[test] fn test_copy_object() { + set_test_config_env(); let rv = C_CopyObject(0, 0, std::ptr::null_mut(), 0, std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ACTION_PROHIBITED); } diff --git a/pkcs11/src/api/pin.rs b/pkcs11/src/api/pin.rs index 5fafe37b..9453ce4a 100644 --- a/pkcs11/src/api/pin.rs +++ b/pkcs11/src/api/pin.rs @@ -70,18 +70,20 @@ mod tests { use cryptoki_sys::CK_ULONG; - use crate::data::SESSION_MANAGER; + use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; use super::*; #[test] fn test_init_pin() { + set_test_config_env(); let rv = C_InitPIN(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_set_pin_null_old_pin() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let newPin = "12345678"; @@ -98,6 +100,7 @@ mod tests { #[test] fn test_set_pin_null_new_pin() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; @@ -114,6 +117,7 @@ mod tests { #[test] fn test_set_pin_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let oldPin = "12345678"; @@ -131,6 +135,7 @@ mod tests { #[test] fn test_set_pin_no_utf8_old_pin() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // random bytes @@ -151,6 +156,7 @@ mod tests { #[test] fn test_set_pin_no_utf8_new_pin() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; @@ -171,6 +177,7 @@ mod tests { #[test] fn test_set_pin_no_user() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; diff --git a/pkcs11/src/api/session.rs b/pkcs11/src/api/session.rs index 68f076dd..2706df37 100644 --- a/pkcs11/src/api/session.rs +++ b/pkcs11/src/api/session.rs @@ -157,6 +157,7 @@ mod tests { #[test] fn test_open_session_null_session() { + set_test_config_env(); let rv = C_OpenSession( 0, cryptoki_sys::CKF_SERIAL_SESSION | cryptoki_sys::CKF_RW_SESSION, @@ -169,6 +170,7 @@ mod tests { #[test] fn test_open_session_parallel() { + set_test_config_env(); let mut session = 0; let rv = C_OpenSession(0, 0, std::ptr::null_mut(), None, &mut session); assert_eq!(rv, cryptoki_sys::CKR_SESSION_PARALLEL_NOT_SUPPORTED); @@ -176,6 +178,7 @@ mod tests { #[test] fn test_delete_session_invalid() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_CloseSession(0); @@ -208,6 +211,7 @@ mod tests { #[test] fn test_get_session_info_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut info = cryptoki_sys::CK_SESSION_INFO::default(); @@ -217,6 +221,7 @@ mod tests { #[test] fn test_get_session_info_null_info() { + set_test_config_env(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetSessionInfo(session_handle, std::ptr::null_mut()); @@ -225,24 +230,28 @@ mod tests { #[test] fn test_get_operation_state() { + set_test_config_env(); let rv = C_GetOperationState(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_set_operation_state() { + set_test_config_env(); let rv = C_SetOperationState(0, std::ptr::null_mut(), 0, 0, 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_get_function_status() { + set_test_config_env(); let rv = C_GetFunctionStatus(0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL); } #[test] fn test_cancel_function() { + set_test_config_env(); let rv = C_CancelFunction(0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL); } diff --git a/pkcs11/src/api/sign.rs b/pkcs11/src/api/sign.rs index 48b6a432..33c9353f 100644 --- a/pkcs11/src/api/sign.rs +++ b/pkcs11/src/api/sign.rs @@ -244,12 +244,13 @@ pub extern "C" fn C_SignEncryptUpdate( #[cfg(test)] mod tests { - use crate::data::SESSION_MANAGER; + use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; use super::*; #[test] fn test_sign_init_null_mechanism() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SignInit(session, std::ptr::null_mut(), 0); @@ -258,6 +259,7 @@ mod tests { #[test] fn test_sign_init_invalid_mechanism() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -272,6 +274,7 @@ mod tests { #[test] fn test_sign_init_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -286,6 +289,7 @@ mod tests { #[test] fn test_sign_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut data = [0u8; 32]; @@ -304,6 +308,7 @@ mod tests { #[test] fn test_sign_null_data() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -321,6 +326,7 @@ mod tests { #[test] fn test_sign_null_signature_len() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -338,6 +344,7 @@ mod tests { #[test] fn test_sign_operation_not_initialized() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -356,6 +363,7 @@ mod tests { // #[test] // fn test_sign_null_signature() { + // set_test_config_env(); // let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // let mut data = [0u8; 32]; @@ -373,6 +381,7 @@ mod tests { #[test] fn test_sign_update_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut data = [0u8; 32]; @@ -383,6 +392,7 @@ mod tests { #[test] fn test_sign_update_null_data() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SignUpdate(session, std::ptr::null_mut(), 0); @@ -391,6 +401,7 @@ mod tests { #[test] fn test_sign_update_operation_not_initialized() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -401,6 +412,7 @@ mod tests { #[test] fn test_sign_final_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut signature = [0u8; 32]; @@ -412,6 +424,7 @@ mod tests { #[test] fn test_sign_final_null_signature_len() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -422,6 +435,7 @@ mod tests { #[test] fn test_sign_final_operation_not_initialized() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -433,12 +447,14 @@ mod tests { #[test] fn test_sign_recover_init() { + set_test_config_env(); let rv = C_SignRecoverInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_sign_recover() { + set_test_config_env(); let rv = C_SignRecover( 0, std::ptr::null_mut(), @@ -451,6 +467,7 @@ mod tests { #[test] fn test_sign_encrypt_update() { + set_test_config_env(); let rv = C_SignEncryptUpdate( 0, std::ptr::null_mut(), diff --git a/pkcs11/src/api/token.rs b/pkcs11/src/api/token.rs index 21bc4f37..38d515d9 100644 --- a/pkcs11/src/api/token.rs +++ b/pkcs11/src/api/token.rs @@ -514,6 +514,7 @@ mod tests { #[test] fn test_get_slot_list_null_count() { + set_test_config_env(); let result = C_GetSlotList(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); } @@ -640,6 +641,7 @@ mod tests { #[test] fn test_login_null_pin() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let result = C_Login(session, CKU_USER, std::ptr::null_mut(), 0); @@ -648,6 +650,7 @@ mod tests { #[test] fn test_login_non_utf8_pin() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pin = [0xFF, 0xFF, 0xFF, 0xFF]; @@ -658,6 +661,7 @@ mod tests { #[test] fn test_login_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pin = "1234".to_string(); @@ -668,6 +672,7 @@ mod tests { #[test] fn test_logout_invalid_session() { + set_test_config_env(); SESSION_MANAGER.lock().unwrap().delete_session(0); let result = C_Logout(0); @@ -676,6 +681,7 @@ mod tests { #[test] fn test_logout() { + set_test_config_env(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let result = C_Logout(session); @@ -684,6 +690,7 @@ mod tests { #[test] fn test_init_token() { + set_test_config_env(); let result = C_InitToken(0, std::ptr::null_mut(), 0, std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } diff --git a/pkcs11/src/api/verify.rs b/pkcs11/src/api/verify.rs index 5b652b20..2de3ec80 100644 --- a/pkcs11/src/api/verify.rs +++ b/pkcs11/src/api/verify.rs @@ -79,16 +79,20 @@ pub extern "C" fn C_VerifyRecover( mod tests { use cryptoki_sys::CK_ULONG; + use crate::backend::slot::set_test_config_env; + use super::*; #[test] fn test_verify_init() { + set_test_config_env(); let rv = C_VerifyInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_verify() { + set_test_config_env(); let mut data = [0u8; 1]; let mut sig = [0u8; 1]; let rv = C_Verify( @@ -103,6 +107,7 @@ mod tests { #[test] fn test_verify_update() { + set_test_config_env(); let mut data = [0u8; 1]; let rv = C_VerifyUpdate(0, data.as_mut_ptr(), data.len() as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); @@ -110,6 +115,7 @@ mod tests { #[test] fn test_verify_final() { + set_test_config_env(); let mut sig = [0u8; 1]; let rv = C_VerifyFinal(0, sig.as_mut_ptr(), sig.len() as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); @@ -117,12 +123,14 @@ mod tests { #[test] fn test_verify_recover_init() { + set_test_config_env(); let rv = C_VerifyRecoverInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_verify_recover() { + set_test_config_env(); let mut sig = [0u8; 1]; let mut data = [0u8; 1]; let mut data_len = 0; From 631be7e93f01785fbb86d65647b6cd9dd10dc98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 4 Jan 2024 16:23:51 +0100 Subject: [PATCH 4/6] Allow C_GetFunctionList regardless of initialization status --- pkcs11/src/api/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pkcs11/src/api/mod.rs b/pkcs11/src/api/mod.rs index f47a5cb6..d1fc905f 100644 --- a/pkcs11/src/api/mod.rs +++ b/pkcs11/src/api/mod.rs @@ -37,7 +37,6 @@ pub extern "C" fn C_GetFunctionList( pp_fn_list: *mut *mut cryptoki_sys::CK_FUNCTION_LIST, ) -> cryptoki_sys::CK_RV { trace!("C_GetFunctionList() called"); - ensure_init!(); if pp_fn_list.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; From ec71b8b4d6c0d20864f1464acbdd04fa0d803414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 5 Jan 2024 11:40:50 +0100 Subject: [PATCH 5/6] Make device be initialized on `C_Initialize` call return CKR_CRYPTOKI_NOT_INITIALIZED in other calls when not initialized --- pkcs11/src/api/decrypt.rs | 42 ++++++++----------- pkcs11/src/api/digest.rs | 28 ++++--------- pkcs11/src/api/encrypt.rs | 44 +++++++++----------- pkcs11/src/api/generation.rs | 43 ++++++++----------- pkcs11/src/api/mod.rs | 49 ++++++++++++---------- pkcs11/src/api/object.rs | 54 +++++++++++------------- pkcs11/src/api/pin.rs | 18 ++++---- pkcs11/src/api/session.rs | 32 ++++++--------- pkcs11/src/api/sign.rs | 43 ++++++++----------- pkcs11/src/api/token.rs | 80 ++++++++++++++++++------------------ pkcs11/src/api/verify.rs | 20 ++++----- pkcs11/src/backend/events.rs | 11 ++++- pkcs11/src/backend/key.rs | 7 +++- pkcs11/src/backend/mod.rs | 13 +++--- pkcs11/src/backend/slot.rs | 21 ++++++++-- pkcs11/src/data.rs | 31 +++----------- 16 files changed, 249 insertions(+), 287 deletions(-) diff --git a/pkcs11/src/api/decrypt.rs b/pkcs11/src/api/decrypt.rs index a5239b21..8422865f 100644 --- a/pkcs11/src/api/decrypt.rs +++ b/pkcs11/src/api/decrypt.rs @@ -13,8 +13,6 @@ pub extern "C" fn C_DecryptInit( ) -> cryptoki_sys::CK_RV { trace!("C_DecryptInit() called"); - ensure_init!(); - let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, None => { @@ -47,8 +45,6 @@ pub extern "C" fn C_Decrypt( ) -> cryptoki_sys::CK_RV { trace!("C_Decrypt() called"); - ensure_init!(); - lock_session!(hSession, session); if pulDataLen.is_null() || pEncryptedData.is_null() { @@ -138,8 +134,6 @@ pub extern "C" fn C_DecryptFinal( ) -> cryptoki_sys::CK_RV { trace!("C_DecryptFinal() called"); - ensure_init!(); - lock_session!(hSession, session); if pulLastPartLen.is_null() { @@ -204,8 +198,6 @@ pub extern "C" fn C_DecryptVerifyUpdate( ) -> cryptoki_sys::CK_RV { trace!("C_DecryptVerifyUpdate() called"); - ensure_init!(); - cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -213,7 +205,7 @@ pub extern "C" fn C_DecryptVerifyUpdate( mod tests { use super::*; - use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; + use crate::{backend::slot::init_for_tests, data::SESSION_MANAGER}; fn setup_session() -> cryptoki_sys::CK_SESSION_HANDLE { SESSION_MANAGER.lock().unwrap().setup_dummy_session() @@ -221,14 +213,14 @@ mod tests { #[test] fn test_decrypt_init_null_mech() { - set_test_config_env(); + init_for_tests(); let rv = C_DecryptInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_decrypt_init_unknown_mech() { - set_test_config_env(); + init_for_tests(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: 15000, // doesn't exist pParameter: std::ptr::null_mut(), @@ -241,7 +233,7 @@ mod tests { #[test] fn test_decrypt_init_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut mech = cryptoki_sys::CK_MECHANISM { @@ -256,7 +248,7 @@ mod tests { #[test] fn test_decrypt_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_Decrypt( @@ -271,7 +263,7 @@ mod tests { #[test] fn test_decrypt_null_data_len() { - set_test_config_env(); + init_for_tests(); let mut pEncryptedData = [0u8; 32]; let session_handle = setup_session(); @@ -288,7 +280,7 @@ mod tests { #[test] fn test_decrypt_null_encrypted_data() { - set_test_config_env(); + init_for_tests(); let mut pulDataLen = 0; let session_handle = setup_session(); @@ -305,7 +297,7 @@ mod tests { #[test] fn test_decrypt_null_data() { - set_test_config_env(); + init_for_tests(); let mut pulDataLen = 0; let session_handle = setup_session(); @@ -324,7 +316,7 @@ mod tests { #[test] fn test_decrypt_update_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_DecryptUpdate( @@ -339,7 +331,7 @@ mod tests { #[test] fn test_decrypt_update_null_encrypted_part() { - set_test_config_env(); + init_for_tests(); let session_handle = setup_session(); let mut pulPartLen = 0; @@ -357,7 +349,7 @@ mod tests { #[test] fn test_decrypt_update_null_part_len() { - set_test_config_env(); + init_for_tests(); let session_handle = setup_session(); let mut pEncryptedPart = [0u8; 32]; @@ -375,7 +367,7 @@ mod tests { #[test] fn test_decrypt_update_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session_handle = setup_session(); let mut pEncryptedPart = [0u8; 32]; @@ -394,7 +386,7 @@ mod tests { #[test] fn test_decrypt_final_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pulLastPartLen = 0; @@ -405,7 +397,7 @@ mod tests { #[test] fn test_decrypt_final_null_last_part_len() { - set_test_config_env(); + init_for_tests(); let session_handle = setup_session(); let mut lastPart = [0u8; 32]; @@ -416,7 +408,7 @@ mod tests { #[test] fn test_decrypt_final_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session_handle = setup_session(); let mut lastPart = [0u8; 32]; @@ -428,7 +420,7 @@ mod tests { // #[test] // fn test_decrypt_final_null_last_part() { - // set_test_config_env(); + // init_for_tests(); // let session_handle = setup_session(); // let mut pulLastPartLen = 0; @@ -440,7 +432,7 @@ mod tests { // unsupported function #[test] fn test_decrypt_verify_update() { - set_test_config_env(); + init_for_tests(); let rv = C_DecryptVerifyUpdate( 0, std::ptr::null_mut(), diff --git a/pkcs11/src/api/digest.rs b/pkcs11/src/api/digest.rs index fb0fff6f..35192301 100644 --- a/pkcs11/src/api/digest.rs +++ b/pkcs11/src/api/digest.rs @@ -10,8 +10,6 @@ pub extern "C" fn C_DigestInit( ) -> cryptoki_sys::CK_RV { trace!("C_DigestInit() called"); - ensure_init!(); - if pMechanism.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -28,8 +26,6 @@ pub extern "C" fn C_Digest( ) -> cryptoki_sys::CK_RV { trace!("C_Digest() called"); - ensure_init!(); - if pData.is_null() || pDigest.is_null() || pulDigestLen.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -44,8 +40,6 @@ pub extern "C" fn C_DigestUpdate( ) -> cryptoki_sys::CK_RV { trace!("C_DigestUpdate() called"); - ensure_init!(); - if pPart.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -60,8 +54,6 @@ pub extern "C" fn C_DigestFinal( ) -> cryptoki_sys::CK_RV { trace!("C_DigestFinal() called"); - ensure_init!(); - if pDigest.is_null() || pulDigestLen.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -75,8 +67,6 @@ pub extern "C" fn C_DigestKey( ) -> cryptoki_sys::CK_RV { trace!("C_DigestKey() called"); - ensure_init!(); - cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -88,7 +78,6 @@ pub extern "C" fn C_DigestEncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DigestEncryptUpdate() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -101,7 +90,6 @@ pub extern "C" fn C_DecryptDigestUpdate( pulPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DecryptDigestUpdate() called "); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -110,12 +98,12 @@ pub extern "C" fn C_DecryptDigestUpdate( mod tests { use cryptoki_sys::CK_ULONG; - use crate::backend::slot::set_test_config_env; + use crate::backend::slot::init_for_tests; use super::*; #[test] fn test_digest_init() { - set_test_config_env(); + init_for_tests(); let rv = C_DigestInit(0, std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -131,7 +119,7 @@ mod tests { #[test] fn test_digest() { - set_test_config_env(); + init_for_tests(); let rv = C_Digest( 0, std::ptr::null_mut(), @@ -157,7 +145,7 @@ mod tests { #[test] fn test_digest_update() { - set_test_config_env(); + init_for_tests(); let rv = C_DigestUpdate(0, std::ptr::null_mut(), 0 as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -169,7 +157,7 @@ mod tests { #[test] fn test_digest_final() { - set_test_config_env(); + init_for_tests(); let rv = C_DigestFinal(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -182,14 +170,14 @@ mod tests { #[test] fn test_digest_key() { - set_test_config_env(); + init_for_tests(); let rv = C_DigestKey(0, 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_digest_encrypt_update() { - set_test_config_env(); + init_for_tests(); let mut encrypted_part_len: CK_ULONG = 0; let mut encrypted_part: Vec = Vec::new(); let mut part: Vec = Vec::new(); @@ -206,7 +194,7 @@ mod tests { #[test] fn test_decrypt_digest_update() { - set_test_config_env(); + init_for_tests(); let mut encrypted_part_len: CK_ULONG = 0; let mut encrypted_part: Vec = Vec::new(); let mut part: Vec = Vec::new(); diff --git a/pkcs11/src/api/encrypt.rs b/pkcs11/src/api/encrypt.rs index 14f6725b..2db4521e 100644 --- a/pkcs11/src/api/encrypt.rs +++ b/pkcs11/src/api/encrypt.rs @@ -15,7 +15,6 @@ pub extern "C" fn C_EncryptInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptInit() called"); - ensure_init!(); let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, @@ -48,7 +47,6 @@ pub extern "C" fn C_Encrypt( pulEncryptedDataLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_Encrypt() called"); - ensure_init!(); lock_session!(hSession, session); @@ -117,7 +115,6 @@ pub extern "C" fn C_EncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptUpdate() called"); - ensure_init!(); lock_session!(hSession, session); @@ -180,7 +177,6 @@ pub extern "C" fn C_EncryptFinal( pulLastEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_EncryptFinal() called"); - ensure_init!(); lock_session!(hSession, session); @@ -245,20 +241,20 @@ pub extern "C" fn C_EncryptFinal( #[cfg(test)] mod tests { - use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; + use crate::{backend::slot::init_for_tests, data::SESSION_MANAGER}; use super::*; #[test] fn test_encrypt_init_null_mechanism() { - set_test_config_env(); + init_for_tests(); let rv = C_EncryptInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_encrypt_init_invalid_mechanism() { - set_test_config_env(); + init_for_tests(); let mut mechanism = cryptoki_sys::CK_MECHANISM { mechanism: 15000, pParameter: std::ptr::null_mut(), @@ -271,7 +267,7 @@ mod tests { #[test] fn test_encrypt_init_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -286,7 +282,7 @@ mod tests { #[test] fn test_encrypt_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut data: Vec = Vec::new(); @@ -305,7 +301,7 @@ mod tests { #[test] fn test_encrypt_update_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut data: Vec = Vec::new(); @@ -324,7 +320,7 @@ mod tests { #[test] fn test_encrypt_final_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(1); let mut encrypted_data: Vec = Vec::new(); @@ -336,7 +332,7 @@ mod tests { #[test] fn test_encrypt_null_data() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedDataLen: CK_ULONG = 0; @@ -354,7 +350,7 @@ mod tests { #[test] fn test_encrypt_null_encrypted_data_len() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -372,7 +368,7 @@ mod tests { #[test] fn test_encrypt_null_encrypted_data() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -390,7 +386,7 @@ mod tests { #[test] fn test_encrypt_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -409,7 +405,7 @@ mod tests { #[test] fn test_encrypt_update_null_part() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPartLen: CK_ULONG = 0; @@ -427,7 +423,7 @@ mod tests { #[test] fn test_encrypt_update_null_encrypted_part_len() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -445,7 +441,7 @@ mod tests { #[test] fn test_encrypt_update_null_encrypted_part() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = Vec::new(); @@ -463,7 +459,7 @@ mod tests { #[test] fn test_encrypt_update_buffer_too_small() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = vec![0; 100]; @@ -482,7 +478,7 @@ mod tests { #[test] fn test_encrypt_update_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data: Vec = vec![0; 100]; @@ -501,7 +497,7 @@ mod tests { #[test] fn test_encrypt_final_null_encrypted_part() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPartLen: CK_ULONG = 0; @@ -512,7 +508,7 @@ mod tests { #[test] fn test_encrypt_final_null_encrypted_part_len() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPart: Vec = Vec::new(); @@ -527,7 +523,7 @@ mod tests { // #[test] // fn test_encrypt_final_buffer_too_small() { - // set_test_config_env(); + // init_for_tests(); // let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // let mut pEncryptedPart: Vec = Vec::new(); @@ -543,7 +539,7 @@ mod tests { #[test] fn test_encrypt_final_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pEncryptedPart: Vec = Vec::new(); diff --git a/pkcs11/src/api/generation.rs b/pkcs11/src/api/generation.rs index bf2c408f..f23b27e5 100644 --- a/pkcs11/src/api/generation.rs +++ b/pkcs11/src/api/generation.rs @@ -19,7 +19,6 @@ pub extern "C" fn C_GenerateKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateKey() called"); - ensure_init!(); // pTemplate and pMechanism are checked for null with `from_raw_ptr` @@ -87,7 +86,6 @@ pub extern "C" fn C_GenerateKeyPair( phPrivateKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateKeyPair() called"); - ensure_init!(); // pMechanism, pPrivateKeyTemplate, pPublicKeyTemplate checked for null with `from_raw_ptr` @@ -168,7 +166,6 @@ pub extern "C" fn C_WrapKey( pulWrappedKeyLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_WrapKey() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -184,7 +181,6 @@ pub extern "C" fn C_UnwrapKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_UnwrapKey() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -198,7 +194,6 @@ pub extern "C" fn C_DeriveKey( phKey: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_DeriveKey() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -210,7 +205,6 @@ pub extern "C" fn C_SeedRandom( ulSeedLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SeedRandom() called"); - ensure_init!(); cryptoki_sys::CKR_OK } @@ -221,7 +215,6 @@ pub extern "C" fn C_GenerateRandom( ulRandomLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_GenerateRandom() called"); - ensure_init!(); if RandomData.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -289,13 +282,13 @@ pub extern "C" fn C_GenerateRandom( #[cfg(test)] mod tests { - use crate::backend::slot::set_test_config_env; + use crate::backend::slot::init_for_tests; use super::*; #[test] fn test_generate_key_null_mech() { - set_test_config_env(); + init_for_tests(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -316,7 +309,7 @@ mod tests { #[test] fn test_generate_key_null_template() { - set_test_config_env(); + init_for_tests(); let mut phKey = 0; let mut mech = cryptoki_sys::CK_MECHANISM { @@ -331,7 +324,7 @@ mod tests { #[test] fn test_generate_key_null_phkey() { - set_test_config_env(); + init_for_tests(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -350,7 +343,7 @@ mod tests { #[test] fn test_generate_key_unknown_mech() { - set_test_config_env(); + init_for_tests(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -371,7 +364,7 @@ mod tests { #[test] fn test_generate_key_pair_null_mech() { - set_test_config_env(); + init_for_tests(); let mut template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -396,7 +389,7 @@ mod tests { #[test] fn test_generate_key_pair_null_public_template() { - set_test_config_env(); + init_for_tests(); let mut phPublicKey = 0; let mut phPrivateKey = 0; @@ -427,7 +420,7 @@ mod tests { #[test] fn test_generate_key_pair_null_private_template() { - set_test_config_env(); + init_for_tests(); let mut phPublicKey = 0; let mut phPrivateKey = 0; @@ -458,7 +451,7 @@ mod tests { #[test] fn test_generate_key_pair_null_ph_public_key() { - set_test_config_env(); + init_for_tests(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: cryptoki_sys::CKM_RSA_PKCS_KEY_PAIR_GEN, pParameter: std::ptr::null_mut(), @@ -492,7 +485,7 @@ mod tests { #[test] fn test_generate_key_pair_null_ph_private_key() { - set_test_config_env(); + init_for_tests(); let mut mech = cryptoki_sys::CK_MECHANISM { mechanism: cryptoki_sys::CKM_RSA_PKCS_KEY_PAIR_GEN, pParameter: std::ptr::null_mut(), @@ -526,7 +519,7 @@ mod tests { #[test] fn test_generate_key_pair_unknown_mech() { - set_test_config_env(); + init_for_tests(); let mut public_template = vec![cryptoki_sys::CK_ATTRIBUTE { type_: 0, pValue: std::ptr::null_mut(), @@ -561,14 +554,14 @@ mod tests { #[test] fn test_generate_random_null_data() { - set_test_config_env(); + init_for_tests(); let rv = C_GenerateRandom(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_generate_random_invalid_length() { - set_test_config_env(); + init_for_tests(); let mut random_data = vec![0; 1500]; let rv = C_GenerateRandom(0, random_data.as_mut_ptr(), 1500); @@ -577,7 +570,7 @@ mod tests { #[test] fn test_generate_random_zero_length() { - set_test_config_env(); + init_for_tests(); let mut random_data = vec![0; 1500]; let rv = C_GenerateRandom(0, random_data.as_mut_ptr(), 0); @@ -586,7 +579,7 @@ mod tests { #[test] fn test_wrap_key() { - set_test_config_env(); + init_for_tests(); let rv = C_WrapKey( 0, std::ptr::null_mut(), @@ -600,7 +593,7 @@ mod tests { #[test] fn test_unwrap_key() { - set_test_config_env(); + init_for_tests(); let rv = C_UnwrapKey( 0, std::ptr::null_mut(), @@ -616,7 +609,7 @@ mod tests { #[test] fn test_derive_key() { - set_test_config_env(); + init_for_tests(); let rv = C_DeriveKey( 0, std::ptr::null_mut(), @@ -630,7 +623,7 @@ mod tests { #[test] fn test_seed_random() { - set_test_config_env(); + init_for_tests(); let rv = C_SeedRandom(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_OK); } diff --git a/pkcs11/src/api/mod.rs b/pkcs11/src/api/mod.rs index d1fc905f..4694aecb 100644 --- a/pkcs11/src/api/mod.rs +++ b/pkcs11/src/api/mod.rs @@ -2,16 +2,6 @@ // for now we allow unused variables, but we should remove this when we have implemented all the functions we need #![allow(unused_variables)] -/// Immediately return an error if the module failed to initialize -/// This is preferable to panicking -macro_rules! ensure_init { - () => { - if *crate::data::DEVICE_ERROR { - return cryptoki_sys::CKR_GENERAL_ERROR; - } - }; -} - pub mod decrypt; pub mod digest; pub mod encrypt; @@ -25,12 +15,12 @@ pub mod verify; use crate::{ backend::events::{fetch_slots_state, EventsManager}, - data::{self, DEVICE, EVENTS_MANAGER, THREADS_ALLOWED, TOKENS_STATE}, + data::{self, DEVICE, DEVICE_INIT, EVENTS_MANAGER, THREADS_ALLOWED, TOKENS_STATE}, defs, utils::padded_str, }; use cryptoki_sys::{CK_INFO, CK_INFO_PTR, CK_RV, CK_VOID_PTR}; -use log::{debug, trace}; +use log::{debug, error, trace}; #[no_mangle] pub extern "C" fn C_GetFunctionList( @@ -51,10 +41,30 @@ pub extern "C" fn C_GetFunctionList( pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { trace!("C_Initialize() called with args: {:?}", pInitArgs); - ensure_init!(); + let mut result = Ok(()); + + DEVICE_INIT.call_once(|| { + let res = crate::config::initialization::initialize_configuration(); + match res { + Ok(device) => { + _ = DEVICE.set(device); + } + Err(err) => result = Err(err), + } + }); + + match result { + Ok(()) => {} + Err(err) => { + error!("Failed to initialize configuration: {err:?}"); + return cryptoki_sys::CKR_FUNCTION_FAILED; + } + } + + let device = DEVICE.get().expect("Device was just initializated"); // we force the initialization of the lazy static here - if DEVICE.slots.is_empty() { + if device.slots.is_empty() { debug!("No slots configured"); } @@ -91,16 +101,15 @@ pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { *EVENTS_MANAGER.write().unwrap() = EventsManager::new(); *TOKENS_STATE.lock().unwrap() = std::collections::HashMap::new(); - fetch_slots_state(); - - cryptoki_sys::CKR_OK + match fetch_slots_state() { + Ok(()) => cryptoki_sys::CKR_OK, + Err(err) => err, + } } pub extern "C" fn C_Finalize(pReserved: CK_VOID_PTR) -> CK_RV { trace!("C_Finalize() called"); - ensure_init!(); - if !pReserved.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } @@ -112,8 +121,6 @@ pub extern "C" fn C_Finalize(pReserved: CK_VOID_PTR) -> CK_RV { pub extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV { trace!("C_GetInfo() called"); - ensure_init!(); - if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } diff --git a/pkcs11/src/api/object.rs b/pkcs11/src/api/object.rs index 9e196673..21ba844f 100644 --- a/pkcs11/src/api/object.rs +++ b/pkcs11/src/api/object.rs @@ -13,7 +13,6 @@ pub extern "C" fn C_FindObjectsInit( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjectsInit() called with session {}", hSession); - ensure_init!(); if ulCount > 0 && pTemplate.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -36,7 +35,6 @@ pub extern "C" fn C_FindObjects( pulObjectCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjects() called"); - ensure_init!(); if phObject.is_null() || pulObjectCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -66,7 +64,6 @@ pub extern "C" fn C_FindObjectsFinal( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_FindObjectsFinal() called"); - ensure_init!(); lock_session!(hSession, session); @@ -81,7 +78,6 @@ pub extern "C" fn C_GetAttributeValue( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_GetAttributeValue() called for object {}.", hObject); - ensure_init!(); if pTemplate.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -122,7 +118,6 @@ pub extern "C" fn C_GetObjectSize( pulSize: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetObjectSize() called"); - ensure_init!(); if pulSize.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -152,7 +147,6 @@ pub extern "C" fn C_CreateObject( phObject: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_CreateObject() called "); - ensure_init!(); // pTemplate checked with from_raw_ptr @@ -196,7 +190,6 @@ pub extern "C" fn C_CopyObject( phNewObject: cryptoki_sys::CK_OBJECT_HANDLE_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_CopyObject() called"); - ensure_init!(); cryptoki_sys::CKR_ACTION_PROHIBITED } @@ -206,7 +199,6 @@ pub extern "C" fn C_DestroyObject( hObject: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_DestroyObject() called : {}", hObject); - ensure_init!(); lock_session!(hSession, session); @@ -223,7 +215,6 @@ pub extern "C" fn C_SetAttributeValue( ulCount: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SetAttributeValue() called"); - ensure_init!(); let template = match unsafe { CkRawAttrTemplate::from_raw_ptr(pTemplate, ulCount as usize) } { Some(template) => template, @@ -238,8 +229,13 @@ pub extern "C" fn C_SetAttributeValue( } }; + let Some(device) = DEVICE.get() else { + error!("Initialization was not performed or failed"); + return cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED; + }; + // if the hack is enabled, we update the key alias map - if DEVICE.enable_set_attribute_value { + if device.enable_set_attribute_value { read_session!(hSession, session); let object = match session.get_object(hObject) { @@ -280,7 +276,7 @@ mod tests { db::{Db, Object}, login::LoginCtx, session::Session, - slot::set_test_config_env, + slot::init_for_tests, }, config::config_file::RetryConfig, data::SESSION_MANAGER, @@ -290,14 +286,14 @@ mod tests { #[test] fn test_find_objects_init_bad_arguments() { - set_test_config_env(); + init_for_tests(); let rv = C_FindObjectsInit(0, std::ptr::null_mut(), 1); assert_eq!(rv, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_find_objects_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -309,7 +305,7 @@ mod tests { #[test] fn test_find_objects_null_object() { - set_test_config_env(); + init_for_tests(); let mut pulObjectCount: cryptoki_sys::CK_ULONG = 0; let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); @@ -320,7 +316,7 @@ mod tests { #[test] fn test_find_objects_null_object_count() { - set_test_config_env(); + init_for_tests(); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); @@ -331,7 +327,7 @@ mod tests { #[test] fn test_find_objects_final_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_FindObjectsFinal(0); @@ -340,7 +336,7 @@ mod tests { #[test] fn test_get_attribute_value_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut template = vec![]; @@ -351,7 +347,7 @@ mod tests { #[test] fn test_get_attribute_value_null_template() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetAttributeValue(session, 0, std::ptr::null_mut(), 0); @@ -360,7 +356,7 @@ mod tests { #[test] fn test_get_attribute_value_invalid_object() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut template = vec![]; @@ -371,7 +367,7 @@ mod tests { #[test] fn test_get_object_size_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pulSize: cryptoki_sys::CK_ULONG = 0; @@ -382,7 +378,7 @@ mod tests { #[test] fn test_get_object_size_null_size() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetObjectSize(session, 0, std::ptr::null_mut()); @@ -391,7 +387,7 @@ mod tests { #[test] fn test_get_object_size_invalid_object() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pulSize: cryptoki_sys::CK_ULONG = 0; @@ -402,7 +398,7 @@ mod tests { #[test] fn test_get_object_size() { - set_test_config_env(); + init_for_tests(); let size = 32; let mut db = Db::new(); let mut object = Object::default(); @@ -444,7 +440,7 @@ mod tests { #[test] fn test_create_object_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut template = vec![]; let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -455,7 +451,7 @@ mod tests { #[test] fn test_create_object_null_object() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut template = vec![]; @@ -466,7 +462,7 @@ mod tests { #[test] fn test_create_object_null_template() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut phObject: cryptoki_sys::CK_OBJECT_HANDLE = 0; @@ -477,7 +473,7 @@ mod tests { #[test] fn test_destroy_object_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_DestroyObject(0, 0); @@ -486,7 +482,7 @@ mod tests { #[test] fn test_set_attribute_null_template() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SetAttributeValue(session, 0, std::ptr::null_mut(), 0); @@ -495,7 +491,7 @@ mod tests { #[test] fn test_copy_object() { - set_test_config_env(); + init_for_tests(); let rv = C_CopyObject(0, 0, std::ptr::null_mut(), 0, std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_ACTION_PROHIBITED); } diff --git a/pkcs11/src/api/pin.rs b/pkcs11/src/api/pin.rs index 9453ce4a..ce283b21 100644 --- a/pkcs11/src/api/pin.rs +++ b/pkcs11/src/api/pin.rs @@ -12,7 +12,6 @@ pub extern "C" fn C_InitPIN( ulPinLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_InitPIN() called "); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -25,7 +24,6 @@ pub extern "C" fn C_SetPIN( ulNewLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SetPIN() called "); - ensure_init!(); lock_session!(hSession, session); @@ -70,20 +68,20 @@ mod tests { use cryptoki_sys::CK_ULONG; - use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; + use crate::{backend::slot::init_for_tests, data::SESSION_MANAGER}; use super::*; #[test] fn test_init_pin() { - set_test_config_env(); + init_for_tests(); let rv = C_InitPIN(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_set_pin_null_old_pin() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let newPin = "12345678"; @@ -100,7 +98,7 @@ mod tests { #[test] fn test_set_pin_null_new_pin() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; @@ -117,7 +115,7 @@ mod tests { #[test] fn test_set_pin_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let oldPin = "12345678"; @@ -135,7 +133,7 @@ mod tests { #[test] fn test_set_pin_no_utf8_old_pin() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // random bytes @@ -156,7 +154,7 @@ mod tests { #[test] fn test_set_pin_no_utf8_new_pin() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; @@ -177,7 +175,7 @@ mod tests { #[test] fn test_set_pin_no_user() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let oldPin = "12345678"; diff --git a/pkcs11/src/api/session.rs b/pkcs11/src/api/session.rs index 2706df37..b5d89c6c 100644 --- a/pkcs11/src/api/session.rs +++ b/pkcs11/src/api/session.rs @@ -16,7 +16,6 @@ pub extern "C" fn C_OpenSession( slotID, flags ); - ensure_init!(); if phSession.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -49,7 +48,6 @@ pub extern "C" fn C_OpenSession( pub extern "C" fn C_CloseSession(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> cryptoki_sys::CK_RV { trace!("C_CloseSession() called with session handle {}.", hSession); - ensure_init!(); let mut manager = SESSION_MANAGER.lock().unwrap(); let result = manager.delete_session(hSession); @@ -67,7 +65,6 @@ pub extern "C" fn C_CloseSession(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> c pub extern "C" fn C_CloseAllSessions(slotID: cryptoki_sys::CK_SLOT_ID) -> cryptoki_sys::CK_RV { trace!("C_CloseAllSessions() called"); - ensure_init!(); if get_slot(slotID as usize).is_err() { error!( @@ -92,7 +89,6 @@ pub extern "C" fn C_GetSessionInfo( "C_GetSessionInfo() called with session handle {}.", hSession ); - ensure_init!(); if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -113,7 +109,6 @@ pub extern "C" fn C_GetOperationState( pulOperationStateLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetOperationState() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -126,7 +121,6 @@ pub extern "C" fn C_SetOperationState( hAuthenticationKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_SetOperationState() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -135,7 +129,6 @@ pub extern "C" fn C_GetFunctionStatus( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_GetFunctionStatus() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL } @@ -144,20 +137,19 @@ pub extern "C" fn C_CancelFunction( hSession: cryptoki_sys::CK_SESSION_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_CancelFunction() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL } #[cfg(test)] mod tests { - use crate::backend::slot::set_test_config_env; + use crate::backend::slot::init_for_tests; use super::*; #[test] fn test_open_session_null_session() { - set_test_config_env(); + init_for_tests(); let rv = C_OpenSession( 0, cryptoki_sys::CKF_SERIAL_SESSION | cryptoki_sys::CKF_RW_SESSION, @@ -170,7 +162,7 @@ mod tests { #[test] fn test_open_session_parallel() { - set_test_config_env(); + init_for_tests(); let mut session = 0; let rv = C_OpenSession(0, 0, std::ptr::null_mut(), None, &mut session); assert_eq!(rv, cryptoki_sys::CKR_SESSION_PARALLEL_NOT_SUPPORTED); @@ -178,7 +170,7 @@ mod tests { #[test] fn test_delete_session_invalid() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let rv = C_CloseSession(0); @@ -187,7 +179,7 @@ mod tests { #[test] fn test_close_all_sessions_invalid_slot() { - set_test_config_env(); + init_for_tests(); let rv = C_CloseAllSessions(99); assert_eq!(rv, cryptoki_sys::CKR_SLOT_ID_INVALID); @@ -195,7 +187,7 @@ mod tests { #[test] fn test_close_all_sessions() { - set_test_config_env(); + init_for_tests(); let slot = get_slot(0).unwrap(); let handle = SESSION_MANAGER.lock().unwrap().create_session(0, slot, 0); @@ -211,7 +203,7 @@ mod tests { #[test] fn test_get_session_info_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut info = cryptoki_sys::CK_SESSION_INFO::default(); @@ -221,7 +213,7 @@ mod tests { #[test] fn test_get_session_info_null_info() { - set_test_config_env(); + init_for_tests(); let session_handle = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_GetSessionInfo(session_handle, std::ptr::null_mut()); @@ -230,28 +222,28 @@ mod tests { #[test] fn test_get_operation_state() { - set_test_config_env(); + init_for_tests(); let rv = C_GetOperationState(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_set_operation_state() { - set_test_config_env(); + init_for_tests(); let rv = C_SetOperationState(0, std::ptr::null_mut(), 0, 0, 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_get_function_status() { - set_test_config_env(); + init_for_tests(); let rv = C_GetFunctionStatus(0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL); } #[test] fn test_cancel_function() { - set_test_config_env(); + init_for_tests(); let rv = C_CancelFunction(0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_PARALLEL); } diff --git a/pkcs11/src/api/sign.rs b/pkcs11/src/api/sign.rs index 33c9353f..0815f68c 100644 --- a/pkcs11/src/api/sign.rs +++ b/pkcs11/src/api/sign.rs @@ -16,7 +16,6 @@ pub extern "C" fn C_SignInit( hKey, hSession ); - ensure_init!(); let raw_mech = match unsafe { CkRawMechanism::from_raw_ptr(pMechanism) } { Some(mech) => mech, @@ -49,7 +48,6 @@ pub extern "C" fn C_Sign( pulSignatureLen: *mut cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Sign() called"); - ensure_init!(); lock_session!(hSession, session); @@ -121,7 +119,6 @@ pub extern "C" fn C_SignUpdate( ulPartLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SignUpdate() called"); - ensure_init!(); lock_session!(hSession, session); @@ -147,7 +144,6 @@ pub extern "C" fn C_SignFinal( pulSignatureLen: *mut cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_SignFinal() called"); - ensure_init!(); lock_session!(hSession, session); @@ -211,7 +207,6 @@ pub extern "C" fn C_SignRecoverInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_SignRecoverInit() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -224,7 +219,6 @@ pub extern "C" fn C_SignRecover( pulSignatureLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_SignRecover() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -237,20 +231,19 @@ pub extern "C" fn C_SignEncryptUpdate( pulEncryptedPartLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_SignEncryptUpdate() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } #[cfg(test)] mod tests { - use crate::{backend::slot::set_test_config_env, data::SESSION_MANAGER}; + use crate::{backend::slot::init_for_tests, data::SESSION_MANAGER}; use super::*; #[test] fn test_sign_init_null_mechanism() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SignInit(session, std::ptr::null_mut(), 0); @@ -259,7 +252,7 @@ mod tests { #[test] fn test_sign_init_invalid_mechanism() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -274,7 +267,7 @@ mod tests { #[test] fn test_sign_init_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut mechanism = cryptoki_sys::CK_MECHANISM { @@ -289,7 +282,7 @@ mod tests { #[test] fn test_sign_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut data = [0u8; 32]; @@ -308,7 +301,7 @@ mod tests { #[test] fn test_sign_null_data() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -326,7 +319,7 @@ mod tests { #[test] fn test_sign_null_signature_len() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -344,7 +337,7 @@ mod tests { #[test] fn test_sign_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -363,7 +356,7 @@ mod tests { // #[test] // fn test_sign_null_signature() { - // set_test_config_env(); + // init_for_tests(); // let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); // let mut data = [0u8; 32]; @@ -381,7 +374,7 @@ mod tests { #[test] fn test_sign_update_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut data = [0u8; 32]; @@ -392,7 +385,7 @@ mod tests { #[test] fn test_sign_update_null_data() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let rv = C_SignUpdate(session, std::ptr::null_mut(), 0); @@ -401,7 +394,7 @@ mod tests { #[test] fn test_sign_update_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut data = [0u8; 32]; @@ -412,7 +405,7 @@ mod tests { #[test] fn test_sign_final_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut signature = [0u8; 32]; @@ -424,7 +417,7 @@ mod tests { #[test] fn test_sign_final_null_signature_len() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -435,7 +428,7 @@ mod tests { #[test] fn test_sign_final_operation_not_initialized() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut signature = [0u8; 32]; @@ -447,14 +440,14 @@ mod tests { #[test] fn test_sign_recover_init() { - set_test_config_env(); + init_for_tests(); let rv = C_SignRecoverInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_sign_recover() { - set_test_config_env(); + init_for_tests(); let rv = C_SignRecover( 0, std::ptr::null_mut(), @@ -467,7 +460,7 @@ mod tests { #[test] fn test_sign_encrypt_update() { - set_test_config_env(); + init_for_tests(); let rv = C_SignEncryptUpdate( 0, std::ptr::null_mut(), diff --git a/pkcs11/src/api/token.rs b/pkcs11/src/api/token.rs index 38d515d9..4413da01 100644 --- a/pkcs11/src/api/token.rs +++ b/pkcs11/src/api/token.rs @@ -26,13 +26,17 @@ pub extern "C" fn C_GetSlotList( pulCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetSlotList() called"); - ensure_init!(); if pulCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } - let count = DEVICE.slots.len() as CK_ULONG; + let Some(device) = DEVICE.get() else { + error!("Initialization was not performed or failed"); + return cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED; + }; + + let count = device.slots.len() as CK_ULONG; // only the count is requested if pSlotList.is_null() { @@ -52,7 +56,7 @@ pub extern "C" fn C_GetSlotList( // list the ids - let id_list: Vec = DEVICE + let id_list: Vec = device .slots .iter() .enumerate() @@ -72,7 +76,6 @@ pub extern "C" fn C_GetSlotInfo( pInfo: cryptoki_sys::CK_SLOT_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetSlotInfo() called with slotID: {}", slotID); - ensure_init!(); if pInfo.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -150,7 +153,6 @@ pub extern "C" fn C_GetTokenInfo( pInfo: cryptoki_sys::CK_TOKEN_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetTokenInfo() called with slotID: {}", slotID); - ensure_init!(); // get the slot let slot = match get_slot(slotID as usize) { @@ -239,7 +241,6 @@ pub extern "C" fn C_InitToken( pLabel: cryptoki_sys::CK_UTF8CHAR_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_InitToken() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -250,7 +251,6 @@ pub extern "C" fn C_GetMechanismList( pulCount: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetMechanismList() called"); - ensure_init!(); if pulCount.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -301,7 +301,6 @@ pub extern "C" fn C_GetMechanismInfo( pInfo: cryptoki_sys::CK_MECHANISM_INFO_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_GetMechanismInfo() called"); - ensure_init!(); if let Err(e) = get_slot(slotID as usize) { return e; @@ -332,7 +331,6 @@ pub extern "C" fn C_Login( ulPinLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Login() called"); - ensure_init!(); if pPin.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; @@ -356,7 +354,6 @@ pub extern "C" fn C_Login( } pub extern "C" fn C_Logout(hSession: cryptoki_sys::CK_SESSION_HANDLE) -> cryptoki_sys::CK_RV { trace!("C_Logout() called"); - ensure_init!(); lock_session!(hSession, session); @@ -372,13 +369,15 @@ pub extern "C" fn C_WaitForSlotEvent( pReserved: cryptoki_sys::CK_VOID_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_WaitForSlotEvent() called"); - ensure_init!(); if pSlot.is_null() { return cryptoki_sys::CKR_ARGUMENTS_BAD; } - fetch_slots_state(); + match fetch_slots_state() { + Ok(()) => {} + Err(err) => return err, + } loop { // check if there is an event in the queue @@ -406,7 +405,10 @@ pub extern "C" fn C_WaitForSlotEvent( std::thread::sleep(std::time::Duration::from_secs(1)); // fetch the slots state so we get the latest events in the next iteration - fetch_slots_state(); + match fetch_slots_state() { + Ok(()) => {} + Err(err) => return err, + } } } } @@ -419,7 +421,7 @@ mod tests { api::C_Finalize, backend::{ events::{update_slot_state, EventsManager}, - slot::set_test_config_env, + slot::init_for_tests, }, data::{SESSION_MANAGER, TOKENS_STATE}, }; @@ -430,7 +432,7 @@ mod tests { #[test] #[ignore] fn test_wait_for_slot_event_no_event() { - set_test_config_env(); + init_for_tests(); *EVENTS_MANAGER.write().unwrap() = EventsManager::new(); *TOKENS_STATE.lock().unwrap() = std::collections::HashMap::new(); @@ -443,7 +445,7 @@ mod tests { #[test] #[ignore] fn test_wait_for_slot_event_one_event() { - set_test_config_env(); + init_for_tests(); *EVENTS_MANAGER.write().unwrap() = EventsManager::new(); *TOKENS_STATE.lock().unwrap() = std::collections::HashMap::new(); @@ -462,7 +464,7 @@ mod tests { #[test] #[ignore] fn test_wait_for_slot_event_blocking_one_event() { - set_test_config_env(); + init_for_tests(); *EVENTS_MANAGER.write().unwrap() = EventsManager::new(); *TOKENS_STATE.lock().unwrap() = std::collections::HashMap::new(); @@ -485,7 +487,7 @@ mod tests { #[test] #[ignore] fn test_wait_for_slot_event_blocking_finalize() { - set_test_config_env(); + init_for_tests(); *EVENTS_MANAGER.write().unwrap() = EventsManager::new(); *TOKENS_STATE.lock().unwrap() = std::collections::HashMap::new(); @@ -506,7 +508,7 @@ mod tests { #[test] fn test_wait_for_slot_event_null_slot_ptr() { - set_test_config_env(); + init_for_tests(); let result = C_WaitForSlotEvent(CKF_DONT_BLOCK, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -514,14 +516,14 @@ mod tests { #[test] fn test_get_slot_list_null_count() { - set_test_config_env(); + init_for_tests(); let result = C_GetSlotList(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); } #[test] fn test_get_slot_list_null_list() { - set_test_config_env(); + init_for_tests(); let mut count = 0; let result = C_GetSlotList(0, std::ptr::null_mut(), &mut count); @@ -531,7 +533,7 @@ mod tests { #[test] fn test_get_slot_list_small_buffer() { - set_test_config_env(); + init_for_tests(); let mut count = 0; let mut list = [0; 1]; @@ -542,7 +544,7 @@ mod tests { #[test] fn test_get_slot_info_invalid_slot() { - set_test_config_env(); + init_for_tests(); let mut info = CK_SLOT_INFO::default(); let result = C_GetSlotInfo(99, &mut info); @@ -551,7 +553,7 @@ mod tests { #[test] fn test_get_slot_info_null_info() { - set_test_config_env(); + init_for_tests(); let result = C_GetSlotInfo(0, std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -559,7 +561,7 @@ mod tests { #[test] fn test_get_mechanism_list_null_count() { - set_test_config_env(); + init_for_tests(); let result = C_GetMechanismList(0, std::ptr::null_mut(), std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -567,7 +569,7 @@ mod tests { #[test] fn test_get_mechanism_list_null_list() { - set_test_config_env(); + init_for_tests(); let mut count = 0; let result = C_GetMechanismList(0, std::ptr::null_mut(), &mut count); @@ -577,7 +579,7 @@ mod tests { #[test] fn test_get_mechanism_list_small_buffer() { - set_test_config_env(); + init_for_tests(); let mut count = 0; let mut list = [0; 1]; @@ -588,7 +590,7 @@ mod tests { #[test] fn test_get_mechanism_list_invalid_slot() { - set_test_config_env(); + init_for_tests(); let mut count = 0; let mut list = [0; 1]; @@ -598,7 +600,7 @@ mod tests { #[test] fn test_get_mechanism_info_invalid_mechanism() { - set_test_config_env(); + init_for_tests(); let mut info = CK_MECHANISM_INFO::default(); let result = C_GetMechanismInfo(0, 15000, &mut info); @@ -607,7 +609,7 @@ mod tests { #[test] fn test_get_mechanism_info_invalid_slot() { - set_test_config_env(); + init_for_tests(); let mut info = CK_MECHANISM_INFO::default(); let result = C_GetMechanismInfo(99, 0, &mut info); @@ -616,7 +618,7 @@ mod tests { #[test] fn test_get_mechanism_info_null_info() { - set_test_config_env(); + init_for_tests(); let result = C_GetMechanismInfo(0, 0, std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -624,7 +626,7 @@ mod tests { #[test] fn test_get_token_info_invalid_slot() { - set_test_config_env(); + init_for_tests(); let mut info = CK_TOKEN_INFO::default(); let result = C_GetTokenInfo(99, &mut info); @@ -633,7 +635,7 @@ mod tests { #[test] fn test_get_token_info_null_info() { - set_test_config_env(); + init_for_tests(); let result = C_GetTokenInfo(0, std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_ARGUMENTS_BAD); @@ -641,7 +643,7 @@ mod tests { #[test] fn test_login_null_pin() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let result = C_Login(session, CKU_USER, std::ptr::null_mut(), 0); @@ -650,7 +652,7 @@ mod tests { #[test] fn test_login_non_utf8_pin() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let mut pin = [0xFF, 0xFF, 0xFF, 0xFF]; @@ -661,7 +663,7 @@ mod tests { #[test] fn test_login_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let mut pin = "1234".to_string(); @@ -672,7 +674,7 @@ mod tests { #[test] fn test_logout_invalid_session() { - set_test_config_env(); + init_for_tests(); SESSION_MANAGER.lock().unwrap().delete_session(0); let result = C_Logout(0); @@ -681,7 +683,7 @@ mod tests { #[test] fn test_logout() { - set_test_config_env(); + init_for_tests(); let session = SESSION_MANAGER.lock().unwrap().setup_dummy_session(); let result = C_Logout(session); @@ -690,7 +692,7 @@ mod tests { #[test] fn test_init_token() { - set_test_config_env(); + init_for_tests(); let result = C_InitToken(0, std::ptr::null_mut(), 0, std::ptr::null_mut()); assert_eq!(result, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } diff --git a/pkcs11/src/api/verify.rs b/pkcs11/src/api/verify.rs index 2de3ec80..4aa74b06 100644 --- a/pkcs11/src/api/verify.rs +++ b/pkcs11/src/api/verify.rs @@ -10,7 +10,6 @@ pub extern "C" fn C_VerifyInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyInit() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -23,7 +22,6 @@ pub extern "C" fn C_Verify( ulSignatureLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_Verify() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -34,7 +32,6 @@ pub extern "C" fn C_VerifyUpdate( ulPartLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyUpdate() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -45,7 +42,6 @@ pub extern "C" fn C_VerifyFinal( ulSignatureLen: cryptoki_sys::CK_ULONG, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyFinal() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -56,7 +52,6 @@ pub extern "C" fn C_VerifyRecoverInit( hKey: cryptoki_sys::CK_OBJECT_HANDLE, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyRecoverInit() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -69,7 +64,6 @@ pub extern "C" fn C_VerifyRecover( pulDataLen: cryptoki_sys::CK_ULONG_PTR, ) -> cryptoki_sys::CK_RV { trace!("C_VerifyRecover() called"); - ensure_init!(); cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED } @@ -79,20 +73,20 @@ pub extern "C" fn C_VerifyRecover( mod tests { use cryptoki_sys::CK_ULONG; - use crate::backend::slot::set_test_config_env; + use crate::backend::slot::init_for_tests; use super::*; #[test] fn test_verify_init() { - set_test_config_env(); + init_for_tests(); let rv = C_VerifyInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_verify() { - set_test_config_env(); + init_for_tests(); let mut data = [0u8; 1]; let mut sig = [0u8; 1]; let rv = C_Verify( @@ -107,7 +101,7 @@ mod tests { #[test] fn test_verify_update() { - set_test_config_env(); + init_for_tests(); let mut data = [0u8; 1]; let rv = C_VerifyUpdate(0, data.as_mut_ptr(), data.len() as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); @@ -115,7 +109,7 @@ mod tests { #[test] fn test_verify_final() { - set_test_config_env(); + init_for_tests(); let mut sig = [0u8; 1]; let rv = C_VerifyFinal(0, sig.as_mut_ptr(), sig.len() as CK_ULONG); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); @@ -123,14 +117,14 @@ mod tests { #[test] fn test_verify_recover_init() { - set_test_config_env(); + init_for_tests(); let rv = C_VerifyRecoverInit(0, std::ptr::null_mut(), 0); assert_eq!(rv, cryptoki_sys::CKR_FUNCTION_NOT_SUPPORTED); } #[test] fn test_verify_recover() { - set_test_config_env(); + init_for_tests(); let mut sig = [0u8; 1]; let mut data = [0u8; 1]; let mut data_len = 0; diff --git a/pkcs11/src/backend/events.rs b/pkcs11/src/backend/events.rs index a797c816..0c8b5d9b 100644 --- a/pkcs11/src/backend/events.rs +++ b/pkcs11/src/backend/events.rs @@ -1,4 +1,5 @@ use cryptoki_sys::CK_SLOT_ID; +use log::error; use nethsm_sdk_rs::{apis::default_api, models::SystemState}; use crate::data::{DEVICE, EVENTS_MANAGER, TOKENS_STATE}; @@ -34,8 +35,13 @@ pub fn update_slot_state(slot_id: CK_SLOT_ID, present: bool) { tokens_state.insert(slot_id, present); } -pub fn fetch_slots_state() { - for (index, slot) in DEVICE.slots.iter().enumerate() { +pub fn fetch_slots_state() -> Result<(), cryptoki_sys::CK_RV> { + let Some(device) = DEVICE.get() else { + error!("Initialization was not performed or failed"); + return Err(cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED); + }; + + for (index, slot) in device.slots.iter().enumerate() { let mut login_ctx = LoginCtx::new(None, None, slot.instances.clone(), slot.retries); let status = login_ctx .try_(default_api::health_state_get, super::login::UserMode::Guest) @@ -44,4 +50,5 @@ pub fn fetch_slots_state() { update_slot_state(index as CK_SLOT_ID, status); } + Ok(()) } diff --git a/pkcs11/src/backend/key.rs b/pkcs11/src/backend/key.rs index 0ebbd915..010f8a23 100644 --- a/pkcs11/src/backend/key.rs +++ b/pkcs11/src/backend/key.rs @@ -172,8 +172,13 @@ fn upload_certificate( } }; + let Some(device) = DEVICE.get() else { + error!("Initialization was not performed or failed"); + return Err(Error::LibraryNotInitialized); + }; + // Check if an alias is defined for this key - if DEVICE.enable_set_attribute_value { + if device.enable_set_attribute_value { if let Some(real_name) = KEY_ALIASES.lock()?.get(&id).cloned() { id = real_name; } diff --git a/pkcs11/src/backend/mod.rs b/pkcs11/src/backend/mod.rs index 0275ff54..af385709 100644 --- a/pkcs11/src/backend/mod.rs +++ b/pkcs11/src/backend/mod.rs @@ -6,11 +6,11 @@ use self::{ mechanism::{MechMode, Mechanism}, }; use cryptoki_sys::{ - CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_VALUE_INVALID, CKR_DATA_INVALID, CKR_DATA_LEN_RANGE, - CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_ENCRYPTED_DATA_LEN_RANGE, - CKR_KEY_HANDLE_INVALID, CKR_MECHANISM_INVALID, CKR_OPERATION_ACTIVE, - CKR_OPERATION_NOT_INITIALIZED, CKR_TOKEN_NOT_PRESENT, CKR_USER_NOT_LOGGED_IN, - CK_ATTRIBUTE_TYPE, CK_OBJECT_HANDLE, CK_RV, + CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_VALUE_INVALID, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_INVALID, + CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, + CKR_ENCRYPTED_DATA_LEN_RANGE, CKR_KEY_HANDLE_INVALID, CKR_MECHANISM_INVALID, + CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED, CKR_TOKEN_NOT_PRESENT, + CKR_USER_NOT_LOGGED_IN, CK_ATTRIBUTE_TYPE, CK_OBJECT_HANDLE, CK_RV, }; use log::error; use nethsm_sdk_rs::apis; @@ -81,6 +81,7 @@ pub enum Error { StringParse(std::string::FromUtf8Error), Login(LoginError), OperationNotInitialized, + LibraryNotInitialized, OperationActive, // a field recieved from the API is not valid KeyField(String), @@ -132,6 +133,7 @@ impl From for CK_RV { Error::InvalidDataLength => CKR_DATA_LEN_RANGE, Error::InvalidObjectHandle(_) => CKR_KEY_HANDLE_INVALID, Error::OperationNotInitialized => CKR_OPERATION_NOT_INITIALIZED, + Error::LibraryNotInitialized => CKR_CRYPTOKI_NOT_INITIALIZED, Error::DbLock => CKR_DEVICE_ERROR, Error::KeyField(_) => CKR_DEVICE_ERROR, Error::OperationActive => CKR_OPERATION_ACTIVE, @@ -174,6 +176,7 @@ impl std::fmt::Display for Error { format!("Object handle does not exist: {}", handle) } Error::OperationNotInitialized => "Operation not initialized".to_string(), + Error::LibraryNotInitialized => "Library not initialized".to_string(), Error::DbLock => "Internal mutex lock error".to_string(), Error::KeyField(field) => { format!("Key field {} received from the NetHSM is not valid", field) diff --git a/pkcs11/src/backend/slot.rs b/pkcs11/src/backend/slot.rs index abd04f6b..ff7bc4f7 100644 --- a/pkcs11/src/backend/slot.rs +++ b/pkcs11/src/backend/slot.rs @@ -1,9 +1,15 @@ use std::sync::Arc; use crate::{config::device::Slot, data::DEVICE}; +use log::error; pub fn get_slot(slot_id: usize) -> Result, cryptoki_sys::CK_RV> { - let slot = DEVICE + let Some(device) = DEVICE.get() else { + error!("Initialization was not performed or failed"); + return Err(cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED); + }; + + let slot = device .slots .get(slot_id) .ok_or(cryptoki_sys::CKR_SLOT_ID_INVALID)?; @@ -11,6 +17,15 @@ pub fn get_slot(slot_id: usize) -> Result, cryptoki_sys::CK_RV> { } #[cfg(test)] -pub fn set_test_config_env() { - std::env::set_var("P11NETHSM_CONFIG_FILE", "../p11nethsm.conf"); +pub fn init_for_tests() { + use std::ptr; + use std::sync::Once; + + use crate::api::C_Initialize; + + static ONCE: Once = Once::new(); + ONCE.call_once(|| { + std::env::set_var("P11NETHSM_CONFIG_FILE", "../p11nethsm.conf"); + assert_eq!(C_Initialize(ptr::null_mut()), cryptoki_sys::CKR_OK); + }) } diff --git a/pkcs11/src/data.rs b/pkcs11/src/data.rs index a69ee68d..f7777c1b 100644 --- a/pkcs11/src/data.rs +++ b/pkcs11/src/data.rs @@ -1,40 +1,21 @@ -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex, Once, OnceLock, RwLock}; use crate::backend::events::EventsManager; -use crate::config::initialization::InitializationError; -use crate::{ - api, - backend::session::SessionManager, - config::{self, device::Device}, -}; +use crate::{api, backend::session::SessionManager, config::device::Device}; use cryptoki_sys::{CK_FUNCTION_LIST, CK_SLOT_ID, CK_VERSION}; use lazy_static::lazy_static; -use log::error; pub const DEVICE_VERSION: CK_VERSION = CK_VERSION { major: 2, minor: 40, }; -lazy_static! { - pub static ref DEVICE_RESULT: Result = config::initialization::initialize_configuration(); - - pub static ref DEVICE: &'static Device = match &*DEVICE_RESULT { - Ok(config) => config, - Err(e) => { - panic!("Error initializing configuration: {:?}", e); - } - }; - - pub static ref DEVICE_ERROR: bool = match &*DEVICE_RESULT { - Ok(_) => false, - Err(e) => { - error!("Error initializing configuration: {:?}", e); - true - } - }; +/// A separate DEVICE_INIT is required because `OnceLock::get_or_try_insert` is unstable +pub static DEVICE_INIT: Once = Once::new(); +pub static DEVICE: OnceLock = OnceLock::new(); +lazy_static! { pub static ref SESSION_MANAGER : Arc> = Arc::new(Mutex::new(SessionManager::new())); // Aliases for the keys, used when enable_set_attribute_value is set. From ff07b5e3a89b8662584259fd0c94ec6e1eab8fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 5 Jan 2024 14:17:33 +0100 Subject: [PATCH 6/6] Add tests for bad configurations --- pkcs11/src/api/mod.rs | 2 +- pkcs11/src/config/config_file.rs | 49 +++++++++++-------- pkcs11/src/config/initialization.rs | 76 +++++++++++++++++++++++++++-- pkcs11/src/config/logging.rs | 3 +- 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/pkcs11/src/api/mod.rs b/pkcs11/src/api/mod.rs index 4694aecb..f4332686 100644 --- a/pkcs11/src/api/mod.rs +++ b/pkcs11/src/api/mod.rs @@ -44,7 +44,7 @@ pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { let mut result = Ok(()); DEVICE_INIT.call_once(|| { - let res = crate::config::initialization::initialize_configuration(); + let res = crate::config::initialization::initialize(); match res { Ok(device) => { _ = DEVICE.set(device); diff --git a/pkcs11/src/config/config_file.rs b/pkcs11/src/config/config_file.rs index ae9a9011..6b33589b 100644 --- a/pkcs11/src/config/config_file.rs +++ b/pkcs11/src/config/config_file.rs @@ -1,3 +1,5 @@ +use std::{io::Read, mem}; + use merge::Merge; use serde::{Deserialize, Serialize}; @@ -11,16 +13,10 @@ pub enum ConfigError { const CONFIG_FILE_NAME: &str = "p11nethsm.conf"; const ENV_VAR_CONFIG_FILE: &str = "P11NETHSM_CONFIG_FILE"; -pub fn read_configuration() -> Result { - let mut config = P11Config::default(); - +pub fn config_files() -> Result>, ConfigError> { if let Ok(file_path) = std::env::var(ENV_VAR_CONFIG_FILE) { - let file = std::fs::File::open(file_path).map_err(ConfigError::Io)?; - let config_file = serde_yaml::from_reader(file).map_err(ConfigError::Yaml)?; - - config.merge(config_file); - - return Ok(config); + let file = std::fs::read(file_path).map_err(ConfigError::Io)?; + return Ok(vec![file]); } let mut config_folders = vec![ @@ -32,28 +28,42 @@ pub fn read_configuration() -> Result { config_folders.push(format!("{}/.config/nitrokey", home)); } - let mut file_read = false; - + let mut res: Vec> = Vec::new(); + let mut buffer: Vec = Vec::new(); for folder in config_folders { let file_path = format!("{}/{}", folder, CONFIG_FILE_NAME); - - if let Ok(file) = std::fs::File::open(file_path) { - let config_file = serde_yaml::from_reader(file).map_err(ConfigError::Yaml)?; - - config.merge(config_file); - file_read = true; + if let Ok(mut file) = std::fs::File::open(file_path) { + file.read_to_end(&mut buffer).map_err(ConfigError::Io)?; + res.push(mem::take(&mut buffer)); } } - // if no config file was found, return an error + Ok(res) +} - if !file_read { +pub fn merge_configurations(configs: Vec>) -> Result { + let mut config = P11Config::default(); + + // if no config file was found, return an error + if configs.is_empty() { return Err(ConfigError::NoConfigFile); } + for file in configs { + let parsed = serde_yaml::from_slice(&file).map_err(ConfigError::Yaml)?; + config.merge(parsed); + } + Ok(config) } +#[cfg(test)] +pub fn read_configuration() -> Result { + let configs = config_files()?; + + merge_configurations(configs) +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum LogLevel { Trace, @@ -198,6 +208,7 @@ mod tests { use super::*; #[test] + #[ignore] fn test_read_home_config() { let config = r#" enable_set_attribute_value: true diff --git a/pkcs11/src/config/initialization.rs b/pkcs11/src/config/initialization.rs index 84cfbf23..a0553a44 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -4,7 +4,7 @@ use std::{ }; use super::{ - config_file::SlotConfig, + config_file::{config_files, SlotConfig}, device::{Device, Slot}, }; use log::{debug, error, trace}; @@ -21,9 +21,9 @@ pub enum InitializationError { NoUser(String), } -pub fn initialize_configuration() -> Result { - let config = - crate::config::config_file::read_configuration().map_err(InitializationError::Config)?; +pub fn initialize_with_configs(configs: Vec>) -> Result { + let config = crate::config::config_file::merge_configurations(configs) + .map_err(InitializationError::Config)?; crate::config::logging::configure_logger(&config); // initialize the clients @@ -38,6 +38,10 @@ pub fn initialize_configuration() -> Result { }) } +pub fn initialize() -> Result { + initialize_with_configs(config_files().map_err(InitializationError::Config)?) +} + struct DangerIgnoreVerifier {} impl ServerCertVerifier for DangerIgnoreVerifier { @@ -159,3 +163,67 @@ fn slot_from_config(slot: &SlotConfig) -> Result { db: Arc::new(Mutex::new(crate::backend::db::Db::new())), }) } + +#[cfg(test)] +mod tests { + use super::*; + + /// Test various good and bad configs for panics + #[test] + fn test_config_loading() { + let configs: Vec> = vec![ + r#" +slots: + - label: LocalHSM + description: Local HSM (docker) + operator: + username: "operator" + password: "opPassphrase" + administrator: + username: "admin" + password: "Administrator" + instances: + - url: "https://localhost:8443/api/v1" + danger_insecure_cert: true + sha256_fingerprints: + - "31:92:8E:A4:5E:16:5C:A7:33:44:E8:E9:8E:64:C4:AE:7B:2A:57:E5:77:43:49:F3:69:C9:8F:C4:2F:3A:3B:6E" + retries: + count: 10 + delay_seconds: 1 + timeout_seconds: 10 + "#.into(), + ]; + + assert!(initialize_with_configs(configs).is_ok()); + + let configs_bad_fingerprint: Vec> = vec![ + r#" +slots: + - label: LocalHSM + description: Local HSM (docker) + operator: + username: "operator" + password: "opPassphrase" + administrator: + username: "admin" + password: "Administrator" + instances: + - url: "https://localhost:8443/api/v1" + danger_insecure_cert: true + sha256_fingerprints: + - "31:92:8E:A4:5Eeeeee:16:5C:A7:33:44:E8:E9:8E:64:C4:AE:7B:2A:57:E5:77:43:49:F3:69:C9:8F:C4:2F:3A:3B:6E" + retries: + count: 10 + delay_seconds: 1 + timeout_seconds: 10 + "#.into(), + ]; + assert!(initialize_with_configs(configs_bad_fingerprint).is_err()); + let configs_bad_yml: Vec> = vec![r#" +dict: +bad_yml + "# + .into()]; + assert!(initialize_with_configs(configs_bad_yml).is_err()); + } +} diff --git a/pkcs11/src/config/logging.rs b/pkcs11/src/config/logging.rs index 7ad5d83c..8e4c43f1 100644 --- a/pkcs11/src/config/logging.rs +++ b/pkcs11/src/config/logging.rs @@ -32,5 +32,6 @@ pub fn configure_logger(config: &P11Config) { builder.target(env_logger::Target::Pipe(file)); } - builder.init() + // Don't crash on re-initialization + builder.try_init().ok(); }