Skip to content

Commit

Permalink
- NET API: added TLS support for server side
Browse files Browse the repository at this point in the history
  • Loading branch information
mzillgith committed May 27, 2018
1 parent 38ee7b4 commit 49d06cc
Show file tree
Hide file tree
Showing 10 changed files with 457 additions and 16 deletions.
25 changes: 17 additions & 8 deletions dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using System.Collections;

using IEC61850.Common;
using IEC61850.TLS;

/// <summary>
/// IEC 61850 API for the libiec61850 .NET wrapper library
Expand Down Expand Up @@ -558,9 +559,6 @@ public delegate CheckHandlerResult CheckHandler (DataObject controlObject, objec
/// </summary>
public class IedServer
{
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedServer_create(IntPtr modelRef);

[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr IedServer_createWithConfig(IntPtr modelRef, IntPtr tlsConfiguration, IntPtr serverConfiguratio);

Expand Down Expand Up @@ -789,19 +787,30 @@ private void connectionIndicationHandler (IntPtr iedServer, IntPtr clientConnect

private Dictionary<IntPtr, ClientConnection> clientConnections = new Dictionary<IntPtr, ClientConnection> ();

public IedServer(IedModel iedModel)


public IedServer(IedModel iedModel, IedServerConfig config = null)
{
self = IedServer_create(iedModel.self);
IntPtr nativeConfig = IntPtr.Zero;

if (config != null)
nativeConfig = config.self;

self = IedServer_createWithConfig (iedModel.self, IntPtr.Zero, nativeConfig);
}

public IedServer(IedModel iedModel, IedServerConfig config)
public IedServer(IedModel iedModel, TLSConfiguration tlsConfig, IedServerConfig config = null)
{
IntPtr nativeConfig = IntPtr.Zero;
IntPtr nativeTLSConfig = IntPtr.Zero;

if (config != null)
nativeConfig = config.self;

self = IedServer_createWithConfig (iedModel.self, IntPtr.Zero, nativeConfig);
if (tlsConfig != null)
nativeTLSConfig = tlsConfig.GetNativeInstance ();

self = IedServer_createWithConfig (iedModel.self, nativeTLSConfig, nativeConfig);
}

// causes undefined behavior
Expand Down Expand Up @@ -850,7 +859,7 @@ public void Start(int tcpPort)
/// <summary>Start MMS server</summary>
public void Start ()
{
Start(102);
Start(-1);
}

/// <summary>
Expand Down
8 changes: 0 additions & 8 deletions dotnet/IEC61850forCSharp/TLS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ public void SetClientMode()
public void SetOwnCertificate(string filename)
{
if (TLSConfiguration_setOwnCertificateFromFile (self, filename) == false) {
Console.WriteLine ("Failed to read certificate from file!");
throw new CryptographicException ("Failed to read certificate from file");
}
}
Expand All @@ -149,15 +148,13 @@ public void SetOwnCertificate(X509Certificate2 cert)
byte[] certBytes = cert.GetRawCertData ();

if (TLSConfiguration_setOwnCertificate (self, certBytes, certBytes.Length) == false) {
Console.WriteLine ("Failed to set certificate!");
throw new CryptographicException ("Failed to set certificate");
}
}

public void AddAllowedCertificate(string filename)
{
if (TLSConfiguration_addAllowedCertificateFromFile (self, filename) == false) {
Console.WriteLine ("Failed to read allowed certificate from file!");
throw new CryptographicException ("Failed to read allowed certificate from file");
}
}
Expand All @@ -167,15 +164,13 @@ public void AddAllowedCertificate(X509Certificate2 cert)
byte[] certBytes = cert.GetRawCertData ();

if (TLSConfiguration_addAllowedCertificate (self, certBytes, certBytes.Length) == false) {
Console.WriteLine ("Failed to add allowed certificate!");
throw new CryptographicException ("Failed to add allowed certificate");
}
}

public void AddCACertificate(string filename)
{
if (TLSConfiguration_addCACertificateFromFile (self, filename) == false) {
Console.WriteLine ("Failed to read CA certificate from file!");
throw new CryptographicException ("Failed to read CA certificate from file");
}
}
Expand All @@ -185,15 +180,13 @@ public void AddCACertificate(X509Certificate2 cert)
byte[] certBytes = cert.GetRawCertData ();

if (TLSConfiguration_addCACertificate (self, certBytes, certBytes.Length) == false) {
Console.WriteLine ("Failed to add CA certificate!");
throw new CryptographicException ("Failed to add CA certificate");
}
}

public void SetOwnKey (string filename, string password)
{
if (TLSConfiguration_setOwnKeyFromFile (self, filename, password) == false) {
Console.WriteLine ("Failed to read own key from file!");
throw new CryptographicException ("Failed to read own key from file");
}
}
Expand All @@ -203,7 +196,6 @@ public void SetOwnKey (X509Certificate2 key, string password)
byte[] certBytes = key.Export (X509ContentType.Pkcs12);

if (TLSConfiguration_setOwnKey (self, certBytes, certBytes.Length, password) == false) {
Console.WriteLine ("Failed to set own key!");
throw new CryptographicException ("Failed to set own key");
}
}
Expand Down
6 changes: 6 additions & 0 deletions dotnet/dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "goose_subscriber", "goose_s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sv_subscriber", "sv_subscriber\sv_subscriber.csproj", "{44651D2D-3252-4FD5-8B8B-5552DBE1B499}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tls_server_example", "tls_server_example\tls_server_example.csproj", "{B63F7A81-1D3A-4F2F-A7C2-D6F77E5BD307}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -96,6 +98,10 @@ Global
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E29B4CE-EE5F-4CA6-85F6-5D1FF8B27BF8}.Release|Any CPU.Build.0 = Release|Any CPU
{B63F7A81-1D3A-4F2F-A7C2-D6F77E5BD307}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B63F7A81-1D3A-4F2F-A7C2-D6F77E5BD307}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B63F7A81-1D3A-4F2F-A7C2-D6F77E5BD307}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B63F7A81-1D3A-4F2F-A7C2-D6F77E5BD307}.Release|Any CPU.Build.0 = Release|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C351CFA4-E54E-49A1-86CE-69643535541A}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
85 changes: 85 additions & 0 deletions dotnet/tls_server_example/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Threading;
using System.Security.Cryptography.X509Certificates;

