crypto_seal/
lib.rs

1pub mod error;
2pub mod key;
3
4use core::marker::PhantomData;
5use serde::{de::DeserializeOwned, Deserialize, Serialize};
6use std::collections::HashMap;
7
8use crate::error::Error;
9use crate::key::{PrivateKey, PublicKey};
10
11pub type Result<T> = std::result::Result<T, Error>;
12
13#[derive(Default, Deserialize, Serialize, Clone, PartialEq, Eq, Debug)]
14#[serde(rename_all = "lowercase")]
15pub enum RecipientCarrier {
16    Direct {
17        public_key: PublicKey,
18    },
19    Bundle {
20        public_keys: HashMap<PublicKey, Vec<u8>>,
21    },
22    #[default]
23    None,
24}
25
26impl RecipientCarrier {
27    fn recipients(&self) -> Vec<PublicKey> {
28        match self {
29            RecipientCarrier::Direct { public_key } => vec![*public_key],
30            RecipientCarrier::Bundle { public_keys } => {
31                public_keys.keys().copied().collect::<Vec<_>>()
32            }
33            RecipientCarrier::None => vec![],
34        }
35    }
36
37    fn is_none(&self) -> bool {
38        matches!(self, RecipientCarrier::None)
39    }
40}
41
42pub trait ToSeal {
43    /// Consume and encrypt a [`serde::Serialize`] compatible type and return a [`Package`] along with a generated [`PrivateKey`]
44    fn seal(self) -> Result<(PrivateKey, Package<Self>)>;
45}
46
47pub trait ToSealRef {
48    /// Borrow and encrypt a [`serde::Serialize`] compatible type and return a [`Package`] along with a generated [`PrivateKey`]
49    fn seal(&self) -> Result<(PrivateKey, Package<Self>)>;
50}
51
52pub trait ToSealWithKey {
53    /// Consume and encrypt a [`serde::Serialize`] compatible type with the supplied [`PrivateKey`] and return a [`Package`]
54    fn seal(self, private_key: &PrivateKey) -> Result<Package<Self>>;
55}
56
57pub trait ToSealRefWithKey {
58    /// Borrow and encrypt a [`serde::Serialize`] compatible type with the supplied [`PrivateKey`] and return a [`Package`]
59    fn seal(&self, private_key: &PrivateKey) -> Result<Package<Self>>;
60}
61
62pub trait ToSealWithSharedKey {
63    /// Consume and encrypt a [`serde::Serialize`] compatible type with a [`PrivateKey`] using the multiple [`PublicKey`] and return a [`Package`]
64    fn seal(self, private_key: &PrivateKey, public_key: Vec<PublicKey>) -> Result<Package<Self>>;
65}
66
67pub trait ToSealRefWithSharedKey {
68    /// Borrow and encrypt a [`serde::Serialize`] compatible type with a [`PrivateKey`] using the multiple [`PublicKey`] and return a [`Package`]
69    fn seal(&self, private_key: &PrivateKey, public_key: Vec<PublicKey>) -> Result<Package<Self>>;
70}
71
72pub trait ToOpen<T> {
73    /// Decrypts [`Package`] using [`PrivateKey`] and returns defined type
74    fn open(&self, key: &PrivateKey) -> Result<T>;
75}
76
77pub trait ToOpenWithPublicKey<T> {
78    /// Decrypts [`Package`] using [`PrivateKey`] and internal [`PublicKey`] and returns defined type
79    fn open(&self, key: &PrivateKey) -> Result<T>;
80}
81
82pub trait ToOpenWithSharedKey<T> {
83    /// Decrypts [`Package`] using [`PrivateKey`] using the recipient [`PublicKey`] and returns defined type
84    fn open(&self, key: &PrivateKey, public_key: &PublicKey) -> Result<T>;
85}
86
87#[derive(Default, Deserialize, Serialize, Clone, PartialEq, Eq, Debug)]
88pub struct Package<T: ?Sized> {
89    data: Vec<u8>,
90    #[serde(skip_serializing_if = "Vec::is_empty")]
91    signature: Vec<u8>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    public_key: Option<PublicKey>,
94    #[serde(default, skip_serializing_if = "RecipientCarrier::is_none")]
95    recipients: RecipientCarrier,
96    #[serde(skip_serializing, skip_deserializing)]
97    marker: PhantomData<T>,
98}
99
100impl<T> Package<T>
101where
102    T: Serialize + DeserializeOwned + Clone,
103{
104    pub fn import(
105        data: Vec<u8>,
106        public_key: Option<PublicKey>,
107        recipients: RecipientCarrier,
108        signature: Option<Vec<u8>>,
109    ) -> Self {
110        let signature = signature.unwrap_or_default();
111        Self {
112            data,
113            signature,
114            public_key,
115            recipients,
116            marker: PhantomData,
117        }
118    }
119
120    pub fn from_bytes<A: AsRef<[u8]>>(data: A) -> Result<Self> {
121        serde_json::from_slice(data.as_ref()).map_err(Error::from)
122    }
123
124    pub fn to_bytes(&self) -> Result<Vec<u8>> {
125        serde_json::to_vec(self).map_err(Error::from)
126    }
127}
128
129impl<T> Package<T> {
130    pub fn has_recipient(&self, public_key: &PublicKey) -> bool {
131        let list = self.recipients();
132        list.contains(public_key)
133    }
134
135    pub fn recipients(&self) -> Vec<PublicKey> {
136        self.recipients.recipients()
137    }
138}
139
140impl<T> ToSeal for T
141where
142    T: Serialize + Default,
143{
144    fn seal(self) -> Result<(PrivateKey, Package<T>)> {
145        ToSealRef::seal(&self)
146    }
147}
148
149impl<T> ToSealRef for T
150where
151    T: Serialize + Default,
152{
153    fn seal(&self) -> Result<(PrivateKey, Package<T>)> {
154        let private_key = PrivateKey::new();
155        let package = ToSealRefWithKey::seal(self, &private_key)?;
156        Ok((private_key, package))
157    }
158}
159
160impl<T> ToSealWithKey for T
161where
162    T: Serialize + Default,
163{
164    fn seal(self, private_key: &PrivateKey) -> Result<Package<T>> {
165        ToSealRefWithKey::seal(&self, private_key)
166    }
167}
168
169impl<T> ToSealRefWithKey for T
170where
171    T: Serialize + Default,
172{
173    fn seal(&self, private_key: &PrivateKey) -> Result<Package<T>> {
174        let mut package = Package::default();
175        let inner_data = serde_json::to_vec(self)?;
176        package.signature = private_key.sign(&inner_data)?;
177        package.data = private_key.encrypt(&inner_data, Default::default())?;
178        if let Ok(public_key) = private_key.public_key() {
179            package.public_key = Some(public_key)
180        }
181        Ok(package)
182    }
183}
184
185impl<T> ToSealWithSharedKey for T
186where
187    T: Serialize + Default,
188{
189    fn seal(self, private_key: &PrivateKey, public_key: Vec<PublicKey>) -> Result<Package<T>> {
190        ToSealRefWithSharedKey::seal(&self, private_key, public_key)
191    }
192}
193
194impl<T> ToSealRefWithSharedKey for T
195where
196    T: Serialize + Default,
197{
198    fn seal(&self, private_key: &PrivateKey, public_key: Vec<PublicKey>) -> Result<Package<T>> {
199        let mut package = Package::default();
200        let inner_data = serde_json::to_vec(self)?;
201        let sig = private_key.sign(&inner_data)?;
202        let ptype = private_key.public_key()?.key_type();
203        let key: [u8; 32] = key::generate::<32>().as_slice().try_into()?;
204        let data = private_key.encrypt(&inner_data, key::CarrierKeyType::Direct { key })?;
205
206        package.data = data;
207        package.signature = sig;
208        package.recipients = RecipientCarrier::Bundle {
209            public_keys: HashMap::from_iter(
210                public_key
211                    .iter()
212                    .filter(|public_key| public_key.key_type() == ptype)
213                    .filter_map(|public_key| {
214                        private_key
215                            .encrypt(
216                                &key,
217                                key::CarrierKeyType::Exchange {
218                                    public_key: *public_key,
219                                },
220                            )
221                            .map(|data| (*public_key, data))
222                            .ok()
223                    }),
224            ),
225        };
226        package.public_key = Some(private_key.public_key()?);
227        Ok(package)
228    }
229}
230
231impl<T> ToOpen<T> for Package<T>
232where
233    T: DeserializeOwned,
234{
235    fn open(&self, key: &PrivateKey) -> Result<T> {
236        let data = key.decrypt(&self.data, Default::default())?;
237        key.verify(&data, &self.signature)?;
238        serde_json::from_slice(&data).map_err(Error::from)
239    }
240}
241
242impl<T> ToOpenWithPublicKey<T> for Package<T>
243where
244    T: DeserializeOwned,
245{
246    fn open(&self, key: &PrivateKey) -> Result<T> {
247        let own_pk = key.public_key()?;
248        if !self.has_recipient(&own_pk) {
249            return Err(Error::InvalidPublickey);
250        }
251
252        let pk = self.public_key.as_ref().ok_or(Error::InvalidPublickey)?;
253
254        let enc_k = match &self.recipients {
255            RecipientCarrier::Bundle { public_keys } => {
256                public_keys.get(&own_pk).expect("recipient available")
257            }
258            _ => return Err(Error::RecipientsNotAvailable),
259        };
260
261        let en_key = key.decrypt(enc_k, key::CarrierKeyType::Exchange { public_key: *pk })?;
262
263        let data = key.decrypt(
264            &self.data,
265            key::CarrierKeyType::Direct {
266                key: en_key.as_slice().try_into()?,
267            },
268        )?;
269
270        pk.verify(&data, &self.signature)?;
271
272        serde_json::from_slice(&data).map_err(Error::from)
273    }
274}