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"); }
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)); }
public JwtTokenParser Build() { PrincipleSignature.VerifyNotNull($"{nameof(PrincipleSignature)} is required"); return(new JwtTokenParser(PrincipleSignature, ValidIssuers, ValidAudiences)); }