- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1
Add test crate #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Add test crate #17
Changes from all commits
      Commits
    
    
            Show all changes
          
          
            6 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      95b3c78
              
                test: Add provider test crate
              
              
                gowthamsk-arm 34a7e14
              
                test: Add build setup for generating test bindings
              
              
                gowthamsk-arm a3f9b89
              
                test: Add support functions for loading a provider and key
              
              
                gowthamsk-arm 4506c11
              
                test: Add tests for provider functions developed
              
              
                gowthamsk-arm 0484378
              
                ci: Update CI script to run the tests
              
              
                gowthamsk-arm dcd55f6
              
                provider: Import missing OSSL_OP_SIGNATURE
              
              
                gowthamsk-arm File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| [package] | ||
| name = "parsec-openssl-provider-shared-test" | ||
| version = "0.1.0" | ||
| authors = ["Parsec Project Contributors"] | ||
| description = "An end to end test framework for the parsec provider" | ||
| license = "Apache-2.0" | ||
| readme = "README.md" | ||
| keywords = ["security", "service"] | ||
| categories = ["cryptography", "hardware-support"] | ||
| edition = "2021" | ||
| repository = "https://github.com/parallaxsecond/parsec-openssl-provider" | ||
|  | ||
| [dependencies] | ||
| foreign-types-shared = "0.1.1" | ||
| parsec-openssl-provider = { path ="../parsec-openssl-provider" } | ||
|  | ||
| [build-dependencies] | ||
| pkg-config = "0.3.18" | ||
| bindgen = { version = "0.66.1" } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // Copyright 2024 Contributors to the Parsec project. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| use std::env; | ||
| use std::io::{Error, ErrorKind}; | ||
| use std::path::PathBuf; | ||
|  | ||
| const MINIMUM_VERSION: &str = "3.0.0"; | ||
|  | ||
| fn main() -> std::io::Result<()> { | ||
| // Use package config to ensure openssl version 3.0.0 or higher is installed | ||
| let openssl = pkg_config::Config::new() | ||
| .atleast_version(MINIMUM_VERSION) | ||
| .probe("openssl") | ||
| .expect("Failed to find openssl version above 3.0.0"); | ||
|  | ||
| // The include path points to the openssl development headers installed by libss-dev | ||
| let openssl_include_path = openssl.include_paths[0] | ||
| .clone() | ||
| .into_os_string() | ||
| .into_string() | ||
| .expect("Error converting OsString to String."); | ||
|  | ||
| // Generate bindings for the required headers | ||
| let openssl_builder = bindgen::Builder::default() | ||
| .header(format!("{}/openssl/evp.h", openssl_include_path)) | ||
| .header(format!("{}/openssl/provider.h", openssl_include_path)) | ||
| .generate_comments(false) | ||
| .size_t_is_usize(true); | ||
|  | ||
| // Build the bindings | ||
| let openssl_bindings = openssl_builder | ||
| .generate() | ||
| .map_err(|_| Error::new(ErrorKind::Other, "Unable to generate bindings to openssl"))?; | ||
|  | ||
| let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| openssl_bindings.write_to_file(out_path.join("openssl_test_bindings.rs"))?; | ||
|  | ||
| Ok(()) | ||
| } | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // Copyright 2024 Contributors to the Parsec project. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| #![allow(clippy::missing_safety_doc)] | ||
|  | ||
| #[allow(non_camel_case_types)] | ||
| #[allow(non_upper_case_globals)] | ||
| #[allow(non_snake_case)] | ||
| #[allow(improper_ctypes)] | ||
|         
                  tgonzalezorlandoarm marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| // These are test bindings generated from the "evp.h" and "provider.h" header files which | ||
