Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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)));
            }
        }