Example #1
0
        public void M5SetupTest()
        {
            var clientPubKey = FixedSaltGenerator.ExpectedClientPubKey;
            var clientProof  = FixedSaltGenerator.ExpectedClientProof;
            var inputData    =
                "059ac2e1aa3fef6c4bc067cd9d26a05b53fa6ad29f953af80c90968757a18fcb270118987a5c26e50f2f8e274750584929d5d5a176a62af5ef0d4002ed6333ee75b0f75d0ee4dbef345f6ae15345cfdcb97e3300d18bf8f827701f6dfcc6cc213dff5ae1cffa03235853df30d8eb6ceec068dc64e9ef8049ce3d9396bbd32c7b2e329005023cf06ed8a60e3e51491b7f7193a807f1f244369a5ee9fd060105";
            var expectedTlvHexReponse =
                "0601060587b0e4a7aa382866e824db4159cc0ecd24900136be360fd6ae64481bf799b1ecc918ecb887285a8dcd5b6f90aa410253451fd1bc638cae716cbab166f763108633555a6bfa311662986ea2d1eb83b76d195724b9bbddf7902dfd3a16e1bbd5bb8e5a5a6e3a56e8eec21c3f06ed2cce21ea17426407d0a1b35c9d692f5a5ee15ecb7ac662ade25ab7";

            var tlv = TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(inputData));

            var fixedSrpGenerator = new FixedSaltGenerator();

            var session = new ConnectionSession
            {
                Salt            = fixedSrpGenerator.GenerateSalt(16),
                Verifier        = FixedSaltGenerator.ExpectedVerifier,
                ServerEphemeral = fixedSrpGenerator.GenerateServerEphemeral(FixedSaltGenerator.ExpectedVerifier)
            };

            session.ServerSession = fixedSrpGenerator.DeriveServerSession(session.ServerEphemeral.Secret, clientPubKey, SrpInteger.FromByteArray(session.Salt).ToHex(), "Pair-Setup", session.Verifier, clientProof);

            var setupController = new PairSetupController(NullLogger.Instance, "031-45-154")
            {
                SrpGenerator = fixedSrpGenerator, KeyGenerator = new FixedEd25519KeyGenerator()
            };

            var ret = setupController.Post(tlv, session);

            var expectedTlvResponse =
                TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(expectedTlvHexReponse));

            var decryptedPayload = TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(
                                                       "011146433a32323a33443a45333a43453a4632032083e6d70e7064effd0c6df6d19451b1ded53f7e2d0dd86e33d4aa1993f5e9cded0a402ac3063b1d193c4d365c546019c51cac8299a23a99c9f8eb2348c46af24b185a53f1f75a92d57193bdeb4dfbc47ccadccc4f9f4e3dc8191eef364d15cd921207"));
            var raw = setupController.HandlePairSetupM5Raw(session, out _);

            Assert.Equal(decryptedPayload.GetType(Constants.Identifier), raw.GetType(Constants.Identifier));
            Assert.Equal(decryptedPayload.GetType(Constants.PublicKey), raw.GetType(Constants.PublicKey));
            Assert.Equal(decryptedPayload.GetType(Constants.Signature), raw.GetType(Constants.Signature));

            var expectedEncryptedData =
                Automatica.Core.Driver.Utility.Utils.ByteArrayToString(expectedTlvResponse.GetType(Constants.EncryptedData).AsSpan());
            var retEncryptedData =
                Automatica.Core.Driver.Utility.Utils.ByteArrayToString(ret.TlvData.GetType(Constants.EncryptedData).AsSpan());

            Assert.Equal(expectedEncryptedData, retEncryptedData);
            Assert.Equal(expectedTlvResponse.GetType(Constants.State), ret.TlvData.GetType(Constants.State));
            Assert.Equal(expectedTlvResponse.GetType(Constants.EncryptedData), ret.TlvData.GetType(Constants.EncryptedData));

            var expectedHttpResponse =
                "485454502F312E3120323030204F4B0D0A436F6E74656E742D4C656E6774683A203134300D0A436F6E74656E742D547970653A206170706C69636174696F6E2F70616972696E672B746C76380D0A446174653A2053756E2C203139204A616E20323032302031353A33313A313320474D540D0A436F6E6E656374696F6E3A206B6565702D616C6976650D0A0D0A0601060587B0E4A7AA382866E824DB4159CC0ECD24900136BE360FD6AE64481BF799B1ECC918ECB887285A8DCD5B6F90AA410253451FD1BC638CAE716CBAB166F763108633555A6BFA311662986EA2D1EB83B76D195724B9BBDDF7902DFD3A16E1BBD5BB8E5A5A6E3A56E8EEC21C3F06ED2CCE21EA17426407D0A1B35C9D692F5A5EE15ECB7AC662ADE25AB7";
            var expectedHttpResponseArray =
                Automatica.Core.Driver.Utility.Utils.StringToByteArray(expectedHttpResponse);

            var requestTime  = new DateTime(2020, 01, 19, 15, 31, 13, DateTimeKind.Utc);
            var httpResponse =
                HttpServerConnection.GetHttpResponse("HTTP/1.1", PairSetupReturn.ContentType, TlvParser.Serialize(ret.TlvData), requestTime);

            Assert.Equal(expectedHttpResponseArray, httpResponse);
        }
Example #2
0
        public void TestPairSetupM6()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM6);


            Assert.Equal(2, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.State));
            Assert.True(tlv.Values.ContainsKey(Constants.EncryptedData));


            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 6 });
            Assert.Equal(tlv.GetType(Constants.EncryptedData),
                         new byte[]
            {
                0x8b, 0xc8, 0x42, 0xd6, 0xb8, 0x60, 0xac, 0x76, 0x36,
                0xe8, 0xb0, 0xe5, 0xc7, 0x7a, 0x5b, 0x56, 0x23, 0xc4,
                0xd4, 0x83, 0x2f, 0xdb, 0x16, 0x24, 0x50, 0x27, 0x7f,
                0xd5, 0xdd, 0xd5, 0x11, 0x9d, 0x5f, 0x95, 0xba, 0xd7,
                0xe0, 0xdd, 0x46, 0x52, 0xa8, 0xaf, 0xd1, 0xc0, 0xe7,
                0x41, 0x2e, 0x5c, 0x54, 0x63, 0x59, 0x55, 0x24, 0x2c,
                0xa1, 0x3e, 0xfb, 0xd7, 0xa7, 0xd1, 0x8d, 0xdc, 0x03,
                0x1d, 0x14, 0x3c, 0x2f, 0x3b, 0x7d, 0x4d, 0x29, 0xf1,
                0x33, 0xe8, 0x68, 0x79, 0x62, 0x52, 0xd6, 0x16, 0x5c,
                0x7f, 0x57, 0xb2, 0xda, 0xbe, 0xe4, 0xb8, 0xfc, 0xb6,
                0xf8, 0x3d, 0x3b, 0xa4, 0xb0, 0x19, 0x3e, 0xf9, 0x25,
                0x2d, 0xe1, 0x2c, 0xab, 0x93, 0x10, 0xfc, 0x08, 0x7e,
                0x59, 0x3b, 0x7a, 0x70, 0x83, 0x4c, 0xf8, 0x46, 0xab,
                0x87, 0x83, 0xa1, 0x67, 0x29, 0xe7, 0x05, 0x5b, 0x8f,
                0x73, 0x1c, 0x57, 0x2f, 0xea, 0xec, 0x33, 0xbe, 0xd5
            });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM6, serialized);
        }
