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
100 changes: 95 additions & 5 deletions parsec-openssl-provider/src/keymgmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,51 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_has(
}
}

/*
should import data indicated by selection into keydata with values taken from the OSSL_PARAM array params
*/
pub unsafe extern "C" fn parsec_provider_kmgmt_import(
key_data: VOID_PTR,
selection: std::os::raw::c_int,
params: *mut OSSL_PARAM,
) -> std::os::raw::c_int {
//TODO: Query the parsec service and get a list of keys, check if the requested import is for a known key and then
// set the parameter
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
return parsec_provider_kmgmt_set_params(key_data, params);
}
let result = super::r#catch(Some(|| super::Error::PROVIDER_KEYMGMT_IMPORT), || {
let keydata_ptr = key_data as *const ParsecProviderKeyObject;
Arc::increment_strong_count(keydata_ptr);
let arc_keydata = Arc::from_raw(keydata_ptr);
let param: openssl_bindings::OSSL_PARAM =
*openssl_returns_nonnull(openssl_bindings::OSSL_PARAM_locate(
params,
PARSEC_PROVIDER_KEY_NAME.as_ptr() as *const std::os::raw::c_char,
))?;

let key_name = std::str::from_utf8_unchecked(core::slice::from_raw_parts(
param.data as *mut u8,
param.data_size,
));

let keys = arc_keydata
.provctx
.get_client()
.list_keys()
.map_err(|_| "Failed to list Parsec Provider's Keys".to_string())?;

OPENSSL_SUCCESS
if keys.iter().any(|kinfo| kinfo.name == key_name) {
Ok(OPENSSL_SUCCESS)
} else {
Err("Specified Key not found in the Parsec Provider".into())
}
});
match result {
// Right now, settable params are the same as the import types, so it's ok to use this
// function
Ok(_) => parsec_provider_kmgmt_set_params(key_data, params),
Err(()) => OPENSSL_ERROR,
}
} else {
OPENSSL_SUCCESS
}
}

/*
Expand Down Expand Up @@ -591,3 +624,60 @@ fn test_kmgmt_match() {
parsec_provider_teardown(provctx as *const OSSL_PROVIDER);
}
}

#[test]
fn test_kmgmt_import() {
use crate::{parsec_provider_provider_init, parsec_provider_teardown};

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());

let keyctx = unsafe { parsec_provider_kmgmt_new(provctx) };

// Check that import fails with "bad" data
let bad_key_name = "BAD-NAME".to_string();
let mut bad_params = [
ossl_param!(PARSEC_PROVIDER_KEY_NAME, OSSL_PARAM_UTF8_PTR, bad_key_name),
ossl_param!(),
];
let bad_import_res = unsafe {
parsec_provider_kmgmt_import(
keyctx,
OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32,
&mut bad_params as _,
)
};
assert_eq!(bad_import_res, OPENSSL_ERROR);

// Check that import succeeds with "good" data
let good_key_name = "PARSEC_TEST_KEYNAME".to_string();
let mut good_params = [
ossl_param!(PARSEC_PROVIDER_KEY_NAME, OSSL_PARAM_UTF8_PTR, good_key_name),
ossl_param!(),
];

let good_import_res = unsafe {
parsec_provider_kmgmt_import(
keyctx,
OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32,
&mut good_params as _,
)
};
assert_eq!(good_import_res, OPENSSL_SUCCESS);

unsafe {
parsec_provider_kmgmt_free(keyctx);
parsec_provider_teardown(provctx as *const OSSL_PROVIDER);
}
}
3 changes: 2 additions & 1 deletion parsec-openssl-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ openssl_errors::openssl_errors! {
PROVIDER_GETTABLE_PARAMS("parsec_provider_gettable_params");
PROVIDER_GET_PARAMS("parsec_provider_get_params");
PROVIDER_KEYMGMT_HAS("parsec_provider_kmgmt_has");
PROVIDER_KEYMGMT_IMPORT("parsec_provider_kmgmt_import");
PROVIDER_KEYMGMT_MATCH("parsec_provider_kmgmt_match");
PROVIDER_KEYMGMT_SET_PARAMS("parsec_provider_kmgmt_set_params");
PROVIDER_KEYMGMT_VALIDATE("parsec_provider_kmgmt_validate");
PROVIDER_QUERY("parsec_provider_query");
PROVIDER_TEARDOWN("parsec_provider_teardown");
PROVIDER_KEYMGMT_VALIDATE("parsec_provider_kmgmt_validate");
}

reasons {
Expand Down