| // provide interfaces for openssl clients. | ||
| pub mod openssl_test_bindings { | ||
| include!(concat!(env!("OUT_DIR"), "/openssl_test_bindings.rs")); | ||
| } | ||
|  | ||
| // Needed to access as_ptr function for LibCtx | ||
| pub use foreign_types_shared::ForeignType; | ||
| pub use openssl_test_bindings::*; | ||
| pub use parsec_openssl_provider::parsec_openssl2::openssl::{lib_ctx::LibCtx, provider::Provider}; | ||
|  | ||
| // These needs to be replaced with consts from the key management module | ||
| pub const PARSEC_PROVIDER_RSA: &[u8; 4] = b"RSA\0"; | ||
| pub const PARSEC_PROVIDER_PROPERTY: &[u8; 17] = b"provider=default\0"; | ||
|  | ||
| // Loads a provider into the given library context | ||
| pub fn load_provider(lib_ctx: &LibCtx, provider_name: &str, provider_path: String) -> Provider { | ||
| assert!(Provider::set_default_search_path(Some(lib_ctx), &provider_path).is_ok()); | ||
| Provider::load(Some(lib_ctx), provider_name).unwrap() | ||
| } | ||
|  | ||
| // Loads a key using the given library context with loaded provider. The param should contain the necessary | ||
| // parameters based on the provider that we are loading. | ||
| pub unsafe fn load_key(lib_ctx: &LibCtx, param: *mut OSSL_PARAM, parsec_pkey: *mut *mut EVP_PKEY) { | ||
| let evp_ctx: *mut EVP_PKEY_CTX = EVP_PKEY_CTX_new_from_name( | ||
| lib_ctx.as_ptr() as *mut ossl_lib_ctx_st, | ||
| PARSEC_PROVIDER_RSA.as_ptr() as *const ::std::os::raw::c_char, | ||
| PARSEC_PROVIDER_PROPERTY.as_ptr() as *const ::std::os::raw::c_char, | ||
| ); | ||
| assert_ne!(evp_ctx, std::ptr::null_mut()); | ||
| assert_eq!(EVP_PKEY_fromdata_init(evp_ctx), 1); | ||
|         
                  tgonzalezorlandoarm marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| assert_eq!( | ||
| EVP_PKEY_fromdata( | ||
| evp_ctx, | ||
| parsec_pkey as _, | ||
| // Change 3: Select the appropriate macro here to load the param value | ||
| EVP_PKEY_KEY_PARAMETERS.try_into().unwrap(), | ||
| param, | ||
| ), | ||
| 1 | ||
| ); | ||
| assert_ne!(*parsec_pkey, std::ptr::null_mut()); | ||
|  | ||
| EVP_PKEY_CTX_free(evp_ctx); | ||
| } | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| // Copyright 2024 Contributors to the Parsec project. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|  | ||
| use parsec_openssl_provider::parsec_openssl2::{openssl_binding, ossl_param}; | ||
| use parsec_openssl_provider_shared_test::*; | ||
| use std::ffi::CStr; | ||
|  | ||
| // Simple test to load a provider. Test fails if load_provider function reports error | ||
| #[test] | ||
| fn test_loading_parsec_provider() { | ||
| let provider_path = String::from("../target/debug"); | ||
| 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); | ||
| } | ||
|  | ||
| // Fetch the provider name from the OSSL interface "OSSL_PROVIDER_get0_name" | ||
| #[test] | ||
| fn test_parsec_provider_name() { | ||
| let provider_path = String::from("../target/debug/"); | ||
| 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); | ||
|  | ||
| unsafe { | ||
| let prov_name = OSSL_PROVIDER_get0_name(provider.as_ptr() as *const ossl_provider_st); | ||
| let prov_name = CStr::from_ptr(prov_name); | ||
| assert_eq!(prov_name.to_str().unwrap(), provider_name); | ||
| } | ||
| } | ||
|  | ||
| // Loads a keys from the provider and returns an EVP_PKEY object with the details. | ||
| // ToDo: This is working with the default provider and currently loads a key with | ||
| // no parameters. In order to test it with the parsec provider 3 changes are needed | ||
| // explained in comments below. | ||
| #[test] | ||
| fn test_loading_keys() { | ||
| let provider_path = String::from("../target/debug/"); | ||
| // Change 1: name the parsec provider here | ||
| let provider_name = String::from("default"); | ||
|  | ||
| let lib_ctx: LibCtx = LibCtx::new().unwrap(); | ||
| let provider: Provider = load_provider(&lib_ctx, &provider_name, provider_path); | ||
|  | ||
| // Change 2: Setup the param as needed for the parsec provider. | ||
| // Create a key beforehand using the parsec-tool and then run the test. | ||
| let mut param = ossl_param!(); | ||
| unsafe { | ||
| let mut parsec_pkey: *mut EVP_PKEY = std::ptr::null_mut(); | ||
| load_key(&lib_ctx, &mut param, &mut parsec_pkey); | ||
| EVP_PKEY_free(parsec_pkey); | ||
| } | ||
| } | ||
|  | ||
| // Checks if the parsec provider returns the expected list in the gettable param | ||
| // structure | ||
| #[test] | ||
| fn test_parsec_provider_gettable_param() { | ||
| let provider_path = String::from("../target/debug/"); | ||
| 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); | ||
| unsafe { | ||
| let gettable_params: *const OSSL_PARAM = | ||
| OSSL_PROVIDER_gettable_params(provider.as_ptr() as *const ossl_provider_st); | ||
|  | ||
| // Checks if the returned structure contains OSSL_PROV_PARAM_NAME | ||
| assert_ne!( | ||
| openssl_binding::OSSL_PARAM_locate( | ||
| gettable_params as _, | ||
| openssl_binding::OSSL_PROV_PARAM_NAME.as_ptr() as *const std::os::raw::c_char, | ||
| ), | ||
| std::ptr::null_mut() | ||
| ); | ||
|  | ||
| // Checks if the returned structure contains OSSL_PROV_PARAM_VERSION | ||
| assert_ne!( | ||
| openssl_binding::OSSL_PARAM_locate( | ||
| gettable_params as _, | ||
| openssl_binding::OSSL_PROV_PARAM_VERSION.as_ptr() as *const std::os::raw::c_char, | ||
| ), | ||
| std::ptr::null_mut() | ||
| ); | ||
|  | ||
| // Checks if the returned structure contains OSSL_PROV_PARAM_STATUS | ||
| assert_ne!( | ||
| openssl_binding::OSSL_PARAM_locate( | ||
| gettable_params as _, | ||
| openssl_binding::OSSL_PROV_PARAM_STATUS.as_ptr() as *const std::os::raw::c_char, | ||
| ), | ||
| std::ptr::null_mut() | ||
| ); | ||
| } | ||
| } | ||
|  | ||
| // Fetch the supported params from the parsec provider and compares if its as expected | ||
| #[test] | ||
| fn test_parsec_provider_get_param() { | ||
| let provider_path = String::from("../target/debug/"); | ||
| 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 mut prov_name: *mut i8 = std::ptr::null_mut(); | ||
| let mut prov_version: *mut i8 = std::ptr::null_mut(); | ||
| let mut prov_status: i32 = 0; | ||
| unsafe { | ||
| let mut params: [OSSL_PARAM; 4] = | ||
| [ossl_param!(), ossl_param!(), ossl_param!(), ossl_param!()]; | ||
|  | ||
| // Construct the 3 parameters | ||
| params[0] = OSSL_PARAM_construct_utf8_ptr( | ||
| openssl_binding::OSSL_PROV_PARAM_NAME.as_ptr() as _, | ||
| &mut prov_name, | ||
| 0, | ||
| ); | ||
| params[1] = OSSL_PARAM_construct_utf8_ptr( | ||
| openssl_binding::OSSL_PROV_PARAM_VERSION.as_ptr() as _, | ||
| &mut prov_version, | ||
| 0, | ||
| ); | ||
| params[2] = OSSL_PARAM_construct_int( | ||
| openssl_binding::OSSL_PROV_PARAM_STATUS.as_ptr() as _, | ||
| &mut prov_status as *mut i32, | ||
| ); | ||
|  | ||
| // Ensure the structure is unpopulated | ||
| assert_eq!(OSSL_PARAM_modified(¶ms as _), 0); | ||
| assert_eq!(OSSL_PARAM_modified(¶ms[1] as _), 0); | ||
| assert_eq!(OSSL_PARAM_modified(¶ms[2] as _), 0); | ||
|  | ||
| // Fetch the providers | ||
| assert_eq!( | ||
| OSSL_PROVIDER_get_params( | ||
| provider.as_ptr() as *const ossl_provider_st, | ||
| params.as_ptr() as *mut OSSL_PARAM, | ||
| ), | ||
| 1 | ||
| ); | ||
|  | ||
| // Ensure the structure is populated by the provider | ||
| assert_eq!(OSSL_PARAM_modified(¶ms as _), 1); | ||
| assert_eq!(OSSL_PARAM_modified(¶ms[1] as _), 1); | ||
| assert_eq!(OSSL_PARAM_modified(¶ms[2] as _), 1); | ||
|  | ||
| // Verify the returned provider parameters | ||
| let prov_name = CStr::from_ptr(prov_name); | ||
| let prov_name = prov_name.to_str().unwrap(); | ||
| assert_eq!(prov_name, "Parsec OpenSSL Provider"); | ||
|  | ||
| let prov_version = CStr::from_ptr(prov_version); | ||
| let prov_version = prov_version.to_str().unwrap(); | ||
| assert_eq!(prov_version, "0.1.0"); | ||
| } | ||
| } | ||
|  | ||
| // Verifies that the provider is able to return a non NULL pointer when queried for | ||
| // a supported function | ||
| #[test] | ||
| fn test_provider_query_supported() { | ||
| let provider_path = String::from("../target/debug"); | ||
| 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 mut no_cache: i32 = 0; | ||
| unsafe { | ||
| assert_ne!( | ||
| OSSL_PROVIDER_query_operation( | ||
| provider.as_ptr() as _, | ||
| OSSL_OP_KEYMGMT.try_into().unwrap(), | ||
| &mut no_cache as _, | ||
| ), | ||
| std::ptr::null_mut() | ||
| ); | ||
| } | ||
| } | ||
|  | ||
| // Verifies that the provider is able to return a NULL pointer when queried for | ||
| // an unsupported function | ||
| #[test] | ||
| fn test_provider_query_unsupported() { | ||
| let provider_path = String::from("../target/debug"); | ||
| 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 mut no_cache: i32 = 0; | ||
| unsafe { | ||
| assert_eq!( | ||
| OSSL_PROVIDER_query_operation( | ||
| provider.as_ptr() as _, | ||
| OSSL_OP_RAND.try_into().unwrap(), | ||
| &mut no_cache as _, | ||
| ), | ||
| std::ptr::null_mut() | ||
| ); | ||
| } | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.