/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![allow(non_snake_case)]
use log::{debug, error, trace}; use pkcs11_bindings::*; use rsclientcerts::manager::{IsSearchingForClientCerts, Manager}; use rsclientcerts::{
declare_pkcs11_find_functions, declare_pkcs11_informational_functions,
declare_pkcs11_session_functions, declare_pkcs11_sign_functions,
declare_unsupported_pkcs11_functions, log_with_thread_id,
}; use std::convert::TryInto; use std::sync::Mutex;
mod backend;
use backend::Backend;
/// The singleton `Manager` that handles state with respect to PKCS #11. Only one thread /// may use it at a time, but there is no restriction on which threads may use it. static MANAGER: Mutex<Option<Manager<Backend, IsGeckoSearchingForClientCerts>>> = Mutex::new(None);
// Obtaining a handle on the manager is a two-step process. First the mutex must be locked, which // (if successful), results in a mutex guard object. We must then get a mutable refence to the // underlying manager (if set - otherwise we return an error). This can't happen all in one macro // without dropping a reference that needs to live long enough for this to be safe. In // practice, this looks like: // let mut manager_guard = try_to_get_manager_guard!(); // let manager = manager_guard_to_manager!(manager_guard);
macro_rules! try_to_get_manager_guard {
() => { match MANAGER.lock() {
Ok(maybe_manager) => maybe_manager,
Err(_) => return CKR_DEVICE_ERROR,
}
};
}
/// This gets called to initialize the module. For this implementation, this consists of /// instantiating the `Manager`. extern"C"fn C_Initialize(_pInitArgs: CK_VOID_PTR) -> CK_RV { letmut manager_guard = try_to_get_manager_guard!(); let _unexpected_previous_manager = manager_guard.replace(Manager::new(vec![Backend::new()]));
CKR_OK
}
extern"C"fn C_Finalize(_pReserved: CK_VOID_PTR) -> CK_RV { // Drop the manager. When C_Finalize is called, there should be only one // reference to this module (which is going away), so there shouldn't be // any concurrency issues. letmut manager_guard = try_to_get_manager_guard!(); match manager_guard.take() {
Some(_) => CKR_OK,
None => CKR_CRYPTOKI_NOT_INITIALIZED,
}
}
// The specification mandates that these strings be padded with spaces to the appropriate length. // Since the length of fixed-size arrays in rust is part of the type, the compiler enforces that // these byte strings are of the correct length. const MANUFACTURER_ID_BYTES: &[u8; 32] = b"Mozilla Corporation "; const LIBRARY_DESCRIPTION_BYTES: &[u8; 32] = b"IPC Client Cert Module ";
/// This is the only function this module exposes. The C stub calls it when NSS /// calls its exposed C_GetFunctionList function to obtain the list of functions /// comprising this module. #[no_mangle] pubunsafeextern"C"fn IPCCC_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV { if ppFunctionList.is_null() { return CKR_ARGUMENTS_BAD;
} unsafe { // CK_FUNCTION_LIST_PTR is a *mut CK_FUNCTION_LIST, but as per the // specification, the caller must treat it as *const CK_FUNCTION_LIST.
*ppFunctionList = std::ptr::addr_of!(FUNCTION_LIST) as CK_FUNCTION_LIST_PTR;
}
CKR_OK
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.