Пример #1
0
    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>();
    }
Пример #2
0
    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>();
    }
Пример #3
0
    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);
    }
Пример #4
0
    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}"),
            });
Пример #5
0
    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);
    }
Пример #6
0
    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);
    }
Пример #7
0
        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();
        }
Пример #8
0
    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}"),
        });
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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();
        }
Пример #12
0
    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,
        });
    }
Пример #13
0
        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
        }
Пример #14
0
 public PrincipalSignature(string kid, string issuer, string?audience, string?subject, PrincipalSignature source)
     : base(kid, issuer, audience, subject)
 {
     _rsa = source._rsa;
 }