pg_core/lib.rs
1#![doc = include_str!("../README.md")]
2#![no_std]
3#![doc(
4 html_favicon_url = "https://postguard.eu/favicon.ico",
5 html_logo_url = "https://postguard.eu/pg_logo_no_text.svg"
6)]
7#![deny(
8 missing_debug_implementations,
9 rust_2018_idioms,
10 missing_docs,
11 rustdoc::broken_intra_doc_links,
12 unsafe_code
13)]
14#![cfg_attr(docsrs, feature(doc_cfg))]
15//! ### Setting up the encryption parameters
16//!
17//! The public key and user secret keys for encryption can be retrieved from the Private Key
18//! Generator (PKG).
19//!
20//! ```rust
21//! use std::time::SystemTime;
22//! use pg_core::identity::{Attribute, Policy, EncryptionPolicy};
23//!
24//! let timestamp = SystemTime::now()
25//! .duration_since(SystemTime::UNIX_EPOCH)
26//! .unwrap()
27//! .as_secs();
28//!
29//! let id1 = String::from("Bob");
30//! let id2 = String::from("Charlie");
31//!
32//! let p1 = Policy {
33//! timestamp,
34//! con: vec![Attribute::new(
35//! "pbdf.gemeente.personalData.bsn",
36//! Some("123bob789"),
37//! )],
38//! };
39//!
40//! let p2 = Policy {
41//! timestamp,
42//! con: vec![
43//! Attribute::new("pbdf.gemeente.personalData.name", Some("Charlie")),
44//! Attribute::new("pbdf.sidn-pbdf.email.email", Some("charlie@example.com")),
45//! ],
46//! };
47//!
48//! let policy = EncryptionPolicy::from([(id1, p1), (id2, p2)]);
49//! ```
50//!
51//! This will specify two recipients who can decrypt, in this case identified by their e-mail
52//! address, but this identifier can be anything which uniquely represents a receiver. The
53//! recipients are only able to decrypt if they are able to prove the that they own the attributes
54//! specified in the `con` field.
55//!
56//! ### Seal a slice using the Rust Crypto backend
57//!
58//! ```rust
59//! use pg_core::client::rust::{SealerMemoryConfig, UnsealerMemoryConfig};
60//! use pg_core::client::{Sealer, Unsealer};
61//! # use pg_core::error::Error;
62//! use pg_core::test::TestSetup;
63//!
64//! # fn main() -> Result<(), Error> {
65//! let mut rng = rand::thread_rng();
66//! # let TestSetup {
67//! # ibe_pk,
68//! # ibs_pk,
69//! # policies,
70//! # usks,
71//! # signing_keys,
72//! # policy,
73//! # ..
74//! # } = TestSetup::new(&mut rng);
75//! # let signing_key = &signing_keys[0];
76//! # let id = "Bob";
77//! # let usk = &usks[2];
78//!
79//! // Sender: retrieve public key, setup policy and signing keys.
80//!
81//! let input = b"SECRET DATA";
82//! let sealed = Sealer::<_, SealerMemoryConfig>::new(&ibe_pk, &policy, &signing_key, &mut rng)?
83//! .seal(input)?;
84//!
85//! // Receiver: retrieve USK and verifying key.
86//!
87//! let (original, verified_sender_id) =
88//! Unsealer::<_, UnsealerMemoryConfig>::new(sealed, &ibs_pk)?.unseal(id, &usk)?;
89//!
90//! assert_eq!(&input.to_vec(), &original);
91//!
92//! assert_eq!(&verified_sender_id.public, &signing_key.policy);
93//! assert_eq!(verified_sender_id.private, None);
94//! # Ok(())
95//! # }
96//! ```
97//!
98#![cfg_attr(
99 feature = "stream",
100 doc = r##"
101 ### Seal a bytestream using the Rust Crypto backend
102
103 ```rust
104 use pg_core::client::rust::stream::{SealerStreamConfig, UnsealerStreamConfig};
105 use pg_core::client::{Sealer, Unsealer};
106 # use pg_core::error::Error;
107 use pg_core::test::TestSetup;
108
109 use futures::io::Cursor;
110
111 # #[tokio::main]
112 # async fn main() -> Result<(), Error> {
113 let mut rng = rand::thread_rng();
114 # let setup = TestSetup::new(&mut rng);
115 # let signing_key = &setup.signing_keys[0];
116 # let vk = setup.ibs_pk;
117 # let usk = &setup.usks[2];
118 let mut input = Cursor::new(b"SECRET DATA");
119 let mut sealed = Vec::new();
120
121 Sealer::<_, SealerStreamConfig>::new(
122 &setup.ibe_pk,
123 &setup.policy,
124 &signing_key,
125 &mut rng,
126 )?
127 .seal(&mut input, &mut sealed)
128 .await?;
129
130 let mut original = Vec::new();
131 let policy = Unsealer::<_, UnsealerStreamConfig>::new(&mut Cursor::new(sealed), &vk)
132 .await?
133 .unseal("Bob", &usk, &mut original)
134 .await?;
135
136 assert_eq!(input.into_inner().to_vec(), original);
137 assert_eq!(&policy.public, &signing_key.policy);
138 assert_eq!(policy.private, None);
139 # Ok(())
140 # }
141 ```
142"##
143)]
144//!
145//! ### Using the Web Crypto backend
146//!
147//! Using the Web Crypto backend in Rust can be useful in Rust web frameworks (e.g.,
148//! Yew/Dioxus/Leptos). For use in JavaScript/TypeScript, there is a seperate NPM package called
149//! [`pg-wasm`](https://www.npmjs.com/package/@e4a/pg-wasm) which offers an FFI interface generated by `wasm-pack`.
150//! See its documentation for examples.
151//!
152//! ### Wire format
153//!
154//! The wire format consists of the following segments, followed by their length in bytes:
155//!
156//! ```text
157//! PREAMBLE (10)
158//! = PRELUDE (4) || VERSION (2) || HEADER LEN (4)
159//!
160//! HEADER (*)
161//! = HEADER (*) || HEADER SIG LEN (4) || HEADER SIG (*)
162//!
163//! PAYLOAD (*)
164//! = DEM.Enc(M (*) || STREAM SIG (*) || STREAM SIG LEN (4))
165//! ```
166
167#[cfg(test)]
168extern crate std;
169
170// We depend on alloc for String, Vec and BTreeMap/HashMap.
171#[macro_use]
172extern crate alloc;
173
174pub mod api;
175pub mod artifacts;
176pub mod consts;
177pub mod error;
178pub mod identity;
179
180#[cfg(any(feature = "rust", feature = "web"))]
181pub mod client;
182
183#[doc(hidden)]
184pub use ibe::{kem, Compress};
185
186#[doc(hidden)]
187pub use ibs;
188
189#[doc(hidden)]
190pub use consts::*;
191
192#[cfg(feature = "test")]
193pub mod test;
194
195mod util;