TLS - Secure client-server communication using certificates or PSK (pre-shared key)

This example shows how secure data communication can be implemented using TLS (Transport Layer Security) in a TwinCAT IEC 61850 client and server application. The TLS protocol only allows encryption of client-server communication. The GOOSE publisher/subscriber data cannot be encrypted in this way. If you are using an older version of the TwinCAT IEC 61850 Telecontrol Configurator, the TLS functionality may not be supported there yet. To compile and test this sample project without errors you need a newer version of the TF6510 IEC 61850 Telecontrol.

System requirement

TF6510 IEC 61850 Telecontrol v3.1.96.7 or newer

Download TwinCAT XAE Project (*.zip): Sample30.zip

General information about this sample project

The TLS sample consists of two separate TwinCAT IEC 61850 projects. After unpacking the zip archive you will find a TwinCAT IEC 61850 client project in the subfolder \ClientWithTLS\Sample30 and a TwinCAT IEC 61850 server project in the subfolder \ServerWithTLS\Sample30.

The here described: Client - Basis sample project and here described: Server - Basis sample project served as basis for the TLS sample project.

This sample mainly shows two ways of TLS data encryption:

  1. TLS with certificates (e.g.: own, self-signed certificates).
  2. TLS with PSK (Pre-Shared Key).

Every TwinCAT IEC 61850 client/server project can be extended with TLS functionality in a relatively simple way. In order for the encryption/decryption of the data to work on both sides, this must also logically be done on both sides, the client and the server. This extension consists mainly of the configuration of private keys (private keys), passwords, certificates or PSK keys. When configuring the private keys and certificates, for example, the server or client function block is informed of the file paths to the folders where the private key files and certificates have been saved. The required TLS configuration parameters are saved in advance in a function block instance of the type: FB_SocketTlsSettingsClass provided for this purpose. This information is transferred to the IEC 61850 client/server function blocks via a defined interface of the type I_SocketTlsSettingsClass, which is implemented by the FB_SocketTlsSettingsClass function block. The IEC 61850 server and client function blocks access the saved TLS configuration and thus also the private key, certificate files via this interface during connection establishment. Upon success, a secure communication link is established.

Format of private keys and certificates

The certificate files must be in PEM (Privacy-Enhanced Mail) format. To ensure that the client or server can easily access the key and certificate files, the recommended location for the files is, for example, the following folder on the Windows target system: \TwinCAT\3.1\Target\Certificates\IEC61850.

The private key files and certificate files are text files. A private key file starts with the line:
"-----BEGIN PRIVATE KEY-----".
This is followed by the key and ends with the line:
"-----END PRIVATE KEY-----".
Example:

-----BEGIN PRIVATE KEY-----
MIIEzAIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDIx4bVTxEHDhuKWl0XJAkLZfqj
NvMkD26sv/VViprpeMCbU/fSun+2oJO1iczd7Ut66SQBBePxsFEQhfAhO0TaGDDrfF9WP7WbkGb7
...
V0um2x+kKJ8hsD9vfORBf7KnwJi0QitwG41PoGDUi6RD8IUybKbLc5a/hx1C5hR0TBnXuxpguzed
pq0NPKFQk7d0ArahQPrYmUySyfagDTALBgNVHQ8xBAMCAJA=
-----END PRIVATE KEY-----

The certificate files start with the line:
"-----BEGIN CERTIFICATE-----".
This is followed by the certificate data and ends with the line:
"-----END CERTIFICATE-----".
Sample:

-----BEGIN CERTIFICATE-----
MIIDyDCCArCgAwIBAgIQRGxL9tvn64FPEmnMEI8FLjANBgkqhkiG9w0BAQsFADBl
MWMwYQYDVQQDDFpSb290IENBLE9VPVR3aW5DQVQsTz1CZWNraG9mZiBBdXRvbWF0
...
6D2L4WEjrzIMR07EWJC4JKvDqxiQMAHsUkpy4vS817ZBsuL0/M8EbG9sTdEGxZp
9+GR0Np4ku7TkdJ5
-----END CERTIFICATE-----

TLS sample configuration with the FB_IEDTLSecurity function block

In order to further simplify the TLS configuration with the help of the function block FB_SocketTlsSettingsClass, an additional auxiliary function block "FB_IEDTLSecurity" was implemented in the "ClientWithTLS\Sample30" and also in the "ServerWithTLS\Sample30" project around the FB_SocketTlsSettingsClass function block.