Example #3
0
        public void M1SetupTest()
        {
            var          fixedSrpGenerator    = new FixedSaltGenerator();
            const string expectedTlvHexString =
                "0601020210deff10eeac3d2c5cf370a2dae3310a4f03ff18ed6bbc1b4338031679acbcd7f6aa4622266e2c1c92432f8c446e0197333a08f0fd0acbd77cee8aeccbf0fe5ad9f526476acb0a26e928620451152f1f5e0c19bf788c9bded644868354256d0ae5a0736b8b5c3a8e8ac7fad4b74b56732af5098254e9acba634a29a0f4d65d75bf9993f5590fa61cd336299703d121632032b1f95fb83cc1d6fa9c6b994dbff8ef68bf269aa62ded2efa1556988a52992ccbfd41dfbfe234490d7b5d310816bd046280e51740c8132d71677a73297080639bf4f39430b166539a07e045048a2a5d8c4f285deee8ea5fd1aa58432b681e519522d3491e528bb15b4f1ea39fb2c08cfa4bfdc11095e7fb1585018e75bb2a7e39038165287d49a816d51852432fc093d884aabec2126bb6febd08fa18857e16bff8b05bf6c03b7b212e5917ea196444cc0bd2cd54fc2bbd25562b89e0f4c90aab68fa7ba999f2082683430d9bdbd01876b72dc3851d74ec973c710d19fc694100342c8139cdc1aad1155be550432d3abf3944643a6bdaa8b20615f7cbe1bc00bb8334b9";

            var tlv = TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray("000100060101"));

            var setupController = new PairSetupController(NullLogger.Instance, "031-45-154")
            {
                SrpGenerator = fixedSrpGenerator
            };

            fixedSrpGenerator.DeriveVerifier(fixedSrpGenerator.DerivePrivateKey("", "", ""));

            var session = new ConnectionSession();
            var ret     = setupController.Post(tlv, session);

            var expectedTlvResponse =
                TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(expectedTlvHexString));

            Assert.Equal(expectedTlvResponse.GetType(Constants.State), ret.TlvData.GetType(Constants.State));
            Assert.Equal(expectedTlvResponse.GetType(Constants.Salt), ret.TlvData.GetType(Constants.Salt));
            Assert.Equal(expectedTlvResponse.GetType(Constants.PublicKey), ret.TlvData.GetType(Constants.PublicKey));
        }
Example #4
0
        public void M2SetupTest()
        {
            var fixedSrpGenerator     = new FixedSaltGenerator();
            var expectedTlvHexReponse =
                "0601040440847786bbdb27e466f3533fa2016f5eaff57ffddc99c55d97d8cc634bcbd95c9c2ba0167e717ecd9fc19aa8b03987a9b0a1b3b676b8e33ce8d097a05bffbd4a24";
            var inputData =
                "06010303ffa080de13894d7d0f183472a4ac1ac1be4efeea83685bd9e318e7e33516ee2637469e35cb3695d2885b9d000a053d8ebac30fb82348915f941e54b4386b2d6e4d7b99b91b94ca937a2026651f9d28b59596e7d5078b220050dc22e4962462f5d59b801c1854ea0238cfecbc3521580597d5abf5035bddf295caf55d528898e1c835d624f3d3e12a62f9ff1363c86b0e5d28cfdd16aed5bb6d13d93c6ab5985f0d5f5325a6c3d22db574e060694d6a373a98335ee0e72c036a413ec2374e7d235e1cb71953bf89ba9712a07d5598323ece6d64f7032add9d7f8787dce3abdadd06d2cad3b6df6376f0dc617c421fc918ad04277f91c722f92e264f2cea5d4af103818bfa268350586190f3cf58f97ea5153970aa3ab48c636ddf043966a3183bc0514616f03bd5e9559cee68208c8e87a5ee5a223f9ad69fa96034053444dfc09280a0068995659007b0ffe0428c833a69c089d1299608575b6c5dc1a0b10c422b6b39574dfa7206f6222d99d822785efa2b6f597377b96107ac59c6722dfdb6f208610440cd09aaf139460ef72317848478c1bee19464b149f3145ecf67a07a6f8829443c3a13d1c5ea4e45cfba291fd7a8d1c8fdc088d709b87882947a3b6dee5738409d";
            var tlv = TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(inputData));

            var session = new ConnectionSession
            {
                Verifier        = FixedSaltGenerator.ExpectedVerifier,
                ServerEphemeral = fixedSrpGenerator.GenerateServerEphemeral(FixedSaltGenerator.ExpectedVerifier)
            };

            var setupController = new PairSetupController(NullLogger.Instance, "031-45-154")
            {
                SrpGenerator = fixedSrpGenerator
            };

            var ret = setupController.Post(tlv, session);

            var expectedTlvResponse =
                TlvParser.Parse(Automatica.Core.Driver.Utility.Utils.StringToByteArray(expectedTlvHexReponse));


            Assert.Equal(expectedTlvResponse.GetType(Constants.State), ret.TlvData.GetType(Constants.State));
            Assert.Equal(expectedTlvResponse.GetType(Constants.Proof), ret.TlvData.GetType(Constants.Proof));
        }
Example #5
0
        public TlvIdentity GetIdentity()
        {
            var payload = ReadFile(FileType.Identity);
            var parser  = new TlvParser();

            return(parser.Parse <TlvIdentity>(payload));
        }
Example #6
0
        public TlvAddress GetAddress()
        {
            var payload = ReadFile(FileType.Address);
            var parser  = new TlvParser();

            return(parser.Parse <TlvAddress>(payload));
        }
