diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs index aef42ee1..9aa0cb4d 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Collections; using IEC61850.Common; +using IEC61850.TLS; /// /// IEC 61850 API for the libiec61850 .NET wrapper library @@ -276,6 +277,9 @@ namespace IEC61850 [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] static extern IntPtr IedConnection_create (); + [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] + static extern IntPtr IedConnection_createWithTlsSupport (IntPtr tlsConfig); + [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] static extern void IedConnection_destroy (IntPtr self); @@ -405,11 +409,23 @@ namespace IEC61850 private InternalConnectionClosedHandler connectionClosedHandler; private ConnectionClosedHandler userProvidedHandler = null; + /// + /// Initializes a new instance of the class. + /// public IedConnection () { connection = IedConnection_create (); } + /// + /// Initializes a new instance of the class. + /// + /// TLS configuration to use + public IedConnection (TLSConfiguration tlsConfig) + { + connection = IedConnection_createWithTlsSupport (tlsConfig.GetNativeInstance ()); + } + /// /// Releases all resource used by the object. /// @@ -504,7 +520,7 @@ namespace IEC61850 /// This exception is thrown if there is a connection or service error. public void Connect (string hostname) { - Connect (hostname, 102); + Connect (hostname, -1); } /// This exception is thrown if there is a connection or service error diff --git a/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj b/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj deleted file mode 100644 index dc2a4dc5..00000000 --- a/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - Debug - AnyCPU - {C35D624E-5506-4560-8074-1728F1FA1A4D} - Library - iec61850dotnet - iec61850dotnet - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - none - true - bin\Release - prompt - 4 - false - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dotnet/authenticate/authenticate.csproj b/dotnet/authenticate/authenticate.csproj index 09bbea29..c05c41f8 100644 --- a/dotnet/authenticate/authenticate.csproj +++ b/dotnet/authenticate/authenticate.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/control/control.csproj b/dotnet/control/control.csproj index c6a4e07f..efe7f4ca 100644 --- a/dotnet/control/control.csproj +++ b/dotnet/control/control.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/datasets/datasets.csproj b/dotnet/datasets/datasets.csproj index 17802618..312ccbfd 100644 --- a/dotnet/datasets/datasets.csproj +++ b/dotnet/datasets/datasets.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/dotnet.sln b/dotnet/dotnet.sln index 79e8b7fd..b199c1aa 100644 --- a/dotnet/dotnet.sln +++ b/dotnet/dotnet.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 VisualStudioVersion = 12.0.40629.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IEC61850forCSharp", "IEC61850forCSharp\IEC61850forCSharp.csproj", "{C35D624E-5506-4560-8074-1728F1FA1A4D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IEC61850.NET", "IEC61850forCSharp\IEC61850.NET.csproj", "{C35D624E-5506-4560-8074-1728F1FA1A4D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example1", "example1\example1.csproj", "{C616A6DF-831E-443C-9310-3F343A6E3D1A}" EndProject @@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{0D2F61 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "server1", "server1\server1.csproj", "{9286D2AB-96ED-4631-AB3C-ED20FF5D6E6C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tls_client_example", "tls_client_example\tls_client_example.csproj", "{6734BF52-2D0D-476B-8EA2-C9C2D1D69B03}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -62,6 +64,10 @@ Global {5E5D0FE0-DF44-48D8-A10E-1FB07D34DEA2}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E5D0FE0-DF44-48D8-A10E-1FB07D34DEA2}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E5D0FE0-DF44-48D8-A10E-1FB07D34DEA2}.Release|Any CPU.Build.0 = Release|Any CPU + {6734BF52-2D0D-476B-8EA2-C9C2D1D69B03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6734BF52-2D0D-476B-8EA2-C9C2D1D69B03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6734BF52-2D0D-476B-8EA2-C9C2D1D69B03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6734BF52-2D0D-476B-8EA2-C9C2D1D69B03}.Release|Any CPU.Build.0 = Release|Any CPU {71485F99-2976-45E6-B73D-4946E594C15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {71485F99-2976-45E6-B73D-4946E594C15C}.Debug|Any CPU.Build.0 = Debug|Any CPU {71485F99-2976-45E6-B73D-4946E594C15C}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/dotnet/example1/Main.cs b/dotnet/example1/Main.cs index eb70ce5c..738d839e 100644 --- a/dotnet/example1/Main.cs +++ b/dotnet/example1/Main.cs @@ -26,7 +26,6 @@ namespace example1 Console.WriteLine("Connect to " + hostname); - try { con.Connect(hostname, port); diff --git a/dotnet/example1/example1.csproj b/dotnet/example1/example1.csproj index 453058eb..592905b5 100644 --- a/dotnet/example1/example1.csproj +++ b/dotnet/example1/example1.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/example2/example2.csproj b/dotnet/example2/example2.csproj index 496e11cb..612fcdb5 100644 --- a/dotnet/example2/example2.csproj +++ b/dotnet/example2/example2.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/example3/example3.csproj b/dotnet/example3/example3.csproj index 53285216..4f60434a 100644 --- a/dotnet/example3/example3.csproj +++ b/dotnet/example3/example3.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/files/files.csproj b/dotnet/files/files.csproj index 2ecf30fe..ba8c3186 100644 --- a/dotnet/files/files.csproj +++ b/dotnet/files/files.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/log_client/log_client.csproj b/dotnet/log_client/log_client.csproj index 28c90c24..23243060 100644 --- a/dotnet/log_client/log_client.csproj +++ b/dotnet/log_client/log_client.csproj @@ -36,9 +36,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/model_browsing/model_browsing.csproj b/dotnet/model_browsing/model_browsing.csproj index 0827b41d..8162b3f8 100644 --- a/dotnet/model_browsing/model_browsing.csproj +++ b/dotnet/model_browsing/model_browsing.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/report_new_dataset/report_new_dataset.csproj b/dotnet/report_new_dataset/report_new_dataset.csproj index b91d522c..ccf2dc93 100644 --- a/dotnet/report_new_dataset/report_new_dataset.csproj +++ b/dotnet/report_new_dataset/report_new_dataset.csproj @@ -35,9 +35,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/reporting/reporting.csproj b/dotnet/reporting/reporting.csproj index 81a9d0ea..53a5829e 100644 --- a/dotnet/reporting/reporting.csproj +++ b/dotnet/reporting/reporting.csproj @@ -51,9 +51,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET diff --git a/dotnet/server1/server1.csproj b/dotnet/server1/server1.csproj index 617705c1..5d820daf 100644 --- a/dotnet/server1/server1.csproj +++ b/dotnet/server1/server1.csproj @@ -36,9 +36,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET \ No newline at end of file diff --git a/dotnet/tests/tests.csproj b/dotnet/tests/tests.csproj index 8d35ba82..ecaf4e89 100644 --- a/dotnet/tests/tests.csproj +++ b/dotnet/tests/tests.csproj @@ -31,9 +31,9 @@ - + {C35D624E-5506-4560-8074-1728F1FA1A4D} - IEC61850forCSharp + IEC61850.NET diff --git a/dotnet/tls_client_example/Program.cs b/dotnet/tls_client_example/Program.cs new file mode 100644 index 00000000..835b33d6 --- /dev/null +++ b/dotnet/tls_client_example/Program.cs @@ -0,0 +1,101 @@ +using System; +using IEC61850.Client; +using IEC61850.Common; +using IEC61850.TLS; +using System.Threading; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; + +namespace tls_client_example +{ + class MainClass + { + public static void Main (string[] args) + { + TLSConfiguration tlsConfig = new TLSConfiguration (); + + tlsConfig.SetOwnCertificate (new X509Certificate2 ("client1.cer")); + + tlsConfig.SetOwnKey ("client1-key.pem", null); + + // Add a CA certificate to check the certificate provided by the server - not required when ChainValidation == false + tlsConfig.AddCACertificate (new X509Certificate2 ("root.cer")); + + // Check if the certificate is signed by a provided CA + tlsConfig.ChainValidation = true; + + // Check that the shown server certificate is in the list of allowed certificates + tlsConfig.AllowOnlyKnownCertificates = false; + + IedConnection con = new IedConnection (tlsConfig); + + string hostname; + + if (args.Length > 0) + hostname = args[0]; + else + hostname = "127.0.0.1"; + + int port = -1; + + if (args.Length > 1) + port = Int32.Parse(args [1]); + + Console.WriteLine("Connect to " + hostname); + + try + { + con.Connect(hostname, port); + + List serverDirectory = con.GetServerDirectory(false); + + foreach (string entry in serverDirectory) + { + Console.WriteLine("LD: " + entry); + } + + List lnDirectory = con.GetLogicalNodeDirectory("simpleIOGenericIO/LLN0", ACSIClass.ACSI_CLASS_DATA_SET); + + foreach (string entry in lnDirectory) + { + Console.WriteLine("Dataset: " + entry); + } + + string vendor = con.ReadStringValue ("simpleIOGenericIO/LLN0.NamPlt.vendor", FunctionalConstraint.DC); + Console.WriteLine ("Vendor: " + vendor); + + /* read FCDO */ + MmsValue value = con.ReadValue("simpleIOGenericIO/GGIO1.AnIn1", FunctionalConstraint.MX); + + if (value.GetType() == MmsType.MMS_STRUCTURE) + { + Console.WriteLine("Value is of complex type"); + + for (int i = 0; i < value.Size(); i++) + { + Console.WriteLine(" element: " + value.GetElement(i).GetType()); + if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME) + { + Console.WriteLine(" -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset()); + } + } + } + + DataSet dataSet = con.ReadDataSetValues("simpleIOGenericIO/LLN0.Events", null); + + Console.WriteLine("Read data set " + dataSet.GetReference()); + + con.Abort(); + } + catch (IedConnectionException e) + { + Console.WriteLine(e.Message); + } + + System.Threading.Thread.Sleep(2000); + + // release all resources - do NOT use the object after this call!! + con.Dispose (); + } + } +} diff --git a/dotnet/tls_client_example/Properties/AssemblyInfo.cs b/dotnet/tls_client_example/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..00fcb3e8 --- /dev/null +++ b/dotnet/tls_client_example/Properties/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle ("tls_client_example")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("mzillgit")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion ("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/dotnet/tls_client_example/client1-key.pem b/dotnet/tls_client_example/client1-key.pem new file mode 100644 index 00000000..c39425cc --- /dev/null +++ b/dotnet/tls_client_example/client1-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxAMUXdnem99n5J8Z8Wa0fdPtoMCTdkQJrOO6WJ4XePrpQgHU +HDziSmdIZDDkpJ3Ey0Byy+b+iiRDmOuIZGSCsI0ehggWaia12h2osUK0BLyThuZ/ +RQw54K0dy61eviNaYsftiBcxHYKyKmWch/wLLYxdd1qLzd0reAbSUaHDkDzrj9hO +8qr7DhKpqx7PoVh1gFhAKPKuY6b+4xqv5eZvt8QflQTWYGxaxmUIEinqCnzh1l5d +tp0rhnBsz9Y4y8dXjh0m7pbXmRNY6opMxXatqgYEqsntLy1N6x7DvWLBqtVvEmox +Tc5bbAoRW3eEToClDdFQBzLsMVcSEX8vwttk3QIDAQABAoIBABHr1ijeiqPlwTH9 ++flAUrBOeCOCd/kQL3JHP/pqOestxbXrROFwD6CN4OiIL999LUkIE3bhH9SxjByn +LElBh1FtFaVbh/EcqPPQUmQinSLxuutSl8BQZdpM+bRtnYP054awkN8of60bDf8i +WzVzrfH0K3eGJ9Iirp7CwOgFykOdpQyxsI+HG8grcwA87x1ZsAIfHhiKmQByliNl +BkbJmYBOtfVgXje5QdxTptlTNljFSbZcaCXv1P3aOqctcgJMQjg0T+E37Y8Cav80 +6SuXbpv/cdacG695MAT7Vtywue0Axh59DvxAzc+deyQT70Hzw+Mo6pgi0clFnwzU +Y5ViDWECgYEAxxhRKzpz7klnmGob5CZvrbqDfC3JUEOxKH0e342S/HmT05bTI21w +N8A0KStNjQXS1mmkAkY/OO1Zutmf6yjqsxAIEO5UMTCSEP7YLRB7qBdN7dOt3JaK +4wxErMCljdT68Vj5Qj8YzIXJkWPk871oFTvVNe2qxgrCUigE5ai2I8cCgYEA/Akv +E0L+2uXayEucEamzO3n9xVziNanjyHilnJJvduvO9gd+crBbxSKqaXSdfPnp2mSa ++e3N7elxP2b/kPrGkzZekSaMh1nPH4Upu+ISK117r1x+vmnxZHRpehrVh1QzOQ5p +Ljt+GaXa3ur3P/6uW5KMbtGGW6MEgDwLMLvpqjsCgYA5pnfyfYWOTWEbCDa1VM/n +zWc/cP6nKELHR5vF/fe+9fFxRm4zBwCElDpGZYyaNkJ75bEhG3g5Irll2phs/rcf +TJgZVvm4GKljFHhCbFByNvVQ1Ye1pT3oSugj4dDOhgp4Elxy61Rh/KeGWxez4Heg +FmhBqmVV3U2xfncUjUrYhwKBgQCKtPM3gpOIHSA/Q31tKxv9C7JiQDAuoIU/+0YJ +2X2G0VhhhtZMgErBP8bRquBRu6i8DMpN6lZ/LQ6qeiEExT8sHawF7lVA2GhpTHwf +btfZDeXYKOuIF/5F7ttt2/7QL8LRD+FLFGrd6q1+KYpRqfSDaS/ofV+YZys+98yg +0YpTqQKBgQCWJpV2ySgXcKJzAUh14VNpLTRzJOMSpsU576nwz0TLUREVjiH6rvKr +gxllDEe1bVNMEekaZ+dOqiJX+4aTnEbIrEXki5Dvz0vq8biImW9RRdPEHgYVTv/d +qBOPHiIq2JiY6abD9XNPM3VQ/z8em6/4mkC8COCJRd2mA89FOYRxOQ== +-----END RSA PRIVATE KEY----- diff --git a/dotnet/tls_client_example/client1.cer b/dotnet/tls_client_example/client1.cer new file mode 100644 index 00000000..a5aa8db3 Binary files /dev/null and b/dotnet/tls_client_example/client1.cer differ diff --git a/dotnet/tls_client_example/root.cer b/dotnet/tls_client_example/root.cer new file mode 100644 index 00000000..87683444 Binary files /dev/null and b/dotnet/tls_client_example/root.cer differ diff --git a/dotnet/tls_client_example/tls_client_example.csproj b/dotnet/tls_client_example/tls_client_example.csproj new file mode 100644 index 00000000..389abef9 --- /dev/null +++ b/dotnet/tls_client_example/tls_client_example.csproj @@ -0,0 +1,55 @@ + + + + Debug + AnyCPU + {6734BF52-2D0D-476B-8EA2-C9C2D1D69B03} + Exe + tls_client_example + tls_client_example + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + + + + + + + + + {C35D624E-5506-4560-8074-1728F1FA1A4D} + IEC61850.NET + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index 30c8a502..2fd5f491 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -504,7 +504,6 @@ IedConnection_create() IedConnection IedConnection_createWithTlsSupport(TLSConfiguration tlsConfig) - { return createNewConnectionObject(tlsConfig); }