示例#1
0
        public void TestGetRevocationIds()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            KeyPair root = new KeyPair(rng);

            SymbolTable  symbols           = Biscuit.Token.Biscuit.DefaultSymbolTable();
            BlockBuilder authority_builder = new BlockBuilder(0, symbols);

            Guid uuid1 = Guid.Parse("0b6d033d-83da-437f-a078-1a44890018bc");

            authority_builder.AddFact(Utils.Fact("revocation_id", Arrays.AsList(Utils.Strings(uuid1.ToString()))));

            Biscuit.Token.Biscuit biscuit = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right;

            BlockBuilder builder = biscuit.CreateBlock();

            builder.AddFact(Utils.Fact(
                                "right",
                                Arrays.AsList(Utils.Symbol("topic"), Utils.Symbol("tenant"), Utils.Symbol("namespace"), Utils.Symbol("topic"), Utils.Symbol("produce"))
                                ));
            Guid uuid2 = Guid.Parse("46a103de-ee65-4d04-936b-9111eac7dd3b");

            builder.AddFact(Utils.Fact("revocation_id", Arrays.AsList(Utils.Strings(uuid2.ToString()))));

            string attenuatedB64 = biscuit.Attenuate(rng, new KeyPair(rng), builder.Build()).Right.SerializeBase64().Right;

            Biscuit.Token.Biscuit b = Biscuit.Token.Biscuit.FromBase64(attenuatedB64).Right;

            Verifier    v1         = b.Verify(root.ToPublicKey()).Right;
            List <Guid> revokedIds = v1.GetRevocationIdentifiers().Right.Select(s => Guid.Parse(s)).ToList();

            Assert.IsTrue(revokedIds.Contains(uuid1));
            Assert.IsTrue(revokedIds.Contains(uuid2));
        }
示例#2
0
        public void TestMultipleAttenuation()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            KeyPair root = new KeyPair(rng);

            SymbolTable  symbols           = Biscuit.Token.Biscuit.DefaultSymbolTable();
            BlockBuilder authority_builder = new BlockBuilder(0, symbols);
            DateTime     date = DateTime.Now;

            authority_builder.AddFact(Utils.Fact("revocation_id", Arrays.AsList(Utils.Date(date))));

            Biscuit.Token.Biscuit biscuit = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right;

            BlockBuilder builder = biscuit.CreateBlock();

            builder.AddFact(Utils.Fact(
                                "right",
                                Arrays.AsList(Utils.Symbol("topic"), Utils.Symbol("tenant"), Utils.Symbol("namespace"), Utils.Symbol("topic"), Utils.Symbol("produce"))
                                ));

            string attenuatedB64 = biscuit.Attenuate(rng, new KeyPair(rng), builder.Build()).Right.SerializeBase64().Right;

            Console.WriteLine("attenuated: " + attenuatedB64);

            var attenuatedB64Biscuit = Biscuit.Token.Biscuit.FromBase64(attenuatedB64);

            Assert.IsTrue(attenuatedB64Biscuit.IsRight);

            string attenuated2B64 = biscuit.Attenuate(rng, new KeyPair(rng), builder.Build()).Right.SerializeBase64().Right;

            Console.WriteLine("attenuated2: " + attenuated2B64);
            var attenuated2B64Biscuit = Biscuit.Token.Biscuit.FromBase64(attenuated2B64);

            Assert.IsTrue(attenuated2B64Biscuit.IsRight);
        }
