public static void Validate(this BlockChain blockChain, IWorkContext context, IPrincipleSignatureContainer keyContainer)
        {
            blockChain.Verify(nameof(blockChain)).IsNotNull();
            keyContainer.Verify(nameof(keyContainer)).IsNotNull();

            blockChain.IsValid()
            .Verify()
            .Assert <bool, SecurityException>(x => x == true, "Block chain has linkage is invalid");

            foreach (var node in blockChain.Blocks)
            {
                // Skip header
                if (node.Index == 0)
                {
                    continue;
                }

                string?issuer = JwtTokenParser.GetIssuerFromJwtToken(node.BlockData.JwtSignature !) !
                                .Verify()
                                .Assert <string, SecurityException>(x => x != null, "Issuer is not found in JWT Signature")
                                .Value;

                PrincipleSignature principleSignature = keyContainer.Get(issuer !) !;
                principleSignature.Verify().IsNotNull("Signature for issuer {issuer} is not in container");

                node.BlockData.Validate(context, principleSignature);
            }
        }
        public void GivenBlockChain_AppendTwoNode_ShouldVerify()
        {
            var now = DateTime.Now;
            var principleSignature = new PrincipleSignature("issuer", "audience", TimeSpan.FromMinutes(1), new RsaPublicPrivateKey());
            var blockChain         = new BlockChain();

            var block1 = new DataBlock <TextBlock>(now, "blockTypeV1", "blockIdV1", new TextBlock("name", "type", "author", "dataV1"));

            block1 = block1.WithSignature(principleSignature);
            blockChain.Add(block1);
            block1.Validate(_workContext, principleSignature);

            var block2 = new DataBlock <TextBlock>(now, "blockTypeV2", "blockIdV2", new TextBlock("name", "type", "author", "dataV2"));

            block2 = block2.WithSignature(principleSignature);
            blockChain.Add(block2);
            block2.Validate(_workContext, principleSignature);

            blockChain.IsValid().Should().BeTrue();

            IPrincipleSignatureContainer keyContainer = new PrincipleSignatureContainer()
            {
                principleSignature,
            };

            blockChain.Validate(_workContext, keyContainer);
        }
        public void GivenBlockChain_AppendSingleNode_ShouldVerify()
        {
            var now = DateTime.Now;
            var principleSignature = new PrincipleSignature("bobTheIssuer", "bobCustomer", TimeSpan.FromMinutes(1), new RsaPublicPrivateKey());
            var blockChain         = new BlockChain();

            var block1 = new DataBlock <TextBlock>(now, "blockTypeV1", "blockIdV1", new TextBlock("name", "type", "author", "dataV1"));

            block1.Validate();
            string block1Digest = block1.Digest;

            block1 = block1.WithSignature(principleSignature);
            blockChain.Add(block1);
            block1.Validate();
            block1Digest.Should().Be(block1.Digest);

            block1.Validate(_workContext, principleSignature);

            blockChain.IsValid().Should().BeTrue();

            IPrincipleSignatureContainer keyContainer = new PrincipleSignatureContainer()
            {
                principleSignature,
            };

            blockChain.Validate(_workContext, keyContainer);
        }
        public static void Validate(this IDataBlock subject, IWorkContext context, PrincipleSignature principleSignature)
        {
            subject.Verify(nameof(subject)).IsNotNull();
            principleSignature.Verify(nameof(principleSignature)).IsNotNull();

            subject.Validate();

            JwtTokenDetails?tokenDetails = principleSignature.ValidateSignature(context, subject.JwtSignature !);

            tokenDetails.Verify().IsNotNull("Signature validation failed");

            string digest = tokenDetails !.Claims.Where(x => x.Type == "blockDigest").Select(x => x.Value).FirstOrDefault();

            (digest == subject.Digest).Verify().Assert <bool, SecurityException>(x => x == true, "Block's digest does not match signature");
        }
        public void GivenBlockChain_AppendManyNode_ShouldVerify()
        {
            var       now = DateTime.Now;
            const int max = 10;
            var       principleSignature = new PrincipleSignature("issuer", "audience", TimeSpan.FromMinutes(1), new RsaPublicPrivateKey());
            var       blockChain         = new BlockChain();

            List <DataBlock <TextBlock> > list = Enumerable.Range(0, max)
                                                 .Select(x => new DataBlock <TextBlock>(now, $"blockTypeV{x}", $"blockIdV{x}", new TextBlock("name", "type", "author", $"dataV{x}")).WithSignature(principleSignature))
                                                 .ToList();

            blockChain.Add(list.ToArray());

            blockChain.IsValid().Should().BeTrue();

            IPrincipleSignatureContainer keyContainer = new PrincipleSignatureContainer()
            {
                principleSignature,
            };

            blockChain.Validate(_workContext, keyContainer);
        }
        public void GivenSetBlockType_WhenChainCreated_ValuesShouldBeVerified()
        {
            var principleSignature = new PrincipleSignature("issuer", "audience", TimeSpan.FromMinutes(1), new RsaPublicPrivateKey());

            var blockChain = new BlockChain()
            {
                new DataBlock <HeaderBlock>("header", "header_1", new HeaderBlock("Master Contract")).WithSignature(principleSignature),
                new DataBlock <BlobBlock>("contract", "contract_1", new BlobBlock("contract.docx", "docx", "me", Encoding.UTF8.GetBytes("this is a contract between two people"))).WithSignature(principleSignature),
                new DataBlock <TrxBlock>("ContractLedger", "Pmt", new TrxBlock("1", "cr", 100)).WithSignature(principleSignature),
            };

            blockChain.Blocks.Count.Should().Be(4);
            blockChain.IsValid().Should().BeTrue();

            IPrincipleSignatureContainer keyContainer = new PrincipleSignatureContainer()
            {
                principleSignature,
            };

            blockChain.Validate(_workContext, keyContainer);

            blockChain.Blocks
            .Select((x, i) => (x, i))
            .All(x => x.x.Index == x.i)
            .Should().BeTrue();

            blockChain.Blocks[0].BlockData.As <DataBlock <HeaderBlock> >().BlockType.Should().Be("genesis");
            blockChain.Blocks[0].BlockData.As <DataBlock <HeaderBlock> >().BlockId.Should().Be("0");

            blockChain.Blocks[1].BlockData.As <DataBlock <HeaderBlock> >().BlockType.Should().Be("header");
            blockChain.Blocks[1].BlockData.As <DataBlock <HeaderBlock> >().BlockId.Should().Be("header_1");

            blockChain.Blocks[2].BlockData.As <DataBlock <BlobBlock> >().BlockType.Should().Be("contract");
            blockChain.Blocks[2].BlockData.As <DataBlock <BlobBlock> >().BlockId.Should().Be("contract_1");

            blockChain.Blocks[3].BlockData.As <DataBlock <TrxBlock> >().BlockType.Should().Be("ContractLedger");
            blockChain.Blocks[3].BlockData.As <DataBlock <TrxBlock> >().BlockId.Should().Be("Pmt");
        }
