I've been struggling with this code for hours.
I need to connect to an OPC UA server (IP 192.168.7.118), it's a Siemens S7-1200 PLC. I'm using the official OPC Foundation NuGet package and the following code:
static void Main(string[] args)
{
// Generate a client application
ApplicationInstance application = new ApplicationInstance();
application.ApplicationType = ApplicationType.Client;
// Load the configuration file
application.LoadApplicationConfiguration(@"./ConsoleReferenceClient.Config.xml", false).Wait();
ApplicationConfiguration m_configuration = application.ApplicationConfiguration;
m_configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = true;
// Connect to a server
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint("opc.tcp://192.168.7.118", false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration) { };
// Create the session
Session session = Session.Create(m_configuration, endpoint, false, false, m_configuration.ApplicationName, (uint)m_configuration.ClientConfiguration.DefaultSessionTimeout, new UserIdentity(), null).Result;
}
I'm getting error Certificate chain validation incomplete on session.Create(). The config.xml file specifies:
<SecurityConfiguration>
<!-- Where the application instance certificate is stored (MachineDefault) -->
<ApplicationCertificate>
<StoreType>Directory</StoreType>
<StorePath>%CommonApplicationData%\OPC Foundation\pki\own</StorePath>
<SubjectName>CN=Quickstart Console Reference Client, C=US, S=Arizona, O=OPC Foundation, DC=localhost</SubjectName>
</ApplicationCertificate>
<!-- Where the issuer certificate are stored (certificate authorities) -->
<TrustedIssuerCertificates>
<StoreType>Directory</StoreType>
<StorePath>%appdata%\opc foundation\pki\issuer</StorePath>
</TrustedIssuerCertificates>
<!-- Where the trust list is stored -->
<TrustedPeerCertificates>
<StoreType>Directory</StoreType>
<StorePath>%appdata%\opc foundation\pki\trusted</StorePath>
</TrustedPeerCertificates>
<!-- The directory used to store invalid certficates for later review by the administrator. -->
<RejectedCertificateStore>
<StoreType>Directory</StoreType>
<StorePath>%appdata%\opc foundation\pki\rejected</StorePath>
</RejectedCertificateStore>
<!-- WARNING: The following setting (to automatically accept untrusted certificates) should be used
for easy debugging purposes ONLY and turned off for production deployments! -->
<AutoAcceptUntrustedCertificates>false</AutoAcceptUntrustedCertificates>
</SecurityConfiguration>
From Siemens Tia Portal, I exported the device certificate under trusted directory, and the issuer certificate under issuer directory. The issuer is the Tia Portal project itself.
I also tried to install both certificates with default Windows Certificate Management, but nothing worked.
I've worked with other OPC UA library in the past, but this is the first time I'm using the official OPC Foundation SDK and honestly I found the documentation a bit challenging to fully understand.
Any help would be much appreciated.
I worked around the problem with the following code:
// Get server certificate
var rawCertificate = endpointDescription.ServerCertificate;
CertificateIdentifier serverCertificate = new(rawCertificate);
// Add server certificate to trusted peers and trusted issuers
configuration.SecurityConfiguration.TrustedPeerCertificates.TrustedCertificates.Add(serverCertificate);
configuration.SecurityConfiguration.TrustedIssuerCertificates.TrustedCertificates.Add(serverCertificate);
This manages to manually add (code-behind instead of configuration file) the server certificate to trusted certificate store. I don't know why, but I could not get it working loading configuration from file.