示例#3
0
        public void TestEmptyVerifier()
        {
            byte[] seed = { 0, 0, 0, 0 };
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed);

            Console.WriteLine("preparing the authority block");

            KeyPair root = new KeyPair(rng);

            Biscuit.Token.Builder.BiscuitBuilder builder = Biscuit.Token.Biscuit.Builder(rng, root);

            builder.AddRight("/folder1/file1", "read");
            builder.AddRight("/folder1/file1", "write");
            builder.AddRight("/folder1/file2", "read");
            builder.AddRight("/folder1/file2", "write");
            builder.AddRight("/folder2/file3", "read");

            Console.WriteLine(builder.Build());
            Biscuit.Token.Biscuit b = builder.Build().Right;

            Console.WriteLine(b.Print());

            BlockBuilder block2 = b.CreateBlock();

            block2.ResourcePrefix("/folder1/");
            block2.CheckRight("read");

            KeyPair keypair2 = new KeyPair(rng);

            Biscuit.Token.Biscuit b2 = b.Attenuate(rng, keypair2, block2.Build()).Right;

            Verifier v1 = new Verifier();

            v1.Allow();

            Either <Error, long> res = v1.Verify();

            Assert.IsTrue(res.IsRight);

            v1.AddToken(b2, Option.Some(root.ToPublicKey())).Get();

            v1.AddResource("/folder2/file1");
            v1.AddOperation("write");

            res = v1.Verify();

            Assert.IsTrue(res.IsLeft);
        }
示例#4
0
        static public Either <Error, Verifier> Make(Biscuit token, Option <PublicKey> root)
        {
            if (!token.IsSealed())
            {
                Either <Error, Void> checkRootKey = token.CheckRootKey(root.Get());
                if (checkRootKey.IsLeft)
                {
                    return(checkRootKey.Left);
                }
            }

            Either <Error, World> world = token.GenerateWorld();

            if (world.IsLeft)
            {
                return(world.Left);
            }

            return(new Right(new Verifier(token, world.Right)));
        }
示例#5
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));
        }
示例#6
0
        public void TestReset()
        {
            byte[] seed = { 0, 0, 0, 0 };
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed);

            Console.WriteLine("preparing the authority block");

            KeyPair root = new KeyPair(rng);

            Biscuit.Token.Builder.BiscuitBuilder builder = Biscuit.Token.Biscuit.Builder(rng, root);

            builder.AddRight("/folder1/file1", "read");
            builder.AddRight("/folder1/file1", "write");
            builder.AddRight("/folder1/file2", "read");
            builder.AddRight("/folder1/file2", "write");
            builder.AddRight("/folder2/file3", "read");

            Console.WriteLine(builder.Build());
            Biscuit.Token.Biscuit b = builder.Build().Right;

            Console.WriteLine(b.Print());

            var block2 = b.CreateBlock();

            block2.ResourcePrefix("/folder1/");
            block2.CheckRight("read");

            KeyPair keypair2 = new KeyPair(rng);

            Biscuit.Token.Biscuit b2 = b.Attenuate(rng, keypair2, block2.Build()).Right;

            Verifier v1 = b2.Verify(root.ToPublicKey()).Right;

            v1.Allow();

            Verifier v2 = v1.Clone();

            v2.AddResource("/folder1/file1");
            v2.AddOperation("read");


            Either <Error, long> res = v2.Verify();

            Assert.IsTrue(res.IsRight);

            Verifier v3 = v1.Clone();

            v3.AddResource("/folder2/file3");
            v3.AddOperation("read");

            res = v3.Verify();
            Console.WriteLine(v3.PrintWorld());

            Assert.IsTrue(res.IsLeft);

            Verifier v4 = v1.Clone();

            v4.AddResource("/folder2/file1");
            v4.AddOperation("write");

            res = v4.Verify();

            Error e = res.Left;

            Assert.IsTrue(res.IsLeft);

            Console.WriteLine(v4.PrintWorld());
            foreach (FailedCheck f in e.FailedCheck().Get())
            {
                Console.WriteLine(f.ToString());
            }
            Assert.AreEqual(
                new FailedLogic(new LogicError.FailedChecks(Arrays.AsList <FailedCheck>(
                                                                new FailedCheck.FailedBlock(1, 0, "check if resource(#ambient, $resource), $resource.starts_with(\"/folder1/\")"),
                                                                new FailedCheck.FailedBlock(1, 1, "check if resource(#ambient, $resource), operation(#ambient, #read), right(#authority, $resource, #read)")
                                                                ))),
                e);
        }
