use crate::error::{check, Result};
use crate::ffi;
use crate::ffi_safe::call_for_owned_bytes;
use std::ptr;
pub struct Subpacket {
pub(crate) handle: ffi::rnp_sig_subpacket_t,
}
impl Subpacket {
pub(crate) fn from_handle(handle: ffi::rnp_sig_subpacket_t) -> Self {
Subpacket { handle }
}
pub fn typ_raw(&self) -> Result<u8> {
let mut t: u8 = 0;
let mut hashed: bool = false;
let mut critical: bool = false;
unsafe {
check(ffi::rnp_signature_subpacket_info(
self.handle,
&mut t,
&mut hashed,
&mut critical,
))?
};
Ok(t)
}
pub fn typ_enum(&self) -> Result<SubpacketType> {
Ok(SubpacketType::from_u8(self.typ_raw()?))
}
pub fn is_hashed(&self) -> Result<bool> {
self.info().map(|(_, hashed, _)| hashed)
}
pub fn is_critical(&self) -> Result<bool> {
self.info().map(|(_, _, critical)| critical)
}
pub fn data(&self) -> Result<Vec<u8>> {
call_for_owned_bytes(|ptr, len| unsafe {
ffi::rnp_signature_subpacket_data(self.handle, ptr, len)
})
}
fn info(&self) -> Result<(u8, bool, bool)> {
let mut t: u8 = 0;
let mut hashed: bool = false;
let mut critical: bool = false;
unsafe {
check(ffi::rnp_signature_subpacket_info(
self.handle,
&mut t,
&mut hashed,
&mut critical,
))?
};
Ok((t, hashed, critical))
}
}
impl Drop for Subpacket {
fn drop(&mut self) {
if !self.handle.is_null() {
unsafe {
let _ = ffi::rnp_signature_subpacket_destroy(self.handle);
}
self.handle = ptr::null_mut();
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
#[non_exhaustive]
pub enum SubpacketType {
SignatureCreationTime = 2,
SignatureExpirationTime = 3,
ExportableCertification = 4,
TrustSignature = 5,
RegularExpression = 6,
Revocable = 7,
KeyExpirationTime = 9,
PreferredSymmetricAlgorithms = 11,
RevocationReason = 12,
IssuerKeyId = 16,
PreferredHashAlgorithms = 21,
PreferredCompressionAlgorithms = 22,
KeyServerPreferences = 23,
PreferredKeyServer = 24,
PrimaryUserId = 25,
PolicyUri = 26,
KeyFlags = 27,
SignerUserId = 28,
ReasonForRevocation = 29,
Features = 30,
IssuerFingerprint = 33,
Other(u8),
}
impl SubpacketType {
pub fn as_u8(self) -> u8 {
match self {
SubpacketType::Other(raw) => raw,
v => {
use SubpacketType::*;
match v {
SignatureCreationTime => 2,
SignatureExpirationTime => 3,
ExportableCertification => 4,
TrustSignature => 5,
RegularExpression => 6,
Revocable => 7,
KeyExpirationTime => 9,
PreferredSymmetricAlgorithms => 11,
RevocationReason => 12,
IssuerKeyId => 16,
PreferredHashAlgorithms => 21,
PreferredCompressionAlgorithms => 22,
KeyServerPreferences => 23,
PreferredKeyServer => 24,
PrimaryUserId => 25,
PolicyUri => 26,
KeyFlags => 27,
SignerUserId => 28,
ReasonForRevocation => 29,
Features => 30,
IssuerFingerprint => 33,
Other(_) => unreachable!(),
}
}
}
}
pub fn from_u8(raw: u8) -> Self {
match raw {
2 => Self::SignatureCreationTime,
3 => Self::SignatureExpirationTime,
4 => Self::ExportableCertification,
5 => Self::TrustSignature,
6 => Self::RegularExpression,
7 => Self::Revocable,
9 => Self::KeyExpirationTime,
11 => Self::PreferredSymmetricAlgorithms,
12 => Self::RevocationReason,
16 => Self::IssuerKeyId,
21 => Self::PreferredHashAlgorithms,
22 => Self::PreferredCompressionAlgorithms,
23 => Self::KeyServerPreferences,
24 => Self::PreferredKeyServer,
25 => Self::PrimaryUserId,
26 => Self::PolicyUri,
27 => Self::KeyFlags,
28 => Self::SignerUserId,
29 => Self::ReasonForRevocation,
30 => Self::Features,
33 => Self::IssuerFingerprint,
_ => Self::Other(raw),
}
}
}
#[allow(dead_code)]
fn _subpacket_type_exhaustive(t: SubpacketType) -> u8 {
t.as_u8()
}