using IEC61850.Server;
using IEC61850.Common;
using IEC61850.TLS;

namespace tls_server_example
{
class MainClass
{
public static void Main (string[] args)
{
bool running = true;

/* run until Ctrl-C is pressed */
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) {
e.Cancel = true;
running = false;
};

IedModel iedModel = ConfigFileParser.CreateModelFromConfigFile ("model.cfg");

if (iedModel == null) {
Console.WriteLine ("No valid data model found!");
return;
}

DataObject spcso1 = (DataObject)iedModel.GetModelNodeByShortObjectReference ("GenericIO/GGIO1.SPCSO1");

TLSConfiguration tlsConfig = new TLSConfiguration ();

tlsConfig.SetOwnCertificate (new X509Certificate2 ("server.cer"));

tlsConfig.SetOwnKey ("server-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;

IedServer iedServer = new IedServer (iedModel, tlsConfig);

iedServer.SetControlHandler (spcso1, delegate(DataObject controlObject, object parameter, MmsValue ctlVal, bool test) {
bool val = ctlVal.GetBoolean();

if (val)
Console.WriteLine("received binary control command: on");
else
Console.WriteLine("received binary control command: off");

return ControlHandlerResult.OK;
}, null);

iedServer.Start ();
Console.WriteLine ("Server started");

GC.Collect ();

DataObject ggio1AnIn1 = (DataObject)iedModel.GetModelNodeByShortObjectReference ("GenericIO/GGIO1.AnIn1");

DataAttribute ggio1AnIn1magF = (DataAttribute)ggio1AnIn1.GetChild ("mag.f");
DataAttribute ggio1AnIn1T = (DataAttribute)ggio1AnIn1.GetChild ("t");

float floatVal = 1.0f;

while (running) {
floatVal += 1f;
iedServer.UpdateTimestampAttributeValue (ggio1AnIn1T, new Timestamp (DateTime.Now));
iedServer.UpdateFloatAttributeValue (ggio1AnIn1magF, floatVal);
Thread.Sleep (100);
}

iedServer.Stop ();
Console.WriteLine ("Server stopped");

iedServer.Destroy ();
}
}
}
27 changes: 27 additions & 0 deletions dotnet/tls_server_example/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -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_server_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("")]

Loading

0 comments on commit 49d06cc

Please sign in to comment.