Skip to content

Commit

Permalink
fixup! Handle compatibility for CKA_EC_POINT
Browse files Browse the repository at this point in the history
  • Loading branch information
simo5 committed Nov 26, 2024
1 parent c6de8d5 commit 1c695b3
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 198 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,3 @@ fips = [ "rusqlite/bundled", "aes", "ecc_fips", "hash_all", "kdf_all", "rsa"]
dynamic = [ ] # Builds against system libcrypto.so

slow = [] # Enables slow tests

pkcs11ver31 = [] # Changes defaults to 3.1 spec
46 changes: 42 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,23 @@ impl Slot {
}
}

#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "encoding")]
pub enum EcPointEncoding {
Bytes,
Der,
}

impl Default for EcPointEncoding {
fn default() -> Self {
EcPointEncoding::Bytes
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
#[serde(default)]
pub ec_point_encoding: EcPointEncoding,
pub slots: Vec<Slot>,
}

Expand All @@ -70,7 +85,10 @@ fn config_error<E: de::Error + 'static>(error: E) -> Error {

impl Config {
pub fn new() -> Config {
Config { slots: Vec::new() }
Config {
ec_point_encoding: EcPointEncoding::default(),
slots: Vec::new(),
}
}

#[cfg(test)]
Expand Down Expand Up @@ -120,7 +138,10 @@ impl Config {
}

fn from_legacy_conf_string(name: &str) -> Result<Config> {
let mut conf = Config { slots: Vec::new() };
let mut conf = Config {
ec_point_encoding: EcPointEncoding::default(),
slots: Vec::new(),
};
/* backwards compatibility where we used to only specify
* a file, this does not support all older options, just
* the more common one of specifying a .sql file with no
Expand Down Expand Up @@ -171,20 +192,37 @@ impl Config {
let filename = Self::find_conf()?;

match Self::from_file(&filename) {
Ok(conf) => return Ok(conf),
Ok(conf) => Ok(conf),
Err(e) => {
/* attempt fallback, return original error on fail */
match Self::from_legacy_conf_string(&filename) {
Ok(mut conf) => {
conf.fix_slot_numbers();
return Ok(conf);
Ok(conf)
}
Err(_) => return Err(e),
}
}
}
}

pub fn load_env_vars_overrides(&mut self) {
match env::var("KRYOPTIC_EC_POINT_ENCODING") {
Ok(var) => {
self.ec_point_encoding = match var.as_str() {
"DER" => EcPointEncoding::Der,
"BYTES" => EcPointEncoding::Bytes,
_ =>
/* ignore */
{
self.ec_point_encoding
}
}
}
Err(_) => (),
}
}

#[cfg(feature = "nssdb")]
fn from_nss_init_args(args: &str) -> Result<Config> {
let mut conf = Config { slots: Vec::new() };
Expand Down
196 changes: 53 additions & 143 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ macro_rules! global_rlock {
Err(_) => return CKR_GENERAL_ERROR,
}
};
(noinitcheck $GLOBAL:expr) => {{
match $GLOBAL.read() {
Ok(r) => r,
Err(_) => return CKR_GENERAL_ERROR,
}
}};
}

