Skip to content
This repository has been archived by the owner on Feb 9, 2023. It is now read-only.

Commit

Permalink
implement Verifier.add_token
Browse files Browse the repository at this point in the history
an empty verifier can be created, adding data, checks, etc. Then when a
request come, we clone the verifier, add the token and test the policies
with that request and token
  • Loading branch information
Geal committed Mar 23, 2021
1 parent 5332eca commit 7832a93
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 49 deletions.
12 changes: 12 additions & 0 deletions src/main/java/com/clevercloud/biscuit/datalog/expressions/Op.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public Value(ID value) {
this.value = value;
}

public ID getValue() {
return value;
}

@Override
public boolean evaluate(Deque<ID> stack, Map<Long, ID> variables) {
if (value instanceof ID.Variable) {
Expand Down Expand Up @@ -106,6 +110,10 @@ public Unary(UnaryOp op) {
this.op = op;
}

public UnaryOp getOp() {
return op;
}

@Override
public boolean evaluate(Deque<ID> stack, Map<Long, ID> variables) {
ID value = stack.pop();
Expand Down Expand Up @@ -236,6 +244,10 @@ public Binary(BinaryOp value) {
this.op = value;
}

public BinaryOp getOp() {
return op;
}

@Override
public boolean evaluate(Deque<ID> stack, Map<Long, ID> variables) {
ID right = stack.pop();
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/clevercloud/biscuit/error/LogicError.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,26 @@ public String toString() {
return "Denied("+id+")";
}
}

public static class VerifierNotEmpty extends LogicError {

public VerifierNotEmpty() {

}

@Override
public int hashCode() {
return super.hashCode();
}

@Override
public boolean equals(Object obj) {
return super.equals(obj);
}

@Override
public String toString() {
return "VerifierNotEmpty";
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/clevercloud/biscuit/token/Biscuit.java
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,17 @@ public Either<Error, Biscuit> attenuate(final SecureRandom rng, final KeyPair ke
return Right(new Biscuit(copiedBiscuit.authority, blocks, symbols, Option.some(container)));
}

public List<List<com.clevercloud.biscuit.datalog.Check>> checks() {
ArrayList<List<com.clevercloud.biscuit.datalog.Check>> l = new ArrayList();
l.add(new ArrayList(this.authority.checks));

for(Block b: this.blocks) {
l.add(new ArrayList<>(b.checks));
}

return l;
}

public List<Option<String>> context() {
ArrayList res = new ArrayList();
if(this.authority.context.isEmpty()) {
Expand Down
142 changes: 94 additions & 48 deletions src/main/java/com/clevercloud/biscuit/token/Verifier.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.clevercloud.biscuit.token;

import com.clevercloud.biscuit.crypto.PublicKey;
import com.clevercloud.biscuit.datalog.ID;
import com.clevercloud.biscuit.datalog.RunLimits;
import com.clevercloud.biscuit.datalog.SymbolTable;
import com.clevercloud.biscuit.datalog.World;
Expand All @@ -26,6 +27,7 @@
public class Verifier {
Biscuit token;
List<Check> checks;
List<List<com.clevercloud.biscuit.datalog.Check>> token_checks;
List<Policy> policies;
World world;
SymbolTable symbols;
Expand All @@ -36,6 +38,7 @@ private Verifier(Biscuit token, World w) {
this.symbols = new SymbolTable(this.token.symbols);
this.checks = new ArrayList<>();
this.policies = new ArrayList<>();
this.token_checks = this.token.checks();
}

/**
Expand All @@ -49,12 +52,15 @@ public Verifier() {
this.symbols = Biscuit.default_symbol_table();
this.checks = new ArrayList<>();
this.policies = new ArrayList<>();
this.token_checks = new ArrayList<>();
}

Verifier(Biscuit token, List<Check> checks, List<Policy> policies, World world, SymbolTable symbols) {
Verifier(Biscuit token, List<Check> checks, List<Policy> policies,
List<List<com.clevercloud.biscuit.datalog.Check>> token_checks, World world, SymbolTable symbols) {
this.token = token;
this.checks = checks;
this.policies = policies;
this.token_checks = token_checks;
this.world = world;
this.symbols = symbols;
}
Expand All @@ -79,16 +85,84 @@ static public Either<Error, Verifier> make(Biscuit token, Option<PublicKey> root
Either<Error, World> res = token.generate_world();
if (res.isLeft()) {
Error e = res.getLeft();
System.out.println(e);
return Left(e);
}

return Right(new Verifier(token, res.get()));
}

public Verifier clone() {
return new Verifier(this.token, new ArrayList<>(this.checks), new ArrayList<>(this.policies), new World(this.world),
new SymbolTable(this.symbols));
return new Verifier(this.token, new ArrayList<>(this.checks), new ArrayList<>(this.policies),
new ArrayList<>(this.token_checks), new World(this.world), new SymbolTable(this.symbols));
}

public Either<Error, Void> add_token(Biscuit token, Option<PublicKey> root) {
if(!token.is_sealed()) {
Either<Error, Void> res = token.check_root_key(root.get());
if (res.isLeft()) {
Error e = res.getLeft();
return Left(e);
}
}

if(this.token != null) {
return Either.left(new Error.FailedLogic(new LogicError.VerifierNotEmpty()));
}

long authority_index = symbols.get("authority").get();
long ambient_index = symbols.get("ambient").get();

for(com.clevercloud.biscuit.datalog.Fact fact: token.authority.facts) {
if (fact.predicate().ids().get(0).equals(new ID.Symbol(ambient_index))) {
return Left(new Error.FailedLogic(new LogicError.InvalidAuthorityFact(symbols.print_fact(fact))));
}

com.clevercloud.biscuit.datalog.Fact converted_fact = Fact.convert_from(fact, token.symbols).convert(this.symbols);
world.add_fact(converted_fact);
}

for(com.clevercloud.biscuit.datalog.Rule rule: token.authority.rules) {
com.clevercloud.biscuit.datalog.Rule converted_rule = Rule.convert_from(rule, token.symbols).convert(this.symbols);
world.add_rule(converted_rule);
}

List<com.clevercloud.biscuit.datalog.Check> authority_checks = new ArrayList<>();
for(com.clevercloud.biscuit.datalog.Check check: token.authority.checks) {
com.clevercloud.biscuit.datalog.Check converted_check = Check.convert_from(check, token.symbols).convert(this.symbols);
authority_checks.add(converted_check);
}
token_checks.add(authority_checks);

for(int i = 0; i < token.blocks.size(); i++) {
Block b = token.blocks.get(i);
if (b.index != i + 1) {
return Left(new Error.InvalidBlockIndex(1 + token.blocks.size(), token.blocks.get(i).index));
}

for (com.clevercloud.biscuit.datalog.Fact fact : b.facts) {
if (fact.predicate().ids().get(0).equals(new ID.Symbol(authority_index)) ||
fact.predicate().ids().get(0).equals(new ID.Symbol(ambient_index))) {
return Left(new Error.FailedLogic(new LogicError.InvalidBlockFact(i, symbols.print_fact(fact))));
}

com.clevercloud.biscuit.datalog.Fact converted_fact = Fact.convert_from(fact, token.symbols).convert(this.symbols);
world.add_fact(converted_fact);
}

for (com.clevercloud.biscuit.datalog.Rule rule : b.rules) {
com.clevercloud.biscuit.datalog.Rule converted_rule = Rule.convert_from(rule, token.symbols).convert(this.symbols);
world.add_rule(converted_rule);
}

List<com.clevercloud.biscuit.datalog.Check> block_checks = new ArrayList<>();
for(com.clevercloud.biscuit.datalog.Check check: b.checks) {
com.clevercloud.biscuit.datalog.Check converted_check = Check.convert_from(check, token.symbols).convert(this.symbols);
block_checks.add(converted_check);
}
token_checks.add(block_checks);
}

return Right(null);
}

public void add_fact(Fact fact) {
Expand Down Expand Up @@ -196,7 +270,6 @@ public Either<Error, List<String>> get_revocation_ids() {
Either<Error, Set<Fact>> queryRes = this.query(getRevocationIds);
if (queryRes.isLeft()) {
Error e = queryRes.getLeft();
System.out.println(e);
return Left(e);
}

Expand Down Expand Up @@ -272,7 +345,6 @@ public Either<Error, Set<Fact>> query(Rule query, RunLimits limits) {
Either<Error, Void> runRes = world.run(limits);
if (runRes.isLeft()) {
Error e = runRes.getLeft();
System.out.println(e);
return Left(e);
}

Expand Down Expand Up @@ -313,36 +385,12 @@ public Either<Error, Long> verify(RunLimits limits) {
Either<Error, Void> runRes = world.run(limits);
if (runRes.isLeft()) {
Error e = runRes.getLeft();
System.out.println(e);
return Left(e);
}

SymbolTable symbols = new SymbolTable(this.symbols);

ArrayList<FailedCheck> errors = new ArrayList<>();
if(this.token != null) {
for (int j = 0; j < this.token.authority.checks.size(); j++) {
boolean successful = false;
com.clevercloud.biscuit.datalog.Check c = this.token.authority.checks.get(j);

for (int k = 0; k < c.queries().size(); k++) {
boolean res = world.test_rule(c.queries().get(k));

if (Instant.now().compareTo(timeLimit) >= 0) {
return Left(new Error.Timeout());
}

if (res) {
successful = true;
break;
}
}

if (!successful) {
errors.add(new FailedCheck.FailedBlock(0, j, symbols.print_check(this.token.authority.checks.get(j))));
}
}
}

for (int j = 0; j < this.checks.size(); j++) {
com.clevercloud.biscuit.datalog.Check c = this.checks.get(j).convert(symbols);
Expand All @@ -366,31 +414,30 @@ public Either<Error, Long> verify(RunLimits limits) {
}
}

if(this.token != null) {
for (int i = 0; i < this.token.blocks.size(); i++) {
Block b = this.token.blocks.get(i);

for (int j = 0; j < b.checks.size(); j++) {
boolean successful = false;
com.clevercloud.biscuit.datalog.Check c = b.checks.get(j);
for (int i = 0; i < this.token_checks.size(); i++) {
List<com.clevercloud.biscuit.datalog.Check> checks = this.token_checks.get(i);

for (int k = 0; k < c.queries().size(); k++) {
boolean res = world.test_rule(c.queries().get(k));
for (int j = 0; j < checks.size(); j++) {
boolean successful = false;
com.clevercloud.biscuit.datalog.Check c = checks.get(j);

if (Instant.now().compareTo(timeLimit) >= 0) {
return Left(new Error.Timeout());
}
for (int k = 0; k < c.queries().size(); k++) {
boolean res = world.test_rule(c.queries().get(k));

if (res) {
successful = true;
break;
}
if (Instant.now().compareTo(timeLimit) >= 0) {
return Left(new Error.Timeout());
}

if (!successful) {
errors.add(new FailedCheck.FailedBlock(b.index, j, symbols.print_check(b.checks.get(j))));
if (res) {
successful = true;
break;
}
}

if (!successful) {
errors.add(new FailedCheck.FailedBlock(i, j, symbols.print_check(checks.get(j))));
}
}
}

Expand Down Expand Up @@ -418,7 +465,6 @@ public Either<Error, Long> verify(RunLimits limits) {

return Left(new Error.FailedLogic(new LogicError.NoMatchingPolicy()));
} else {
System.out.println(errors);
return Left(new Error.FailedLogic(new LogicError.FailedChecks(errors)));
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/clevercloud/biscuit/token/builder/Check.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ public com.clevercloud.biscuit.datalog.Check convert(SymbolTable symbols) {
return new com.clevercloud.biscuit.datalog.Check(queries);
}

public static Check convert_from(com.clevercloud.biscuit.datalog.Check r, SymbolTable symbols) {
ArrayList<Rule> queries = new ArrayList<>();

for(com.clevercloud.biscuit.datalog.Rule q: r.queries()) {
queries.add(Rule.convert_from(q, symbols));
}

return new Check(queries);
}

@Override
public String toString() {
return "check if "+queries;
Expand Down
Loading

0 comments on commit 7832a93

Please # to comment.