Example #7
0
        public void TestPairSetupM2()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM2);

            Assert.Equal(3, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.State));
            Assert.True(tlv.Values.ContainsKey(Constants.Salt));
            Assert.True(tlv.Values.ContainsKey(Constants.PublicKey));


            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 2 });
            Assert.Equal(tlv.GetType(Constants.Salt), new byte[] { 0x9e, 0x31, 0x7e, 0x30, 0x58, 0x10, 0xd5, 0x69, 0x2b, 0x73, 0x00, 0xd1, 0x63, 0x95, 0xe0, 0x03 });
            Assert.Equal(tlv.GetType(Constants.PublicKey), new byte[] {
                0x4b, 0x20, 0x6a, 0x23, 0x3c, 0x2b, 0x33, 0xf0, 0x29, 0xf1,
                0xd2, 0x82, 0xa4, 0xe1, 0x4c, 0xb9, 0x39, 0x96, 0x24, 0x99,
                0x48, 0x3f, 0x48, 0xdb, 0xd7, 0x51, 0x3c, 0xb4, 0x3f, 0x9d,
                0xcd, 0x73, 0x32, 0x61, 0x2e, 0xaf, 0x0f, 0xca, 0x70, 0x6d,
                0xd1, 0x15, 0x93, 0xa5, 0x69, 0x81, 0xe1, 0xcd, 0x21, 0x09,
                0x5c, 0x09, 0x38, 0x84, 0x96, 0x19, 0xbc, 0xcb, 0xd7, 0x1d,
                0xf6, 0x5b, 0x2e, 0xe5, 0xe3, 0x74, 0x81, 0x78, 0xb7, 0x43,
                0x14, 0x7f, 0x53, 0xad, 0x86, 0x5c, 0x19, 0xf0, 0x5f, 0xb7,
                0x73, 0x10, 0x5b, 0xf4, 0xcb, 0x5a, 0x4a, 0x09, 0x84, 0xda,
                0x4b, 0xaa, 0x63, 0x08, 0xc3, 0xd0, 0x46, 0xff, 0x3e, 0x24,
                0xd6, 0xcf, 0xaa, 0xaf, 0xd8, 0x44, 0x76, 0xa9, 0x1d, 0x24,
                0x0e, 0x5c, 0x58, 0xa4, 0x96, 0xf4, 0x85, 0x87, 0x94, 0x42,
                0xc3, 0xb9, 0xd8, 0x1d, 0xe8, 0xb8, 0x14, 0x0d, 0x36, 0x8e,
                0xc0, 0x0e, 0x67, 0x8e, 0xce, 0xb8, 0x0d, 0x1f, 0x22, 0x9c,
                0xb5, 0x4d, 0x30, 0x9b, 0x81, 0x09, 0x23, 0xac, 0xcd, 0xc9,
                0x8f, 0x89, 0x14, 0xb0, 0x74, 0x75, 0xd1, 0xfb, 0xee, 0x69,
                0xb9, 0x2f, 0xaa, 0x6f, 0xce, 0x83, 0xfe, 0xbe, 0xae, 0xd1,
                0x52, 0x8d, 0x21, 0x1b, 0x9e, 0x2b, 0xb2, 0xe1, 0x88, 0x2f,
                0x0f, 0xfc, 0x2d, 0xf2, 0x0b, 0xe2, 0x51, 0x0d, 0xb4, 0xf4,
                0xd9, 0x0e, 0x25, 0xce, 0x99, 0x6d, 0x42, 0x76, 0x50, 0xb3,
                0x75, 0xcc, 0x98, 0x31, 0xc3, 0x4d, 0x50, 0x90, 0xd1, 0x2e,
                0x3c, 0x3f, 0x94, 0x23, 0xef, 0xc6, 0x99, 0xf7, 0x60, 0x7a,
                0x97, 0x30, 0x61, 0x43, 0xeb, 0x7a, 0x4d, 0x56, 0xfd, 0x26,
                0x27, 0x88, 0x8b, 0xf4, 0xa7, 0x4d, 0x28, 0x94, 0x1e, 0x9a,
                0xbf, 0xe2, 0x48, 0x19, 0xb7, 0x29, 0x96, 0xda, 0x3e, 0x4d,
                0x84, 0xee, 0xcf, 0xe3, 0x82,

                0x1f, 0x03, 0x9d, 0x75, 0x26, 0x37, 0xfd, 0x60, 0xbb, 0xbc,
                0x47, 0xbd, 0x2e, 0x9a, 0xc8, 0xa0, 0x7d, 0x6e, 0x00, 0x09,
                0x05, 0xe3, 0xc5, 0x78, 0x7b, 0x8d, 0x34, 0x1b, 0x4c, 0x1a,
                0x02, 0xef, 0x3a, 0xcc, 0xf1, 0x34, 0xf2, 0x4a, 0x28, 0x9d,
                0xc9, 0xa4, 0xdd, 0x0a, 0x2b, 0xee, 0xd3, 0x5c, 0x4e, 0x66,
                0x18, 0xa2, 0x27, 0x00, 0x09, 0xb7, 0x32, 0x8e, 0x8a, 0x0b,
                0x4a, 0x15, 0x04, 0xf9, 0x5e, 0x88, 0xf0, 0x6a, 0xf0, 0x02,
                0x5b, 0xb4, 0x89, 0xfb, 0x3b, 0xc5, 0xdd, 0x36, 0xe4, 0xdd,
                0xa7, 0x4f, 0xb7, 0xdf, 0x22, 0xbb, 0x03, 0x3c, 0xd7, 0xcd,
                0xe1, 0x39, 0x17, 0x6f, 0x1d, 0xfa, 0xfd, 0xa1, 0x23, 0x3a,
                0xf3, 0x15, 0x56, 0x08, 0xda, 0x57, 0x19, 0xd8, 0x10, 0x78,
                0xd3, 0x89, 0xe1, 0x97, 0xa4, 0x0f, 0x77, 0x48, 0xae, 0x10,
                0xf0, 0xcd, 0xd3, 0xb2, 0x71, 0xdb, 0x84, 0x23, 0x8f
            });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM2, serialized);
        }
Example #8
0
        private Tuple <string, byte[]> ReturnError(int state, ErrorCodes error)
        {
            var tlvData = new Tlv();

            tlvData.AddType(Constants.State, state++);
            tlvData.AddType(Constants.Error, error);
            byte[] output = TlvParser.Serialise(tlvData);

            return(new Tuple <string, byte[]>("application/pairing+tlv8", output));
        }
Example #9
0
        public void TlvReaderReturnsNullOnEmptyStream()
        {
            var parser = new TlvParser(1, 1);

            using (var memStream = new MemoryStream(new byte[] { }))
            {
                var tlv = parser.Decode(memStream);
                Assert.Equal(null, tlv);
            }
        }
Example #10
0
        void TlvReaderDecodes(uint typeLength, uint sizeLength, byte[] serializedTlv, Tlv expectedTlv)
        {
            var parser = new TlvParser(typeLength, sizeLength);

            using (var memStream = new MemoryStream(serializedTlv))
            {
                var tlv = parser.Decode(memStream);
                Assert.Equal(expectedTlv, tlv);
            }
        }
Example #11
0
        private Tuple <string, byte[]> ReturnError(int state, ErrorCodes error)
        {
            _logger.LogDebug($"Return error code: {error} state {state}");
            var tlvData = new Tlv();

            tlvData.AddType(Constants.State, state++);
            tlvData.AddType(Constants.Error, error);
            byte[] output = TlvParser.Serialize(tlvData);

            return(new Tuple <string, byte[]>("application/pairing+tlv8", output));
        }
Example #12
0
        void TlvReaderEncodes(uint typeLength, uint sizeLength, byte[] expectedOutput, Tlv tlv)
        {
            var parser = new TlvParser(typeLength, sizeLength);

            using (var memStream = new MemoryStream())
            {
                parser.Encode(memStream, tlv);
                var output = memStream.ToArray();
                Assert.Equal(expectedOutput, output);
            }
        }
Example #13
0
        public void TestBorderCaseLength0()
        {
            var tlv = TlvParser.Parse(TlvTestData.BorderCaseLength0);

            Assert.Single(tlv.Values);
            Assert.True(tlv.Values.ContainsKey(Constants.Method));

            Assert.Equal(tlv.GetType(Constants.Method), new byte[] { });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.BorderCaseLength0, serialized);
        }
Example #14
0
        public void TestPairSetupM1()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM1);

            Assert.Equal(2, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.Method));
            Assert.True(tlv.Values.ContainsKey(Constants.State));

            Assert.Equal(tlv.GetType(Constants.Method), new byte[] { 0 });
            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 1 });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM1, serialized);
        }
