Skip to content

Commit

Permalink
Make the module config re-loadable
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Sep 13, 2024
1 parent 0c67cd8 commit e342b16
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 32 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkcs11/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ digest = { default-features = false, version = "0.10" }
rayon = "1.8.0"
syslog = "6.1.0"
thiserror = "1.0.63"
arc-swap = "1.7.1"

config_file = { path = "config_file" }

Expand Down
28 changes: 10 additions & 18 deletions pkcs11/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ pub mod sign;
pub mod token;
pub mod verify;

use std::ptr::addr_of_mut;
use std::sync::atomic::Ordering;
use std::{ptr::addr_of_mut, sync::Arc};

use crate::{
backend::events::{fetch_slots_state, EventsManager},
data::{self, DEVICE, DEVICE_INIT, EVENTS_MANAGER, THREADS_ALLOWED, TOKENS_STATE},
data::{self, DEVICE, EVENTS_MANAGER, THREADS_ALLOWED, TOKENS_STATE},
defs,
utils::padded_str,
};
Expand All @@ -44,27 +44,18 @@ 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);

let mut result = Ok(());

DEVICE_INIT.call_once(|| {
let res = crate::config::initialization::initialize();
match res {
Ok(device) => {
_ = DEVICE.set(device);
}
Err(err) => result = Err(err),
let res = crate::config::initialization::initialize();
let device = match res {
Ok(device) => {
let arced = Arc::new(device);
DEVICE.store(Some(arced.clone()));
arced
}
});

match result {
Ok(()) => {}
Err(err) => {
error!("NetHSM PKCS#11: 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() {
Expand Down Expand Up @@ -118,6 +109,7 @@ pub extern "C" fn C_Finalize(pReserved: CK_VOID_PTR) -> CK_RV {
if !pReserved.is_null() {
return cryptoki_sys::CKR_ARGUMENTS_BAD;
}
DEVICE.store(None);
EVENTS_MANAGER.write().unwrap().finalized = true;

cryptoki_sys::CKR_OK
Expand Down
2 changes: 1 addition & 1 deletion pkcs11/src/api/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ pub extern "C" fn C_SetAttributeValue(
}
};

let Some(device) = DEVICE.get() else {
let Some(device) = DEVICE.load_full() else {
error!("Initialization was not performed or failed");
return cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED;
};
Expand Down
2 changes: 1 addition & 1 deletion pkcs11/src/api/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub extern "C" fn C_GetSlotList(
return cryptoki_sys::CKR_ARGUMENTS_BAD;
}

let Some(device) = DEVICE.get() else {
let Some(device) = DEVICE.load_full() else {
error!("Initialization was not performed or failed");
return cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED;
};
Expand Down
2 changes: 1 addition & 1 deletion pkcs11/src/backend/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn update_slot_state(slot_id: CK_SLOT_ID, present: bool) {
}

pub fn fetch_slots_state() -> Result<(), cryptoki_sys::CK_RV> {
let Some(device) = DEVICE.get() else {
let Some(device) = DEVICE.load_full() else {
error!("Initialization was not performed or failed");
return Err(cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED);
};
Expand Down
2 changes: 1 addition & 1 deletion pkcs11/src/backend/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn upload_certificate(
}
};

let Some(device) = DEVICE.get() else {
let Some(device) = DEVICE.load_full() else {
error!("Initialization was not performed or failed");
return Err(Error::LibraryNotInitialized);
};
Expand Down
8 changes: 3 additions & 5 deletions pkcs11/src/backend/slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{config::device::Slot, data::DEVICE};
use log::error;

pub fn get_slot(slot_id: usize) -> Result<Arc<Slot>, cryptoki_sys::CK_RV> {
let Some(device) = DEVICE.get() else {
let Some(device) = DEVICE.load_full() else {
error!("Initialization was not performed or failed");
return Err(cryptoki_sys::CKR_CRYPTOKI_NOT_INITIALIZED);
};
Expand All @@ -19,13 +19,11 @@ pub fn get_slot(slot_id: usize) -> Result<Arc<Slot>, cryptoki_sys::CK_RV> {
#[cfg(test)]
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(|| {
if DEVICE.load().is_none() {
std::env::set_var("P11NETHSM_CONFIG_FILE", "../p11nethsm.conf");
assert_eq!(C_Initialize(ptr::null_mut()), cryptoki_sys::CKR_OK);
})
}
}
2 changes: 1 addition & 1 deletion pkcs11/src/config/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub fn initialize_with_configs(
pub fn initialize() -> Result<Device, InitializationError> {
rustls::crypto::ring::default_provider()
.install_default()
.unwrap();
.ok();
initialize_with_configs(config_files())
}

Expand Down
7 changes: 3 additions & 4 deletions pkcs11/src/data.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::collections::HashMap;
use std::sync::{atomic::AtomicBool, Mutex, Once, OnceLock, RwLock};
use std::sync::{atomic::AtomicBool, Mutex, RwLock};

use crate::backend::events::EventsManager;

use crate::{api, backend::session::SessionManager, config::device::Device};
use arc_swap::ArcSwapOption;
use cryptoki_sys::{CK_FUNCTION_LIST, CK_SLOT_ID, CK_VERSION};
use lazy_static::lazy_static;

Expand All @@ -12,9 +13,7 @@ pub const DEVICE_VERSION: CK_VERSION = CK_VERSION {
minor: 40,
};

/// 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<Device> = OnceLock::new();
pub static DEVICE: ArcSwapOption<Device> = ArcSwapOption::const_empty();

lazy_static! {
pub static ref SESSION_MANAGER : Mutex<SessionManager> = Mutex::new(SessionManager::new());
Expand Down

0 comments on commit e342b16

Please sign in to comment.