04/22/2022
OfflineBeen trying to use certificate auth to connect to a series of Honeywell Experion PKS OPC UA servers.
Was working fine with anonymous/basic auth during local testing, but I'm running into failures now trying to connect to a customer OPC UA server leveraging certificates.
Looking for any guidance, as both this auth problem and certificate problems in general are a little out of my depth.
I am not using an XML config for the application configuration, I have most of it hard coded with some choices exposed through default ASP.NET Core `IConfiguration`.
I thought that using a single certificate would be better than allowing the application to generate its own on session handshake, so I used an F# script to generate a certificate and provided the `pem` and `der` to the customer to add to the `trusted` folder of their OPC UA server. I'm pulling in the `.pfx` file to use during the handshake.
Any help or guidance towards documentation/examples to help me resolve this problem would be greatly appreciated!
Here is the log message/exception that I'm getting:
```
info: ReachPapermakingClient.OpcUaClientFactoryV2[0]
Loaded OPC UA client certificate: Subject=CN=ProjectName, O=CompanyName, OU=OPC UA Client, Thumbprint=12345abcdefg, ValidTo=04/13/2036 10:44:59
info: ReachPapermakingClient.OpcUaClientFactoryV2[0]
OPC UA application configuration validated
info: ReachPapermakingClient.OpcUaClientFactoryV2[0]
Connecting: Endpoint=opc.tcp://myendpoint.com:4840, Session=REACH_Papermaking_Client_Primary, Auth=Username (opc_test)
info: ReachPapermakingClient.OpcUaClientFactoryV2[0]
Selected endpoint: opc.tcp://myendpoint.com:4840, SecurityPolicy=https://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss, SecurityMode=SignAndEncrypt
info: ReachPapermakingClient.OpcUaClientFactoryV2[0]
Using username/password identity for user: opc_test
Unhandled exception. Opc.Ua.ServiceResultException: ApplicationCertificate for the security profile https://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss cannot be found.
at Opc.Ua.Client.Session.LoadCertificateAsync(ApplicationConfiguration configuration, String securityProfile)
at Opc.Ua.Client.Session.CreateChannelAsync(ApplicationConfiguration configuration,
ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, Boolean updateBeforeConnect, Boolean checkDomain, CancellationToken ct)
at Opc.Ua.Client.Session.CreateAsync(ISessionInstantiator sessionInstantiator, ApplicationConfiguration configuration, ITransportWaitingConnection connection, ConfiguredEndpoint endpoint, Boolean updateBeforeConnect, Boolean checkDomain, String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales, CancellationToken ct)
at Opc.Ua.Client.DefaultSessionFactory.CreateAsync(ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, Boolean updateBeforeConnect, Boolean checkDomain, String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales, CancellationToken ct)
at Opc.Ua.Client.TraceableSessionFactory.CreateAsync(ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, Boolean updateBeforeConnect, String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales, CancellationToken ct)
at ReachPapermakingClient.OpcUaClientFactoryV2.CreateClientAsync(ApplicationConfiguration config, String endpointUrl, String sessionName) in D:\agent\_work\3348\s\OpcUa\OpcUaClientFactoryV2.cs:line 206
at ReachPapermakingClient.OpcUaClientFactoryV2.CreateRedundantOpcUaClient(String sessionName, ILogger`1 logger) in D:\agent\_work\3348\s\OpcUa\OpcUaClientFactoryV2.cs:line 58
at Program.<Main>$(String[] args) in D:\agent\_work\3348\s\Worker\Program.cs:line 74
at Program.<Main>(String[] args)
Aborted
```
Here is the application configuration that I'm using to build out the OPC UA Client:
```cs
private ApplicationConfiguration BuildApplicationConfiguration()
{
var certificate = LoadClientCertificate();
return new ApplicationConfiguration
{
ApplicationName = ApplicationName,
ApplicationUri = ApplicationUri,
ApplicationType = ApplicationType.Client,
SecurityConfiguration = new SecurityConfiguration
{
ApplicationCertificate = new CertificateIdentifier
{
StoreType = "Directory",
StorePath = GetCertificateStorePath("own"),
SubjectName = certificate.Subject,
Certificate = certificate
},
AutoAcceptUntrustedCertificates = true,
RejectSHA1SignedCertificates = false,
RejectUnknownRevocationStatus = false,
AddAppCertToTrustedStore = true,
TrustedPeerCertificates = new CertificateTrustList
{
StoreType = "Directory",
StorePath = GetCertificateStorePath("trusted")
},
TrustedIssuerCertificates = new CertificateTrustList
{
StoreType = "Directory",
StorePath = GetCertificateStorePath("issuer")
},
RejectedCertificateStore = new CertificateStoreIdentifier
{
StoreType = "Directory",
StorePath = GetCertificateStorePath("rejected")
}
},
TransportConfigurations = new TransportConfigurationCollection(),
TransportQuotas = new TransportQuotas { OperationTimeout = 30_000 },
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60_000 },
};
}
```
Here is the F# script that is used to create the cert that we're using (in case we need to embed the security profile in the generation somehow? Again, i have no idea here)
```fs
let applicationName = "REACH_Papermaking"
let applicationUri = "urn:REACH_Papermaking:OpcUaClient"
let subjectName = "CN=ProjectName, O=CompanyName, OU=OPC UA Client"
let outputDir =
let dir = Path.Combine(__SOURCE_DIRECTORY__, "..", "Worker", "Certificates")
let dir = Path.GetFullPath(dir)
Directory.CreateDirectory(dir) |> ignore
dir
let lifetimeMonths = uint16 (10 * 12)
let cert =
CertificateFactory
.CreateCertificate(applicationUri, applicationName, subjectName, null)
.SetNotBefore(DateTime.UtcNow.AddDays(-1.0))
.SetLifeTime(lifetimeMonths)
.SetHashAlgorithm(X509Utils.GetRSAHashAlgorithmName(uint32 CertificateFactory.DefaultHashSize))
.SetRSAKeySize(CertificateFactory.DefaultKeySize)
.CreateForRSA()
let derPath = Path.Combine(outputDir, $"{applicationName}.der")
File.WriteAllBytes(derPath, cert.RawData)
let pfxPath = Path.Combine(outputDir, $"{applicationName}.pfx")
File.WriteAllBytes(pfxPath, cert.Export(X509ContentType.Pfx))
let pemPath = Path.Combine(outputDir, $"{applicationName}.pem")
File.WriteAllText(pemPath, cert.ExportCertificatePem())
exit 0
```
04/22/2022
OfflineFound a resolution from this github dicussion
1 Guest(s)


Log In

Usage Policy