Example #15
0
        public void WhenDeserializeIdentityTlvThenDataAreCorrect()
        {
            // ARRANGE
            var hexStr       = "010a423137343739383734370210534c494e33660013930d2388e90e2f36030a33302e30312e32303134040a33302e30312e32303139050942727578656c6c6573060b38393130303733393537330706486162617274080e5468696572727920526f6265727409000a064672616e63650b0b52616d626f75696c6c65740c0c3037204f43542020313938390d014d0e000f02313510013011140b03673050c41f10d5085d002afd27499b805cb1120230301300";
            var secondHexStr = "010a423233333633323738320210534c47905100000061767d2e12925169030a30372e30382e32303135040a30372e30382e323032300514576f6c7577652d5361696e742d4c616d62657274060b3737303131353439313034070a446f6e6162656469616e080e4461766964204ac3a972c3b46d6509000a064672616e63650b0f4169782d456e2d50726f76656e63650c0c3135204a414e2020313937370d014d0e000f0231361001301114e23a1410ffd7d3";
            var file         = StringToByteArray(hexStr);
            var secondFile   = StringToByteArray(secondHexStr);
            var tlvParser    = new TlvParser();

            // ACT
            var identity       = tlvParser.Parse <Identity>(file);
            var secondIdentity = tlvParser.Parse <Identity>(secondFile);

            // ASSERT
            Assert.NotNull(identity);
            Assert.NotNull(secondIdentity);
            Assert.Equal("89100739573", identity.NationalNumber);
        }
Example #16
0
        public void WhenDeserializeAddressTlvThenDataAreCorrect()
        {
            // ARRANGE
            var hexStr       = "011c4176656e7565206465732043726f6978206475204665752032323320020431303230030942727578656c6c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
            var secondHexStr = "010e52756520447269657320323037200204313230300314576f6c7577652d5361696e742d4c616d626572740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
            var file         = StringToByteArray(hexStr);
            var secondFile   = StringToByteArray(secondHexStr);
            var tlvParser    = new TlvParser();

            // ACT
            var address       = tlvParser.Parse <Address>(file);
            var secondAddress = tlvParser.Parse <Address>(secondFile);

            // ASSERT
            Assert.NotNull(address);
            Assert.NotNull(secondAddress);
            Assert.Equal("Bruxelles", address.Municipality);
            Assert.Equal("1020", address.Zip);
        }
Example #17
0
        public void TestBorderCaseLength255()
        {
            var tlv = TlvParser.Parse(TlvTestData.BorderCaseLength255);

            Assert.Single(tlv.Values);
            Assert.True(tlv.Values.ContainsKey(Constants.Method));

            Assert.Equal(tlv.GetType(Constants.Method), new byte[] {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
                0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
                0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
                0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
                0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
                0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
                0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
                0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
                0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
                0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64,
                0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
                0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
                0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82,
                0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
                0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
                0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
                0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
                0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
                0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
                0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
                0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2,
                0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,
                0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
                0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
                0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
                0xfb, 0xfc, 0xfd, 0xfe, 0xff
            });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.BorderCaseLength255, serialized);
        }
Example #18
0
        public void TestPairSetupM4()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM4);

            Assert.Equal(2, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.State));
            Assert.True(tlv.Values.ContainsKey(Constants.Proof));

            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 4 });
            Assert.Equal(tlv.GetType(Constants.Proof), new byte[] { 0x5f, 0x7a, 0x20, 0xd3, 0x4d, 0x1f, 0x16, 0x8f,
                                                                    0x2b, 0x5f, 0x0f, 0xcd, 0x0c, 0x7f, 0xe3, 0x27,
                                                                    0xa5, 0x40, 0xa5, 0x51, 0x7c, 0xf7, 0x0b, 0x7e,
                                                                    0x2a, 0x34, 0x88, 0x01, 0x48, 0x90, 0x7e, 0xe4,
                                                                    0x25, 0xf2, 0x6c, 0xb0, 0xbd, 0x63, 0x2a, 0xa0,
                                                                    0x39, 0x98, 0xc8, 0xc8, 0x7b, 0xbb, 0xcd, 0xdc,
                                                                    0x2f, 0x0d, 0x08, 0x89, 0xb7, 0x70, 0x0a, 0xf8,
                                                                    0x1c, 0x46, 0xb6, 0x31, 0x83, 0x3f, 0x57, 0xf9 });


            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM4, serialized);
        }
Example #19
0
        public void TestPairSetupM5()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM5);

            Assert.Equal(2, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.State));
            Assert.True(tlv.Values.ContainsKey(Constants.EncryptedData));

            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 5 });
            Assert.Equal(tlv.GetType(Constants.EncryptedData),
                         new byte[]
            {
                0xef, 0x74, 0x54, 0x5d, 0xab, 0x72, 0xfb, 0xcc, 0x34,
                0x02, 0xd9, 0x0b, 0x79, 0xcc, 0xd1, 0xa6, 0x00, 0x66,
                0x4f, 0xf8, 0x2b, 0x30, 0x3a, 0x64, 0x1b, 0xa7, 0xe5,
                0xf9, 0xef, 0xe3, 0xda, 0x5c, 0x9c, 0x0d, 0x67, 0x46,
                0x7d, 0x7e, 0x05, 0x3c, 0xd3, 0x32, 0x30, 0x6e, 0xc6,
                0xc6, 0x06, 0xfa, 0x38, 0x69, 0x20, 0xb7, 0x33, 0xfd,
                0xfd, 0x25, 0x1e, 0xe7, 0xd9, 0x4b, 0x31, 0x5a, 0xc6,
                0x51, 0x02, 0xaf, 0x8b, 0x08, 0x6e, 0x95, 0x25, 0xbd,
                0x93, 0xa9, 0x2b, 0x62, 0xc3, 0x6d, 0xdb, 0x01, 0xde,
                0xe9, 0x46, 0x15, 0x78, 0x18, 0x87, 0xc5, 0x7d, 0x2e,
                0xd7, 0x8a, 0x4e, 0x7b, 0x2d, 0x3a, 0x59, 0x17, 0xb7,
                0xe1, 0x69, 0x4e, 0x86, 0x74, 0xc0, 0xaa, 0xf7, 0xe7,
                0xea, 0x46, 0x67, 0xf8, 0xea, 0x4f, 0x1f, 0x59, 0x75,
                0xd4, 0x6f, 0x01, 0x30, 0xf1, 0x7a, 0x72, 0x1e, 0x38,
                0x72, 0x47, 0xdc, 0x2f, 0x1b, 0x1f, 0xea, 0x5e, 0xd0,
                0x8d, 0x0d, 0x8a, 0x1c, 0x22, 0x67, 0xd9, 0xf9, 0x3f,
                0xb8, 0xf0, 0xe8, 0xbe, 0x5a, 0x58, 0x06, 0x19, 0x85,
                0x7a
            });

            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM5, serialized);
        }
        internal PairSetupReturn HandlePairSetupM5(Tlv parts, ConnectionSession session)
        {
            _logger.LogDebug("Pair Setup Step 5/5");
            _logger.LogDebug("Exchange Response");

            try
            {
                var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A
                var zeros            = new byte[] { 0, 0, 0, 0 };
                var nonce            = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05"));
                var hdkf             = new HkdfSha512();
                var hkdfEncKey       = hdkf.DeriveBytes(
                    SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()),
                    Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"),
                    Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32);


                var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                    new byte[0], iOsEncryptedData, out var output);
                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 6);
                if (!decrypt)
                {
                    responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = responseTlv,
                        Ok = false
                    });
                }

                var subData = TlvParser.Parse(output);

                byte[] username = subData.GetType(Constants.Identifier);
                byte[] ltpk     = subData.GetType(Constants.PublicKey);
                byte[] proof    = subData.GetType(Constants.Signature);


                var okm = hdkf.DeriveBytes(
                    SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()),
                    Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"),
                    Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32);

                var completeData = okm.Concat(username).Concat(ltpk).ToArray();


                if (!SignatureAlgorithm.Ed25519.Verify(
                        PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData,
                        proof))
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var m5Response = HandlePairSetupM5Raw(session, out var keyPair);
                var plaintext  = TlvParser.Serialize(m5Response);

                _logger.LogDebug($"Decrypted payload {Automatica.Core.Driver.Utility.Utils.ByteArrayToString(plaintext.AsSpan())}");


                var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06"));

                var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6,
                    new byte[0], plaintext);

                responseTlv.AddType(Constants.EncryptedData, encryptedOutput);

                return(new PairSetupReturn
                {
                    State = 5,
                    TlvData = responseTlv,
                    Ok = true,
                    Ltsk = ByteArrayToString(keyPair.PrivateKey),
                    Ltpk = ByteArrayToString(ltpk)
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"{e}, Could not exchange request");
                throw;
            }
        }
