Skip to main content

rsop_oct/
lib.rs

1// SPDX-FileCopyrightText: Heiko Schaefer <heiko@schaefer.name>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4mod card;
5mod cmd;
6mod util;
7
8use std::io;
9
10use pgp::packet::Signature;
11use rpgpie::certificate::Certificate;
12
13/// Error type for this crate
14#[derive(thiserror::Error, Debug)]
15#[non_exhaustive]
16pub enum Error {
17    #[error("rPGP error: {0}")]
18    Rpgp(pgp::errors::Error),
19
20    #[error("rpgpie error: {0}")]
21    Rpgpie(rpgpie::Error),
22
23    #[error("OcardRpgp error: {0}")]
24    OcardRpgp(openpgp_card_rpgp::Error),
25
26    #[error("openpgp_card error: {0}")]
27    Ocard(openpgp_card::Error),
28
29    #[error("Internal error: {0}")]
30    Message(String),
31}
32
33impl From<pgp::errors::Error> for Error {
34    fn from(value: pgp::errors::Error) -> Self {
35        Error::Rpgp(value)
36    }
37}
38
39impl From<rpgpie::Error> for Error {
40    fn from(value: rpgpie::Error) -> Self {
41        Error::Rpgpie(value)
42    }
43}
44
45impl From<openpgp_card_rpgp::Error> for Error {
46    fn from(value: openpgp_card_rpgp::Error) -> Self {
47        Error::OcardRpgp(value)
48    }
49}
50
51impl From<openpgp_card::Error> for Error {
52    fn from(value: openpgp_card::Error) -> Self {
53        Error::Ocard(value)
54    }
55}
56
57#[derive(Clone, Copy, Default)]
58pub struct RPGSOPOCT {}
59
60// SOP singleton
61const SOP: RPGSOPOCT = RPGSOPOCT {};
62
63pub struct Certs {
64    certs: Vec<Certificate>,
65    source_name: Option<String>,
66}
67
68pub struct Keys {
69    keys: Vec<Certificate>, // certificates that are backed by keys on OpenPGP cards
70    source_name: Option<String>,
71}
72
73pub struct Sigs {
74    sigs: Vec<Signature>,
75    source_name: Option<String>,
76}
77
78impl sop::SOP<'_> for RPGSOPOCT {
79    type Keys = Keys;
80    type Certs = Certs;
81    type Sigs = Sigs;
82
83    fn version(&'_ self) -> sop::Result<Box<dyn sop::ops::Version<'_>>> {
84        Ok(Box::new(cmd::version::Version::new()))
85    }
86
87    fn generate_key(
88        &'_ self,
89    ) -> sop::Result<Box<dyn sop::ops::GenerateKey<'_, Self, Self::Keys> + '_>> {
90        Err(sop::errors::Error::NotImplemented)
91    }
92
93    fn change_key_password(
94        &'_ self,
95    ) -> sop::Result<Box<dyn sop::ops::ChangeKeyPassword<'_, Self, Self::Keys>>> {
96        Err(sop::errors::Error::NotImplemented)
97    }
98
99    fn revoke_key(
100        &'_ self,
101    ) -> sop::Result<Box<dyn sop::ops::RevokeKey<'_, Self, Self::Certs, Self::Keys>>> {
102        Err(sop::errors::Error::NotImplemented)
103    }
104
105    fn extract_cert(
106        &'_ self,
107    ) -> sop::Result<Box<dyn sop::ops::ExtractCert<'_, Self, Self::Certs, Self::Keys> + '_>> {
108        Err(sop::errors::Error::NotImplemented)
109    }
110
111    fn update_key(
112        &'_ self,
113    ) -> sop::Result<Box<dyn sop::ops::UpdateKey<'_, Self, Self::Certs, Self::Keys> + '_>> {
114        Ok(Box::new(cmd::update_key::UpdateKey::new()))
115    }
116
117    fn merge_certs(
118        &'_ self,
119    ) -> sop::Result<Box<dyn sop::ops::MergeCerts<'_, Self, Self::Certs> + '_>> {
120        Err(sop::errors::Error::NotImplemented)
121    }
122
123    fn certify_userid(
124        &'_ self,
125    ) -> sop::Result<Box<dyn sop::ops::CertifyUserID<'_, Self, Self::Certs, Self::Keys> + '_>> {
126        Ok(Box::new(cmd::certify::CertifyUserID::new()))
127    }
128
129    fn validate_userid(
130        &'_ self,
131    ) -> sop::Result<Box<dyn sop::ops::ValidateUserID<'_, Self, Self::Certs> + '_>> {
132        Err(sop::errors::Error::NotImplemented)
133    }
134
135    fn sign(
136        &'_ self,
137    ) -> sop::Result<Box<dyn sop::ops::Sign<'_, Self, Self::Keys, Self::Sigs> + '_>> {
138        Ok(Box::new(cmd::sign::Sign::new()))
139    }
140
141    fn verify(
142        &'_ self,
143    ) -> sop::Result<Box<dyn sop::ops::Verify<'_, Self, Self::Certs, Self::Sigs> + '_>> {
144        Err(sop::errors::Error::NotImplemented)
145    }
146
147    fn encrypt(
148        &'_ self,
149    ) -> sop::Result<Box<dyn sop::ops::Encrypt<'_, Self, Self::Certs, Self::Keys> + '_>> {
150        Err(sop::errors::Error::NotImplemented)
151    }
152
153    fn decrypt(
154        &'_ self,
155    ) -> sop::Result<Box<dyn sop::ops::Decrypt<'_, Self, Self::Certs, Self::Keys> + '_>> {
156        Ok(Box::new(cmd::decrypt::Decrypt::new()))
157    }
158
159    fn armor(&'_ self) -> sop::Result<Box<dyn sop::ops::Armor<'_>>> {
160        Err(sop::errors::Error::NotImplemented)
161    }
162
163    fn dearmor(&'_ self) -> sop::Result<Box<dyn sop::ops::Dearmor<'_>>> {
164        Err(sop::errors::Error::NotImplemented)
165    }
166    fn inline_detach(&'_ self) -> sop::Result<Box<dyn sop::ops::InlineDetach<'_, Self::Sigs>>> {
167        Err(sop::errors::Error::NotImplemented)
168    }
169    fn inline_verify(
170        &'_ self,
171    ) -> sop::Result<Box<dyn sop::ops::InlineVerify<'_, Self, Self::Certs> + '_>> {
172        Err(sop::errors::Error::NotImplemented)
173    }
174    fn inline_sign(
175        &'_ self,
176    ) -> sop::Result<Box<dyn sop::ops::InlineSign<'_, Self, Self::Keys> + '_>> {
177        Ok(Box::new(cmd::inline_sign::InlineSign::new()))
178    }
179}
180
181impl sop::Load<'_, RPGSOPOCT> for Certs {
182    fn from_reader(
183        _sop: &RPGSOPOCT,
184        mut source: &mut (dyn io::Read + Send + Sync),
185        source_name: Option<String>,
186    ) -> sop::Result<Self> {
187        let certs = Certificate::load(&mut source).expect("FIXME");
188
189        Ok(Certs { certs, source_name })
190    }
191
192    fn source_name(&self) -> Option<&str> {
193        self.source_name.as_deref()
194    }
195}
196
197impl sop::Save for Certs {
198    fn to_writer(
199        &self,
200        armored: bool,
201        sink: &mut (dyn io::Write + Send + Sync),
202    ) -> sop::Result<()> {
203        Certificate::save_all(&self.certs, armored, sink).expect("FIXME");
204
205        Ok(())
206    }
207}
208
209impl sop::Load<'_, RPGSOPOCT> for Keys {
210    fn from_reader(
211        _sop: &'_ RPGSOPOCT,
212        mut source: &mut (dyn io::Read + Send + Sync),
213        source_name: Option<String>,
214    ) -> sop::Result<Self> {
215        let keys = Certificate::load(&mut source).expect("FIXME");
216
217        Ok(Keys { keys, source_name })
218    }
219
220    fn source_name(&self) -> Option<&str> {
221        self.source_name.as_deref()
222    }
223}
224
225impl sop::Save for Keys {
226    fn to_writer(
227        &self,
228        armored: bool,
229        sink: &mut (dyn io::Write + Send + Sync),
230    ) -> sop::Result<()> {
231        Certificate::save_all(&self.keys, armored, sink).expect("FIXME");
232
233        Ok(())
234    }
235}
236
237impl sop::Load<'_, RPGSOPOCT> for Sigs {
238    fn from_reader(
239        _sop: &'_ RPGSOPOCT,
240        mut source: &mut (dyn io::Read + Send + Sync),
241        source_name: Option<String>,
242    ) -> sop::Result<Self> {
243        let sigs = rpgpie::signature::load(&mut source).expect("FIXME");
244
245        Ok(Sigs { sigs, source_name })
246    }
247
248    fn source_name(&self) -> Option<&str> {
249        self.source_name.as_deref()
250    }
251}
252
253impl sop::Save for Sigs {
254    fn to_writer(
255        &self,
256        armored: bool,
257        mut sink: &mut (dyn io::Write + Send + Sync),
258    ) -> sop::Result<()> {
259        rpgpie::signature::save(&self.sigs, armored, &mut sink).expect("FIXME");
260
261        Ok(())
262    }
263}
264
265impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Certs {
266    fn sop(&self) -> &'s RPGSOPOCT {
267        &SOP
268    }
269}
270
271impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Keys {
272    fn sop(&self) -> &'s RPGSOPOCT {
273        &SOP
274    }
275}
276
277impl<'s> sop::plumbing::SopRef<'s, RPGSOPOCT> for Sigs {
278    fn sop(&self) -> &'s RPGSOPOCT {
279        &SOP
280    }
281}