Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["biscuit-auth", "biscuit-quote", "biscuit-parser", "biscuit-capi"]
members = ["biscuit-auth", "biscuit-proto", "biscuit-quote", "biscuit-parser", "biscuit-capi"]
resolver = "2"

# Used by capi crate
Expand Down
10 changes: 9 additions & 1 deletion biscuit-auth/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
- `Term` implements `From<Uuid>` with the `uuid` feature.
- Scope parameters are `Into<PublicKeyData>` so they can take anything which can be converted into a
public key (including `&K: SerializePublicKey`).
- `Authorizer` gains inspection methods that don't require going through a snapshot:
`dump_facts_with_origins`, `dump_rules_with_origins`, `dump_checks_with_origins` and
`dump_policies`

## Breaking changes

- `KeyPair` is removed; use `PrivateKey` directly instead of `KeyPair`. APIs that previously took a
keypair are replaced with APIs that take a `PrivateKey` (i.e. `append_with_keypair` ->
`append_with_key`, `append_third_party_with_keypair` -> `append_third_party_with_key`).
- `Biscuit` and `UnverifiedBiscuit` are generic over the private key type contained in their
proof. These are defaulted to `PrivateKey`, so this change should be transparent for most users
proof. These are defaulted to `PrivateKey`, so this change should be transpfarent for most users
who use the default crypto types.
- `RootKeyProvider` has an associated `Key` type, which is the type of the root key that is
provided.
Expand All @@ -26,6 +29,11 @@
for custom types should implement `From<MyType> for Term` instead.
- The `set_macro_param` and `set_macro_scope_param` methods are removed; macros now call
`set_lenient` and `set_scope_lenient`.
- Protobuf generated code is no longer part of the public API of this crate. The protobuf generated
schema is now available at the crate `biscuit-proto` and versioned independently of
`biscuit-rust`. The `format::schema` and `format::convert` modules are no longer part of the
public API of this crate and the protobuf conversion methods are no longer public. Types can still
be serialized/deserialized to and from their binary representation.

# `6.0.0`

Expand Down
7 changes: 1 addition & 6 deletions biscuit-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version = "6.0.0"
description = "an authorization token with decentralized verification and offline attenuation"
authors = ["Geoffroy Couprie <contact@geoffroycouprie.com>"]
edition = "2018"
build = "build.rs"
license = "Apache-2.0"
documentation = "https://docs.rs/biscuit-auth"
homepage = "https://github.com/biscuit-auth/biscuit"
Expand All @@ -29,7 +28,7 @@ pem = ["ed25519-dalek/pem", "ed25519-dalek/pkcs8"]
rand_core = "^0.6"
sha2 = "^0.9"
prost = "0.10"
prost-types = "0.10"
biscuit-proto = { version = "0.1.0", path = "../biscuit-proto" }
regex = { version = "1.5", default-features = false, features = ["std"] }
nom = { version = "7", default-features = false, features = ["std"] }
hex = "0.4"
Expand Down Expand Up @@ -59,14 +58,10 @@ bencher = "0.1.5"
rand = "0.8"
chrono = { version = "0.4.26", features = ["serde", "clock"] }
colored-diff = "0.2.3"
prost-build = "0.10"
serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.67"
codspeed-bencher-compat = "2.6.0"

#[build-dependencies]
#prost-build = "0.10"

[[example]]
name = "testcases"
required-features = ["serde-error"]
Expand Down
8 changes: 0 additions & 8 deletions biscuit-auth/build.rs

This file was deleted.

115 changes: 22 additions & 93 deletions biscuit-auth/examples/testcases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ extern crate biscuit_auth as biscuit;
use biscuit::builder::BlockBuilder;
use biscuit::datalog::SymbolTable;
use biscuit::error;
use biscuit::format::convert;
use biscuit::macros::*;
use biscuit::public_keys::PublicKeyData;
use biscuit::{builder::*, builder_ext::*, Biscuit};
Expand All @@ -23,12 +22,7 @@ use rand::prelude::*;
use serde::Serialize;
use std::collections::HashMap;
use std::sync::Arc;
use std::{
collections::{BTreeMap, BTreeSet},
fs::File,
io::Write,
time::*,
};
use std::{collections::BTreeMap, fs::File, io::Write, time::*};