Example #21
0
        public void TestPairSetupM3()
        {
            var tlv = TlvParser.Parse(TlvTestData.PairSetupM3);


            Assert.Equal(3, tlv.Values.Count);
            Assert.True(tlv.Values.ContainsKey(Constants.State));
            Assert.True(tlv.Values.ContainsKey(Constants.PublicKey));
            Assert.True(tlv.Values.ContainsKey(Constants.Proof));

            Assert.Equal(tlv.GetType(Constants.State), new byte[] { 3 });
            Assert.Equal(tlv.GetType(Constants.PublicKey), new byte[] {
                0x9e, 0xa8, 0xbb, 0x50, 0x00, 0xc3, 0x76, 0x47, 0x8d, 0x52,
                0xa8, 0x94, 0xa0, 0xf2, 0xe2, 0x83, 0x4c, 0x93, 0xc5, 0x02,
                0x0d, 0xc7, 0x94, 0xa7, 0x8e, 0xeb, 0x1a, 0xb5, 0xc2, 0xd2,
                0xa8, 0x00, 0x51, 0x9b, 0x31, 0x15, 0x3f, 0xe2, 0x58, 0xda,
                0x3b, 0x69, 0x53, 0x6a, 0x3d, 0xa5, 0x60, 0x7c, 0xaa, 0x70,
                0x42, 0x97, 0x6c, 0x7b, 0xc7, 0xb8, 0xe4, 0x4b, 0x9e, 0x43,
                0xbd, 0xd7, 0xe5, 0x2f, 0xc6, 0xd4, 0x91, 0xcb, 0x39, 0xd8,
                0xf7, 0x85, 0x63, 0x99, 0x67, 0xa0, 0x61, 0xc9, 0x72, 0x56,
                0x24, 0xfb, 0x3c, 0x31, 0xbe, 0x11, 0x6d, 0xab, 0xc6, 0x50,
                0xd1, 0x65, 0x19, 0x87, 0xa6, 0xa1, 0xdf, 0xbf, 0xe2, 0x57,
                0xb4, 0xa3, 0xed, 0x46, 0x09, 0x34, 0x3c, 0x8e, 0xd6, 0x88,
                0xb2, 0x79, 0x32, 0xd4, 0x6d, 0x64, 0xc5, 0x31, 0xce, 0x61,
                0x48, 0x86, 0x4b, 0x92, 0x0a, 0x3e, 0xf3, 0xdc, 0xff, 0xb5,
                0x10, 0xb3, 0xf8, 0xca, 0x04, 0x04, 0xa0, 0x7f, 0x14, 0x82,
                0x23, 0x8c, 0x32, 0x52, 0x37, 0x15, 0x7b, 0x53, 0xba, 0xd8,
                0x91, 0x06, 0x31, 0xf3, 0x64, 0x52, 0xed, 0x81, 0xe8, 0xe1,
                0x5b, 0xbe, 0x50, 0x9e, 0xdc, 0x2f, 0x92, 0x6a, 0xc2, 0xc6,
                0xb4, 0x3e, 0x29, 0xbe, 0xeb, 0xf7, 0xb5, 0x17, 0x06, 0x83,
                0x56, 0x01, 0xe6, 0x8f, 0x59, 0x21, 0x15, 0x8c, 0x72, 0xd5,
                0x13, 0x47, 0x6a, 0x8e, 0x73, 0x65, 0x68, 0xa9, 0x6c, 0xe9,
                0xce, 0xac, 0xb7, 0xd5, 0x29, 0x38, 0x50, 0x68, 0x8e, 0xf5,
                0xfe, 0xec, 0xb9, 0x06, 0x5c, 0x4a, 0xf5, 0x41, 0xe1, 0x0c,
                0x6d, 0x80, 0x23, 0x95, 0x71, 0x37, 0x6f, 0x97, 0xf3, 0x4d,
                0xf8, 0x0c, 0xf3, 0x26, 0x45, 0x1b, 0x49, 0x38, 0xb9, 0xde,
                0x9b, 0x24, 0x8d, 0xf3, 0xdb, 0x16, 0xa1, 0x50, 0x52, 0xbf,
                0xa2, 0xc1, 0x02, 0x6f, 0x42,

                0x71, 0xbd, 0x15, 0xe3, 0x66, 0x8c, 0xb3, 0x56, 0x36, 0xc3,
                0xe7, 0x4b, 0x1f, 0xb0, 0xfb, 0x17, 0x0e, 0x50, 0x37, 0xde,
                0xf8, 0xb7, 0x38, 0xd1, 0x35, 0x81, 0xd3, 0xfd, 0x16, 0x81,
                0x48, 0xc5, 0x3f, 0x61, 0xab, 0x9f, 0x26, 0x0d, 0xa5, 0x1b,
                0x4f, 0xa7, 0x40, 0x9b, 0x4b, 0xcf, 0x33, 0x4a, 0x30, 0x7f,
                0x94, 0x7a, 0xd9, 0xb6, 0xf8, 0xf9, 0x50, 0x60, 0x2e, 0xa7,
                0xf7, 0xe2, 0x20, 0x70, 0xd1, 0x49, 0x20, 0x6d, 0xf1, 0xb4,
                0x37, 0x0a, 0x4c, 0xaa, 0x60, 0x69, 0xa8, 0xe9, 0x62, 0xd8,
                0xd1, 0xb7, 0x54, 0xc7, 0xb3, 0xe4, 0x0b, 0x0c, 0xe1, 0xf3,
                0xe3, 0x2d, 0xbe, 0xc2, 0xb5, 0xcb, 0x3e, 0x9c, 0x7a, 0x3e,
                0xf1, 0x53, 0x3d, 0x71, 0xae, 0x04, 0xf3, 0x07, 0x0f, 0x32,
                0xf2, 0x53, 0x73, 0x26, 0xbc, 0x14, 0x50, 0x38, 0xd4, 0x5a,
                0xb1, 0x0f, 0xed, 0x15, 0x3f, 0xa1, 0x70, 0x07, 0xbc,
            });
            Assert.Equal(tlv.GetType(Constants.Proof), new byte[] { 0x54, 0xa2, 0x3c, 0x5b, 0xb1, 0x0a, 0xc8, 0x78,
                                                                    0x8a, 0xb4, 0xbe, 0x87, 0x94, 0x3c, 0x30, 0xd2,
                                                                    0x77, 0x8c, 0xa3, 0xeb, 0x98, 0xcf, 0x6c, 0xbb,
                                                                    0x37, 0x9b, 0x66, 0x37, 0x0a, 0x0c, 0xa3, 0xe0,
                                                                    0x13, 0x36, 0x99, 0x50, 0x84, 0xc2, 0xef, 0xbc,
                                                                    0x67, 0x51, 0xa0, 0xa8, 0x5b, 0x1d, 0x62, 0x75,
                                                                    0xbd, 0x40, 0x19, 0x92, 0xa6, 0x44, 0xa6, 0x5f,
                                                                    0x69, 0xbe, 0xd2, 0xc2, 0x03, 0x4e, 0x69, 0x74 });


            var serialized = TlvParser.Serialize(tlv);

            Assert.Equal(TlvTestData.PairSetupM3, serialized);
        }
