ironoxide/crypto/
transform.rs1use crate::internal::{
2 IronOxideErr, PublicKey, WithKey,
3 document_api::{DocAccessEditErr, UserOrGroup},
4};
5use itertools::{Either, Itertools};
6use recrypt::{
7 api::{DerivedSymmetricKey, EncryptedValue, Plaintext, PrivateKey, RecryptErr},
8 prelude::*,
9};
10
11pub fn generate_new_doc_key<CR: rand::CryptoRng + rand::RngCore>(
13 recrypt: &Recrypt<Sha256, Ed25519, RandomBytes<CR>>,
14) -> (Plaintext, DerivedSymmetricKey) {
15 let dek = recrypt.gen_plaintext();
16 let symmetric_key = recrypt.derive_symmetric_key(&dek);
17 (dek, symmetric_key)
18}
19
20pub fn gen_group_keys<R: CryptoOps + KeyGenOps>(
22 recrypt: &R,
23) -> Result<(Plaintext, PrivateKey, PublicKey), IronOxideErr> {
24 let plaintext = recrypt.gen_plaintext();
25 let priv_key = recrypt.derive_private_key(&plaintext);
26 let pub_key = recrypt.compute_public_key(&priv_key)?;
27 Ok((plaintext, priv_key, pub_key.into()))
28}
29
30pub fn decrypt_as_symmetric_key<CR: rand::CryptoRng + rand::RngCore>(
32 recrypt: &Recrypt<Sha256, Ed25519, RandomBytes<CR>>,
33 encrypted_plaintext: EncryptedValue,
34 user_device_private_key: &PrivateKey,
35) -> Result<DerivedSymmetricKey, IronOxideErr> {
36 let plaintext = recrypt.decrypt(encrypted_plaintext, user_device_private_key)?;
37 let symmetric_key = recrypt.derive_symmetric_key(&plaintext);
38 Ok(symmetric_key)
39}
40
41pub fn decrypt_as_private_key<CR: rand::CryptoRng + rand::RngCore>(
44 recrypt: &Recrypt<Sha256, Ed25519, RandomBytes<CR>>,
45 encrypted_plaintext: EncryptedValue,
46 user_device_private_key: &PrivateKey,
47) -> Result<(Plaintext, PrivateKey), IronOxideErr> {
48 let plaintext = recrypt.decrypt(encrypted_plaintext, user_device_private_key)?;
49 let private_key = recrypt.derive_private_key(&plaintext);
50 Ok((plaintext, private_key))
51}
52
53pub fn encrypt_to_with_key<T, CR: rand::CryptoRng + rand::RngCore>(
56 recrypt: &Recrypt<Sha256, Ed25519, RandomBytes<CR>>,
57 plaintext: &recrypt::api::Plaintext,
58 signing_keys: &recrypt::api::SigningKeypair,
59 with_keys: Vec<WithKey<T>>,
60) -> (
61 Vec<(WithKey<T>, recrypt::api::RecryptErr)>,
62 Vec<(WithKey<T>, recrypt::api::EncryptedValue)>,
63) {
64 let enc_results_iter = with_keys.into_iter().map(move |key_entry| {
66 let enc_result = recrypt.encrypt(
67 plaintext,
68 &key_entry.public_key.clone().into(),
69 signing_keys,
70 );
71 match enc_result {
72 Ok(recrypt_transform_key) => Either::Right((key_entry, recrypt_transform_key)),
73 Err(e) => Either::Left((key_entry, e)),
74 }
75 });
76 enc_results_iter.partition_map(std::convert::identity)
79}
80impl From<(WithKey<UserOrGroup>, RecryptErr)> for DocAccessEditErr {
81 fn from((user_or_group, err): (WithKey<UserOrGroup>, RecryptErr)) -> Self {
82 let WithKey { id, .. } = user_or_group;
83 DocAccessEditErr::new(id, format!("Access grant failed with error {err}"))
84 }
85}