fn main() {
let mut args = std::env::args();
Expand Down Expand Up @@ -295,7 +289,7 @@ struct AuthorizerWorld {

#[derive(Debug, Serialize, PartialEq, Eq, PartialOrd, Ord)]
struct Facts {
origin: BTreeSet<Option<usize>>,
origin: Vec<Option<usize>>,
facts: Vec<String>,
}

Expand Down Expand Up @@ -372,102 +366,37 @@ fn validate_token_with_limits_and_external_functions(

let res = authorizer.authorize_with_limits(run_limits);
//println!("authorizer world:\n{}", authorizer.print_world());
let (_, _, _, policies) = authorizer.dump();
let snapshot = authorizer.snapshot().unwrap();

let symbols = SymbolTable::from_symbols_and_public_keys(
snapshot.world.symbols,
snapshot
.world
.public_keys
.iter()
.map(PublicKeyData::from_proto)
.collect(),
)
.unwrap();
let facts_with_origin = authorizer.dump_facts_with_origins();
let rules_with_origin = authorizer.dump_rules_with_origins();
let checks_with_origin = authorizer.dump_checks_with_origins();
let policies = authorizer.dump_policies();

let mut authorizer_facts = Vec::new();
let mut authorizer_rules = Vec::new();
let mut authorizer_checks = Vec::new();
for (i, block) in snapshot.world.blocks.iter().enumerate() {
let mut rules: Vec<String> = Vec::new();
for rule in block.rules.iter() {
let r =
convert::proto_rule_to_token_rule(rule, snapshot.world.version.unwrap()).unwrap();
rules.push(symbols.print_rule(&r.0));
}
if !rules.is_empty() {
rules.sort();
authorizer_rules.push(Rules {
origin: Some(i),
rules,
});
}

let mut checks = Vec::new();
for check in block.checks.iter() {
let c = convert::proto_check_to_token_check(check, snapshot.world.version.unwrap())
.unwrap();
checks.push(symbols.print_check(&c));
}
if !checks.is_empty() {
checks.sort();
authorizer_checks.push(Checks {
origin: Some(i),
checks,
});
}
}

let mut rules: Vec<String> = Vec::new();
for rule in snapshot.world.authorizer_block.rules {
let r = convert::proto_rule_to_token_rule(&rule, snapshot.world.version.unwrap()).unwrap();

rules.push(symbols.print_rule(&r.0));
}
if !rules.is_empty() {
for (origin, rules) in rules_with_origin {
let mut rules: Vec<String> = rules.into_iter().map(|r| r.to_string()).collect();
rules.sort();
authorizer_rules.push(Rules {
origin: Some(usize::MAX),
origin: Some(origin.unwrap_or(usize::MAX)),
rules,
});
}

let mut checks = Vec::new();
for check in snapshot.world.authorizer_block.checks {
let c =
convert::proto_check_to_token_check(&check, snapshot.world.version.unwrap()).unwrap();
checks.push(symbols.print_check(&c));
}
if !checks.is_empty() {
for (origin, checks) in checks_with_origin {
let mut checks: Vec<String> = checks.into_iter().map(|c| c.to_string()).collect();
checks.sort();
authorizer_checks.push(Checks {
origin: Some(usize::MAX),
origin: Some(origin.unwrap_or(usize::MAX)),
checks,
});
}

for factset in snapshot.world.generated_facts {
use biscuit_auth::format::schema::origin::Content;
let mut origin = BTreeSet::new();

for o in factset.origins {
match o.content.unwrap() {
Content::Authorizer(_) => origin.insert(None),
Content::Origin(i) => origin.insert(Some(i as usize)),
};
}

let mut facts = Vec::new();

for fact in factset.facts {
let f = convert::proto_fact_to_token_fact(&fact).unwrap();
facts.push(symbols.print_fact(&f));
}
if !facts.is_empty() {
facts.sort();
authorizer_facts.push(Facts { origin, facts });
}
for (origin, facts) in facts_with_origin {
let mut facts: Vec<String> = facts.into_iter().map(|f| f.to_string()).collect();
facts.sort();
authorizer_facts.push(Facts { origin, facts });
}
authorizer_facts.sort();

Expand Down Expand Up @@ -664,8 +593,8 @@ fn invalid_signature_format(target: &str, root: &PrivateKey, test: bool) -> Test
let data = if test {
load_testcase(target, &filename)
} else {
let serialized = biscuit2.container();
let mut proto = serialized.to_proto();
let serialized = biscuit2.to_vec().unwrap();
let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap();
proto.authority.signature.truncate(16);
let mut data = Vec::new();
proto.encode(&mut data).unwrap();
Expand Down Expand Up @@ -715,8 +644,8 @@ fn random_block(target: &str, root: &PrivateKey, test: bool) -> TestResult {
let data = if test {
load_testcase(target, &filename)
} else {
let serialized = biscuit2.container();
let mut proto = serialized.to_proto();
let serialized = biscuit2.to_vec().unwrap();
let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap();
let arr: [u8; 32] = rng.gen();
proto.blocks[0].block = Vec::from(&arr[..]);
let mut data = Vec::new();
Expand Down Expand Up @@ -767,8 +696,8 @@ fn invalid_signature(target: &str, root: &PrivateKey, test: bool) -> TestResult
let data = if test {
load_testcase(target, &filename)
} else {
let serialized = biscuit2.container();
let mut proto = serialized.to_proto();
let serialized = biscuit2.to_vec().unwrap();
let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap();
proto.authority.signature[0] += 1;
let mut data = Vec::new();
proto.encode(&mut data).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion biscuit-auth/src/crypto/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl PartialEq for PublicKey {

impl Hash for PublicKey {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(crate::format::schema::public_key::Algorithm::Ed25519 as i32).hash(state);
(biscuit_proto::public_key::Algorithm::Ed25519 as i32).hash(state);
self.0.to_bytes().hash(state);
}
}
23 changes: 0 additions & 23 deletions biscuit-auth/src/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use rand_core::{CryptoRng, RngCore};
use zeroize::Zeroizing;

use crate::builder::Algorithm;
use crate::format::schema;
use crate::format::ThirdPartyVerificationMode;

use super::error;
Expand Down Expand Up @@ -308,28 +307,6 @@ impl PublicKey {
Self::from_bytes(&bytes, algorithm)
}

pub fn from_proto(key: &schema::PublicKey) -> Result<Self, error::Format> {
if key.algorithm == schema::public_key::Algorithm::Ed25519 as i32 {
Ok(PublicKey::Ed25519(ed25519::PublicKey::from_bytes(
&key.key,
)?))
} else if key.algorithm == schema::public_key::Algorithm::Secp256r1 as i32 {
Ok(PublicKey::P256(p256::PublicKey::from_bytes(&key.key)?))
} else {
Err(error::Format::DeserializationError(format!(
"deserialization error: unexpected key algorithm {}",
key.algorithm
)))
}
}

pub fn to_proto(&self) -> schema::PublicKey {
schema::PublicKey {
algorithm: self.algorithm() as i32,
key: self.to_bytes(),
}
}

#[cfg(feature = "pem")]
pub fn from_der_with_algorithm(
bytes: &[u8],
Expand Down
2 changes: 1 addition & 1 deletion biscuit-auth/src/crypto/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl PublicKey {

impl Hash for PublicKey {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(crate::format::schema::public_key::Algorithm::Secp256r1 as i32).hash(state);
(biscuit_proto::public_key::Algorithm::Secp256r1 as i32).hash(state);
self.to_bytes().hash(state);
}
}
Expand Down
5 changes: 1 addition & 4 deletions biscuit-auth/src/datalog/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use super::{MapKey, SymbolIndex, Term};
use super::{SymbolTable, TemporarySymbolTable};
use regex::Regex;
use std::sync::Arc;
use std::{
collections::HashMap,
convert::TryFrom,
};
use std::{collections::HashMap, convert::TryFrom};

#[derive(Clone)]
pub struct ExternFunc(
Expand Down
Loading
Loading