Example #22
0
 public void TestOnlyLastTlvFragmentItemInContiguousTlvMyHaveNon255Length()
 {
     Assert.Throws <TlvFragmentLengthException>(() => TlvParser.Parse(TlvTestData.OnlyLastTlvMayHaveNo255Length));
 }
Example #23
0
 public void TestEveryTlvFragmentMustHaveNon0Length()
 {
     Assert.Throws <TlvFragmentLengthException>(() => TlvParser.Parse(TlvTestData.EveryTlvFragmentNon0Length));
 }
Example #24
0
 public void TestEveryTlvTypeSingleAndNotFragmented()
 {
     Assert.Throws <TlvTypeDuplicationException>(() => TlvParser.Parse(TlvTestData.EveryTlvNotFragmented));
 }
Example #25
0
        public PairVerifyReturn Post(Tlv parts, HapSession session)
        {
            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1)
            {
                _logger.LogDebug("* Pair Verify Step 1/4");
                _logger.LogDebug("* Verify Start Request");

                var clientPublicKey = parts.GetType(Constants.PublicKey);

                byte[] privateKey = new byte[32];

                Random random = new Random();
                random.NextBytes(privateKey);

                var publicKey    = Curve25519.GetPublicKey(privateKey);
                var sharedSecret = Curve25519.GetSharedSecret(privateKey, clientPublicKey);

                var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);

                var material      = publicKey.Concat(serverUsername).Concat(clientPublicKey).ToArray();
                var accessoryLtsk = StringToByteArray(HapControllerServer.HapControllerLtsk);

                var proof = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);

                var hdkf       = new HkdfSha512();
                var hkdfEncKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Salt"),
                                                  Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Info"), 32);

                var encoder = new Tlv();
                encoder.AddType(Constants.Identifier, serverUsername);
                encoder.AddType(Constants.Signature, proof);
                var plaintext = TlvParser.Serialize(encoder);

                var zeros = new byte[] { 0, 0, 0, 0 };
                var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg02"));

                var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                    new byte[0], plaintext);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.EncryptedData, encryptedOutput);
                responseTlv.AddType(Constants.PublicKey, publicKey);

                // Store the details on the session.
                //
                session.ClientPublicKey = clientPublicKey;
                session.PrivateKey      = privateKey;
                session.PublicKey       = publicKey;
                session.SharedSecret    = sharedSecret;
                session.HkdfPairEncKey  = hkdfEncKey;


                var encSalt   = Encoding.UTF8.GetBytes("Control-Salt");
                var infoRead  = Encoding.UTF8.GetBytes("Control-Read-Encryption-Key");
                var infoWrite = Encoding.UTF8.GetBytes("Control-Write-Encryption-Key");

                session.AccessoryToControllerKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoRead, 32);
                session.ControllerToAccessoryKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoWrite, 32);

                return(new PairVerifyReturn
                {
                    TlvData = responseTlv,
                    Ok = true,
                    HapSession = session
                });
            }

            if (state == 3)
            {
                _logger.LogDebug("* Pair Verify Step 3/4");
                _logger.LogDebug("* Verify Finish Request");

                var encryptedData = parts.GetType(Constants.EncryptedData);
                var zeros         = new byte[] { 0, 0, 0, 0 };
                var nonce         = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg03"));

                var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(Key.Import(AeadAlgorithm.ChaCha20Poly1305, session.HkdfPairEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], encryptedData, out var output);

                if (!decrypt)
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var subData        = TlvParser.Parse(output);
                var clientUserName = subData.GetType(Constants.Identifier);
                var signature      = subData.GetType(Constants.Signature);

                var clientPublicKey = StringToByteArray(HapControllerServer.HapControllerLtpk);
                var material        = session.ClientPublicKey.Concat(clientUserName).Concat(session.PublicKey).ToArray();

                session.ClientUsername = Automatica.Core.Driver.Utility.Utils.ByteArrayToString(in clientUserName);

                if (!Chaos.NaCl.Ed25519.Verify(signature, material, clientPublicKey))
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);

                session.IsVerified          = true;
                session.SkipFirstEncryption = true;

                return(new PairVerifyReturn
                {
                    Ok = true,
                    TlvData = responseTlv
                });
            }

            return(null);
        }