The "FB_IEDTLSecurity" function block now has only one method: "Enable". The "Enable" method parameters can be used to enable/disable the TLS configuration and specify the type of TLS encryption in our example.

METHOD FINAL Enable : I_SocketTlsSettingsClass
VAR_INPUT
    bEnable : BOOL;
    bPSK    : BOOL;
END_VAR

bEnable: Enables/disables the TLS configuration. If "TRUE", all necessary TLS configuration settings are saved in the local instance "fbTls" of the FB_SocketTlsSettingsClass function block. The TLS configuration should be enabled in this case. The value "FALSE" disables the TLS configuration.

bPSK: Configures the type of encryption. If "TRUE", a secure TLS connection is established by using a PSK (Pre-Shared Key). If "FALSE", a secure TLS connection is established by exchanging the certificates.

Return parameter: If a valid interface pointer to the TLS configuration settings is returned (return value <> 0), then a secure TLS client-server connection shall be established. If the return value is null, a conventional connection (without TLS) should be established.

Server TLS sample configuration

The implementation of the "FB_IEDTLSecurity.Enable" method differs in the client and server projects. In the server project, the paths of the certificates and private keys of the server are configured, and in the client project, those of the client. The root CA certificate is the same certificate on both sides. The root CA certificate must be present on both systems.