示例#7
0
        public string Build()
        {
            PrincipleSignature.VerifyNotNull($"{nameof(PrincipleSignature)} is required");

            var header = new JwtHeader(PrincipleSignature.GetSigningCredentials());

            if (!PrincipleSignature.Kid.IsEmpty())
            {
                header["kid"] = PrincipleSignature.Kid;
            }

            var addClaims = new[]
            {
                PrincipleSignature.Subject.IsEmpty() ? null : new Claim(JwtStandardClaimNames.SubjectName, PrincipleSignature.Subject),
                Digest.IsEmpty() ? null : new Claim(JwtStandardClaimNames.DigestName, Digest),
            }.Where(x => x != null);

            var payload = new JwtPayload(PrincipleSignature.Issuer, PrincipleSignature.Audience, Claims.Concat(addClaims), NotBefore, Expires, IssuedAt);

            var jwtToken     = new JwtSecurityToken(header, payload);
            var tokenHandler = new JwtSecurityTokenHandler();

            return(tokenHandler.WriteToken(jwtToken));
        }
示例#8
0
        public JwtTokenParser Build()
        {
            PrincipleSignature.VerifyNotNull($"{nameof(PrincipleSignature)} is required");

            return(new JwtTokenParser(PrincipleSignature, ValidIssuers, ValidAudiences));
        }