Example #26
0
        public Tuple <string, byte[]> Invoke(string connectionId, string url, string method, byte[] inputData,
                                             ConnectionSession session)
        {
            if (!_sessions.ContainsKey(connectionId))
            {
                _sessions.TryAdd(connectionId, new HapSession());
            }


            _logger.LogDebug($"Working on request {url}");
            var queryString = new NameValueCollection();

            if (url.Contains("?"))
            {
                var parts = url.Split('?');

                queryString = HttpUtility.ParseQueryString(parts[1]);
                url         = parts[0];
            }

            try
            {
                if (inputData.Length > 0)
                {
                    var parts = TlvParser.Parse(inputData);

                    if (method == "POST")
                    {
                        var state = parts.GetTypeAsInt(Constants.State);

                        if (url.EndsWith("pair-setup"))
                        {
                            _logger.LogDebug($"Working on pair-setup request");
                            if (_pairController != null && state == 1)
                            {
                                return(ReturnError(state, ErrorCodes.Busy));
                            }

                            if (state == 1 && _pairController == null)
                            {
                                _pairController =
                                    new PairSetupController(_logger, _pairCode);
                            }

                            if (_pairController == null)
                            {
                                _logger.LogError($"Something is wrong here, closing tcp connection");
                                throw new ArgumentException($"Something is wrong here, closing tcp connection");
                            }

                            var data = _pairController.Post(parts, session);

                            var raw = TlvParser.Serialize(data.TlvData);

                            if (!data.Ok)
                            {
                                _pairController = null;
                                _sessions.TryRemove(connectionId, out var _);
                            }
                            else if (data.State == 5)
                            {
                                PairingCompleted?.Invoke(this, new PairSetupCompleteEventArgs(data.Ltsk, data.Ltpk));
                                _pairController = null;
                            }

                            return(new Tuple <string, byte[]>(PairSetupReturn.ContentType, raw));
                        }

                        if (url.EndsWith("pair-verify"))
                        {
                            _logger.LogDebug($"Working on pair-verify request");
                            if (string.IsNullOrEmpty(HapControllerServer.HapControllerLtsk))
                            {
                                return(ReturnError(state, ErrorCodes.Busy));
                            }

                            var verify = new PairVerifyController(_logger);
                            var data   = verify.Post(parts, _sessions[connectionId]);

                            if (data.HapSession != null)
                            {
                                _sessions[connectionId] = data.HapSession;
                            }

                            var raw = TlvParser.Serialize(data.TlvData);
                            return(new Tuple <string, byte[]>(data.ContentType, raw));
                        }

                        if (url.EndsWith("pairings"))
                        {
                            _logger.LogDebug($"Working on pairings");
                            var pair = new PairingController(_logger);
                            var data = pair.Post(parts);

                            var raw = TlvParser.Serialize(data.TlvData);
                            return(new Tuple <string, byte[]>(data.ContentType, raw));
                        }

                        if (url.EndsWith("identify"))
                        {
                            var identify = new IdentifyController();
                            var data     = identify.Post(inputData);

                            return(new Tuple <string, byte[]>(data.ContentType, new byte[0]));
                        }
                    }
                    else if (method == "PUT")
                    {
                        if (url.EndsWith("characteristics"))
                        {
                            _logger.LogDebug($"Working on characteristics");
                            var c    = new CharacteristicsController(_logger);
                            var data = c.Put(inputData, _sessions[connectionId], _homeKitServer);

                            // response with no data if the call was successful - errors need to be implemented
                            return(new Tuple <string, byte[]>(data.ContentType, new byte[0]));
                        }
                    }
                }
                else
                {
                    if (method == "GET")
                    {
                        if (url.EndsWith("accessories"))
                        {
                            _logger.LogDebug($"Working on accessories");

                            var accessoryController = new AccesoriesController(_logger);
                            var accessories         = accessoryController.Get(_homeKitServer, queryString);
                            var strValue            = JsonConvert.SerializeObject(accessories, JsonSettings);

                            _logger.LogDebug($"Sending {strValue}");

                            return(new Tuple <string, byte[]>("application/hap+json", Encoding.UTF8.GetBytes(strValue)));
                        }

                        if (url.EndsWith("characteristics"))
                        {
                            _logger.LogDebug($"Working on characteristics");

                            var ids      = queryString["id"].Split(",");
                            var c        = new CharacteristicsController(_logger);
                            var data     = c.Get(ids, _homeKitServer);
                            var strValue = JsonConvert.SerializeObject(data, JsonSettings);

                            _logger.LogDebug($"Sending {strValue}");

                            return(new Tuple <string, byte[]>(data.ContentType, Encoding.UTF8.GetBytes(strValue)));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"{e}: Error occured while processing request");
                _pairController = null;
            }

            throw new InvalidOperationException();
        }
Example #27
0
        public Tuple <string, byte[]> Invoke(string connectionId, string url, string method, byte[] inputData)
        {
            if (!_sessions.ContainsKey(connectionId))
            {
                _sessions.Add(connectionId, new HapSession());
            }

            var queryString = new NameValueCollection();

            if (url.Contains("?"))
            {
                var parts = url.Split('?');

                queryString = HttpUtility.ParseQueryString(parts[1]);
                url         = parts[0];
            }

            try
            {
                if (inputData.Length > 0)
                {
                    var parts = TlvParser.Parse(inputData);

                    if (method == "POST")
                    {
                        var state = parts.GetTypeAsInt(Constants.State);

                        if (url.EndsWith("pair-setup"))
                        {
                            if (_pairController != null && state == 1)
                            {
                                return(ReturnError(state, ErrorCodes.Busy));
                            }

                            if (state == 1 && _pairController == null)
                            {
                                _pairController =
                                    new PairSetupController(_logger, _pairCode); //Todo: change code to param
                            }

                            var data = _pairController.Post(parts);

                            var raw = TlvParser.Serialise(data.TlvData);

                            if (!data.Ok)
                            {
                                _pairController = null;
                                _sessions.Remove(connectionId);
                            }
                            else if (data.State == 5)
                            {
                                PairingCompleted?.Invoke(this, new PairSetupCompleteEventArgs(data.Ltsk, data.Ltpk));
                                _pairController = null;
                            }

                            return(new Tuple <string, byte[]>(data.ContentType, raw));
                        }

                        if (url.EndsWith("pair-verify"))
                        {
                            if (string.IsNullOrEmpty(HapControllerServer.HapControllerLtsk))
                            {
                                return(ReturnError(state, ErrorCodes.Busy));
                            }

                            var verify = new PairVerifyController(_logger);
                            var data   = verify.Post(parts, _sessions[connectionId]);

                            if (data.HapSession != null)
                            {
                                _sessions[connectionId] = data.HapSession;
                            }

                            var raw = TlvParser.Serialise(data.TlvData);
                            return(new Tuple <string, byte[]>(data.ContentType, raw));
                        }

                        if (url.EndsWith("pairings"))
                        {
                            var pair = new PairingController(_logger);
                            var data = pair.Post(parts);

                            var raw = TlvParser.Serialise(data.TlvData);
                            return(new Tuple <string, byte[]>(data.ContentType, raw));
                        }

                        if (url.EndsWith("identify"))
                        {
                            var identify = new IdentifyController();
                            var data     = identify.Post(inputData);

                            return(new Tuple <string, byte[]>(data.ContentType, new byte[0]));
                        }
                    }
                    else if (method == "PUT")
                    {
                        if (url.EndsWith("characteristics"))
                        {
                            var c    = new CharacteristicsController(_logger);
                            var data = c.Put(inputData, _sessions[connectionId], _homeKitServer);

                            if (data.Characteristics.Count == 0)
                            {
                                return(new Tuple <string, byte[]>(data.ContentType, new byte[0]));
                            }
                            return(new Tuple <string, byte[]>(data.ContentType, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data))));
                        }
                    }
                }
                else
                {
                    if (method == "GET")
                    {
                        if (url.EndsWith("accessories"))
                        {
                            var accessoryController = new AccesoriesController();
                            var accessories         = accessoryController.Get(_homeKitServer, queryString);
                            var strValue            = JsonConvert.SerializeObject(accessories, JsonSettings);

                            return(new Tuple <string, byte[]>("application/hap+json", Encoding.UTF8.GetBytes(strValue)));
                        }

                        if (url.EndsWith("characteristics"))
                        {
                            var ids  = queryString["id"].Split(",");
                            var c    = new CharacteristicsController(_logger);
                            var data = c.Get(ids, _homeKitServer);

                            return(new Tuple <string, byte[]>(data.ContentType, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data, JsonSettings))));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Error occured while processing request");
                _pairController = null;
            }

            throw new InvalidOperationException();
        }
        public PairSetupReturn Post(Tlv parts)
        {
            var customParams = SrpParameters.Create3072 <SHA512>();

            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1) //srp sign up
            {
                var rnd = new Random();
                _salt = new byte[16];
                rnd.NextBytes(_salt);

                _saltInt = SrpInteger.FromByteArray(_salt);

                var srp = new SrpClient(customParams);
                _privateKey = srp.DerivePrivateKey(_saltInt.ToHex(), Username, _code);
                _verifier   = srp.DeriveVerifier(_privateKey);

                _server          = new SrpServer(customParams);
                _serverEphemeral = _server.GenerateEphemeral(_verifier);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.PublicKey, StringToByteArray(_serverEphemeral.Public));
                responseTlv.AddType(Constants.Salt, _salt);

                return(new PairSetupReturn
                {
                    State = 1,
                    TlvData = responseTlv,
                    Ok = true
                });
            }

            if (state == 3) //srp authenticate
            {
                _logger.LogDebug("Pair Setup Step 3/6");
                _logger.LogDebug("SRP Verify Request");

                var pubKey = parts.GetType(Constants.PublicKey);
                var proof  = parts.GetType(Constants.Proof);

                var iOsPublicKey = SrpInteger.FromByteArray(pubKey);
                var iOsProof     = SrpInteger.FromByteArray(proof);


                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);
                var ok = true;
                try
                {
                    _serverSession = _server.DeriveSession(_serverEphemeral.Secret, iOsPublicKey.ToHex(), _saltInt.ToHex(), Username, _verifier,
                                                           iOsProof.ToHex());
                    _logger.LogInformation("Verification was successful. Generating Server Proof (M2)");

                    responseTlv.AddType(Constants.Proof, StringToByteArray(_serverSession.Proof));
                }
                catch (Exception)
                {
                    ok = false;
                    _logger.LogError("Verification failed as iOS provided code was incorrect");
                    responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                }
                return(new PairSetupReturn
                {
                    State = 3,
                    Ok = ok,
                    TlvData = responseTlv
                });
            }

            if (state == 5)
            {
                _logger.LogDebug("Pair Setup Step 5/6");
                _logger.LogDebug("Exchange Response");

                try
                {
                    var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A
                    var zeros            = new byte[] { 0, 0, 0, 0 };
                    var nonce            = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05"));
                    var hdkf             = new HkdfSha512();
                    var hkdfEncKey       = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32);


                    var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                        new byte[0], iOsEncryptedData, out var output);
                    var responseTlv = new Tlv();
                    responseTlv.AddType(Constants.State, 6);
                    if (!decrypt)
                    {
                        responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = responseTlv,
                            Ok = false
                        });
                    }

                    var subData = TlvParser.Parse(output);

                    byte[] username = subData.GetType(Constants.Identifier);
                    byte[] ltpk     = subData.GetType(Constants.PublicKey);
                    byte[] proof    = subData.GetType(Constants.Signature);


                    var okm = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32);

                    var completeData = okm.Concat(username).Concat(ltpk).ToArray();


                    if (!SignatureAlgorithm.Ed25519.Verify(
                            PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData,
                            proof))
                    {
                        var errorTlv = new Tlv();
                        errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = errorTlv,
                            Ok = false
                        });
                    }

                    var accessory = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32);


                    var seed = new byte[32];
                    RandomNumberGenerator.Create().GetBytes(seed);
                    Chaos.NaCl.Ed25519.KeyPairFromSeed(out var accessoryLtpk, out var accessoryLtsk, seed);

                    var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);
                    var material       = accessory.Concat(serverUsername).Concat(accessoryLtpk).ToArray();

                    var signature = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);


                    var encoder = new Tlv();
                    encoder.AddType(Constants.Identifier, serverUsername);
                    encoder.AddType(Constants.PublicKey, accessoryLtpk);
                    encoder.AddType(Constants.Signature, signature);

                    var plaintext = TlvParser.Serialise(encoder);

                    var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06"));

                    var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6,
                        new byte[0], plaintext);

                    responseTlv.AddType(Constants.EncryptedData, encryptedOutput);

                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = responseTlv,
                        Ok = true,
                        Ltsk = ByteArrayToString(accessoryLtsk),
                        Ltpk = ByteArrayToString(ltpk)
                    });
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Could not exchange request");
                    throw;
                }
            }

            return(null);
        }
