mod card;
mod cmd;
mod util;
use std::io;
use pgp::packet::Signature;
use rpgpie::certificate::Certificate;
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("rPGP error: {0}")]
Rpgp(pgp::errors::Error),
#[error("rpgpie error: {0}")]
Rpgpie(rpgpie::Error),
#[error("OcardRpgp error: {0}")]
OcardRpgp(openpgp_card_rpgp::Error),
#[error("Internal error: {0}")]
Message(String),
}
impl From<pgp::errors::Error> for Error {
fn from(value: pgp::errors::Error) -> Self {
Error::Rpgp(value)
}
}
impl From<rpgpie::Error> for Error {
fn from(value: rpgpie::Error) -> Self {
Error::Rpgpie(value)
}
}
impl From<openpgp_card_rpgp::Error> for Error {
fn from(value: openpgp_card_rpgp::Error) -> Self {
Error::OcardRpgp(value)
}
}
#[derive(Clone, Copy, Default)]
pub struct RPGSOPOCT {}
const SOP: RPGSOPOCT = RPGSOPOCT {};
pub struct Certs {
certs: Vec<Certificate>,
source_name: Option<String>,
}
pub struct Keys {
keys: Vec<Certificate>, source_name: Option<String>,
}
pub struct Sigs {
sigs: Vec<Signature>,
source_name: Option<String>,
}
impl sop::SOP<'_> for RPGSOPOCT {
type Keys = Keys;
type Certs = Certs;
type Sigs = Sigs;
fn version(&'_ self) -> sop::Result<Box<dyn sop::ops::Version<'_>>> {
Ok(Box::new(cmd::version::Version::new()))
}
fn generate_key(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::GenerateKey<'_, Self, Self::Keys> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn change_key_password(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::ChangeKeyPassword<'_, Self, Self::Keys>>> {
Err(sop::errors::Error::NotImplemented)
}
fn revoke_key(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::RevokeKey<'_, Self, Self::Certs, Self::Keys>>> {
Err(sop::errors::Error::NotImplemented)
}
fn extract_cert(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::ExtractCert<'_, Self, Self::Certs, Self::Keys> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn update_key(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::UpdateKey<'_, Self, Self::Certs, Self::Keys> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn merge_certs(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::MergeCerts<'_, Self, Self::Certs> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn certify_userid(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::CertifyUserID<'_, Self, Self::Certs, Self::Keys> + '_>> {
Ok(Box::new(cmd::certify::CertifyUserID::new()))
}
fn validate_userid(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::ValidateUserID<'_, Self, Self::Certs> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn sign(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::Sign<'_, Self, Self::Keys, Self::Sigs> + '_>> {
Ok(Box::new(cmd::sign::Sign::new()))
}
fn verify(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::Verify<'_, Self, Self::Certs, Self::Sigs> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn encrypt(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::Encrypt<'_, Self, Self::Certs, Self::Keys> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn decrypt(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::Decrypt<'_, Self, Self::Certs, Self::Keys> + '_>> {
Ok(Box::new(cmd::decrypt::Decrypt::new()))
}
fn armor(&'_ self) -> sop::Result<Box<dyn sop::ops::Armor<'_>>> {
Err(sop::errors::Error::NotImplemented)
}
fn dearmor(&'_ self) -> sop::Result<Box<dyn sop::ops::Dearmor<'_>>> {
Err(sop::errors::Error::NotImplemented)
}
fn inline_detach(&'_ self) -> sop::Result<Box<dyn sop::ops::InlineDetach<'_, Self::Sigs>>> {
Err(sop::errors::Error::NotImplemented)
}
fn inline_verify(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::InlineVerify<'_, Self, Self::Certs> + '_>> {
Err(sop::errors::Error::NotImplemented)
}
fn inline_sign(
&'_ self,
) -> sop::Result<Box<dyn sop::ops::InlineSign<'_, Self, Self::Keys> + '_>> {
Ok(Box::new(cmd::inline_sign::InlineSign::new()))
}
}
impl sop::Load<'_, RPGSOPOCT> for Certs {
fn from_reader(
_sop: &RPGSOPOCT,
mut source: &mut (dyn io::Read + Send + Sync),
source_name: Option<String>,
) -> sop::Result<Self> {
let certs = Certificate::load(&mut source).expect("FIXME");
Ok(Certs { certs, source_name })
}
fn source_name(&self) -> Option<&str> {
self.source_name.as_deref()
}
}
impl sop::Save for Certs {
fn to_writer(
&self,
armored: bool,
sink: &mut (dyn io::Write + Send + Sync),
) -> sop::Result<()> {
Certificate::save_all(&self.certs, armored, sink).expect("FIXME");
Ok(())
}
}
impl sop::Load<'_, RPGSOPOCT> for Keys {
fn from_reader(
_sop: &'_ RPGSOPOCT,
mut source: &mut (dyn io::Read + Send + Sync),
source_name: Option<String>,
) -> sop::Result<Self> {
let keys = Certificate::load(&mut source).expect("FIXME");
Ok(Keys { keys, source_name })
}
fn source_name(&self) -> Option<&str> {
self.source_name.as_deref()
}
}
impl sop::Save for Keys {
fn to_writer(
&self,
_armored: bool,
_sink: &mut (dyn io::Write + Send + Sync),
) -> sop::Result<()> {
Err(sop::errors::Error::NotImplemented)
}
}
impl sop::Load<'_, RPGSOPOCT> for Sigs {
fn from_reader(
_sop: &'_ RPGSOPOCT,
mut source: &mut (dyn io::Read + Send + Sync),
source_name: Option<String>,
) -> sop::Result<Self> {
let sigs = rpgpie::signature::load(&mut source).expect("FIXME");
Ok(Sigs { sigs, source_name })
}
fn source_name(&self) -> Option<&str> {
self.source_name.as_deref()
}
}
impl sop::Save for Sigs {
fn to_writer(
&self,
armored: bool,
mut sink: &mut (dyn io::Write + Send + Sync),
) -> sop::Result<()> {
rpgpie::signature::save(&self.sigs, armored, &mut sink).expect("FIXME");
Ok(())
}
}
impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Certs {
fn sop(&self) -> &'s RPGSOPOCT {
&SOP
}
}
impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Keys {
fn sop(&self) -> &'s RPGSOPOCT {
&SOP
}
}
impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Sigs {
fn sop(&self) -> &'s RPGSOPOCT {
&SOP
}
}