use crate::ffi_safe::{
call_for_bool, call_for_optional_string, call_for_string, call_for_u32, call_for_u64,
call_for_usize,
};
use crate::keygen;
use crate::{dump, ffi};
use super::{ExportFlags, Key, RevocationReason};
use std::ffi::CString;
use std::ptr;
impl<'ctx> Key<'ctx> {
pub fn export(&self, flags: ExportFlags) -> crate::error::Result<Vec<u8>> {
use crate::error::check;
use crate::ops::Output;
let output = Output::to_memory()?;
unsafe {
check(ffi::rnp_key_export(self.handle, output.as_ptr(), flags.bits()))?;
}
output.into_bytes()
}
pub fn raw_public_data(&self) -> crate::error::Result<Vec<u8>> {
use crate::ffi_safe::call_for_owned_bytes;
call_for_owned_bytes(|ptr, len| unsafe {
ffi::rnp_get_public_key_data(self.handle, ptr, len)
})
}
pub fn raw_secret_data(&self) -> crate::error::Result<Vec<u8>> {
use crate::ffi_safe::call_for_owned_bytes;
call_for_owned_bytes(|ptr, len| unsafe {
ffi::rnp_get_secret_key_data(self.handle, ptr, len)
})
}
pub fn export_autocrypt(
&self,
subkey: Option<&Key<'_>>,
uid: Option<&str>,
flags: ExportFlags,
) -> crate::error::Result<Vec<u8>> {
use crate::error::{check, Error};
use crate::ops::Output;
let subkey_handle = subkey.map(|k| k.handle).unwrap_or(self.handle);
let uid_c = uid
.map(|s| CString::new(s).map_err(|_| Error::NulByte))
.transpose()?;
let uid_ptr = uid_c.as_ref().map(|c| c.as_ptr()).unwrap_or(ptr::null());
let output = Output::to_memory()?;
unsafe {
check(ffi::rnp_key_export_autocrypt(
self.handle,
subkey_handle,
uid_ptr,
output.as_ptr(),
flags.bits(),
))?;
}
output.into_bytes()
}
pub fn export_revocation(
&self,
flags: ExportFlags,
reason: RevocationReason,
hash: keygen::Hash,
) -> crate::error::Result<Vec<u8>> {
super::export_revocation_impl(self.handle, flags, reason, hash)
}
pub fn primary_uid(&self) -> crate::error::Result<Option<String>> {
call_for_optional_string(|out| unsafe {
ffi::rnp_key_get_primary_uid(self.handle, out)
})
}
pub fn alg(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_alg(self.handle, out) })
}
pub fn bits(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_get_bits(self.handle, out) })
}
pub fn dsa_qbits(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_get_dsa_qbits(self.handle, out) })
}
pub fn curve(&self) -> crate::error::Result<Option<String>> {
call_for_optional_string(|out| unsafe { ffi::rnp_key_get_curve(self.handle, out) })
}
pub fn version(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_get_version(self.handle, out) })
}
pub fn creation(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_get_creation(self.handle, out) })
}
pub fn expiration(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_get_expiration(self.handle, out) })
}
pub fn keyid(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_keyid(self.handle, out) })
}
pub fn fingerprint(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_fprint(self.handle, out) })
}
pub fn grip(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_grip(self.handle, out) })
}
pub fn primary_fprint(&self) -> crate::error::Result<Option<String>> {
call_for_optional_string(|out| unsafe { ffi::rnp_key_get_primary_fprint(self.handle, out) })
}
pub fn primary_grip(&self) -> crate::error::Result<Option<String>> {
call_for_optional_string(|out| unsafe { ffi::rnp_key_get_primary_grip(self.handle, out) })
}
pub fn allows_usage(&self, usage: keygen::KeyUsage) -> crate::error::Result<bool> {
let usage_c = CString::new(usage.as_str()).unwrap();
call_for_bool(|out| unsafe { ffi::rnp_key_allows_usage(self.handle, usage_c.as_ptr(), out) })
}
pub fn have_secret(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_have_secret(self.handle, out) })
}
pub fn have_public(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_have_public(self.handle, out) })
}
pub fn is_primary(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_primary(self.handle, out) })
}
pub fn is_sub(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_sub(self.handle, out) })
}
pub fn is_valid(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_valid(self.handle, out) })
}
pub fn is_revoked(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_revoked(self.handle, out) })
}
pub fn is_locked(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_locked(self.handle, out) })
}
pub fn is_protected(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_is_protected(self.handle, out) })
}
pub fn valid_till(&self) -> crate::error::Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_key_valid_till(self.handle, out) })
}
pub fn valid_till64(&self) -> crate::error::Result<u64> {
call_for_u64(|out| unsafe { ffi::rnp_key_valid_till64(self.handle, out) })
}
pub fn is_expired(&self) -> crate::error::Result<bool> {
let till = self.valid_till()?;
if till == u32::MAX {
return Ok(false);
}
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs() as u32)
.unwrap_or(0);
Ok(till < now)
}
pub fn protection_type(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_protection_type(self.handle, out) })
}
pub fn protection_mode(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_protection_mode(self.handle, out) })
}
pub fn protection_cipher(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_protection_cipher(self.handle, out) })
}
pub fn protection_hash(&self) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_protection_hash(self.handle, out) })
}
pub fn protection_iterations(&self) -> crate::error::Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_key_get_protection_iterations(self.handle, out) })
}
pub fn revocation_reason(&self) -> crate::error::Result<Option<String>> {
call_for_optional_string(|out| unsafe {
ffi::rnp_key_get_revocation_reason(self.handle, out)
})
}
pub fn revoker_count(&self) -> crate::error::Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_key_get_revoker_count(self.handle, out) })
}
pub fn revoker_at(&self, idx: usize) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_get_revoker_at(self.handle, idx, out) })
}
pub fn is_25519_bits_tweaked(&self) -> crate::error::Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_key_25519_bits_tweaked(self.handle, out) })
}
pub fn uid_count(&self) -> crate::error::Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_key_get_uid_count(self.handle, out) })
}
pub fn uid_at(&self, idx: usize) -> crate::error::Result<Option<crate::Uid<'_>>> {
use crate::error::check;
let mut handle: ffi::rnp_uid_handle_t = ptr::null_mut();
unsafe {
check(ffi::rnp_key_get_uid_handle_at(self.handle, idx, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Uid::from_handle(handle)))
}
}
pub fn uids(&self) -> crate::error::Result<Vec<crate::Uid<'_>>> {
let n = self.uid_count()?;
(0..n)
.map(|i| self.uid_at(i)?.ok_or(crate::error::Error::NullPointer))
.collect()
}
pub fn subkey_count(&self) -> crate::error::Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_key_get_subkey_count(self.handle, out) })
}
pub fn subkey_at(&self, idx: usize) -> crate::error::Result<Option<crate::Subkey<'_>>> {
let mut handle: ffi::rnp_key_handle_t = ptr::null_mut();
unsafe {
crate::error::check(ffi::rnp_key_get_subkey_at(self.handle, idx, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Subkey::from_handle(handle)))
}
}
pub fn subkeys(&self) -> crate::error::Result<Vec<crate::Subkey<'_>>> {
let n = self.subkey_count()?;
(0..n)
.map(|i| self.subkey_at(i)?.ok_or(crate::error::Error::NullPointer))
.collect()
}
pub fn signature_count(&self) -> crate::error::Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_key_get_signature_count(self.handle, out) })
}
pub fn signature_at(&self, idx: usize) -> crate::error::Result<Option<crate::Signature<'_>>> {
let mut handle: ffi::rnp_signature_handle_t = ptr::null_mut();
unsafe {
crate::error::check(ffi::rnp_key_get_signature_at(self.handle, idx, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Signature::from_handle(handle)))
}
}
pub fn signatures(&self) -> crate::error::Result<Vec<crate::Signature<'_>>> {
let n = self.signature_count()?;
(0..n)
.map(|i| self.signature_at(i)?.ok_or(crate::error::Error::NullPointer))
.collect()
}
pub fn default_key_for(
&self,
usage: keygen::KeyUsage,
) -> crate::error::Result<Option<Key<'_>>> {
use crate::error::check;
let usage_c = CString::new(usage.as_str()).unwrap();
let mut handle: ffi::rnp_key_handle_t = ptr::null_mut();
unsafe {
check(ffi::rnp_key_get_default_key(
self.handle,
usage_c.as_ptr(),
0,
&mut handle,
))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(Key::from_handle(handle)))
}
}
pub fn to_json(&self, flags: dump::JsonFlags) -> crate::error::Result<String> {
call_for_string(|out| unsafe { ffi::rnp_key_to_json(self.handle, flags.bits(), out) })
}
pub fn packets_to_json(
&self,
secret: bool,
flags: dump::JsonDumpFlags,
) -> crate::error::Result<String> {
call_for_string(|out| unsafe {
ffi::rnp_key_packets_to_json(self.handle, secret, flags.bits(), out)
})
}
}