QuickOPC User's Guide and Reference
Providing OPC UA Client Instance Certificate
Fundamentals > Security > OPC UA Client-Server Security > Providing OPC UA Client Instance Certificate
In This Topic

Similarly to server instance certificate checking described above, in a secured OPC-UA solution, the OPC client identifies itself to the OPC server using its own instance certificate. The OPC server authenticates the certificate and checks whether the communication with that OPC client is authorized. Typically, the process of checking other party’s instance certificate is achieved through use of certificate trust lists, accessible programmatically and by means of UA Configuration Tool (installed with our product, and with OPC-UA downloads provided by OPC Foundation).

Since with QuickOPC-UA you are developing an OPC-UA client application, this client application must therefore typically provide its instance certificate to the OPC servers it is connecting to. QuickOPC-UA attempts to make this process easier by automatically selecting parameters for the certificate, and if the certificate does not exist yet, by creating it and storing into the appropriate certificate store on the computer. Depending on your deployment scenario, you may also create the certificate and put it into the certificate store by some other means, and in that case, you would simply let QuickOPC-UA use that certificate.

// This example demonstrates how to set the application name for the client certificate.

using System;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._UAApplicationManifest
{
    class ApplicationName
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (not in .NET Standard)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Hook static events
            EasyUAClient.LogEntry += EasyUAClientOnLogEntry;

            try
            {
                // Set the application name, which determines the subject of the client certificate.
                // Note that this only works once in each host process.
                EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest.ApplicationName = 
                    "QuickOPC - CSharp example application";

                // Do something - invoke an OPC read, to trigger some loggable entries.
                var client = new EasyUAClient();
                try
                {
                    client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");
                }
                catch (UAException uaException)
                {
                    Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                }

                // The certificate will be located or created in a directory similar to:
                // C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
                // and its subject will be as given by the application name.

                Console.WriteLine("Processing log entry events for 10 seconds...");
                System.Threading.Thread.Sleep(10 * 1000);

                Console.WriteLine("Finished.");
            }
            finally
            {
                // Unhook static events
                EasyUAClient.LogEntry -= EasyUAClientOnLogEntry;
            }
        }

        // Event handler for the LogEntry event.
        // Print the loggable entry containing client certificate parameters.
        private static void EasyUAClientOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            if (logEntryEventArgs.EventId == 161)
                Console.WriteLine(logEntryEventArgs);
        }
    }
}
// This example demonstrates how to set the application name for the client certificate.

type
  TClientManagementEventHandlers103 = class
    procedure OnLogEntry(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _LogEntryEventArgs);
  end;

// Event handler for the LogEntry event.
// Print the loggable entry containing client certificate parameters.
procedure TClientManagementEventHandlers103.OnLogEntry(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _LogEntryEventArgs);
begin
  if eventArgs.EventId = 161 then
      WriteLn(eventArgs.ToString);
end;

class procedure ApplicationName.Main;
var
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  ClientManagement: TEasyUAClientManagement;
  ClientManagementEventHandlers: TClientManagementEventHandlers103;
  Value: OleVariant;
begin
  // The configuration object allows access to static behavior - here, the
  // shared LogEntry event.
  ClientManagement := TEasyUAClientManagement.Create(nil);
  ClientManagementEventHandlers := TClientManagementEventHandlers103.Create;
  ClientManagement.OnLogEntry := ClientManagementEventHandlers.OnLogEntry;
  ClientManagement.Connect;

  try
    // Set the application name, which determines the subject of the client certificate.
    // Note that this only works once in each host process.
    ClientManagement.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest.ApplicationName :=
      'QuickOPC - Delphi example application';

    // Do something - invoke an OPC read, to trigger some loggable entries.
    Client := CoEasyUAClient.Create;
    try
      Value := Client.ReadValue(
        'http://opcua.demo-this.com:51211/UA/SampleServer',
        'nsu=http://test.org/UA/Data/ ;i=10853');
    except
      on E: EOleException do
      begin
        WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      end;
    end;

    // The certificate will be located or created in a directory similar to:
    // C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
    // and its subject will be as given by the application name.

    WriteLn('Processing log entry events for 10 seconds...');
    PumpSleep(10*1000);

    WriteLn('Finished...');
  finally
    FreeAndNil(ClientManagement);
    FreeAndNil(ClientManagementEventHandlers);
  end;
end;
// This example demonstrates how to set the application name for the client certificate.

class ClientConfigurationEvents {
    // Event handler for the LogEntry event.
    // Print the loggable entry containing client certificate parameters.
    function LogEntry($Sender, $E)
    {
        if ($E->EventId = 161)
            printf("%s\n", $E);
    }
}

