warg_protocol/
serde_envelope.rs

1use serde::{Deserialize, Serialize};
2use warg_crypto::{signing, Signable};
3
4#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "camelCase")]
6pub struct SerdeEnvelope<Contents> {
7    /// The content represented by content_bytes
8    contents: Contents,
9    /// The hash of the key that signed this envelope
10    key_id: signing::KeyID,
11    /// The signature for the content_bytes
12    signature: signing::Signature,
13}
14
15impl<Contents> SerdeEnvelope<Contents> {
16    /// Creates a new `SerdeEnvelope` from the given content, key ID, and signature.
17    ///
18    /// Note that this does not verify the signature matches the contents (hence unchecked).
19    pub fn from_parts_unchecked(
20        contents: Contents,
21        key_id: signing::KeyID,
22        signature: signing::Signature,
23    ) -> Self {
24        Self {
25            contents,
26            key_id,
27            signature,
28        }
29    }
30
31    /// Create an envelope for some contents using a signature.
32    pub fn signed_contents(
33        private_key: &signing::PrivateKey,
34        contents: Contents,
35    ) -> Result<Self, signing::SignatureError>
36    where
37        Contents: Signable,
38    {
39        let key_id = private_key.public_key().fingerprint();
40        let signature = contents.sign(private_key)?;
41        Ok(SerdeEnvelope {
42            contents,
43            key_id,
44            signature,
45        })
46    }
47
48    pub fn into_contents(self) -> Contents {
49        self.contents
50    }
51
52    pub fn key_id(&self) -> &signing::KeyID {
53        &self.key_id
54    }
55
56    pub fn signature(&self) -> &signing::Signature {
57        &self.signature
58    }
59}
60
61impl<Content> AsRef<Content> for SerdeEnvelope<Content> {
62    fn as_ref(&self) -> &Content {
63        &self.contents
64    }
65}