1use std::convert::TryInto;
2
3use super::{default_symbol_table, Biscuit, Block};
4use crate::{
5 builder::BlockBuilder,
6 crypto,
7 crypto::PublicKey,
8 datalog::SymbolTable,
9 error,
10 format::{convert::proto_block_to_token_block, schema, SerializedBiscuit},
11 token::{ThirdPartyBlockContents, ThirdPartyRequest},
12 KeyPair, RootKeyProvider,
13};
14use prost::Message;
15
16#[derive(Clone, Debug)]
24pub struct UnverifiedBiscuit {
25 pub(crate) authority: schema::Block,
26 pub(crate) blocks: Vec<schema::Block>,
27 pub(crate) symbols: SymbolTable,
28 container: SerializedBiscuit,
29}
30
31impl UnverifiedBiscuit {
32 pub fn from<T>(slice: T) -> Result<Self, error::Token>
34 where
35 T: AsRef<[u8]>,
36 {
37 Self::from_with_symbols(slice.as_ref(), default_symbol_table())
38 }
39
40 pub fn from_base64<T>(slice: T) -> Result<Self, error::Token>
42 where
43 T: AsRef<[u8]>,
44 {
45 Self::from_base64_with_symbols(slice, default_symbol_table())
46 }
47
48 #[deprecated(since = "4.1.0", note = "please use `verify` instead")]
49 pub fn check_signature<F>(self, f: F) -> Result<Biscuit, error::Format>
51 where
52 F: Fn(Option<u32>) -> PublicKey,
53 {
54 self.verify(|kid| Ok(f(kid)))
55 }
56
57 pub fn verify<KP>(self, key_provider: KP) -> Result<Biscuit, error::Format>
59 where
60 KP: RootKeyProvider,
61 {
62 let key = key_provider.choose(self.root_key_id())?;
63 self.container.verify(&key)?;
64
65 Ok(Biscuit {
66 root_key_id: self.container.root_key_id,
67 authority: self.authority,
68 blocks: self.blocks,
69 symbols: self.symbols,
70 container: self.container,
71 })
72 }
73
74 pub fn append(&self, block_builder: BlockBuilder) -> Result<Self, error::Token> {
79 let keypair = KeyPair::new_with_rng(&mut rand::rngs::OsRng);
80 self.append_with_keypair(&keypair, block_builder)
81 }
82
83 pub fn to_vec(&self) -> Result<Vec<u8>, error::Token> {
85 self.container.to_vec().map_err(error::Token::Format)
86 }
87
88 pub fn to_base64(&self) -> Result<String, error::Token> {
90 self.container
91 .to_vec()
92 .map_err(error::Token::Format)
93 .map(|v| base64::encode_config(v, base64::URL_SAFE))
94 }
95
96 pub fn from_with_symbols(slice: &[u8], mut symbols: SymbolTable) -> Result<Self, error::Token> {
98 let container = SerializedBiscuit::deserialize(slice)?;
99
100 let (authority, blocks) = container.extract_blocks(&mut symbols)?;
101
102 Ok(UnverifiedBiscuit {
103 authority,
104 blocks,
105 symbols,
106 container,
107 })
108 }
109
110 pub fn from_base64_with_symbols<T>(slice: T, symbols: SymbolTable) -> Result<Self, error::Token>
112 where
113 T: AsRef<[u8]>,
114 {
115 let decoded = base64::decode_config(slice, base64::URL_SAFE)?;
116 Self::from_with_symbols(&decoded, symbols)
117 }
118
119 pub fn append_with_keypair(
124 &self,
125 keypair: &KeyPair,
126 block_builder: BlockBuilder,
127 ) -> Result<Self, error::Token> {
128 let block = block_builder.build(self.symbols.clone());
129
130 if !self.symbols.is_disjoint(&block.symbols) {
131 return Err(error::Token::Format(error::Format::SymbolTableOverlap));
132 }
133
134 let authority = self.authority.clone();
135 let mut blocks = self.blocks.clone();
136 let mut symbols = self.symbols.clone();
137
138 let container = self.container.append(keypair, &block, None)?;
139
140 symbols.extend(&block.symbols)?;
141 symbols.public_keys.extend(&block.public_keys)?;
142
143 let deser = schema::Block::decode(
144 &container
145 .blocks
146 .last()
147 .expect("a new block was just added so the list is not empty")
148 .data[..],
149 )
150 .map_err(|e| {
151 error::Token::Format(error::Format::BlockDeserializationError(format!(
152 "error deserializing block: {:?}",
153 e
154 )))
155 })?;
156 blocks.push(deser);
157
158 Ok(UnverifiedBiscuit {
159 authority,
160 blocks,
161 symbols,
162 container,
163 })
164 }
165
166 pub fn root_key_id(&self) -> Option<u32> {
168 self.container.root_key_id
169 }
170
171 pub fn revocation_identifiers(&self) -> Vec<Vec<u8>> {
176 let mut res = vec![self.container.authority.signature.to_bytes().to_vec()];
177
178 for block in self.container.blocks.iter() {
179 res.push(block.signature.to_bytes().to_vec());
180 }
181
182 res
183 }
184
185 pub fn external_public_keys(&self) -> Vec<Option<Vec<u8>>> {
191 let mut res = vec![None];
192
193 for block in self.container.blocks.iter() {
194 res.push(
195 block
196 .external_signature
197 .as_ref()
198 .map(|sig| sig.public_key.to_bytes().to_vec()),
199 );
200 }
201
202 res
203 }
204
205 pub fn block_count(&self) -> usize {
207 1 + self.container.blocks.len()
208 }
209
210 pub fn print_block_source(&self, index: usize) -> Result<String, error::Token> {
212 self.block(index).map(|block| {
213 let symbols = if block.external_key.is_some() {
214 &block.symbols
215 } else {
216 &self.symbols
217 };
218 block.print_source(symbols)
219 })
220 }
221
222 pub(crate) fn block(&self, index: usize) -> Result<Block, error::Token> {
223 let mut block = if index == 0 {
224 proto_block_to_token_block(
225 &self.authority,
226 self.container
227 .authority
228 .external_signature
229 .as_ref()
230 .map(|ex| ex.public_key),
231 )
232 .map_err(error::Token::Format)?
233 } else {
234 if index > self.blocks.len() + 1 {
235 return Err(error::Token::Format(
236 error::Format::BlockDeserializationError("invalid block index".to_string()),
237 ));
238 }
239
240 proto_block_to_token_block(
241 &self.blocks[index - 1],
242 self.container.blocks[index - 1]
243 .external_signature
244 .as_ref()
245 .map(|ex| ex.public_key),
246 )
247 .map_err(error::Token::Format)?
248 };
249
250 block.symbols.public_keys = self.symbols.public_keys.clone();
253 Ok(block)
254 }
255
256 pub fn seal(&self) -> Result<UnverifiedBiscuit, error::Token> {
260 let container = self.container.seal()?;
261 let mut token = self.clone();
262 token.container = container;
263 Ok(token)
264 }
265
266 pub fn third_party_request(&self) -> Result<ThirdPartyRequest, error::Token> {
267 ThirdPartyRequest::from_container(&self.container)
268 }
269
270 pub fn append_third_party(&self, slice: &[u8]) -> Result<Self, error::Token> {
271 let next_keypair = KeyPair::new_with_rng(&mut rand::rngs::OsRng);
272
273 let ThirdPartyBlockContents {
274 payload,
275 external_signature,
276 } = schema::ThirdPartyBlockContents::decode(slice).map_err(|e| {
277 error::Format::DeserializationError(format!("deserialization error: {:?}", e))
278 })?;
279
280 if external_signature.public_key.algorithm != schema::public_key::Algorithm::Ed25519 as i32
281 {
282 return Err(error::Token::Format(error::Format::DeserializationError(
283 format!(
284 "deserialization error: unexpected key algorithm {}",
285 external_signature.public_key.algorithm
286 ),
287 )));
288 }
289 let external_key =
290 PublicKey::from_bytes(&external_signature.public_key.key).map_err(|e| {
291 error::Format::BlockSignatureDeserializationError(format!(
292 "block external public key deserialization error: {:?}",
293 e
294 ))
295 })?;
296
297 let bytes: [u8; 64] = (&external_signature.signature[..])
298 .try_into()
299 .map_err(|_| error::Format::InvalidSignatureSize(external_signature.signature.len()))?;
300
301 let signature = ed25519_dalek::Signature::from_bytes(&bytes);
302 let previous_key = self
303 .container
304 .blocks
305 .last()
306 .unwrap_or(&self.container.authority)
307 .next_key;
308 let mut to_verify = payload.clone();
309 to_verify
310 .extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
311 to_verify.extend(&previous_key.to_bytes());
312
313 let block = schema::Block::decode(&payload[..]).map_err(|e| {
314 error::Token::Format(error::Format::DeserializationError(format!(
315 "deserialization error: {:?}",
316 e
317 )))
318 })?;
319
320 let external_signature = crypto::ExternalSignature {
321 public_key: external_key,
322 signature,
323 };
324
325 let mut symbols = self.symbols.clone();
326 let mut blocks = self.blocks.clone();
327
328 let container =
329 self.container
330 .append_serialized(&next_keypair, payload, Some(external_signature))?;
331
332 let token_block = proto_block_to_token_block(&block, Some(external_key)).unwrap();
333 for key in &token_block.public_keys.keys {
334 symbols.public_keys.insert_fallible(key)?;
335 }
336
337 blocks.push(block);
338
339 Ok(UnverifiedBiscuit {
340 authority: self.authority.clone(),
341 blocks,
342 symbols,
343 container,
344 })
345 }
346
347 pub fn append_third_party_base64<T>(&self, slice: T) -> Result<Self, error::Token>
348 where
349 T: AsRef<[u8]>,
350 {
351 let decoded = base64::decode_config(slice, base64::URL_SAFE)?;
352 self.append_third_party(&decoded)
353 }
354}