// The configuration object allows access to static behavior - here, the
// shared LogEntry event.
$ClientConfiguration = new COM("OpcLabs.EasyOpc.UA.EasyUAClientConfiguration");
$ClientConfigurationEvents = new ClientConfigurationEvents();
com_event_sink($ClientConfiguration, $ClientConfigurationEvents, "DEasyUAClientConfigurationEvents");

// Set the application name, which determines the subject of the client certificate.
// Note that this only works once in each host process.
$ClientConfiguration->SharedParameters->EngineParameters->ApplicationParameters->ApplicationManifest->ApplicationName =
    "QuickOPC - PHP example application";

// Do something - invoke an OPC read, to trigger some loggable entries.
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
try
{
    $value = $Client->ReadValue("http://opcua.demo-this.com:51211/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853");
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
}

// The certificate will be located or created in a directory similar to:
// C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
// and its subject will be as given by the application name.

printf("Processing log entry events for 10 seconds...");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 10);

printf("Finished.\n");
Rem This example demonstrates how to set the application name for the client certificate.

Private Sub ApplicationName_Main_Command_Click()
    OutputText = ""
    
    Set ClientManagement1 = New EasyUAClientManagement
    
    ' Set the application name, which determines the subject of the client certificate.
    ' Note that this only works once in each host process.
    ClientManagement1.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest.applicationName = "QuickOPC - VB6 example application"

    ' Do something - invoke an OPC read, to trigger some loggable entries.
    Dim Client As New EasyUAClient
    On Error Resume Next
    Dim value As Variant
    value = Client.ReadValue("http://opcua.demo-this.com:51211/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853")
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    ' The certificate will be located or created in a directory similar to:
    ' C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
    ' and its subject will be as given by the application name.

    OutputText = OutputText & "Processing log entry events for 10 seconds..." & vbCrLf
    Pause 10000
    
    Set ClientManagement1 = Nothing
    OutputText = OutputText & "Finished..." & vbCrLf
End Sub
' Event handler for the LogEntry event. It simply prints out the event.
Private Sub ClientManagement1_LogEntry(ByVal sender As Variant, ByVal eventArgs As OpcLabs_BaseLib.LogEntryEventArgs)
    If eventArgs.eventId = 161 Then
        OutputText = OutputText & eventArgs & vbCrLf
    End If
End Sub
' This example demonstrates how to set the application name for the client certificate.

Imports OpcLabs.BaseLib.Instrumentation
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace UADocExamples._UAApplicationManifest
    Friend Class ApplicationName
        Public Shared Sub Main1()

            Dim endpointDescriptor As UAEndpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (not in .NET Standard)
            ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            ' Hook static events
            AddHandler EasyUAClient.LogEntry, AddressOf EasyUAClientOnLogEntry

            Try
                ' Set the application name, which determines the subject of the client certificate.
                ' Note that this only works once in each host process.
                EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest.ApplicationName =
                    "QuickOPC - VBNet example application"

                ' Do something - invoke an OPC read, to trigger some loggable entries.
                Dim client = New EasyUAClient()
                Try
                    client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")
                Catch uaException As UAException
                    Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                    Exit Sub
                End Try

                ' The certificate will be located or created in a directory similar to:
                ' C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
                ' and its subject will be as given by the application name.

                Console.WriteLine("Processing log entry events for 10 seconds...")
                Threading.Thread.Sleep(10 * 1000)

                Console.WriteLine("Finished.")
            Finally
                ' Unhook static events
                RemoveHandler EasyUAClient.LogEntry, AddressOf EasyUAClientOnLogEntry
            End Try

        End Sub


        ' Event handler for the LogEntry event.
        ' Print the loggable entry containing client certificate parameters.
        Private Shared Sub EasyUAClientOnLogEntry(ByVal sender As Object, ByVal logEntryEventArgs As LogEntryEventArgs)
            If (logEntryEventArgs.EventId = 161) Then
                Console.WriteLine(logEntryEventArgs)
            End If
        End Sub
    End Class
End Namespace
Rem This example demonstrates how to set the application name for the client certificate.

Option Explicit

' The configuration object allows access to static behavior.
Dim ClientConfiguration: Set ClientConfiguration = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClientConfiguration")
WScript.ConnectObject ClientConfiguration, "ClientConfiguration_"

' Set the application name, which determins the subject of the client certificate.
' Note that this only works once in each host process.
ClientConfiguration.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest.ApplicationName = "QuickOPC - VBScript example application"

