pg_core/client/
mod.rs

1//! PostGuard client API.
2//!
3//! Used for:
4//! - Encrypting, signing, packing metadata (*sealing*),
5//! - Decrypting, verifying, unpacking metadata (*unsealing*).
6
7mod header;
8
9pub use header::{Algorithm, Header, Mode, RecipientHeader};
10
11#[cfg(feature = "rust")]
12pub mod rust;
13
14#[cfg(feature = "web")]
15pub mod web;
16
17use crate::artifacts::VerifyingKey;
18use crate::identity::Policy;
19use crate::util::*;
20use crate::{artifacts::SigningKeyExt, consts::*};
21use header::SignatureExt;
22use ibs::gg::Verifier;
23use serde::{Deserialize, Serialize};
24
25/// A Sealer is used to encrypt and sign data using PostGuard.
26#[derive(Debug)]
27pub struct Sealer<'r, R, C> {
28    // The prebuilt header.
29    header: Header,
30
31    // An exclusive reference to a random number generator.
32    rng: &'r mut R,
33
34    // The flavor-specific configuration.
35    config: C,
36
37    // The public signing key. Used to sign public data, such as the header.
38    // The signature and claims are visible to outsiders.
39    pub_sign_key: SigningKeyExt,
40
41    // An optional private signing key.
42    // The signature and claims are encrypted and not visible to outsiders.
43    priv_sign_key: Option<SigningKeyExt>,
44}
45
46impl<'r, R, C> Sealer<'r, R, C> {
47    /// Add a private signing key and policy.
48    ///
49    /// This policy is safe to include private data as it is encrypted after signing.
50    pub fn with_priv_signing_key(mut self, priv_sign_key: SigningKeyExt) -> Self {
51        self.priv_sign_key = Some(priv_sign_key);
52        self
53    }
54}
55
56/// An Unsealer is used to decrypt and verify data using PostGuard.
57///
58/// Unsealing is a two-step process:
59///
60/// 1. First the header is read. This yields information for whom the message is encrypted. Using
61///    this information the user can retrieve a user secret key.
62///
63/// 2. Then, the user has input the user secret key and the recipient for which decryption should
64///    take place.
65#[derive(Debug)]
66pub struct Unsealer<R, C: UnsealerConfig> {
67    /// The version found before the raw header.
68    pub version: u16,
69
70    /// The parsed header.
71    pub header: Header,
72
73    /// The verified public identity which was used to sign the header.
74    pub pub_id: Policy,
75
76    // The input.
77    r: R,
78
79    // The implementation-specific configuration.
80    config: C,
81
82    // The message verifier.
83    verifier: Verifier,
84
85    // The message verifier key.
86    vk: VerifyingKey,
87}
88
89/// Sender verification result.
90#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
91pub struct VerificationResult {
92    /// The public signing verified claims.
93    pub public: Policy,
94
95    /// The private signing verified claims.
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub private: Option<Policy>,
98}
99
100/// Sealer configuration.
101///
102/// This trait is sealed, you cannot implement it yourself.
103#[doc(hidden)]
104pub trait SealerConfig: sealed::SealerConfig {}
105
106/// Unsealer configuration.
107///
108/// This trait is sealed, you cannot implement it yourself.
109#[doc(hidden)]
110pub trait UnsealerConfig: sealed::UnsealerConfig {}
111
112pub(crate) mod sealed {
113    pub trait UnsealerConfig {}
114    pub trait SealerConfig {}
115}
116
117#[cfg(any(feature = "stream", target_arch = "wasm32"))]
118impl From<futures::io::Error> for crate::error::Error {
119    fn from(e: futures::io::Error) -> Self {
120        Self::FuturesIO(e)
121    }
122}
123
124#[cfg(feature = "stream")]
125pub(self) fn stream_mode_checked(
126    h: &Header,
127) -> Result<(u32, (u64, Option<u64>)), crate::error::Error> {
128    let (segment_size, size_hint) = match h {
129        Header {
130            mode:
131                Mode::Streaming {
132                    segment_size,
133                    size_hint,
134                },
135            ..
136        } => (segment_size, size_hint),
137        _ => return Err(crate::error::Error::ModeNotSupported(h.mode)),
138    };
139
140    if *segment_size > MAX_SYMMETRIC_CHUNK_SIZE {
141        return Err(crate::error::Error::ConstraintViolation);
142    }
143
144    Ok((*segment_size, *size_hint))
145}