示例#7
0
        public void TestSealedTokens()
        {
            byte[] seed = { 0, 0, 0, 0 };
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed);

            Console.WriteLine("preparing the authority block");

            KeyPair root = new KeyPair(rng);

            SymbolTable  symbols           = Biscuit.Token.Biscuit.DefaultSymbolTable();
            BlockBuilder authority_builder = new BlockBuilder(0, symbols);

            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("read"))));
            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file2"), Utils.Symbol("read"))));
            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("write"))));

            Biscuit.Token.Biscuit b = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right;

            Console.WriteLine(b.Print());

            Console.WriteLine("serializing the first token");

            byte[] data = b.Serialize().Right;

            Console.Write("data len: ");
            Console.WriteLine(data.Length);
            //Console.WriteLine(hex(data));

            Console.WriteLine("deserializing the first token");
            Biscuit.Token.Biscuit deser = Biscuit.Token.Biscuit.FromBytes(data).Right;

            Console.WriteLine(deser.Print());

            // SECOND BLOCK
            Console.WriteLine("preparing the second block");

            KeyPair keypair2 = new KeyPair(rng);

            BlockBuilder builder = deser.CreateBlock();

            builder.AddCheck(Utils.Check(Utils.Rule(
                                             "caveat1",
                                             Arrays.AsList(Utils.Var("resource")),
                                             Arrays.AsList(
                                                 Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Var("resource"))),
                                                 Utils.Pred("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))),
                                                 Utils.Pred("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Var("resource"), Utils.Symbol("read")))
                                                 )
                                             )));

            Biscuit.Token.Biscuit b2 = deser.Attenuate(rng, keypair2, builder.Build()).Right;

            Console.WriteLine(b2.Print());

            Console.WriteLine("sealing the second token");

            byte[] testkey = Encoding.UTF8.GetBytes("testkey");

            var sealedd = b2.Seal(testkey).Right;

            Console.Write("sealed data len: ");
            Console.WriteLine(sealedd.Length);

            Console.WriteLine("deserializing the sealed token with an invalid key");
            Error e = Biscuit.Token.Biscuit.FromSealed(sealedd, Encoding.UTF8.GetBytes("not this key")).Left;

            Console.WriteLine(e);
            Assert.AreEqual(new SealedSignature(), e);

            Console.WriteLine("deserializing the sealed token with a valid key");
            Biscuit.Token.Biscuit deser2 = Biscuit.Token.Biscuit.FromSealed(sealedd, Encoding.UTF8.GetBytes("testkey")).Right;
            Console.WriteLine(deser2.Print());

            Console.WriteLine("trying to attenuate to a sealed token");
            _ = deser2.CreateBlock();
            _ = deser2.Attenuate(rng, keypair2, builder.Build()).Left;

            Verifier v = deser2.VerifySealed().Right;

            Console.WriteLine(v.PrintWorld());
        }