' Do something - invoke an OPC read, to trigger some loggable entries.
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")
On Error Resume Next
Dim value: value = Client.ReadValue("http://opcua.demo-this.com:51211/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

' The certificate will be located or created in a directory similar to:
' C:\Users\All Users\OPC Foundation\CertificateStores\UA Applications\certs\
' and its subject will be as given by the application name.

WScript.Echo "Processing log entry events for 10 seconds..."
WScript.Sleep 10*1000

WScript.Echo "Finished."



' Event handler for the LogEntry event.
' Print the loggable entry containing client certificate parameters.
Sub ClientConfiguration_LogEntry(Sender, e)
    If e.EventId = 161 Then WScript.Echo e
End Sub

 

 

The type and location of client instance certificate store can be controlled by properties in EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest, such as the InstanceOwnStorePath Property. By default, QuickOPC-UA uses a standard directory-based store defined by OPC Foundation (“MachineDefault”).

The AllowOwnCertificatePrompt property in EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters determines whether the component can interact with the user when checking or creating an application instance certificate. If set to false (the default), no dialogs will be displayed.

Certificate Auto-Generation

If you let QuickOPC-UA create the certificate and add it to the store, it should be noted that it is a security-sensitive operation that would typically be allowed only to administrators. QuickOPC-UA will attempt to do this if the certificate is not found, which may be when the application is first started on the computer, but if your application is not running with privileges required for this operation, the certificate will not be added.

In order to allow your application be run under usual privileges, and make its behavior more predictable, it is recommended that you assure the generation of the certificate during the application deployment, when administrative privileges are usually required anyway. One way to do this is call the static method EasyUAClient.Install during the deployment process.  For more information, see the “Application Deployment” chapter.

The validity period of the auto-generated certificate is chosen by QuickOPC and cannot currently be changed. It is set to 600 months (50 years) when targeting .NET Framework (or for COM tools), or 12 months (1 year) when targeting .NET Standard.

If you do not like the parameters of the auto-generated certificate, you can create your own and place it into the appropriate certificate store(s). As long as it has the proper Subject Name, it will be found by QuickOPC and used.

When using the EasyUAClient.Install method during the deployment process, make sure that the application (certificate) name is the same during deployment, and during the normal application. With automatically generated application name (which is the default), a different name might be generated if you use a separate application for the deployment, or if use you use utilities such as InstallUtil.exe which effectively act as a host for your application. In such situations, always set the application name explicitly, to the same value during the deployment and in normal application executions.

QuickOPC attempt to re-generate the own instance certificate whenever it is needed and not found. You can therefore enforce re-creation of the instance certificate (e.g. periodically, in order to prevents its expiration) by simply removing it from the appropriate certificate store (e.g. by a script called from Windows Task Scheduler). Note that when the instance certificate is replaced, the other parties (communication peers) will most likely no longer trust the certificate, and the trust will have to be reestablished on their side.

Peer Auto-Trust

When QuickOPC creates or checks the client instance certificate (in the application certificate store), it also makes sure that the certificate is to be found in the trusted peers certificate store ("UA Applications", normally). If the client instance certificate store is not found there, a copy of it (without the private key) is placed into the trusted peers certificate store automatically.

With this peer auto-trust mechanism, OPC UA servers that use the same trusted peers certificate store can automatically trust the client application(s) created with QuickOPC.

QuickOPC applications also check the trust status of their own application instance certificate using basically the same mechanism as other applications. For this reason, the peer-auto trust is actually needed not just for the peer application, but also for proper function of the QuickOPC application itself. A copy (without the private key) of the application instance certificate should also always exist in the trusted peers certificate store.
With the default settings effective when targeting .NET Standard, applications use separate certificate stores and not system-wide "shared" certificate stores. The peer auto-trust mechanism is still invoked under .NET Standard, but with the default settings it may have no observable effect, because other applications are using different certificate stores.

Checking Application Instance Certificate

If the application instance certificate is found in the appropriate certificate store, QuickOPC checks the certificate. If any checks fails, QuickOPC create a new certificate and replaces the certificate in the store.

  1. The certificate must be valid.
  2. The size of the certificate's public key must be at least the minimum size. Currently, QuickOPC uses zero as minimum size, therefore all certificates pass this check.
  3. If the application type includes a Server, the certificate's domains are checked against the server configuration. QuickOPC applications are normally client-only (unless you specify otherwise), and therefore this check always passes in the default QuickOPC configuration.
  4. The application URI must be specified (non-empty) in the certificate. The application URI is an URI from the certificate extension with OID 2.5.29.7 (subjectAltName) or 2.5.29.17 (Subject Alternative Name).
By the quirk in the checking algorithm, the client application certificate must also be trusted, which can be assured by placing a copy of it (without private key) into the trusted peers certificate store ("UA Applications", normally). The certificate auto-creation in QuickOPC does this automatically, but do not forget about this step when generating and placing your application certificate manually.

Additional information

OPC-UA requires that both parties (client and server) mutually identify themselves using application certificates. The certificates are supposed to be unique for each application (instance), and therefore cannot be a constant part of the "toolkit" (such as QuickOPC), and need to be generated. In order to make this process invisible (in common cases) to the developer, QuickOPC

a) determines the parameters of the certificate automatically, using values such as the EXE name or the calling assembly name,

