use crate::error::{self, check, Result};
use crate::ffi;
use crate::ffi_safe::{
call_for_bool, call_for_optional_string, call_for_string, call_for_u32, call_for_usize,
cstr_to_optional_string,
};
use std::os::raw::c_char;
use std::ptr;
use super::{Signature, SignatureType, Subpacket, SubpacketType};
impl<'parent> Signature<'parent> {
pub fn sig_type(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_type(self.handle, out) })
}
pub fn sig_type_enum(&self) -> Result<SignatureType> {
Ok(SignatureType::parse(&self.sig_type()?))
}
pub fn alg(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_alg(self.handle, out) })
}
pub fn hash_alg(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_hash_alg(self.handle, out) })
}
pub fn creation(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_creation(self.handle, out) })
}
pub fn expiration(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_expiration(self.handle, out) })
}
pub fn key_flags(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_key_flags(self.handle, out) })
}
pub fn key_expiration(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_key_expiration(self.handle, out) })
}
pub fn primary_uid(&self) -> Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_signature_get_primary_uid(self.handle, out) })
}
pub fn features(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_features(self.handle, out) })
}
pub fn keyid(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_keyid(self.handle, out) })
}
pub fn key_fprint(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_key_fprint(self.handle, out) })
}
pub fn signer_keyid(&self) -> Result<String> {
call_for_string(|out| unsafe { ffi::rnp_signature_get_keyid(self.handle, out) })
}
pub fn preferred_ciphers(&self) -> Result<Vec<String>> {
super::preferred_list(self.handle, super::PreferredKind::Cipher)
}
pub fn preferred_hashes(&self) -> Result<Vec<String>> {
super::preferred_list(self.handle, super::PreferredKind::Hash)
}
pub fn preferred_compressions(&self) -> Result<Vec<String>> {
super::preferred_list(self.handle, super::PreferredKind::Compression)
}
pub fn key_server(&self) -> Result<Option<String>> {
call_for_optional_string(|out| unsafe {
ffi::rnp_signature_get_key_server(self.handle, out)
})
}
pub fn key_server_prefs(&self) -> Result<u32> {
call_for_u32(|out| unsafe { ffi::rnp_signature_get_key_server_prefs(self.handle, out) })
}
pub fn trust_level(&self) -> Result<u8> {
let mut level: u8 = 0;
let mut amount: u8 = 0;
unsafe {
check(ffi::rnp_signature_get_trust_level(
self.handle,
&mut level,
&mut amount,
))?
};
Ok(level)
}
pub fn trust_amount(&self) -> Result<u8> {
let mut level: u8 = 0;
let mut amount: u8 = 0;
unsafe {
check(ffi::rnp_signature_get_trust_level(
self.handle,
&mut level,
&mut amount,
))?
};
Ok(amount)
}
pub fn revocation_reason(&self) -> Result<Option<(String, String)>> {
let mut code_raw: *mut c_char = ptr::null_mut();
let mut reason_raw: *mut c_char = ptr::null_mut();
unsafe {
let code = ffi::rnp_signature_get_revocation_reason(
self.handle,
&mut code_raw,
&mut reason_raw,
);
if code == error::NOT_FOUND {
return Ok(None);
}
check(code)?;
let c = cstr_to_optional_string(code_raw).unwrap_or_default();
let r = cstr_to_optional_string(reason_raw).unwrap_or_default();
Ok(Some((c, r)))
}
}
pub fn is_valid(&self) -> Result<bool> {
let code = unsafe { ffi::rnp_signature_is_valid(self.handle, 0) };
Ok(code == error::SUCCESS)
}
pub fn subpacket_count(&self) -> Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_signature_subpacket_count(self.handle, out) })
}
pub fn subpacket_at(&self, idx: usize) -> Result<Option<Subpacket>> {
let mut handle: ffi::rnp_sig_subpacket_t = ptr::null_mut();
unsafe {
let code = ffi::rnp_signature_subpacket_at(self.handle, idx, &mut handle);
if code == error::NOT_FOUND {
return Ok(None);
}
check(code)?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(Subpacket::from_handle(handle)))
}
}
pub fn subpackets(&self) -> Result<Vec<Subpacket>> {
let n = self.subpacket_count()?;
(0..n)
.map(|i| self.subpacket_at(i)?.ok_or(error::Error::NullPointer))
.collect()
}
pub fn packet_to_json(&self, flags: crate::dump::JsonDumpFlags) -> Result<String> {
call_for_string(|raw| unsafe {
ffi::rnp_signature_packet_to_json(self.handle, flags.bits(), raw)
})
}
pub fn signer_key(&self) -> Result<Option<crate::Key<'_>>> {
let mut handle: ffi::rnp_key_handle_t = ptr::null_mut();
unsafe {
check(ffi::rnp_signature_get_signer(self.handle, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Key::from_handle(handle)))
}
}
pub fn find_subpacket(
&self,
typ: SubpacketType,
hashed: Option<bool>,
skip: usize,
) -> Result<Option<Subpacket>> {
let mut handle: ffi::rnp_sig_subpacket_t = ptr::null_mut();
let code = unsafe {
ffi::rnp_signature_subpacket_find(
self.handle,
typ.as_u8(),
hashed.unwrap_or(false),
skip,
&mut handle,
)
};
if code == error::NOT_FOUND {
return Ok(None);
}
check(code)?;
if handle.is_null() {
Ok(None)
} else {
Ok(Some(Subpacket::from_handle(handle)))
}
}
}