Example #29
0
        public void WhenAuthenticateUserWithSamlTokenThenNoExceptionIsThrown()
        {
            string       outerXml;
            XmlDocument  xmlDocument;
            SoapEnvelope soapEnvelope;
            var          beIdCardConnector = new BeIdCardConnector();
            var          context           = beIdCardConnector.EstablishContext();
            var          readers           = beIdCardConnector.GetReaders();
            var          connection        = beIdCardConnector.Connect(readers.First());

            var ehealthSamlTokenRequestBuilder = new EhealthSamlTokenRequestBuilder(); // 1. Construct SAML token.
            var certificate     = beIdCardConnector.GetAuthenticateCertificate();
            var tlvParser       = new TlvParser();
            var identityPayload = beIdCardConnector.GetIdentity();
            var addressPayload  = beIdCardConnector.GetAddress();
            var identity        = tlvParser.Parse <Identity>(identityPayload);
            var address         = tlvParser.Parse <Address>(addressPayload);

            ehealthSamlTokenRequestBuilder.New(certificate).SetIdentity(identity);

            soapEnvelope = ehealthSamlTokenRequestBuilder.Build();
            var signSamlToken = new SignSamlToken(); // 2. Build signature.
            var signatureNode = signSamlToken.BuildSignatureWithEid(soapEnvelope, "0726", beIdCardConnector);

            soapEnvelope.Header.Security.Signature = signatureNode;
            var soapSerializer = new SoapMessageSerializer(); // 3. Serialize the request.

            xmlDocument = soapSerializer.Serialize(soapEnvelope);
            outerXml    = xmlDocument.OuterXml;

            beIdCardConnector.Dispose();

            var nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);

            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.Ds, Common.Saml.Constants.XmlNamespaces.Ds);
            nsmgr.AddNamespace(Common.Saml.Constants.XmlPrefixes.Wsse, Common.Saml.Constants.XmlNamespaces.Wsse);
            var signatureValue      = xmlDocument.SelectSingleNode("//ds:SignatureValue", nsmgr).InnerText; // 5. Check signature value.
            var binarySecurityToken = xmlDocument.SelectSingleNode("//wsse:BinarySecurityToken", nsmgr).InnerText;
            var signedInfo          = xmlDocument.SelectSingleNode("//ds:SignedInfo", nsmgr).OuterXml;
            var serializer          = new XmlDsigExcC14NTransform();
            var doc = new XmlDocument();

            doc.LoadXml(signedInfo);
            serializer.LoadInput(doc);
            var c14n = new StreamReader((Stream)serializer.GetOutput(typeof(Stream))).ReadToEnd();
            var signedInfoPayload = Encoding.UTF8.GetBytes(c14n);
            var b64 = Convert.ToBase64String(signedInfoPayload);

            byte[] hashResult = null;
            using (var sha = new SHA1CryptoServiceProvider())
            {
                hashResult = sha.ComputeHash(signedInfoPayload);
            }

            var b64Hash            = Convert.ToBase64String(hashResult);
            var signature          = System.Convert.FromBase64String(signatureValue);
            var x509Certificate    = new X509Certificate2(Convert.FromBase64String(binarySecurityToken));
            var publicKey          = x509Certificate.GetRSAPublicKey();
            var isSignatureCorrect = publicKey.VerifyHash(hashResult, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);

            Assert.True(isSignatureCorrect);
        }