public void GivenIdentity_WhenSigned_ShouldFailWithOtherIdentity() { var documentId = new DocumentId("test/unit-tests-identity/identity1"); var documentId2 = new DocumentId("test/unit-tests-identity/identity2"); string kid = Guid.NewGuid().ToString(); string subject = "*****@*****.**"; string digest = Guid.NewGuid().ToString(); RSAParameters rsaParameter = Create(documentId); RSAParameters rsaParameter2 = Create(documentId2); IPrincipalSignature principle = new PrincipalSignature(kid, "test.com", "spin.com", subject, rsaParameter); IPrincipalSignature principle2 = new PrincipalSignature(kid, "test.com", "spin.com", subject, rsaParameter2); string token = new JwtTokenBuilder() .SetDigest(digest) .SetExpires(DateTime.Now.AddDays(10)) .SetIssuedAt(DateTime.Now) .SetPrincipleSignature(principle) .Build(); token.Should().NotBeNullOrEmpty(); Action test = () => new JwtTokenParserBuilder() .SetPrincipleSignature(principle2) .Build() .Parse(token); test.Should().Throw <SecurityTokenSignatureKeyNotFoundException>(); }
public void GivenJwtSigned_WhenAnotherPrincipleIsUsed_ShouldFailValidate() { string kid = Guid.NewGuid().ToString(); string kid2 = Guid.NewGuid().ToString(); string subject = "*****@*****.**"; string digest = Guid.NewGuid().ToString(); IPrincipalSignature principle = new PrincipalSignature(kid, "test.com", "spin.com", subject); IPrincipalSignature principle2 = new PrincipalSignature(kid2, "test2.com", "spin2.com", subject); string token = new JwtTokenBuilder() .SetDigest(digest) .SetExpires(DateTime.Now.AddDays(10)) .SetIssuedAt(DateTime.Now) .SetPrincipleSignature(principle) .Build(); token.Should().NotBeNullOrEmpty(); Action test = () => new JwtTokenParserBuilder() .SetPrincipleSignature(principle2) .Build() .Parse(token); test.Should().Throw <SecurityTokenUnableToValidateException>(); }
public void GivenIdentity_WhenSigned_ShouldValidate() { var documentId = new DocumentId("test/unit-tests-identity/identity1"); string kid = Guid.NewGuid().ToString(); string subject = "*****@*****.**"; string digest = Guid.NewGuid().ToString(); RSAParameters rsaParameter = Create(documentId); IPrincipalSignature principle = new PrincipalSignature(kid, "test.com", "spin.com", subject, rsaParameter); string token = new JwtTokenBuilder() .SetDigest(digest) .SetExpires(DateTime.Now.AddDays(10)) .SetIssuedAt(DateTime.Now) .SetPrincipleSignature(principle) .Build(); token.Should().NotBeNullOrEmpty(); JwtTokenDetails tokenDetails = new JwtTokenParserBuilder() .SetPrincipleSignature(principle) .Build() .Parse(token); tokenDetails.JwtSecurityToken.Header.Kid.Should().Be(kid); tokenDetails.JwtSecurityToken.Subject.Should().Be(subject); }
public void GivenBlockChain_WhenContainerIsMemory_ShouldRoundTrip() { const string issuer = "*****@*****.**"; const string issuer2 = "*****@*****.**"; const string zipPath = "$block"; var date = DateTime.UtcNow; var issuerSignature = new PrincipalSignature(issuer, issuer, "*****@*****.**"); var issuerSignature2 = new PrincipalSignature(issuer2, issuer2, "*****@*****.**"); BlockChain blockChain = new BlockChainBuilder() .SetPrincipleId(issuer) .Build() .Sign(x => issuerSignature); var payload = new Payload { Name = "Name1", Value = 2, Price = 10.5f }; var payload2 = new Payload2 { Last = "Last", Current = date, Author = "test" }; blockChain.Add(payload, issuer); blockChain.Add(payload2, issuer); var getSignature = (string kid) => { return(kid switch { issuer => issuerSignature, issuer2 => issuerSignature2, _ => throw new ArgumentException($"Invalid kid={kid}"), });
public async Task <bool> Validate(ValidateRequest validateRequest, CancellationToken token) { _logger.LogTrace($"Validate for id={validateRequest.Id}"); foreach (var request in validateRequest.PrincipleDigests) { IdentityEntry?identityEntry = await GetIdentity(request.PrincipleId, token); if (identityEntry == null || request.JwtSignature.IsEmpty()) { _logger.LogError($"Cannot find signing data for PrincipleId={request.PrincipleId}"); return(false); } IPrincipalSignature principleSignature = new PrincipalSignature(request.PrincipleId, _issuer, _audience, identityEntry.Subject, identityEntry.GetRsaParameters()); try { JwtTokenDetails tokenDetails = new JwtTokenParserBuilder() .SetPrincipleSignature(principleSignature) .Build() .Parse(request.JwtSignature); _logger.LogTrace($"JWT validated for PrincipleId={request.PrincipleId}"); } catch (Exception ex) { _logger.LogError(ex, $"Failed validation for PrincipleId={request.PrincipleId}"); return(false); } } return(true); }
public void GivenJwtSigned_ShouldValidate() { string kid = Guid.NewGuid().ToString(); string subject = "*****@*****.**"; string digest = Guid.NewGuid().ToString(); IPrincipalSignature principle = new PrincipalSignature(kid, "test.com", "spin.com", subject); string token = new JwtTokenBuilder() .SetDigest(digest) .SetExpires(DateTime.Now.AddDays(10)) .SetIssuedAt(DateTime.Now) .SetPrincipleSignature(principle) .Build(); token.Should().NotBeNullOrEmpty(); JwtTokenDetails tokenDetails = new JwtTokenParserBuilder() .SetPrincipleSignature(principle) .Build() .Parse(token); tokenDetails.JwtSecurityToken.Header.Kid.Should().Be(kid); tokenDetails.JwtSecurityToken.Subject.Should().Be(subject); }
public void GivenBlockChain_TwoTypes_ShouldVerify() { const string issuer = "*****@*****.**"; const string issuer2 = "*****@*****.**"; var now = UnixDate.UtcNow; var date = DateTime.UtcNow; var issuerSignature = new PrincipalSignature(issuer, issuer, "*****@*****.**"); var issuerSignature2 = new PrincipalSignature(issuer2, issuer2, "*****@*****.**"); BlockChain blockChain = new BlockChainBuilder() .SetPrincipleId(issuer) .Build(); var payload = new Payload { Name = "Name1", Value = 2, Price = 10.5f }; var payload2 = new Payload2 { Last = "Last", Current = date, Author = "test" }; blockChain.Add(payload, issuer); blockChain.Add(payload2, issuer2); var getSignature = (string kid) => kid switch { issuer => issuerSignature, issuer2 => issuerSignature2, _ => throw new ArgumentException($"Invalid kid={kid}"), }; blockChain = blockChain.Sign(getSignature); blockChain.Validate(getSignature); // Get payload of data block blockChain.Blocks.Count.Should().Be(3); DataBlock receiveBlock = blockChain.Blocks[1].DataBlock; TestBlockNode(receiveBlock, "Payload", "1"); Payload p1 = receiveBlock.Data.ToObject <Payload>().VerifyNotNull("payload failed"); (payload == p1).Should().BeTrue(); DataBlock receiveBlock2 = blockChain.Blocks[2].DataBlock; TestBlockNode(receiveBlock2, "Payload2", "2"); Payload2 p2 = receiveBlock2.Data.ToObject <Payload2>().VerifyNotNull("payload2 failed"); (payload2 == p2).Should().BeTrue(); }
public static IPrincipalSignature WithAudience(this IPrincipalSignature principalSignature, string audience) { principalSignature.VerifyNotNull(nameof(principalSignature)); return(principalSignature switch { PrincipalSignature v => new PrincipalSignature(v.Kid, v.Issuer, audience, v.Subject, v), PrincipalSignatureCertificate v => new PrincipalSignatureCertificate(v.Kid, v.Issuer, audience, v.Certificate, v.Subject), _ => throw new ArgumentException($"Unknown type={principalSignature.GetType().FullName}"), });
public void GivenEmptyBlockChain_ShouldVerify() { const string issuer = "*****@*****.**"; var now = UnixDate.UtcNow; IPrincipalSignature principleSignature = new PrincipalSignature(issuer, issuer, "*****@*****.**"); BlockChain blockChain = new BlockChainBuilder() .SetPrincipleId(issuer) .Build() .Sign(x => principleSignature); blockChain.Validate(x => principleSignature); }
public void GivenBlockData_WhenValuesSet_VerifyNoChangeAndSignature() { const string issuer = "*****@*****.**"; var now = DateTime.UtcNow; IPrincipalSignature principleSignature = new PrincipalSignature(issuer, issuer, "test.com"); var dataPayload = new { Name = "Name", Type = "Type", Author = "Author", Data = "Data" }; string payloadJson = dataPayload.ToJson(); DataBlock data = new DataBlockBuilder() .SetTimeStamp(now) .SetBlockType("blockType") .SetBlockId("blockId") .SetData(payloadJson) .SetPrincipleId(issuer) .Build(); data = data with { JwtSignature = principleSignature.Sign(data.Digest) }; principleSignature.ValidateSignature(data.JwtSignature); string json = data.ToJson(); DataBlock received = Json.Default.Deserialize <DataBlock>(json).VerifyNotNull("Json is null"); data.TimeStamp.Should().Be(now.ToUnixDate().TimeStamp); received.BlockType.Should().Be("blockType"); received.BlockId.Should().Be("blockId"); received.Data.Should().Be(payloadJson); received.JwtSignature.Should().Be(data.JwtSignature); received.Digest.Should().Be(received.GetDigest()); Dictionary <string, string>?readData = Json.Default.Deserialize <Dictionary <string, string> >(data.Data) !; readData["name"].Should().Be(dataPayload.Name); readData["type"].Should().Be(dataPayload.Type); readData["author"].Should().Be(dataPayload.Author); readData["data"].Should().Be(dataPayload.Data); }
public void GivenBlockChain_AppendSingleNode_ShouldVerify() { const string issuer = "*****@*****.**"; var now = DateTime.UtcNow; IPrincipalSignature principleSignature = new PrincipalSignature(issuer, issuer, "*****@*****.**"); var dataPayload = new { Name = "Name", Type = "Type", Author = "Author", Data = "Data" }; string payloadJson = dataPayload.ToJson(); DataBlock data = new DataBlockBuilder() .SetTimeStamp(now) .SetBlockType("blockType") .SetBlockId("blockId") .SetData(payloadJson) .SetPrincipleId(issuer) .Build(); BlockChain blockChain = new BlockChainBuilder() .SetPrincipleId(issuer) .Build() .Add(data) .Sign(x => principleSignature); blockChain.Validate(x => principleSignature); // Get payload of data block blockChain.Blocks.Count.Should().Be(2); DataBlock receiveBlock = blockChain.Blocks[1].DataBlock; TestBlockNode(receiveBlock, "blockType", "blockId"); Dictionary <string, string> receivedPayload = receiveBlock.Data.ToObject <Dictionary <string, string> >().VerifyNotNull("payload failed"); (receivedPayload["name"] == "Name").Should().BeTrue(); (receivedPayload["type"] == "Type").Should().BeTrue(); (receivedPayload["author"] == "Author").Should().BeTrue(); (receivedPayload["data"] == "Data").Should().BeTrue(); }
public async Task <SignRequestResponse> Sign(SignRequest signRequest, CancellationToken token) { signRequest.Verify(); _logger.LogTrace($"Sign for id={signRequest.Id}"); List <PrincipleDigest> response = new List <PrincipleDigest>(); List <string> errors = new(); foreach (var request in signRequest.PrincipleDigests) { IdentityEntry?identityEntry = await GetIdentity(request.PrincipleId, token); if (identityEntry == null) { string msg = $"Cannot find signing data for directoryId={request.PrincipleId}"; _logger.LogError(msg); errors.Add(msg); response.Add(request); continue; } _logger.LogTrace($"Signing for PrincipleId={request.PrincipleId}"); IPrincipalSignature principleSignature = new PrincipalSignature(request.PrincipleId, _issuer, _audience, identityEntry.Subject, identityEntry.GetRsaParameters()); string jwt = new JwtTokenBuilder() .SetDigest(request.Digest) .SetPrincipleSignature(principleSignature) .SetExpires(DateTime.Now.AddYears(10)) .SetIssuedAt(DateTime.Now) .Build(); _logger.LogInformation($"Signed for directoryId={request.PrincipleId}"); response.Add(request with { JwtSignature = jwt }); } return(new SignRequestResponse { PrincipleDigests = response, Errors = errors, }); }
public void GivenBlockData_WhenTestForEqual_ShouldPass() { const string issuer = "*****@*****.**"; var now = DateTime.UtcNow; IPrincipalSignature principleSignature = new PrincipalSignature(issuer, issuer, "*****@*****.**"); var dataPayload = new { Name = "Name", Type = "Type", Author = "Author", Data = "Data" }; string payloadJson = dataPayload.ToJson(); DataBlock data1 = new DataBlockBuilder() .SetTimeStamp(now) .SetBlockType("blockType") .SetBlockId("blockId") .SetData(payloadJson) .SetPrincipleId(issuer) .Build(); DataBlock data2 = new DataBlockBuilder() .SetTimeStamp(now) .SetBlockType("blockType") .SetBlockId("blockId") .SetData(payloadJson) .SetPrincipleId(issuer) .Build(); data1.TimeStamp.Should().Be(data2.TimeStamp); data1.BlockType.Should().Be(data2.BlockType); data1.BlockId.Should().Be(data2.BlockId); data1.Data.Should().Be(data2.Data); data1.Digest.Should().Be(data2.Digest); (data1 == data2).Should().BeTrue(); // Will fail because of timestamp on JwtSignature }
public PrincipalSignature(string kid, string issuer, string?audience, string?subject, PrincipalSignature source) : base(kid, issuer, audience, subject) { _rsa = source._rsa; }