示例#8
0
        public void TestBasic()
        {
            byte[] seed = { 0, 0, 0, 0 };
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed);

            Console.WriteLine("preparing the authority block");

            KeyPair root = new KeyPair(rng);

            SymbolTable  symbols           = Biscuit.Token.Biscuit.DefaultSymbolTable();
            BlockBuilder authority_builder = new BlockBuilder(0, symbols);

            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("read"))));
            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file2"), Utils.Symbol("read"))));
            authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("write"))));

            Biscuit.Token.Biscuit b = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right;

            Console.WriteLine(b.Print());

            Console.WriteLine("serializing the first token");

            byte[] data = b.Serialize().Right;

            Console.Write("data len: ");
            Console.WriteLine(data.Length);
            //Console.WriteLine(hex(data));

            Console.WriteLine("deserializing the first token");
            Biscuit.Token.Biscuit deser = Biscuit.Token.Biscuit.FromBytes(data).Right;

            Console.WriteLine(deser.Print());

            // SECOND BLOCK
            Console.WriteLine("preparing the second block");

            KeyPair keypair2 = new KeyPair(rng);

            BlockBuilder builder = deser.CreateBlock();

            builder.AddCheck(Utils.Check(Utils.Rule(
                                             "caveat1",
                                             Arrays.AsList(Utils.Var("resource")),
                                             Arrays.AsList(
                                                 Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Var("resource"))),
                                                 Utils.Pred("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))),
                                                 Utils.Pred("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Var("resource"), Utils.Symbol("read")))
                                                 )
                                             )));

            Biscuit.Token.Biscuit b2 = deser.Attenuate(rng, keypair2, builder.Build()).Right;

            Console.WriteLine(b2.Print());

            Console.WriteLine("serializing the second token");

            byte[] data2 = b2.Serialize().Right;

            Console.Write("data len: ");
            Console.WriteLine(data2.Length);
            //Console.WriteLine(hex(data2));

            Console.WriteLine("deserializing the second token");
            Biscuit.Token.Biscuit deser2 = Biscuit.Token.Biscuit.FromBytes(data2).Right;

            Console.WriteLine(deser2.Print());

            // THIRD BLOCK
            Console.WriteLine("preparing the third block");

            KeyPair keypair3 = new KeyPair(rng);

            BlockBuilder builder3 = deser2.CreateBlock();

            builder3.AddCheck(Utils.Check(Utils.Rule(
                                              "caveat2",
                                              Arrays.AsList(Utils.Symbol("file1")),
                                              Arrays.AsList(
                                                  Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file1")))
                                                  )
                                              )));

            Biscuit.Token.Biscuit b3 = deser2.Attenuate(rng, keypair3, builder3.Build()).Right;

            Console.WriteLine(b3.Print());

            Console.WriteLine("serializing the third token");

            byte[] data3 = b3.Serialize().Right;

            Console.Write("data len: ");
            Console.WriteLine(data3.Length);
            //Console.WriteLine(hex(data3));

            Console.WriteLine("deserializing the third token");
            Biscuit.Token.Biscuit final_token = Biscuit.Token.Biscuit.FromBytes(data3).Right;

            Console.WriteLine(final_token.Print());

            // check
            Console.WriteLine("will check the token for resource=file1 and operation=read");

            SymbolTable check_symbols = new SymbolTable(final_token.Symbols);
            List <Fact> ambient_facts = Arrays.AsList(
                Utils.Fact("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file1"))).Convert(check_symbols),
                Utils.Fact("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))).Convert(check_symbols)
                );

            Either <Error, Dictionary <string, HashSet <Fact> > > res = final_token.Check(check_symbols, ambient_facts,
                                                                                          new List <Rule>(), new List <Check>(), new Dictionary <string, Rule>());

            Assert.IsTrue(res.IsRight);

            Console.WriteLine("will check the token for resource=file2 and operation=write");

            SymbolTable check_symbols2 = new SymbolTable(final_token.Symbols);
            List <Fact> ambient_facts2 = Arrays.AsList(
                Utils.Fact("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file2"))).Convert(check_symbols2),
                Utils.Fact("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("write"))).Convert(check_symbols2)
                );

            Either <Error, Dictionary <string, HashSet <Fact> > > res2 = final_token.Check(check_symbols2, ambient_facts2,
                                                                                           new List <Rule>(), new List <Check>(), new Dictionary <string, Rule>());

            Assert.IsTrue(res2.IsLeft);
            Console.WriteLine(res2.Left);

            Assert.AreEqual(
                new FailedLogic(new LogicError.FailedChecks(Arrays.AsList <FailedCheck>(
                                                                new FailedCheck.FailedBlock(1, 0, "check if resource(#ambient, $resource), operation(#ambient, #read), right(#authority, $resource, #read)"),
                                                                new FailedCheck.FailedBlock(2, 0, "check if resource(#ambient, #file1)")
                                                                ))),
                res2.Left);
        }
示例#9
0
 /// <summary>
 /// Deserializes a Biscuit token from a byte array
 /// This checks the signature, but does not verify that the first key is the root key,
 /// to allow appending blocks without knowing about the root key.
 /// The root key check is performed in the verify method
 /// This method uses the default symbol table
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 static public Either <Error, Biscuit> FromBytes(byte[] data)
 {
     return(Biscuit.FromBytesWithSymbols(data, DefaultSymbolTable()));
 }
示例#10
0
 /// <summary>
 /// Deserializes a Biscuit token from a hex string
 /// This checks the signature, but does not verify that the first key is the root key,
 /// to allow appending blocks without knowing about the root key.
 /// The root key check is performed in the verify method
 /// This method uses the default symbol table
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static Either <Error, Biscuit> FromBase64(string data)
 {
     return(Biscuit.FromBytes(Convert.FromBase64String(data)));
 }