in releases/rust/db_esdk/src/ecdh.rs [181:235]
fn inner_get_public_key(
key_bytes: &[u8],
expected_curve_nid: i32,
) -> Result<Vec<u8>, String> {
let mut out = null_mut();
let evp_pkey = unsafe {
aws_lc_sys::d2i_PrivateKey(
EVP_PKEY_EC,
&mut out,
&mut key_bytes.as_ptr(),
key_bytes
.len()
.try_into()
.map_err(|_| "Key too long".to_string())?,
)
};
if evp_pkey.is_null() {
return Err("Error in d2i_PrivateKey in GetPublicKey.".to_string());
}
let ec_key = unsafe { EVP_PKEY_get0_EC_KEY(evp_pkey) };
if ec_key.is_null() {
return Err("Error in EVP_PKEY_get0_EC_KEY in GetPublicKey.".to_string());
}
let ec_group = unsafe { EC_KEY_get0_group(ec_key) };
if ec_group.is_null() {
return Err("Error in EC_KEY_get0_group in GetPublicKey.".to_string());
}
let key_nid = unsafe { EC_GROUP_get_curve_name(ec_group) };
if key_nid != expected_curve_nid {
return Err("Wrong Algorithm".to_string());
}
let key_size_bytes: usize = unsafe { EVP_PKEY_size(evp_pkey) }.try_into().unwrap();
let mut cbb: CBB = Default::default();
unsafe { CBB_init(&mut cbb as *mut CBB, key_size_bytes * 5) };
if 1 != unsafe { EVP_marshal_public_key(&mut cbb, evp_pkey) } {
return Err("Error in EVP_marshal_public_key in GetPublicKey.".to_string());
};
let mut out_data = null_mut::<u8>();
let mut out_len: usize = 0;
if 1 != unsafe { CBB_finish(&mut cbb, &mut out_data, &mut out_len) } {
return Err("Error in CBB_finish in GetPublicKey.".to_string());
};
let slice = unsafe { std::slice::from_raw_parts(out_data, out_len) };
let slice = slice.to_vec();
unsafe { OPENSSL_free(out_data as *mut ::std::os::raw::c_void) };
unsafe { EVP_PKEY_free(evp_pkey) };
Ok(slice)
}