I am quite new to OPC UA protocol; I recently wrote a C interface to connect to some machines using the libraries from OPCFoundation, and so far I did not have to deal with certificates, since all the machines allowed unsecured connections.
Having now to connect to a machine that uses certificates, how should I modify my code in order to simulate the "trust server certificate" action I can take on UAExpert software, which warns about the certificate, but allows me to trust the certificate from the machine (saving it to a local folder) and continue with the session?
In my code, I have "AutoAcceptUntrustedCertificates = true"
, but when I try to open the session I get a
Opc.Ua.ServiceResultException "Certificate is not trusted.\r\nSubjectName: CN=NxOpcUaServer@192.168.1.10 ..."
Thanks in advance
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
private static String CallOpcUA(string indirizzoMacchina, string displayNome, string idNodo)
{
var config = new ApplicationConfiguration()
{
ApplicationName = "MyApp",
ApplicationUri = Utils.Format(@"urn:{0}:MyApp", System.Net.Dns.GetHostName()),
ApplicationType = ApplicationType.Client,
SecurityConfiguration = new SecurityConfiguration
{
ApplicationCertificate = new CertificateIdentifier { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", SubjectName = "MyApp" },
TrustedIssuerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Certificate Authorities" },
TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Applications" },
RejectedCertificateStore = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\RejectedCertificates" },
AutoAcceptUntrustedCertificates = true
},
TransportConfigurations = new TransportConfigurationCollection(),
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
TraceConfiguration = new TraceConfiguration()
};
config.Validate(ApplicationType.Client).GetAwaiter().GetResult();
if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
{
config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateTimeInvalid); };
}
var application = new ApplicationInstance
{
ApplicationName = "MyApplication",
ApplicationType = ApplicationType.Client,
ApplicationConfiguration = config
};
try
{
application.CheckApplicationInstanceCertificate(false, 2048).GetAwaiter().GetResult();
}
catch (System.IO.FileLoadException e)
{
}
try
{
identity = new UserIdentity();
var selectedEndpoint = CoreClientUtils.SelectEndpoint(indirizzoMacchina, useSecurity: false);
using (var session = Session.Create(config, new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)), false, "", 60000, identity, null).GetAwaiter().GetResult())
{
[read value from the node]
}
}
catch (Opc.Ua.ServiceResultException e)
{
}
}