Skip to content

Commit d81ab70

Browse files
committed
Add test crate
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
1 parent 8059af2 commit d81ab70

File tree

7 files changed

+305
-3
lines changed

7 files changed

+305
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ members = [
44
"parsec-openssl2",
55
"parsec-openssl-provider",
66
"parsec-openssl-provider-shared",
7+
"parsec-openssl-provider-shared-test",
78
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "parsec-openssl-provider-shared-test"
3+
version = "0.1.0"
4+
authors = ["Parsec Project Contributors"]
5+
description = "A parsec openssl provider dynamic library"
6+
license = "Apache-2.0"
7+
readme = "README.md"
8+
keywords = ["security", "service"]
9+
categories = ["cryptography", "hardware-support"]
10+
edition = "2021"
11+
12+
[dependencies]
13+
openssl = "0.10.63"
14+
parsec-openssl2 = { path = "../parsec-openssl2" }
15+
foreign-types = "0.3"
16+
foreign-types-shared = "0.1"
17+
parsec-openssl-provider = { path ="../parsec-openssl-provider" }
18+
19+
[build-dependencies]
20+
pkg-config = "0.3.18"
21+
bindgen = { version = "0.66.1" }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2024 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
use std::env;
4+
use std::io::{Error, ErrorKind};
5+
use std::path::PathBuf;
6+
7+
const MINIMUM_VERSION: &str = "3.0.0";
8+
9+
fn main() -> std::io::Result<()> {
10+
// Use package config to ensure openssl version 3.0.0 or higher is installed
11+
let openssl = pkg_config::Config::new()
12+
.atleast_version(MINIMUM_VERSION)
13+
.probe("openssl")
14+
.expect("Failed to find openssl version above 3.0.0");
15+
16+
// The include path points to the openssl development headers installed by libss-dev
17+
let openssl_include_path = openssl.include_paths[0]
18+
.clone()
19+
.into_os_string()
20+
.into_string()
21+
.expect("Error converting OsString to String.");
22+
23+
// Generate bindings for the required headers
24+
let openssl_builder = bindgen::Builder::default()
25+
.header(format!("{}/openssl/evp.h", openssl_include_path))
26+
.header(format!("{}/openssl/provider.h", openssl_include_path))
27+
.generate_comments(false)
28+
.size_t_is_usize(true);
29+
30+
// Build the bindings
31+
let openssl_bindings = openssl_builder
32+
.generate()
33+
.map_err(|_| Error::new(ErrorKind::Other, "Unable to generate bindings to openssl"))?;
34+
35+
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
36+
openssl_bindings.write_to_file(out_path.join("openssl_test_bindings.rs"))?;
37+
38+
Ok(())
39+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2024 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use openssl::error::ErrorStack;
5+
use openssl::{lib_ctx::LibCtx, provider::Provider};
6+
use parsec_openssl2::openssl_binding;
7+
use parsec_openssl2::types::VOID_PTR_PTR;
8+
9+
#[allow(non_camel_case_types)]
10+
#[allow(non_upper_case_globals)]
11+
#[allow(non_snake_case)]
12+
#[allow(improper_ctypes)]
13+
#[ignore]
14+
pub mod openssl_test_bindings {
15+
16+
include!(concat!(env!("OUT_DIR"), "/openssl_test_bindings.rs"));
17+
}
18+
use openssl_test_bindings::*;
19+
20+
use foreign_types_shared::ForeignType;
21+
pub const PARSEC_PROVIDER_RSA: &[u8; 4] = b"RSA\0";
22+
pub const PARSEC_PROVIDER_PROPERTY: &[u8; 17] = b"provider=default\0";
23+
24+
pub fn load_provider(lib_ctx: &LibCtx, provider_name: &String, provider_path: String) -> Provider {
25+
assert_eq!(
26+
Provider::set_default_search_path(Some(&lib_ctx), &provider_path).is_ok(),
27+
true
28+
);
29+
let provider = Provider::load(Some(&lib_ctx), &provider_name).unwrap();
30+
provider
31+
}
32+
33+
pub unsafe fn load_key(
34+
lib_ctx: LibCtx,
35+
param_ptr: *mut OSSL_PARAM,
36+
mut parsec_pkey: *mut EVP_PKEY,
37+
) -> LibCtx {
38+
let mut evp_ctx: *mut EVP_PKEY_CTX = EVP_PKEY_CTX_new_from_name(
39+
lib_ctx.as_ptr() as *mut ossl_lib_ctx_st,
40+
PARSEC_PROVIDER_RSA.as_ptr() as *const ::std::os::raw::c_char,
41+
PARSEC_PROVIDER_PROPERTY.as_ptr() as *const ::std::os::raw::c_char,
42+
);
43+
assert_ne!(evp_ctx, std::ptr::null_mut());
44+
assert_eq!(EVP_PKEY_fromdata_init(evp_ctx), 1);
45+
assert_eq!(
46+
EVP_PKEY_fromdata(
47+
evp_ctx,
48+
&mut parsec_pkey as *mut *mut EVP_PKEY,
49+
// Change 3: Select the appropriate macro here to load the param value
50+
EVP_PKEY_KEY_PARAMETERS.try_into().unwrap(),
51+
param_ptr,
52+
),
53+
1
54+
);
55+
assert_ne!(parsec_pkey, std::ptr::null_mut());
56+
57+
EVP_PKEY_CTX_free(evp_ctx);
58+
lib_ctx
59+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2024 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use foreign_types_shared::ForeignType;
5+
use openssl::{lib_ctx::LibCtx, provider::Provider};
6+
use openssl_test_bindings::*;
7+
use parsec_openssl2::openssl_binding;
8+
use parsec_openssl2::{openssl_returns_nonnull, ossl_param};
9+
use parsec_openssl_provider::provider::PARSEC_PROVIDER_NAME;
10+
use parsec_openssl_provider::provider::PARSEC_PROVIDER_PARAM_TYPES;
11+
use parsec_openssl_provider_shared_test::*;
12+
use std::ffi::CStr;
13+
14+
// Simple test to load a provider. Test fails if load_provider function reports error
15+
#[test]
16+
fn test_loading_parsec_provider() {
17+
let provider_path = String::from("../target/debug");
18+
let provider_name = String::from("libparsec_openssl_provider_shared");
19+
//let provider_name = String::from("default");
20+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
21+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
22+
}
23+
24+
#[test]
25+
fn test_parsec_provider_name() {
26+
let provider_path = String::from("../target/debug/");
27+
let provider_name = String::from("libparsec_openssl_provider_shared");
28+
//let provider_name = String::from("default");
29+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
30+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
31+
unsafe {
32+
let prov_name = OSSL_PROVIDER_get0_name(provider.as_ptr() as *const ossl_provider_st);
33+
let prov_name = CStr::from_ptr(prov_name);
34+
let prov_name = prov_name.to_str().unwrap();
35+
// assert_eq!(prov_name.to_bytes().len(), provider_name.len());
36+
//prov_name= prov_name.to_string_lossy();//.to_string();
37+
assert_eq!(prov_name, provider_name);
38+
}
39+
}
40+
41+
// Loads a keys from the provider and returns an EVP_PKEY object with the details
42+
// This is working against the default provider and currently loads a key with
43+
// no parameters. In order to test it with the parsec provider 3 changes are needed
44+
// explained in comments below.
45+
#[test]
46+
fn test_loading_keys() {
47+
// Change 1: toggle comment below to load the parsec provider
48+
let provider_path = String::from("../target/debug/");
49+
//let provider_name = String::from("libparsec_openssl_provider_shared");
50+
51+
let provider_name = String::from("default");
52+
53+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
54+
let mut parsec_pkey: *mut EVP_PKEY = std::ptr::null_mut();
55+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
56+
57+
// Change 2: Setup the param as needed for the parsec provider.
58+
// Create a key beforehand using the parsec-tool and then run the test.
59+
let mut param = ossl_param!();
60+
unsafe {
61+
lib_ctx = load_key(lib_ctx, &mut param, parsec_pkey);
62+
EVP_PKEY_free(parsec_pkey);
63+
}
64+
65+
//OSSL_PARAM_free(param_ptr);
66+
}
67+
68+
#[test]
69+
fn test_parsec_provider_gettable_param() {
70+
let provider_path = String::from("../target/debug/");
71+
let provider_name = String::from("libparsec_openssl_provider_shared");
72+
//let provider_name = String::from("default");
73+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
74+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
75+
unsafe {
76+
let gettable_params: *const OSSL_PARAM =
77+
OSSL_PROVIDER_gettable_params(provider.as_ptr() as *const ossl_provider_st);
78+
assert_ne!(
79+
openssl_binding::OSSL_PARAM_locate(
80+
gettable_params as _,
81+
openssl_binding::OSSL_PROV_PARAM_NAME.as_ptr() as *const std::os::raw::c_char,
82+
),
83+
std::ptr::null_mut()
84+
);
85+
assert_ne!(
86+
openssl_binding::OSSL_PARAM_locate(
87+
gettable_params as _,
88+
openssl_binding::OSSL_PROV_PARAM_VERSION.as_ptr() as *const std::os::raw::c_char,
89+
),
90+
std::ptr::null_mut()
91+
);
92+
assert_ne!(
93+
openssl_binding::OSSL_PARAM_locate(
94+
gettable_params as _,
95+
openssl_binding::OSSL_PROV_PARAM_STATUS.as_ptr() as *const std::os::raw::c_char,
96+
),
97+
std::ptr::null_mut()
98+
);
99+
}
100+
}
101+
102+
#[test]
103+
fn test_parsec_provider_get_param() {
104+
let provider_path = String::from("../target/debug/");
105+
let provider_name = String::from("libparsec_openssl_provider_shared");
106+
//let provider_name = String::from("default");
107+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
108+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
109+
110+
let mut prov_name: *mut i8 = std::ptr::null_mut();
111+
let mut prov_version: *mut i8 = std::ptr::null_mut();
112+
let mut prov_status: i32 = 0;
113+
unsafe {
114+
let mut params: [OSSL_PARAM; 4] =
115+
[ossl_param!(), ossl_param!(), ossl_param!(), ossl_param!()];
116+
params[0] = OSSL_PARAM_construct_utf8_ptr(
117+
openssl_binding::OSSL_PROV_PARAM_NAME.as_ptr() as _,
118+
&mut prov_name,
119+
0,
120+
);
121+
params[1] = OSSL_PARAM_construct_utf8_ptr(
122+
openssl_binding::OSSL_PROV_PARAM_VERSION.as_ptr() as _,
123+
&mut prov_version,
124+
0,
125+
);
126+
params[2] = OSSL_PARAM_construct_int(
127+
openssl_binding::OSSL_PROV_PARAM_STATUS.as_ptr() as _,
128+
&mut prov_status as *mut i32,
129+
);
130+
assert_eq!(OSSL_PARAM_modified(&params as _), 0);
131+
assert_eq!(OSSL_PARAM_modified(&params[1] as _), 0);
132+
assert_eq!(OSSL_PARAM_modified(&params[2] as _), 0);
133+
assert_eq!(
134+
OSSL_PROVIDER_get_params(
135+
provider.as_ptr() as *const ossl_provider_st,
136+
params.as_ptr() as *mut OSSL_PARAM,
137+
),
138+
1
139+
);
140+
assert_eq!(OSSL_PARAM_modified(&params as _), 1);
141+
assert_eq!(OSSL_PARAM_modified(&params[1] as _), 1);
142+
assert_eq!(OSSL_PARAM_modified(&params[2] as _), 1);
143+
144+
let prov_name = CStr::from_ptr(prov_name);
145+
let prov_name = prov_name.to_str().unwrap();
146+
assert_eq!(prov_name, "Parsec OpenSSL Provider");
147+
148+
let prov_version = CStr::from_ptr(prov_version);
149+
let prov_version = prov_version.to_str().unwrap();
150+
assert_eq!(prov_version, "0.1.0");
151+
}
152+
}
153+
154+
#[test]
155+
fn test_provider_query() {
156+
let provider_path = String::from("../target/debug");
157+
let provider_name = String::from("libparsec_openssl_provider_shared");
158+
//let provider_name = String::from("default");
159+
let mut lib_ctx: LibCtx = LibCtx::new().unwrap();
160+
let mut provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path);
161+
162+
let mut no_cache: i32 = 0;
163+
unsafe {
164+
assert_ne!(
165+
OSSL_PROVIDER_query_operation(
166+
provider.as_ptr() as _,
167+
OSSL_OP_KEYMGMT.try_into().unwrap(),
168+
&mut no_cache as _,
169+
),
170+
std::ptr::null_mut()
171+
);
172+
assert_eq!(
173+
OSSL_PROVIDER_query_operation(
174+
provider.as_ptr() as _,
175+
OSSL_OP_RAND.try_into().unwrap(),
176+
&mut no_cache as _,
177+
),
178+
std::ptr::null_mut()
179+
);
180+
}
181+
}

parsec-openssl-provider/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use parsec_openssl2::types::VOID_PTR;
1616
use parsec_openssl2::{openssl_binding, types};
1717

1818
mod keymgmt;
19-
mod provider;
19+
20+
pub mod provider;
2021
use provider::*;
2122

2223
mod catch;
@@ -30,7 +31,7 @@ pub unsafe fn parsec_provider_provider_init(
3031
out: *mut *const OSSL_DISPATCH,
3132
provctx: types::VOID_PTR_PTR,
3233
) -> Result<(), parsec_openssl2::Error> {
33-
env_logger::init();
34+
//env_logger::init();
3435

3536
let parsec_provider_teardown_ptr: ProviderTeardownPtr = parsec_provider_teardown;
3637

parsec-openssl-provider/src/provider.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub const PARSEC_PROVIDER_NAME: &[u8; 24] = b"Parsec OpenSSL Provider\0";
2222
pub const PARSEC_PROVIDER_VERSION: &[u8; 6] = b"0.1.0\0";
2323

2424
// The types of parameters the provider supplies to the openssl library
25-
const PARSEC_PROVIDER_PARAM_TYPES: [OSSL_PARAM; 5] = [
25+
pub const PARSEC_PROVIDER_PARAM_TYPES: [OSSL_PARAM; 5] = [
2626
// Provider name
2727
ossl_param!(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR),
2828
// Provider version

0 commit comments

Comments
 (0)