diff --git a/parsec-openssl-provider/src/keymgmt/mod.rs b/parsec-openssl-provider/src/keymgmt/mod.rs index e35ae55..e912cd7 100644 --- a/parsec-openssl-provider/src/keymgmt/mod.rs +++ b/parsec-openssl-provider/src/keymgmt/mod.rs @@ -59,7 +59,7 @@ impl ParsecProviderKeyObject { } } -// Ec supported curve name +// Ec supported curve name. This is the only supported curve name. const EC_CURVE_NAME: &str = "prime256v1\0"; /* should create a provider side key object. The provider context provctx is passed and may be incorporated @@ -138,25 +138,28 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_rsa_get_params( keydata: VOID_PTR, params: *mut OSSL_PARAM, ) -> std::os::raw::c_int { - let result = super::r#catch(Some(|| super::Error::PROVIDER_KEYMGMT_GET_PARAMS), || { - if keydata.is_null() || params.is_null() { - Err("Null pointer received as parameter".into()) - } else { - Arc::increment_strong_count(keydata as *const RwLock); - let key_data = Arc::from_raw(keydata as *const RwLock); - let reader_key_data = key_data.read().unwrap(); + let result = super::r#catch( + Some(|| super::Error::PROVIDER_KEYMGMT_RSA_GET_PARAMS), + || { + if keydata.is_null() || params.is_null() { + Err("Null pointer received as parameter".into()) + } else { + Arc::increment_strong_count(keydata as *const RwLock); + let key_data = Arc::from_raw(keydata as *const RwLock); + let reader_key_data = key_data.read().unwrap(); - if let Some(public_key) = reader_key_data.get_rsa_key() { - let modulus = public_key.modulus.as_unsigned_bytes_be(); + if let Some(public_key) = reader_key_data.get_rsa_key() { + let modulus = public_key.modulus.as_unsigned_bytes_be(); - locate_and_set_int_param(OSSL_PKEY_PARAM_BITS, modulus.len() * 8, params)?; - locate_and_set_int_param(OSSL_PKEY_PARAM_SECURITY_BITS, 112, params)?; - locate_and_set_int_param(OSSL_PKEY_PARAM_MAX_SIZE, modulus.len(), params)?; - } + locate_and_set_int_param(OSSL_PKEY_PARAM_BITS, modulus.len() * 8, params)?; + locate_and_set_int_param(OSSL_PKEY_PARAM_SECURITY_BITS, 112, params)?; + locate_and_set_int_param(OSSL_PKEY_PARAM_MAX_SIZE, modulus.len(), params)?; + } - Ok(OPENSSL_SUCCESS) - } - }); + Ok(OPENSSL_SUCCESS) + } + }, + ); match result { Ok(result) => result, @@ -178,55 +181,59 @@ fn get_ec_secbits(bits: usize) -> usize { if bits < 512 { return 192; } - return 256; + 256 } pub unsafe extern "C" fn parsec_provider_ecdsa_kmgmt_get_params( keydata: VOID_PTR, params: *mut OSSL_PARAM, ) -> std::os::raw::c_int { - let result = super::r#catch(Some(|| super::Error::PROVIDER_KEYMGMT_GET_PARAMS), || { - if keydata.is_null() || params.is_null() { - Err("Null pointer received as parameter".into()) - } else { - Arc::increment_strong_count(keydata as *const RwLock); - let key_data = Arc::from_raw(keydata as *const RwLock); - let reader_key_data = key_data.read().unwrap(); + let result = super::r#catch( + Some(|| super::Error::PROVIDER_KEYMGMT_ECDSA_GET_PARAMS), + || { + if keydata.is_null() || params.is_null() { + Err("Null pointer received as parameter".into()) + } else { + Arc::increment_strong_count(keydata as *const RwLock); + let key_data = Arc::from_raw(keydata as *const RwLock); + let reader_key_data = key_data.read().unwrap(); - let key_name = match reader_key_data.key_name { - None => return Err("Key name is not set".to_string().into()), - Some(ref name) => name, - }; + let key_name = match reader_key_data.key_name { + None => return Err("Key name is not set".to_string().into()), + Some(ref name) => name, + }; - let key_attrs = reader_key_data - .provctx - .get_client() - .key_attributes(key_name) - .map_err(|e| format!("Failed to retrived key attributes: {}", e))?; + let key_attrs = reader_key_data + .provctx + .get_client() + .key_attributes(key_name) + .map_err(|e| format!("Failed to retrived key attributes: {}", e))?; - if let Ok(ptr) = openssl_returns_nonnull(openssl_bindings::OSSL_PARAM_locate( - params, - OSSL_PKEY_PARAM_GROUP_NAME.as_ptr() as *const std::os::raw::c_char, - )) { - let mut s = EC_CURVE_NAME.to_string(); - (*ptr).data_type = OSSL_PARAM_UTF8_STRING; - (*ptr).return_size = s.len(); - std::ptr::copy(s.as_mut_ptr() as _, (*ptr).data, s.len()); + if let Ok(ptr) = openssl_returns_nonnull(openssl_bindings::OSSL_PARAM_locate( + params, + OSSL_PKEY_PARAM_GROUP_NAME.as_ptr() as *const std::os::raw::c_char, + )) { + // This is the only supported curve name + let mut s = EC_CURVE_NAME.to_string(); + (*ptr).data_type = OSSL_PARAM_UTF8_STRING; + (*ptr).return_size = s.len(); + std::ptr::copy(s.as_mut_ptr() as _, (*ptr).data, s.len()); + } + let _ = locate_and_set_int_param(OSSL_PKEY_PARAM_BITS, key_attrs.bits, params); + let _ = locate_and_set_int_param( + OSSL_PKEY_PARAM_SECURITY_BITS, + get_ec_secbits(key_attrs.bits), + params, + ); + let _ = locate_and_set_int_param( + OSSL_PKEY_PARAM_MAX_SIZE, + 3 + (key_attrs.bits + 4) * 2, + params, + ); + Ok(OPENSSL_SUCCESS) } - let _ = locate_and_set_int_param(OSSL_PKEY_PARAM_BITS, key_attrs.bits, params); - let _ = locate_and_set_int_param( - OSSL_PKEY_PARAM_SECURITY_BITS, - get_ec_secbits(key_attrs.bits), - params, - ); - let _ = locate_and_set_int_param( - OSSL_PKEY_PARAM_MAX_SIZE, - (3 + (key_attrs.bits + 4) * 2).try_into().unwrap(), - params, - ); - Ok(OPENSSL_SUCCESS) - } - }); + }, + ); match result { Ok(result) => result, @@ -594,9 +601,7 @@ pub unsafe extern "C" fn parsec_provider_ecdsa_kmgmt_import_types( static mut IMPORT_TYPES_TABLE: [OSSL_PARAM; 1] = [ossl_param!(); 1]; ONCE_INIT.call_once(|| { - IMPORT_TYPES_TABLE = [ - ossl_param!(), - ]; + IMPORT_TYPES_TABLE = [ossl_param!()]; }); IMPORT_TYPES_TABLE.as_ptr() @@ -685,7 +690,9 @@ pub unsafe extern "C" fn parsec_provider_ecdsa_kmgmt_match( group.set_asn1_flag(openssl::ec::Asn1Flag::NAMED_CURVE); let mut big_num_context = openssl::bn::BigNumContext::new()?; - let are_equal = a.eq(group.as_ref(), b, &mut big_num_context).map_err(|e| format!("Failed to match keys: {}", e))?; + let are_equal = a + .eq(group.as_ref(), b, &mut big_num_context) + .map_err(|e| format!("Failed to match keys: {}", e))?; if are_equal { Ok(OPENSSL_SUCCESS) } else { @@ -735,7 +742,7 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_rsa_query_operation_name( pub unsafe extern "C" fn parsec_provider_ecdsa_kmgmt_query_operation_name( _operation_id: std::os::raw::c_int, ) -> *const std::os::raw::c_char { - return PARSEC_PROVIDER_ECDSA_NAME.as_ptr() as *const std::os::raw::c_char; + PARSEC_PROVIDER_ECDSA_NAME.as_ptr() as *const std::os::raw::c_char } const OSSL_FUNC_KEYMGMT_RSA_QUERY_OPERATION_NAME_PTR: KeyMgmtQueryOperationNamePtr = @@ -773,7 +780,8 @@ const OSSL_FUNC_KEYMGMT_RSA_IMPORT_TYPES_PTR: KeyMgmtImportTypesPtr = const OSSL_FUNC_KEYMGMT_ECDSA_IMPORT_TYPES_PTR: KeyMgmtImportTypesPtr = parsec_provider_ecdsa_kmgmt_import_types; const OSSL_FUNC_KEYMGMT_SET_PARAMS_PTR: KeyMgmtSetParamsPtr = parsec_provider_kmgmt_set_params; -const OSSL_FUNC_KEYMGMT_RSA_GET_PARAMS_PTR: KeyMgmtGetParamsPtr = parsec_provider_kmgmt_rsa_get_params; +const OSSL_FUNC_KEYMGMT_RSA_GET_PARAMS_PTR: KeyMgmtGetParamsPtr = + parsec_provider_kmgmt_rsa_get_params; const OSSL_FUNC_KEYMGMT_ECDSA_GET_PARAMS_PTR: KeyMgmtGetParamsPtr = parsec_provider_ecdsa_kmgmt_get_params; const OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS_PTR: KeyMgmtSettableParamsPtr = diff --git a/parsec-openssl-provider/src/lib.rs b/parsec-openssl-provider/src/lib.rs index 896ae3d..18400e9 100644 --- a/parsec-openssl-provider/src/lib.rs +++ b/parsec-openssl-provider/src/lib.rs @@ -116,6 +116,7 @@ openssl_errors::openssl_errors! { PROVIDER_KEYMGMT_ECDSA_IMPORT("parsec_provider_kmgmt_ecdsa_import"); PROVIDER_KEYMGMT_MATCH("parsec_provider_kmgmt_match"); PROVIDER_KEYMGMT_SET_PARAMS("parsec_provider_kmgmt_set_params"); + PROVIDER_KEYMGMT_ECDSA_GET_PARAMS("parsec_provider_kmgmt_ecdsa_get_params"); PROVIDER_KEYMGMT_RSA_GET_PARAMS("parsec_provider_kmgmt_rsa_get_params"); PROVIDER_KEYMGMT_VALIDATE("parsec_provider_kmgmt_validate"); PROVIDER_QUERY("parsec_provider_query"); diff --git a/parsec-openssl-provider/src/signature/mod.rs b/parsec-openssl-provider/src/signature/mod.rs index 5dc9319..b8a7be3 100644 --- a/parsec-openssl-provider/src/signature/mod.rs +++ b/parsec-openssl-provider/src/signature/mod.rs @@ -96,91 +96,96 @@ unsafe extern "C" fn parsec_provider_signature_digest_sign( tbs: *const std::os::raw::c_uchar, tbslen: std::os::raw::c_uint, ) -> std::os::raw::c_int { - let result = super::r#catch(Some(|| super::Error::PROVIDER_SIGNATURE_DIGEST_SIGN), || { - if ctx.is_null() || siglen.is_null() { - return Err("Received unexpected NULL pointer as an argument.".into()); - } + let result = super::r#catch( + Some(|| super::Error::PROVIDER_SIGNATURE_DIGEST_SIGN), + || { + if ctx.is_null() || siglen.is_null() { + return Err("Received unexpected NULL pointer as an argument.".into()); + } - Arc::increment_strong_count(ctx as *const RwLock); - let sig_ctx = Arc::from_raw(ctx as *const RwLock); + Arc::increment_strong_count(ctx as *const RwLock); + let sig_ctx = Arc::from_raw(ctx as *const RwLock); + + let reader_sig_ctx = sig_ctx.read().unwrap(); + let key_data = match reader_sig_ctx.keyobj { + None => { + return Err( + "Key Object not set. This should be done through sign_init()".into(), + ) + } + Some(ref keyobj) => keyobj.read().unwrap(), + }; + + let key_name = match key_data.get_key_name() { + None => return Err("Key name not set in the Key Object".into()), + Some(ref name) => name, + }; + + let key_attributes = key_data + .get_provctx() + .get_client() + .key_attributes(key_name) + .map_err(|e| format!("Failed to get specified key's attributes: {}", e))?; + let siglength = get_signature_len(key_attributes).map_err(|e| { + format!( + "Failed to Get correct signature length for the given key: {}", + e + ) + })?; - let reader_sig_ctx = sig_ctx.read().unwrap(); - let key_data = match reader_sig_ctx.keyobj { - None => { - return Err("Key Object not set. This should be done through sign_init()".into()) + if sig.is_null() { + *siglen = siglength as std::os::raw::c_uint; + return Ok(OPENSSL_SUCCESS); } - Some(ref keyobj) => keyobj.read().unwrap(), - }; - - let key_name = match key_data.get_key_name() { - None => return Err("Key name not set in the Key Object".into()), - Some(ref name) => name, - }; - - let key_attributes = key_data - .get_provctx() - .get_client() - .key_attributes(key_name) - .map_err(|e| format!("Failed to get specified key's attributes: {}", e))?; - let siglength = get_signature_len(key_attributes).map_err(|e| { - format!( - "Failed to Get correct signature length for the given key: {}", - e - ) - })?; - - if sig.is_null() { - *siglen = siglength as std::os::raw::c_uint; - return Ok(OPENSSL_SUCCESS); - } - - if (sigsize as usize) < siglength { - return Err(format!( - "Signature length is bigger than sigsize. Signature length: {}", - siglength - ) - .into()); - } - if tbs.is_null() { - return Err("Received unexpected NULL pointer as an argument.".into()); - } + if (sigsize as usize) < siglength { + return Err(format!( + "Signature length is bigger than sigsize. Signature length: {}", + siglength + ) + .into()); + } - let tbs_slice: &[u8] = core::slice::from_raw_parts(tbs, tbslen as usize); + if tbs.is_null() { + return Err("Received unexpected NULL pointer as an argument.".into()); + } - let sign_algorithm = match key_attributes.policy.permitted_algorithms { - Algorithm::AsymmetricSignature(signature_algo) => signature_algo, - _ => { - return Err( - "Specified key does not permit the AsymmetricSignature algorithm".into(), - ) + let tbs_slice: &[u8] = core::slice::from_raw_parts(tbs, tbslen as usize); + + let sign_algorithm = match key_attributes.policy.permitted_algorithms { + Algorithm::AsymmetricSignature(signature_algo) => signature_algo, + _ => { + return Err( + "Specified key does not permit the AsymmetricSignature algorithm".into(), + ) + } + }; + + let hash_res: Vec = key_data + .get_provctx() + .get_client() + .psa_hash_compute(Hash::Sha256, tbs_slice) + .map_err(|e| format!("Parsec Client failed to hash: {:?}", e))?; + + let mut sign_res: Vec = key_data + .get_provctx() + .get_client() + .psa_sign_hash(key_name, &hash_res, sign_algorithm) + .map_err(|e| format!("Parsec Client failed to sign: {:?}", e))?; + + if sign_algorithm.is_ecc_alg() { + let s = IntegerAsn1::from_bytes_be_unsigned(sign_res.split_off(sign_res.len() / 2)); + sign_res = picky_asn1_der::to_vec(&EccSignature { + r: IntegerAsn1::from_bytes_be_unsigned(sign_res), + s, + }) + .map_err(|e| format!("Failed to convert ECC Signature: {:?}", e))?; } - }; - - let hash_res: Vec = key_data - .get_provctx() - .get_client() - .psa_hash_compute(Hash::Sha256, tbs_slice) - .map_err(|e| format!("Parsec Client failed to hash: {:?}", e))?; - - let mut sign_res: Vec = key_data - .get_provctx() - .get_client() - .psa_sign_hash(key_name, &hash_res, sign_algorithm) - .map_err(|e| format!("Parsec Client failed to sign: {:?}", e))?; - - if sign_algorithm.is_ecc_alg() { - let s = IntegerAsn1::from_bytes_be_unsigned(sign_res.split_off(sign_res.len() / 2)); - sign_res = picky_asn1_der::to_vec(&EccSignature { - r: IntegerAsn1::from_bytes_be_unsigned(sign_res), - s, - }) - .map_err(|e| format!("Failed to convert ECC Signature: {:?}", e))?; - } - std::ptr::copy(sign_res.as_ptr(), sig, sign_res.len()); - *siglen = sign_res.len() as u32; - Ok(OPENSSL_SUCCESS) - }); + std::ptr::copy(sign_res.as_ptr(), sig, sign_res.len()); + *siglen = sign_res.len() as u32; + Ok(OPENSSL_SUCCESS) + }, + ); match result { Ok(result) => result, @@ -194,49 +199,50 @@ unsafe extern "C" fn parsec_provider_signature_digest_sign_init( provkey: VOID_PTR, params: *const OSSL_PARAM, ) -> std::os::raw::c_int { - let result = super::r#catch(Some(|| super::Error::PROVIDER_SIGNATURE_DIGEST_SIGN_INIT), || { - if ctx.is_null() || provkey.is_null() { - return Err("Neither ctx nor provkey pointers should be NULL.".into()); - } - - Arc::increment_strong_count(ctx as *const RwLock); - let sig_ctx = Arc::from_raw(ctx as *const RwLock); - let mut writer_sig_ctx = sig_ctx.write().unwrap(); - Arc::increment_strong_count(provkey as *const RwLock); - let prov_key = Arc::from_raw(provkey as *const RwLock); + let result = super::r#catch( + Some(|| super::Error::PROVIDER_SIGNATURE_DIGEST_SIGN_INIT), + || { + if ctx.is_null() || provkey.is_null() { + return Err("Neither ctx nor provkey pointers should be NULL.".into()); + } - writer_sig_ctx.keyobj = Some(prov_key.clone()); - let key_data = match writer_sig_ctx.keyobj { - None => { - return Err("Key Object not set.".into()) + Arc::increment_strong_count(ctx as *const RwLock); + let sig_ctx = Arc::from_raw(ctx as *const RwLock); + let mut writer_sig_ctx = sig_ctx.write().unwrap(); + Arc::increment_strong_count(provkey as *const RwLock); + let prov_key = Arc::from_raw(provkey as *const RwLock); + + writer_sig_ctx.keyobj = Some(prov_key.clone()); + let key_data = match writer_sig_ctx.keyobj { + None => return Err("Key Object not set.".into()), + Some(ref keyobj) => keyobj.read().unwrap(), + }; + + let key_name = match key_data.get_key_name() { + None => return Err("Key name not set in the Key Object".into()), + Some(ref name) => name, + }; + // Currently we only support SHA256 hash function. + // Return error if any other function is selected. + if let Ok(hash_function) = CStr::from_ptr(mdname).to_str() { + if hash_function != "SHA256" && hash_function != "SHA2-256" { + return Err("Invalid hash function".into()); + } } - Some(ref keyobj) => keyobj.read().unwrap(), - }; - - let key_name = match key_data.get_key_name() { - None => return Err("Key name not set in the Key Object".into()), - Some(ref name) => name, - }; - // Currently we only support SHA256 hash function. - // Return error if any other function is selected. - if let Ok(hash_function) = CStr::from_ptr(mdname).to_str() { - if hash_function != "SHA256" && hash_function != "SHA2-256" { - return Err("Invalid hash function".into()); + let key_attributes = key_data + .get_provctx() + .get_client() + .key_attributes(key_name) + .map_err(|e| format!("Failed to get specified key's attributes: {}", e))?; + match key_attributes.key_type { + Type::RsaKeyPair => Ok(parsec_provider_signature_rsa_set_params(ctx, params)), + Type::EccKeyPair { + curve_family: EccFamily::SecpR1, + } => Ok(parsec_provider_signature_ecdsa_set_params(ctx, params)), + _ => Err("Key type not recognized".to_string().into()), } - } - let key_attributes = key_data - .get_provctx() - .get_client() - .key_attributes(key_name) - .map_err(|e| format!("Failed to get specified key's attributes: {}", e))?; - match key_attributes.key_type { - Type::RsaKeyPair => Ok(parsec_provider_signature_rsa_set_params(ctx, params)), - Type::EccKeyPair { - curve_family: EccFamily::SecpR1, - } => Ok(parsec_provider_signature_ecdsa_set_params(ctx, params)), - _ => Err("Key type not recognized".to_string().into()), - } - }); + }, + ); match result { Ok(result) => result,