Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion parsec-openssl-provider-shared/e2e_tests/tests/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn test_loading_keys() {
let provider_name = String::from("libparsec_openssl_provider_shared");

let lib_ctx: LibCtx = LibCtx::new().unwrap();
let provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
let _provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);

// Create a key beforehand using the parsec-tool and then run the test.
let my_key_name = "PARSEC_TEST_KEYNAME".to_string();
Expand Down
109 changes: 104 additions & 5 deletions parsec-openssl-provider/src/keymgmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

use crate::openssl_bindings::{
OSSL_ALGORITHM, OSSL_DISPATCH, OSSL_FUNC_KEYMGMT_FREE, OSSL_FUNC_KEYMGMT_IMPORT,
OSSL_FUNC_KEYMGMT_IMPORT_TYPES, OSSL_FUNC_KEYMGMT_NEW, OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS,
OSSL_FUNC_KEYMGMT_SET_PARAMS, OSSL_FUNC_KEYMGMT_VALIDATE, OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS,
OSSL_PARAM, OSSL_PARAM_UTF8_PTR,
OSSL_ALGORITHM, OSSL_DISPATCH, OSSL_FUNC_KEYMGMT_FREE, OSSL_FUNC_KEYMGMT_HAS,
OSSL_FUNC_KEYMGMT_IMPORT, OSSL_FUNC_KEYMGMT_IMPORT_TYPES, OSSL_FUNC_KEYMGMT_NEW,
OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, OSSL_FUNC_KEYMGMT_SET_PARAMS, OSSL_FUNC_KEYMGMT_VALIDATE,
OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS, OSSL_PARAM, OSSL_PARAM_UTF8_PTR,
};
use crate::{
ParsecProviderContext, PARSEC_PROVIDER_DESCRIPTION_RSA, PARSEC_PROVIDER_DFLT_PROPERTIES,
Expand Down Expand Up @@ -110,6 +110,41 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_set_params(
}
}

/*
should return 1 if all the selected data subsets are contained in the given keydata or 0 otherwise.
For algorithms where some selection is not meaningful the function should just return 1 as the
selected subset is not really missing in the key.
*/
pub unsafe extern "C" fn parsec_provider_kmgmt_has(
keydata: VOID_PTR,
selection: std::os::raw::c_int,
) -> std::os::raw::c_int {
let result = super::r#catch(Some(|| super::Error::PROVIDER_KEYMGMT_HAS), || {
if keydata.is_null() {
return Err("keydata pointer should not be NULL.".into());
}

if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
let keydata_ptr = keydata as *const ParsecProviderKeyObject;
Arc::increment_strong_count(keydata_ptr);
let arc_keydata = Arc::from_raw(keydata_ptr);
let key_name = arc_keydata.key_name.lock().unwrap();
if key_name.is_some() {
Ok(OPENSSL_SUCCESS)
} else {
Err("key name has not been set.".into())
}
} else {
Ok(OPENSSL_SUCCESS)
}
});

match result {
Ok(result) => result,
Err(()) => OPENSSL_ERROR,
}
}

