public Either <Error, Void> AddToken(Biscuit token, Option <PublicKey> root) { if (!token.IsSealed()) { Either <Error, Void> res = token.CheckRootKey(root.Get()); if (res.IsLeft) { return(res.Left); } } if (this.token != null) { return(new FailedLogic(new LogicError.VerifierNotEmpty())); } ulong authority_index = symbols.Get("authority").Get(); ulong ambient_index = symbols.Get("ambient").Get(); foreach (Fact fact in token.Authority.Facts) { if (fact.Predicate.Ids[0].Equals(new ID.Symbol(ambient_index))) { return(new FailedLogic(new LogicError.InvalidAuthorityFact(symbols.PrintFact(fact)))); } Fact converted_fact = FactBuilder.ConvertFrom(fact, token.Symbols).Convert(this.symbols); world.AddFact(converted_fact); } foreach (Rule rule in token.Authority.Rules) { Rule converted_rule = RuleBuilder.ConvertFrom(rule, token.Symbols).Convert(this.symbols); world.AddPrivilegedRule(converted_rule); } List <Check> authority_checks = new List <Check>(); foreach (Check check in token.Authority.Checks) { Datalog.Check converted_check = CheckBuilder.ConvertFrom(check, token.Symbols).Convert(this.symbols); authority_checks.Add(converted_check); } token_checks.Add(authority_checks); for (int i = 0; i < token.Blocks.Count; i++) { Block b = token.Blocks[i]; if (b.Index != i + 1) { return(new InvalidBlockIndex(1 + token.Blocks.Count, token.Blocks[i].Index)); } foreach (Fact fact in b.Facts) { if (fact.Predicate.Ids[0].Equals(new ID.Symbol(authority_index)) || fact.Predicate.Ids[0].Equals(new ID.Symbol(ambient_index))) { return(new FailedLogic(new LogicError.InvalidBlockFact(i, symbols.PrintFact(fact)))); } Fact converted_fact = FactBuilder.ConvertFrom(fact, token.Symbols).Convert(this.symbols); world.AddFact(converted_fact); } foreach (Rule rule in b.Rules) { Rule converted_rule = RuleBuilder.ConvertFrom(rule, token.Symbols).Convert(this.symbols); world.AddRule(converted_rule); } List <Check> block_checks = new List <Check>(); foreach (Check check in b.Checks) { Check converted_check = CheckBuilder.ConvertFrom(check, token.Symbols).Convert(this.symbols); block_checks.Add(converted_check); } token_checks.Add(block_checks); } List <RevocationIdentifier> revocation_ids = token.RevocationIdentifiers; ulong rev = symbols.Get("revocation_id").Get(); for (int i = 0; i < revocation_ids.Count; i++) { byte[] id = revocation_ids[i].Bytes; world.AddFact(new Fact(new Predicate(rev, Arrays.AsList <ID>(new ID.Integer(i), new ID.Bytes(id))))); } return(new Right(null)); }
public Either <Error, long> Verify(RunLimits limits) { DateTime timeLimit = DateTime.Now.Add(limits.MaxTime); if (this.symbols.Get("authority").IsEmpty() || this.symbols.Get("ambient").IsEmpty()) { return(new MissingSymbols()); } HashSet <ulong> restricted_symbols = new HashSet <ulong> { this.symbols.Get("authority").Get(), this.symbols.Get("ambient").Get() }; Either <Error, Void> runRes = world.Run(limits, restricted_symbols); if (runRes.IsLeft) { return(runRes.Left); } SymbolTable symbols = new SymbolTable(this.symbols); List <FailedCheck> errors = new List <FailedCheck>(); for (int j = 0; j < this.checks.Count; j++) { Datalog.Check c = this.checks[j].Convert(symbols); bool successful = false; for (int k = 0; k < c.Queries.Count && !successful; k++) { bool res = world.TestRule(c.Queries[k]); if (DateTime.Now.CompareTo(timeLimit) >= 0) { return(new TimeoutError()); } if (res) { successful = true; } } if (!successful) { errors.Add(new FailedCheck.FailedVerifier(j, symbols.PrintCheck(c))); } } for (int i = 0; i < this.token_checks.Count; i++) { List <Check> checks = this.token_checks[i]; for (int j = 0; j < checks.Count; j++) { bool successful = false; Check c = checks[j]; for (int k = 0; k < c.Queries.Count && !successful; k++) { bool res = world.TestRule(c.Queries[k]); if (DateTime.Now.CompareTo(timeLimit) >= 0) { return(new TimeoutError()); } if (res) { successful = true; } } if (!successful) { errors.Add(new FailedCheck.FailedBlock(i, j, symbols.PrintCheck(checks[j]))); } } } if (errors.IsEmpty()) { for (int i = 0; i < this.policies.Count; i++) { Check c = this.policies[i].Convert(symbols); for (int k = 0; k < c.Queries.Count; k++) { bool res = world.TestRule(c.Queries[k]); if (DateTime.Now.CompareTo(timeLimit) >= 0) { return(new TimeoutError()); } if (res) { if (this.policies[i].kind == Policy.Kind.Deny) { return(new FailedLogic(new LogicError.Denied(i))); } else { return(new Right((long)i)); } } } } return(new FailedLogic(new LogicError.NoMatchingPolicy())); } else { return(new FailedLogic(new LogicError.FailedChecks(errors))); } }