15:57, EEST
December 20, 2021
Hello,
I have some doubts about self-generated certificates:
– What happens if the server is communicating with a client and the server date is changed? Maybe moved in the past?
– What if the server hostname is changed at runtime?
Does the server recreate them automatically?
Best regards,
Francesco
14:33, EEST
April 3, 2012
Hi,
Did you just ask out of interest, or did you have an actual case where some of these are happening?
https://reference.opcfoundation.org/Core/Part6/v104/docs/6.3
“All SecurityProtocols require that system clocks on communicating machines be reasonably synchronized…”
Thus, in general it is sort of a situation that should not happen.
In general SDK doesn’t expect the clock to magically jump and that can lead to basically any undefined behavior. Some of Java’s scheduledexecutors behave interestingly as well. For example, schedulewithfixedrate ignores the rate if it has not exec’d as many times as it should have if clock moves suddenly to the future. Things might timeout etc. However, in most cases the client would just reconnect to the server. IF the clock moves part the cert validity period it might stop the client. If the clock moves to the future enough that the server cert is not valid anymore the UaServer must be restarted with the new cert as far as I know.
For the certs, assuming you use one of the ApplicationIdentity.loadOrCreateCertificate, in practice if the hostname changes, then when that method is called it wouldn’t find the old file and thus would make a new cert with the new hostname (i.e. SDK doesn’t automatically check this periodically, if that is what you are asking). If the cert exist and is expired and enableRenew is true it would re-create it. I should note that in the future once we support GDS i.e. Global Discovery Server spec (https://reference.opcfoundation.org/GDS/v105/docs/) that would typically handle all certificates on a site. In practice certificate management is complicated and most have just used self-signed certificate that would last like 10 years or something. And the GDS will be a solution to that. Probably here we must also make something that allows swapping the cert while the app runs (or keep the old one for a roll-over period or something; though, I’m not exactly sure how clients will react to this kind of situations..).
If the hostname changes while the application runs, I’m not sure. At least the com.prosysopc.ua.ApplicationIdentity.getActualHostName() caches the value and returns the same value in subsequent calls, thus SDK wont notice it until the JVM restarts (or you can use ApplicationIdentity.setActualHostName(String), if you set null it would resolve it again). Note that I’m specifically meaning with hostname here the computername (e.g. what ‘hostname’ would result in when run in command line). Also the server would have the old hostname EndpointUrls, which some clients use when connecting (we do not, UaClient keeps using the original connection address given to it, because in reality the EndpointUrls might be from behind NATs etc.). Some clients do verify the connection address hostname part is found from the cert (similar to web browsers) and might fail, but the connection address maybe doesn’t change if the hostname changes, though typically the hostname is used as the connection address. So it depends.
15:36, EEST
December 20, 2021
Hello Bjarne,
we are trying real test cases.
We are testing the server with self-generated certified future data.
I delete the PKI folder. I set the date to today. The server creates the certificate valid from 2023-2033.If I move to 2035 and restart the server, it explodes with the error:
at com.prosysopc.ua.ApplicationIdentity.loadCertificate(SourceFile:1203)
at com.prosysopc.ua.ApplicationIdentity.loadOrCreateIssuerCertificate(SourceFile:864)
at com.aa.galileo.structure.protocol.opcua.OPCUAServer.initCertificates(OPCUAServer.java:490)
at com.aa.galileo.structure.protocol.opcua.OPCUAServer.initialize(OPCUAServer.java:336)
at com.aa.galileo.structure.protocol.opcua.modules.OPCUABaseModule.connect(OPCUABaseModule.java:64)
at com.aa.galileo.structure.protocol.opcua.daalistener.SocketOPCUA.connect(SocketOPCUA.java:45)
at com.aa.galileo.structure.protocol.application.PFConnectionGenericThread.connectSocket(PFConnectionGenericThread.java:48)
at com.aa.galileo.structure.protocol.application.PFConnectionGenericThread.run(PFConnectionGenericThread.java:26)
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu Oct 20 11:27:15 CEST 2033
at java.base/sun.security.x509.CertificateValidity.valid(CertificateValidity.java:277)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:675)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:648)
at com.prosysopc.ua.ApplicationIdentity.loadCertificate(SourceFile:1198)
… 7 common frames omitted
I am currently using the following parameters to manage the self-generated certificate:
"MyCompany Spa", /* Private Key Password */"*****", /* Key File Path */privatePath,
/* Issuer Certificate & Private Key */(useCA ? issuerCertificate : null),
/* Key Sizes for instance certificates to create */keySizes,
/* Enable renewing the certificate */true);
I’m using the SDK version 5.0.2-105.
Please can you check the method loadOrCreateCertificate ?
Thanks,
Francesco
15:53, EEST
April 3, 2012
In the stacktrace
at com.prosysopc.ua.ApplicationIdentity.loadOrCreateIssuerCertificate(SourceFile:864)
at com.aa.galileo.structure.protocol.opcua.OPCUAServer.initCertificates(OPCUAServer.java:490)
you call loadOrCreateIssuerCertificate, not loadOrCreateCertificate. Do you use the ‘enableRenew’ true also for the loadOrCreateIssuerCertificate call? (you showed loadOrCreateCertificate instead), because if it is false and it is expired you would get the very exception you saw.
If you just copied from the samples, it would seem the
KeyPair issuerCertificate = ApplicationIdentity.loadOrCreateIssuerCertificate(
“ProsysSampleCA@” + ApplicationIdentity.getActualHostNameWithoutDomain() + “_https_” + certKeySize, privatePath,
privateKeyPassword, 3650, false, certKeySize);
part does use ‘false’ for that. Though in the sample the whole CA cert is only created for the sake of the https cert, and the whole opc.https is also by default disabled in 5.x sampleconsoleserver (as really no-one should use opc.https).
Like you can make a CA cert this way and also use it for opc.tcp, though it is a bit odd if an application makes it, typically you have something more central that would manage the CA cert (unless you were test that). If an application itself makes a cert, typically that is just a self-signed cert (some SDKs didn’t work for opc.https unless there was a CA cert in use, thus that is why that exists there).
But if that is based on 4.x samples and you happen to have the opc.https stuff there, then it probably did break on that before it reached your loadOrCreateCertificate line.
17:20, EEST
December 20, 2021
Hello Bjarne,
the method loadOrCreateCertificate works correctly. I didn’t read the stack trace correctly.
“But if that is based on 4.x samples and you happen to have the opc.https stuff there, then it probably did break on that before it reached your loadOrCreateCertificate line.”
You’re right.
Regards,
Francesco
10:28, EEST
December 20, 2021
Hi Bjarne,
the enableRenew=true flag works as expected: if the server certificate has expired, it is recreated when I restart the OPC UA server.
We have another problem to handle: our system allows you to move the date before the validity period of the current certificate.
When I reboot, the server explodes with the following stack trace:
at java.base/sun.security.x509.CertificateValidity.valid(CertificateValidity.java:273)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:675)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:648)
at com.prosysopc.ua.ApplicationIdentity.loadCertificate(SourceFile:1198)
… 7 common frames omitted
How could I handle this error?
Regards,
Francesco
11:03, EEST
April 3, 2012
e.g. try-catch
But really, SDK is not designed to work on a system where the clock would be magically moved to the past. That is not at all how a normal system would work. The only scenario could be if the clock was incorrectly set to the future and would need to be fixed one-time. But you should anyway have NTP or equivalent to force the current time synchronization, as required by the OPC UA Security.
12:29, EEST
December 20, 2021
Hi Bjarne,
I’m facing the following real use case:
an OPC UA client connected to my OPC UA server needs to call the EUROMAP 83 SetMachineTime method every 60 minutes:
https://www.euromap.org/euromap83
The SetMachineTime Method allows setting the server time together with TimeZoneOffset.
Signature
SetMachineTime (
[in] 0:DateTime DateTime
[in] 0:TimeZoneDataType TimeZoneOffset);
In certain situations (first installation, repair) the OPC UA server may have a very different time from real time. I also can’t use an NTP server.
As a result, the OPC UA server time may change at runtime.
I think the EUROMAP 83 SetMachineTime method is inconsistent with the OPC UA specifications we have discussed.
13:59, EEST
April 3, 2012
I don’t think that can be supported by the SDK.
Yes, I do see a scenario where that method might make sense if it is an embedded device having a single OPC UA Server configurable only by UA and it would only be used by a single user-client and thus it could modify the “operating system time”, but anywhere else (i.e. more typical cases) it would just mess up every other application running on the same OS (and possibly even on the same JVM).
12:58, EET
December 20, 2021
Hi Bjarne,
I would need to handle the following use case:
– an OPC UA client calls EUROMAP 83 method “SetMachineTime” to set my OPC UA server time every 60 minutes.
– the client and server are not connected to the Internet.
– the client connected to my server is the only device that can set the server time
– My server runs on a Linux operating system.
When the client sets a time that deviates from the server’s current time by at least one minute, this behavior occurs:
– the client stops receiving subscription updates
– the client stops receiving alarm events.
If I make a new client connection, the situation goes back to normal.
This behavior occurs with both the UaExpert client and the Prosys OPC UA Browser client.
As you had already explained to me before, if I change the server system time, unexpected behavior may occur.
Please could you tell me if it is possible to force the refresh of client sessions or invalidate them from the server?
Thanks for your help.
Francesco
9:12, EET
Moderators
February 11, 2020
Hello,
The OPC UA specification doesn’t provide any means for a Server to tell a Client that it needs to refresh its Session.
What you could try is shutting the Server down using the shutdown(int secondsTillShutdown, LocalizedText shutdownReason, boolean closeServer) method of UaServer class. This will set its State (/Root/Objects/Server/ServerStatus/State) to Shutdown and you also utilize ShutdownReason (/Root/Objects/Server/ServerStatus/ShutdownReason) to let Clients know why the Server was shutdown. Since you’re planning to restart the Server, you should set closeServer to false when calling the method. After shutting the Server down, you can then restart the UaServer by calling its start() method.
Clients that are compliant with the OPC UA Specification should monitor the State of the Server by MonitoredItems and Subscriptions or by periodic reads and attempt reconnecting on shutdown and connection errors. However, it depends on Client applications how frequently they check the Server State. For example, Client developed with Prosys OPC UA SDK for Java check the State once every second by reading it when using the default status check interval. If the check is infrequent, there is a chance that the Client will miss the shutdown and assume that its Session is still valid. Naturally, it will depend on the Client applications how well they can handle situation like this. To avoid this, you should leave some time between shutting the Server down and restarting it to give Clients a chance to notice that it has been shutdown.
Fore more information on re-estabilishing connections, see https://reference.opcfoundation.org/Core/Part4/v105/docs/6.7
Most Users Ever Online: 1919
Currently Online:
18 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 737
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1524
Posts: 6450
Newest Members:
fannielima, kristiewinkle8, rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerleyModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1