VAR
    key       : ARRAY[0..14] OF BYTE:=[16#1B,16#D0,16#6F,16#D2,16#56,16#16,16#7D,16#C1,16#E8,16#C7,16#48,16#2A,16#8E,16#F5,16#FF];
    sIdentity : STRING(TCPADS_TLS_PSK_IDENTITY_SIZE)    :='MyIdentity';
    sCaPath   : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\rootCA.pem';
    sCertPath : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\127.0.0.1.pem';
    sKeyPath  : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\127.0.0.1.key';
    sKeyPwd   : STRING(TCPADS_TLS_KEY_PASSWORD_SIZE)    :='ServerPass';
    sCrlPath  : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='';
    flags     : ST_TlsListenFlags :=DEFAULT_TLSLISTENFLAGS;
END_VAR
IF bEnable THEN
    Enable:=fbTls.Reset();
    IF bPSK THEN
        fbTls.AddPsk(key:=key, sIdentity:=sIdentity);
    ELSE
        fbTls.AddCa(sCaPath:=sCaPath);
        fbTls.AddCert(sCertPath:=sCertPath, sKeyPath:=sKeyPath, sKeyPwd:=sKeyPwd);
        IF sCrlPath <> '' THEN
            fbTls.AddCrl(sCrlPath:=sCrlPath);
        END_IF
        fbTls.SetListenFlags(flags:=flags);
    END_IF
END_IF

Client TLS sample configuration

VAR
    key       : ARRAY[0..14] OF BYTE:=[16#1B,16#D0,16#6F,16#D2,16#56,16#16,16#7D,16#C1,16#E8,16#C7,16#48,16#2A,16#8E,16#F5,16#FF];
    sIdentity : STRING(TCPADS_TLS_PSK_IDENTITY_SIZE)    :='MyIdentity';
    sCaPath   : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\rootCA.pem';
    sCertPath : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\client.pem';
    sKeyPath  : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='C:\TwinCAT\3.1\Target\Certificates\IEC61850\client.key';
    sKeyPwd   : STRING(TCPADS_TLS_KEY_PASSWORD_SIZE)    :='ClientPass';
    sCrlPath  : STRING(TCPADS_TLS_CERTIFICATE_PATH_SIZE):='';
    flags     : ST_TlsConnectFlags :=DEFAULT_TLSCONNECTFLAGS;
END_VAR
IF bEnable THEN
    Enable:=fbTls.Reset();
    IF bPSK THEN
        fbTls.AddPsk(key:=key, sIdentity:=sIdentity);
    ELSE
        fbTls.AddCa(sCaPath:=sCaPath);
        fbTls.AddCert(sCertPath:=sCertPath, sKeyPath:=sKeyPath, sKeyPwd:=sKeyPwd);
        IF sCrlPath <> '' THEN
            fbTls.AddCrl(sCrlPath:=sCrlPath);
        END_IF
        fbTls.SetConnectFlags(flags:=flags);
    END_IF
END_IF

Initialization of the TLS configuration in the IEC 61850 server or client

The "FB_IEDTLSecurity" function block is instantiated in the "TcTelecontrol" global variable list. The TLS configuration settings are passed to the IEC 61850 server or client by setting the "ipTLS" property in the server or client protocol settings. By assigning a valid interface pointer to the "ipTLS" property, the TLS configuration settings and thus TLS encryption are enabled. By assigning a null to the "ipTLS" property, the TLS configuration and encryption is disabled. In this example, we use the return value of the "Enable" method to enable (return value <> null) or disable (return value = null) TLS encryption. The return value of the "Enable" method is always null if the "bEnable" method parameter is "FALSE".

Set the server TLS configuration

The server in this sample has the IP address: "127.0.0.1". This address may need to be adjusted.

VAR_GLOBAL

    fbIEDTLSecurity: FB_IEDTLSecurity;
    fbIEDServer: FB_iec61850ServerClass := (ipIED:=fbIED, settings:=(bEnable:=TRUE, sLocalHost:='127.0.0.1', ipTLS:=fbIEDTLSecurity.Enable(bEnable:=TRUE, bPSK:=TRUE)));

END_VAR

Setting the client TLS configuration

The client in this sample connects to a server with the IP address: "127.0.0.1". This address may also need to be adjusted.

VAR_GLOBAL

    fbIEDTLSecurity: FB_IEDTLSecurity;
    fbIEDClient: FB_IEDClient := (fbConnection:=(ipIED:=fbIED, settings:=(sRemoteHost:='127.0.0.1', ipTLS:=fbIEDTLSecurity.Enable(bEnable:=TRUE, bPSK:=TRUE))));

END_VAR

Special features of the server certificate

For TLS data encryption with certificates, the host name or IP address of the server is configured as either a "CommonName" or "Subject Alternative Name" parameter in the certificate. I.e. if you have adjusted the IP addresses in this sample and want to test the TLS encryption with certificates then you must also set the "CommonName" or the "Subject Alternative Name" in your certificate accordingly. Self-signed certificates can be used for testing. Such certificates can be created, for example, under Windows using a Power Shell script. Under Windows, the "CommonName" or the "Subject Alternative Name" can be checked relatively easily.

Sample certificate with "CommonName"='192.168.10.160':

TLS - Secure client-server communication using certificates or PSK (pre-shared key) 1:

Sample certificate with "Subject Alternative Name" = '127.0.0.1':

TLS - Secure client-server communication using certificates or PSK (pre-shared key) 2:

Secure ISO TP0 port

It is recommended to use the (Secure ISO TP0) port number specified by IANA for active TLS communication (default value: 3782). Via the property "FB_SocketTlsSettingsClass.nSecurePort" this port number (for the server and client) can be reconfigured to another value. In our implementation, this port number is automatically used once TLS configuration has been enabled by setting the "ipTLS" property in the IEC 61850 client or server function block. If no TLS configuration is active then the port number: "fbIEDServer.settings.nLocalPort" is used for the server and the port number: "fbIEDClient.fbConnection.settings.nRemotePort" is used for the client (default value: 102).

Test of the secure TLS connection with PSK

In both, client/server sample projects, TLS with PSK (Pre-Shared Key) is configured and enabled by default. No certificates are required for TLS with PSK. For a simple function test, only the IP addresses in both projects need to be adjusted.

Test of the secure TLS connection with certificates

If you want to test TLS with certificates, then first copy the certificates and private keys to the server and client target systems.

Server target system:

Client target system:

The file names above are only example names. You can adjust the paths and file names in the "Enable" method of the "FB_IEDTLSecurirty" function block. To enable the TLS configuration with certificates, the "bPSK" parameter in the "FB_IEDTLSecurity.Enable" method must be set to "FALSE".

Enable TLS with certificate in the server project:

VAR_GLOBAL

fbIEDServer: FB_iec61850ServerClass := (ipIED:=fbIED, settings:=(bEnable:=TRUE, sLocalHost:='192.168.10.141', ipTLS:=fbIEDTLSecurity.Enable(bEnable:=TRUE, bPSK:=FALSE)));

END_VAR

Enable TLS with certificate in the client project:

VAR_GLOBAL

fbIEDClient: FB_IEDClient := (fbConnection:=(ipIED:=fbIED, settings:=(sRemoteHost:='192.168.10.141', ipTLS:=fbIEDTLSecurity.Enable(bEnable:=TRUE, bPSK:=FALSE))));

END_VAR