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); }
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); }
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)); }
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)); }
public TlvIdentity GetIdentity() { var payload = ReadFile(FileType.Identity); var parser = new TlvParser(); return(parser.Parse <TlvIdentity>(payload)); }
public TlvAddress GetAddress() { var payload = ReadFile(FileType.Address); var parser = new TlvParser(); return(parser.Parse <TlvAddress>(payload)); }
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); }
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)); }
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); } }
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); } }
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)); }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
public void TestOnlyLastTlvFragmentItemInContiguousTlvMyHaveNon255Length() { Assert.Throws <TlvFragmentLengthException>(() => TlvParser.Parse(TlvTestData.OnlyLastTlvMayHaveNo255Length)); }
public void TestEveryTlvFragmentMustHaveNon0Length() { Assert.Throws <TlvFragmentLengthException>(() => TlvParser.Parse(TlvTestData.EveryTlvFragmentNon0Length)); }
public void TestEveryTlvTypeSingleAndNotFragmented() { Assert.Throws <TlvTypeDuplicationException>(() => TlvParser.Parse(TlvTestData.EveryTlvNotFragmented)); }
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); }
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(); }
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); }
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); }