b) attempts to look up the certificate in the certificate store,

c) if not found, it attempts to create it, and save it into the certificate store. 

The algorithm described above does not, however fit well with hosted environments such as IIS, for two reasons:

For usage in such environments, the recommendation is:

On Windows, application certificate can be generated using Opc.Ua.CertificateGenerator.exe utility, available from the OPC Foundation. The utility is typically located at "C:\Program Files (x86)\Common Files\OPC Foundation\UA\v1.0\Bin". Run it with "/?" to obtain usage instructions. See also Certificate Generator page.

QuickOPC normally does not need the Opc.Ua.CertificateGenerator utility be present on the disk. For COM and .NET Framework target platforms, it has its own internal copy of this utility which it loads and executes. For .NET Standard development platform, the Opc.Ua.CertificateGenerator utility is not used.

Setting the certificate parameters is done by modifying properties in EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters (EasyUAClient.SharedParameteres is a static property, and you need to set the values before creating the first instance EasyUAClient, in order for it to have the desired effect). The properties of interest are:

The values should match those used when the certificate was generated, because they (or at least some of them) are used to look up the certificate in the store.

The default certificate store for OPC-UA applications is not one of the Windows stores, but instead, a file-system (directory) based store. It defaults to "%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", where %CommonApplicationData% is e.g. "C:\ProgramData". The best way to inspect the UA certificates (on Windows) is to use the OPC UA Configuration tool from the OPC Foundation. After installation, run (e.g.)  Start -> All Programs -> OPC Foundation -> UA SDK 1.01 -> UA Configuration Tool. Then, select the "Manage Certificates" tab, press the drop-down next to "Store Path", select the store I listed above, and press the View Certificates button. 

QuickOPC also includes the UA Configuration Tool in the Bonus Material part of its full installation for Windows. You can access the UA Configuration Tool from the Start menu (under QuickOPC program group), or using the QuickOPC Launcher application.

You should not use the same certificate for multiple applications. And, you should not use the same certificate even for multiple instances of the same application (such as when you deploy the application on multiple computers). Each instance of the application (typically, this means each application/computer combination, but can be even more) should have its own, unique certificate. This is how UA security is meant to work, because there needs to be a way for the server to authenticate each client connection separately and possibly deny the connection to unsecure or compromised clients. Technically, if you violate this and use the same certificate, things will probably work OK on the surface, but it is against the OPC-UA security specs. This is the reason why the certificate is generated anew on the computer - and the cause of some troubles.

Actually, while using the CertificateGenerator manually is possible, it would be probably too complicated to try to assemble the right set of parameters so that the generated certificate is then properly found by the client application. Instead, we suggest that you create a small app (e.g. Windows Forms app, or a console app). In it, you set the 4 parameters in EasyUAClient.SharedParameters to meaningful values, and then call a static method EasyUAClient.Install(). You then run this application with administrator/elevated privileges, and it will create the certificate (verify it with the UA Configuration Tool described above). In your actual client app, set the parameters in precisely the same way before instantiating the EasyUAClient object, and doing so should assure that it will find and use the certificate. Still, your app (which may be a Web app) needs to have read access to the directory of the cert store - you may have to modify the permissions). The additional app you created may become part of your installation procedure.

Obtaining Instance Certificate from the GDS 

If your OPC UA setup includes an OPC UA Global Registration Server (GDS), you might be able to obtain the application instance certificate from the GDS (in the role of Certificate Manager, CM). For more information, see OPC UA Client Application Service (or, less preferrably, OPC UA Certificate Management Client).

Troubleshooting

Some common problem scenarios include:

Certificate generation works on one computer, does not on other. For example, when you first run your application your development computer, you may use the development Web server built-in in Visual Studio. This one uses different accounts and permissions from IIS, and the certificate creates just fine. On the production computer, IIS is used, and the certificate generation may fail. See further below for related information.

Certificate generation fails under IIS. Most likely this is due to permissions. IIS settings are VERY restrictive (for good reason), and the defaults won't allow the certification generation or storing it into the store.  

See Also

Examples - OPC UA GDS

Examples - OPC UA Application