biscuit_auth/token/
third_party.rs1use ed25519_dalek::Signer;
2use prost::Message;
3
4use crate::{
5 builder::BlockBuilder,
6 crypto::PublicKey,
7 datalog::SymbolTable,
8 error,
9 format::{convert::token_block_to_proto_block, schema, SerializedBiscuit},
10 KeyPair, PrivateKey,
11};
12
13#[derive(Debug)]
15pub struct ThirdPartyRequest {
16 pub(crate) previous_key: PublicKey,
17}
18
19impl ThirdPartyRequest {
20 pub(crate) fn from_container(
21 container: &SerializedBiscuit,
22 ) -> Result<ThirdPartyRequest, error::Token> {
23 if container.proof.is_sealed() {
24 return Err(error::Token::AppendOnSealed);
25 }
26
27 let previous_key = container
28 .blocks
29 .last()
30 .unwrap_or(&container.authority)
31 .next_key;
32
33 Ok(ThirdPartyRequest { previous_key })
34 }
35
36 pub fn serialize(&self) -> Result<Vec<u8>, error::Token> {
37 let previous_key = self.previous_key.to_proto();
38
39 let request = schema::ThirdPartyBlockRequest {
40 previous_key,
41 public_keys: Vec::new(),
42 };
43 let mut v = Vec::new();
44
45 request.encode(&mut v).map(|_| v).map_err(|e| {
46 error::Token::Format(error::Format::SerializationError(format!(
47 "serialization error: {:?}",
48 e
49 )))
50 })
51 }
52
53 pub fn serialize_base64(&self) -> Result<String, error::Token> {
54 Ok(base64::encode_config(self.serialize()?, base64::URL_SAFE))
55 }
56
57 pub fn deserialize(slice: &[u8]) -> Result<Self, error::Token> {
58 let data = schema::ThirdPartyBlockRequest::decode(slice).map_err(|e| {
59 error::Format::DeserializationError(format!("deserialization error: {:?}", e))
60 })?;
61
62 let previous_key = PublicKey::from_proto(&data.previous_key)?;
63
64 if !data.public_keys.is_empty() {
65 return Err(error::Token::Format(error::Format::DeserializationError(
66 "public keys were provided in third-party block request".to_owned(),
67 )));
68 }
69
70 Ok(ThirdPartyRequest { previous_key })
71 }
72
73 pub fn deserialize_base64<T>(slice: T) -> Result<Self, error::Token>
74 where
75 T: AsRef<[u8]>,
76 {
77 let decoded = base64::decode_config(slice, base64::URL_SAFE)?;
78 Self::deserialize(&decoded)
79 }
80
81 pub fn create_block(
83 self,
84 private_key: &PrivateKey,
85 block_builder: BlockBuilder,
86 ) -> Result<ThirdPartyBlock, error::Token> {
87 let symbols = SymbolTable::new();
88 let mut block = block_builder.build(symbols);
89 block.version = super::MAX_SCHEMA_VERSION;
90
91 let mut v = Vec::new();
92 token_block_to_proto_block(&block)
93 .encode(&mut v)
94 .map_err(|e| {
95 error::Format::SerializationError(format!("serialization error: {:?}", e))
96 })?;
97 let payload = v.clone();
98
99 v.extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
100 v.extend(self.previous_key.to_bytes());
101
102 let keypair = KeyPair::from(private_key);
103 let signature = keypair
104 .kp
105 .try_sign(&v)
106 .map_err(|s| s.to_string())
107 .map_err(error::Signature::InvalidSignatureGeneration)
108 .map_err(error::Format::Signature)?;
109
110 let public_key = keypair.public();
111 let content = schema::ThirdPartyBlockContents {
112 payload,
113 external_signature: schema::ExternalSignature {
114 signature: signature.to_bytes().to_vec(),
115 public_key: public_key.to_proto(),
116 },
117 };
118
119 Ok(ThirdPartyBlock(content))
120 }
121}
122
123#[derive(Clone, Debug)]
128pub struct ThirdPartyBlock(pub(crate) schema::ThirdPartyBlockContents);
129
130impl ThirdPartyBlock {
131 pub fn serialize(&self) -> Result<Vec<u8>, error::Token> {
132 let mut buffer = vec![];
133 self.0.encode(&mut buffer).map(|_| buffer).map_err(|e| {
134 error::Token::Format(error::Format::SerializationError(format!(
135 "serialization error: {:?}",
136 e
137 )))
138 })
139 }
140
141 pub fn serialize_base64(&self) -> Result<String, error::Token> {
142 Ok(base64::encode_config(self.serialize()?, base64::URL_SAFE))
143 }
144}