pub unsafe extern "C" fn parsec_provider_kmgmt_import(
key_data: VOID_PTR,
selection: std::os::raw::c_int,
Expand Down Expand Up @@ -175,6 +210,7 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_validate(

pub type KeyMgmtNewPtr = unsafe extern "C" fn(VOID_PTR) -> VOID_PTR;
pub type KeyMgmtFreePtr = unsafe extern "C" fn(VOID_PTR);
pub type KeyMgmtHasPtr = unsafe extern "C" fn(VOID_PTR, std::os::raw::c_int) -> std::os::raw::c_int;
pub type KeyMgmtImportPtr =
unsafe extern "C" fn(VOID_PTR, std::os::raw::c_int, *mut OSSL_PARAM) -> std::os::raw::c_int;
pub type KeyMgmtImportTypesPtr = unsafe extern "C" fn(std::os::raw::c_int) -> *const OSSL_PARAM;
Expand All @@ -186,6 +222,7 @@ pub type KeyMgmtValidatePtr =

const OSSL_FUNC_KEYMGMT_NEW_PTR: KeyMgmtNewPtr = parsec_provider_kmgmt_new;
const OSSL_FUNC_KEYMGMT_FREE_PTR: KeyMgmtFreePtr = parsec_provider_kmgmt_free;
const OSSL_FUNC_KEYMGMT_HAS_PTR: KeyMgmtHasPtr = parsec_provider_kmgmt_has;
const OSSL_FUNC_KEYMGMT_IMPORT_PTR: KeyMgmtImportPtr = parsec_provider_kmgmt_import;
const OSSL_FUNC_KEYMGMT_IMPORT_TYPES_PTR: KeyMgmtImportTypesPtr =
parsec_provider_kmgmt_import_types;
Expand All @@ -194,9 +231,10 @@ const OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS_PTR: KeyMgmtSettableParamsPtr =
parsec_provider_kmgmt_settable_params;
const OSSL_FUNC_KEYMGMT_VALIDATE_PTR: KeyMgmtValidatePtr = parsec_provider_kmgmt_validate;

const PARSEC_PROVIDER_RSA_KEYMGMT_IMPL: [OSSL_DISPATCH; 8] = [
const PARSEC_PROVIDER_RSA_KEYMGMT_IMPL: [OSSL_DISPATCH; 9] = [
unsafe { ossl_dispatch!(OSSL_FUNC_KEYMGMT_NEW, OSSL_FUNC_KEYMGMT_NEW_PTR) },
unsafe { ossl_dispatch!(OSSL_FUNC_KEYMGMT_FREE, OSSL_FUNC_KEYMGMT_FREE_PTR) },
unsafe { ossl_dispatch!(OSSL_FUNC_KEYMGMT_HAS, OSSL_FUNC_KEYMGMT_HAS_PTR) },
unsafe { ossl_dispatch!(OSSL_FUNC_KEYMGMT_IMPORT, OSSL_FUNC_KEYMGMT_IMPORT_PTR) },
unsafe {
ossl_dispatch!(
Expand Down Expand Up @@ -229,3 +267,64 @@ pub const PARSEC_PROVIDER_KEYMGMT: [OSSL_ALGORITHM; 2] = [
),
ossl_algorithm!(),
];

#[test]
fn test_kmgmt_has() {
use crate::openssl_bindings::OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
use crate::parsec_provider_provider_init;

let out: *const OSSL_DISPATCH = std::ptr::null();
let mut provctx: types::VOID_PTR = std::ptr::null_mut();

// Initialize the provider
let result: Result<(), parsec_openssl2::Error> = unsafe {
parsec_provider_provider_init(
std::ptr::null(),
std::ptr::null(),
&out as *const _ as *mut _,
&mut provctx as *mut VOID_PTR,
)
};
assert!(result.is_ok());

// Test parsec_provider_kmgmt_has when keyobj is null. Selection should not matter in this case
let selec_w_null = unsafe {
parsec_provider_kmgmt_has(
std::ptr::null_mut(),
OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32,
)
};
assert_eq!(selec_w_null, OPENSSL_ERROR);

let keyobj = unsafe { parsec_provider_kmgmt_new(provctx) };
/* Test parsec_provider_kmgmt_has when the name parameter in keyobj has not been set and the correct selection is
used */
let selec_no_init =
unsafe { parsec_provider_kmgmt_has(keyobj, OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32) };
assert_eq!(selec_no_init, OPENSSL_ERROR);

/* Test parsec_provider_kmgmt_has when the name parameter in keyobj has not been set but a superfluous selection
is used */
let no_selec_no_init =
unsafe { parsec_provider_kmgmt_has(keyobj, OSSL_KEYMGMT_SELECT_PRIVATE_KEY as i32) };
assert_eq!(no_selec_no_init, OPENSSL_SUCCESS);

// Set the key data with the correct name
let my_key_name = "PARSEC_TEST_KEYNAME".to_string();
let mut params = [
ossl_param!(PARSEC_PROVIDER_KEY_NAME, OSSL_PARAM_UTF8_PTR, my_key_name),
ossl_param!(),
];

let set_params_res = unsafe { parsec_provider_kmgmt_set_params(keyobj, &mut params as _) };
assert_eq!(set_params_res, OPENSSL_SUCCESS);

// Check parsec_provider_kmgmt_has confirms that keyobj now has the correct data
let selec_init =
unsafe { parsec_provider_kmgmt_has(keyobj, OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32) };
assert_eq!(selec_init, OPENSSL_SUCCESS);

unsafe {
parsec_provider_kmgmt_free(keyobj);
}
}
5 changes: 3 additions & 2 deletions parsec-openssl-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ openssl_errors::openssl_errors! {
#[allow(clippy::empty_enum)]
pub library Error("parsec_openssl_provider") {
functions {
PROVIDER_TEARDOWN("parsec_provider_teardown");
PROVIDER_GETTABLE_PARAMS("parsec_provider_gettable_params");
PROVIDER_GET_PARAMS("parsec_provider_get_params");
PROVIDER_QUERY("parsec_provider_query");
PROVIDER_KEYMGMT_HAS("parsec_provider_kmgmt_has");
PROVIDER_KEYMGMT_SET_PARAMS("parsec_provider_kmgmt_set_params");
PROVIDER_QUERY("parsec_provider_query");
PROVIDER_TEARDOWN("parsec_provider_teardown");
}

reasons {
Expand Down