use crate::ffi;
use crate::la_error::Result;
use crate::private::{bridge_bool, bridge_bytes, bridge_unit, cstring, OwnedHandle};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SecKeyAlgorithm(String);
impl SecKeyAlgorithm {
#[must_use]
pub fn from_raw_name(name: impl Into<String>) -> Self {
Self(name.into())
}
#[must_use]
pub fn raw_name(&self) -> &str {
&self.0
}
#[must_use]
pub fn ecdsa_signature_message_x962_sha256() -> Self {
Self::from_raw_name("algid:sign:ECDSA:message-X962:SHA256")
}
#[must_use]
pub fn ecdsa_signature_digest_x962_sha256() -> Self {
Self::from_raw_name("algid:sign:ECDSA:digest-X962:SHA256")
}
#[must_use]
pub fn ecies_encryption_standard_variable_iv_x963_sha256_aes_gcm() -> Self {
Self::from_raw_name("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM-KDFIV")
}
#[must_use]
pub fn ecies_encryption_cofactor_variable_iv_x963_sha256_aes_gcm() -> Self {
Self::from_raw_name("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV")
}
#[must_use]
pub fn ecdh_key_exchange_cofactor_x963_sha256() -> Self {
Self::from_raw_name("algid:keyexchange:ECDHC:KDFX963:SHA256")
}
}
impl From<&str> for SecKeyAlgorithm {
fn from(value: &str) -> Self {
Self::from_raw_name(value)
}
}
impl From<String> for SecKeyAlgorithm {
fn from(value: String) -> Self {
Self::from_raw_name(value)
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct SecKeyExchangeParameters {
requested_size: Option<usize>,
shared_info: Option<Vec<u8>>,
}
impl SecKeyExchangeParameters {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub const fn with_requested_size(requested_size: usize) -> Self {
Self {
requested_size: Some(requested_size),
shared_info: None,
}
}
#[must_use]
pub const fn requested_size(mut self, requested_size: usize) -> Self {
self.requested_size = Some(requested_size);
self
}
#[must_use]
pub fn with_shared_info(mut self, shared_info: impl Into<Vec<u8>>) -> Self {
self.shared_info = Some(shared_info.into());
self
}
#[must_use]
pub fn without_shared_info(mut self) -> Self {
self.shared_info = None;
self
}
#[must_use]
pub(crate) const fn requested_size_value(&self) -> Option<usize> {
self.requested_size
}
#[must_use]
pub(crate) fn shared_info_value(&self) -> Option<&[u8]> {
self.shared_info.as_deref()
}
}
#[derive(Debug)]
pub struct LAPublicKey {
handle: OwnedHandle,
}
impl LAPublicKey {
pub(crate) fn from_raw(raw: std::ptr::NonNull<core::ffi::c_void>) -> Self {
Self {
handle: OwnedHandle::new(raw, ffi::la_public_key::la_public_key_release),
}
}
pub fn export_bytes(&self) -> Result<Vec<u8>> {
bridge_bytes(|out, out_len, error_out| unsafe {
ffi::la_public_key::la_public_key_export_bytes(
self.handle.as_ptr(),
out,
out_len,
error_out,
)
})
}
pub fn can_encrypt_using(&self, algorithm: &SecKeyAlgorithm) -> Result<bool> {
let algorithm = cstring(algorithm.raw_name())?;
bridge_bool(|out, error_out| unsafe {
ffi::la_public_key::la_public_key_can_encrypt_using_algorithm(
self.handle.as_ptr(),
algorithm.as_ptr(),
out,
error_out,
)
})
}
pub fn encrypt(&self, data: &[u8], algorithm: &SecKeyAlgorithm) -> Result<Vec<u8>> {
let algorithm = cstring(algorithm.raw_name())?;
bridge_bytes(|out, out_len, error_out| unsafe {
ffi::la_public_key::la_public_key_encrypt_data(
self.handle.as_ptr(),
data.as_ptr(),
data.len(),
algorithm.as_ptr(),
out,
out_len,
error_out,
)
})
}
pub fn can_verify_using(&self, algorithm: &SecKeyAlgorithm) -> Result<bool> {
let algorithm = cstring(algorithm.raw_name())?;
bridge_bool(|out, error_out| unsafe {
ffi::la_public_key::la_public_key_can_verify_using_algorithm(
self.handle.as_ptr(),
algorithm.as_ptr(),
out,
error_out,
)
})
}
pub fn verify(
&self,
signed_data: &[u8],
signature: &[u8],
algorithm: &SecKeyAlgorithm,
) -> Result<()> {
let algorithm = cstring(algorithm.raw_name())?;
bridge_unit(|error_out| unsafe {
ffi::la_public_key::la_public_key_verify_data(
self.handle.as_ptr(),
signed_data.as_ptr(),
signed_data.len(),
signature.as_ptr(),
signature.len(),
algorithm.as_ptr(),
error_out,
)
})
}
}