macro_rules! global_wlock {
Expand Down Expand Up @@ -394,12 +400,13 @@ static CONFIG: Lazy<RwLock<GlobalConfig>> = Lazy::new(|| {
/* if there is no config file or the configuration is malformed,
* set an empty config, an error will be returned later at
* fn_initialize() time */
let global_conf = GlobalConfig {
let mut global_conf = GlobalConfig {
conf: match Config::default_config() {
Ok(conf) => conf,
Err(_) => Config::new(),
},
};
global_conf.conf.load_env_vars_overrides();
RwLock::new(global_conf)
});

Expand Down Expand Up @@ -471,6 +478,20 @@ fn force_load_config() -> CK_RV {
return CKR_OK;
}

#[cfg(test)]
fn get_ec_point_encoding(save: &mut config::EcPointEncoding) -> CK_RV {
let gconf = global_rlock!(noinitcheck CONFIG);
*save = gconf.conf.ec_point_encoding;
CKR_OK
}

#[cfg(test)]
fn set_ec_point_encoding(val: config::EcPointEncoding) -> CK_RV {
let mut gconf = global_wlock!(noinitcheck CONFIG);
gconf.conf.ec_point_encoding = val;
CKR_OK
}

extern "C" fn fn_finalize(_reserved: CK_VOID_PTR) -> CK_RV {
global_wlock!(STATE).finalize()
}
Expand Down Expand Up @@ -890,37 +911,36 @@ extern "C" fn fn_get_attribute_value(
let cnt = cast_or_ret!(usize from count => CKR_ARGUMENTS_BAD);
let mut tmpl: &mut [CK_ATTRIBUTE] =
unsafe { std::slice::from_raw_parts_mut(template, cnt) };
ret_to_rv!(token.get_object_attrs(o_handle, &mut tmpl))
}

#[cfg(any(feature = "eddsa", feature = "ec_montgomery"))]
extern "C" fn fn_get_attribute_value_30(
s_handle: CK_SESSION_HANDLE,
o_handle: CK_OBJECT_HANDLE,
template: CK_ATTRIBUTE_PTR,
count: CK_ULONG,
) -> CK_RV {
use ec::{point_buf_to_der, point_len_to_der};

/* Ensure EC_POINT has enough space if there is an attempt to fecth */
let mut ec_point_len: Option<usize> = None;
let cnt = cast_or_ret!(usize from count => CKR_ARGUMENTS_BAD);
let tmpl: &mut [CK_ATTRIBUTE] =
unsafe { std::slice::from_raw_parts_mut(template, cnt) };
for a in tmpl.iter_mut() {
if a.type_ == CKA_EC_POINT {
let buflen =
cast_or_ret!(usize from a.ulValueLen => CKR_ARGUMENTS_BAD);
ec_point_len = Some(buflen);
#[cfg(any(feature = "eddsa", feature = "ec_montgomery"))]
let ec_point_len = match tmpl.iter().find(|a| a.type_ == CKA_EC_POINT) {
Some(a) => {
let gconf = global_rlock!(noinitcheck CONFIG);
/* enable the whole thing only if we need to convert to bacwards
* compatible DER encoding */
if gconf.conf.ec_point_encoding == config::EcPointEncoding::Der {
let buflen =
cast_or_ret!(usize from a.ulValueLen => CKR_ARGUMENTS_BAD);
Some(buflen)
} else {
None
}
}
}
None => None,
};

let result = ret_to_rv!(token.get_object_attrs(o_handle, &mut tmpl));

let ret = fn_get_attribute_value(s_handle, o_handle, template, count);
#[cfg(any(feature = "eddsa", feature = "ec_montgomery"))]
if let Some(bufsize) = ec_point_len {
for a in tmpl {
if a.type_ == CKA_EC_POINT
&& a.ulValueLen != CK_UNAVAILABLE_INFORMATION
{
use ec::{point_buf_to_der, point_len_to_der};

match tmpl.iter_mut().find(|a| a.type_ == CKA_EC_POINT) {
Some(a) => {
if a.ulValueLen == CK_UNAVAILABLE_INFORMATION {
/* do not touch this */
return result;
}
let buflen =
cast_or_ret!(usize from a.ulValueLen => CKR_GENERAL_ERROR);
if a.pValue == std::ptr::null_mut() {
Expand Down Expand Up @@ -952,19 +972,10 @@ extern "C" fn fn_get_attribute_value_30(
}
}
}
None => (),
}
}
ret
}

#[cfg(not(all(feature = "eddsa", feature = "ec_montgomery")))]
extern "C" fn fn_get_attribute_value_30(
s_handle: CK_SESSION_HANDLE,
o_handle: CK_OBJECT_HANDLE,
template: CK_ATTRIBUTE_PTR,
count: CK_ULONG,
) -> CK_RV {
fn_get_attribute_value(s_handle, o_handle, template, count)
result
}

extern "C" fn fn_set_attribute_value(
Expand All @@ -991,6 +1002,7 @@ extern "C" fn fn_set_attribute_value(
unsafe { std::slice::from_raw_parts_mut(template, cnt) };
ret_to_rv!(token.set_object_attrs(o_handle, &mut tmpl))
}

extern "C" fn fn_find_objects_init(
s_handle: CK_SESSION_HANDLE,
template: CK_ATTRIBUTE_PTR,
Expand Down Expand Up @@ -2406,7 +2418,7 @@ pub static FNLIST_240: CK_FUNCTION_LIST = CK_FUNCTION_LIST {
C_CopyObject: Some(fn_copy_object),
C_DestroyObject: Some(fn_destroy_object),
C_GetObjectSize: Some(fn_get_object_size),
C_GetAttributeValue: Some(fn_get_attribute_value_30),
C_GetAttributeValue: Some(fn_get_attribute_value),
C_SetAttributeValue: Some(fn_set_attribute_value),
C_FindObjectsInit: Some(fn_find_objects_init),
C_FindObjects: Some(fn_find_objects),
Expand Down Expand Up @@ -3149,103 +3161,6 @@ pub static FNLIST_300: CK_FUNCTION_LIST_3_0 = CK_FUNCTION_LIST_3_0 {
C_CopyObject: Some(fn_copy_object),
C_DestroyObject: Some(fn_destroy_object),
C_GetObjectSize: Some(fn_get_object_size),
C_GetAttributeValue: Some(fn_get_attribute_value_30),
C_SetAttributeValue: Some(fn_set_attribute_value),
C_FindObjectsInit: Some(fn_find_objects_init),
C_FindObjects: Some(fn_find_objects),
C_FindObjectsFinal: Some(fn_find_objects_final),
C_EncryptInit: Some(fn_encrypt_init),
C_Encrypt: Some(fn_encrypt),
C_EncryptUpdate: Some(fn_encrypt_update),
C_EncryptFinal: Some(fn_encrypt_final),
C_DecryptInit: Some(fn_decrypt_init),
C_Decrypt: Some(fn_decrypt),
C_DecryptUpdate: Some(fn_decrypt_update),
C_DecryptFinal: Some(fn_decrypt_final),
C_DigestInit: Some(fn_digest_init),
C_Digest: Some(fn_digest),
C_DigestUpdate: Some(fn_digest_update),
C_DigestKey: Some(fn_digest_key),
C_DigestFinal: Some(fn_digest_final),
C_SignInit: Some(fn_sign_init),
C_Sign: Some(fn_sign),
C_SignUpdate: Some(fn_sign_update),
C_SignFinal: Some(fn_sign_final),
C_SignRecoverInit: Some(fn_sign_recover_init),
C_SignRecover: Some(fn_sign_recover),
C_VerifyInit: Some(fn_verify_init),
C_Verify: Some(fn_verify),
C_VerifyUpdate: Some(fn_verify_update),
C_VerifyFinal: Some(fn_verify_final),
C_VerifyRecoverInit: Some(fn_verify_recover_init),
C_VerifyRecover: Some(fn_verify_recover),
C_DigestEncryptUpdate: Some(fn_digest_encrypt_update),
C_DecryptDigestUpdate: Some(fn_decrypt_digest_update),
C_SignEncryptUpdate: Some(fn_sign_encrypt_update),
C_DecryptVerifyUpdate: Some(fn_decrypt_verify_update),
C_GenerateKey: Some(fn_generate_key),
C_GenerateKeyPair: Some(fn_generate_key_pair),
C_WrapKey: Some(fn_wrap_key),
C_UnwrapKey: Some(fn_unwrap_key),
C_DeriveKey: Some(fn_derive_key),
C_SeedRandom: Some(fn_seed_random),
C_GenerateRandom: Some(fn_generate_random),
C_GetFunctionStatus: Some(fn_get_function_status),
C_CancelFunction: Some(fn_cancel_function),
C_WaitForSlotEvent: Some(fn_wait_for_slot_event),
C_GetInterfaceList: Some(C_GetInterfaceList),
C_GetInterface: Some(C_GetInterface),
C_LoginUser: Some(fn_login_user),
C_SessionCancel: Some(fn_session_cancel),
C_MessageEncryptInit: Some(fn_message_encrypt_init),
C_EncryptMessage: Some(fn_encrypt_message),
C_EncryptMessageBegin: Some(fn_encrypt_message_begin),
C_EncryptMessageNext: Some(fn_encrypt_message_next),
C_MessageEncryptFinal: Some(fn_message_encrypt_final),
C_MessageDecryptInit: Some(fn_message_decrypt_init),
C_DecryptMessage: Some(fn_decrypt_message),
C_DecryptMessageBegin: Some(fn_decrypt_message_begin),
C_DecryptMessageNext: Some(fn_decrypt_message_next),
C_MessageDecryptFinal: Some(fn_message_decrypt_final),
C_MessageSignInit: Some(fn_message_sign_init),
C_SignMessage: Some(fn_sign_message),
C_SignMessageBegin: Some(fn_sign_message_begin),
C_SignMessageNext: Some(fn_sign_message_next),
C_MessageSignFinal: Some(fn_message_sign_final),
C_MessageVerifyInit: Some(fn_message_verify_init),
C_VerifyMessage: Some(fn_verify_message),
C_VerifyMessageBegin: Some(fn_verify_message_begin),
C_VerifyMessageNext: Some(fn_verify_message_next),
C_MessageVerifyFinal: Some(fn_message_verify_final),
};

#[cfg(feature = "pkcs11ver31")]
pub static FNLIST_301: CK_FUNCTION_LIST_3_0 = CK_FUNCTION_LIST_3_0 {
version: CK_VERSION { major: 3, minor: 1 },
C_Initialize: Some(fn_initialize),
C_Finalize: Some(fn_finalize),
C_GetInfo: Some(fn_get_info),
C_GetFunctionList: Some(C_GetFunctionList),
C_GetSlotList: Some(fn_get_slot_list),
C_GetSlotInfo: Some(fn_get_slot_info),
C_GetTokenInfo: Some(fn_get_token_info),
C_GetMechanismList: Some(fn_get_mechanism_list),
C_GetMechanismInfo: Some(fn_get_mechanism_info),
C_InitToken: Some(fn_init_token),
C_InitPIN: Some(fn_init_pin),
C_SetPIN: Some(fn_set_pin),
C_OpenSession: Some(fn_open_session),
C_CloseSession: Some(fn_close_session),
C_CloseAllSessions: Some(fn_close_all_sessions),
C_GetSessionInfo: Some(fn_get_session_info),
C_GetOperationState: Some(fn_get_operation_state),
C_SetOperationState: Some(fn_set_operation_state),
C_Login: Some(fn_login),
C_Logout: Some(fn_logout),
C_CreateObject: Some(fn_create_object),
C_CopyObject: Some(fn_copy_object),
C_DestroyObject: Some(fn_destroy_object),
C_GetObjectSize: Some(fn_get_object_size),
C_GetAttributeValue: Some(fn_get_attribute_value),
C_SetAttributeValue: Some(fn_set_attribute_value),
C_FindObjectsInit: Some(fn_find_objects_init),
Expand Down Expand Up @@ -3344,12 +3259,7 @@ unsafe impl Sync for InterfaceData {}
unsafe impl Send for InterfaceData {}

static INTERFACE_SET: Lazy<Vec<InterfaceData>> = Lazy::new(|| {
let mut v = Vec::with_capacity(4);
#[cfg(feature = "pkcs11ver31")]
v.push(InterfaceData {
interface: std::ptr::addr_of!(INTERFACE_300),
version: FNLIST_301.version,
});
let mut v = Vec::with_capacity(3);
v.push(InterfaceData {
interface: std::ptr::addr_of!(INTERFACE_300),
version: FNLIST_300.version,
Expand Down
Loading

0 comments on commit 1c695b3

Please sign in to comment.