Implementing ServerConfiguration's ResetToServerDefaults
Posted: 20 Mar 2023, 05:48
Hi, all. I'm evaluating the .NET SDK to see if it's suitable for a server project, and I seem to be running into a little snag around certificate management. I'll sketch out what I'm doing and perhaps someone can point out where I've gone astray. For full disclosure, I'm pretty new to OPC UA as well, so going astray comes easily.
One of the requirements I need to support for this server is the Push Management model as outlined in Section 12 of the spec. When I connect to my server with UaExpert with admin credentials on an encrypted endpoint, I can browse the ServerConfiguration object. As far as I can tell from poking at it with UaExpert, this mostly works as expected.
Where things start getting more difficult is that I also need to implement the optional ResetToServerDefaults method on the ServerConfiguration object. The IServerConfigurationMethods interface doesn't define any of the optional ServerConfiguration methods, but I eventually figured out how to create the method with the correct NodeId with CoreNodeManager.CreateMethod(), then attach it to the CoreNodeManager's list of dispatchers using CoreNodeManager.SetMethodDispatcher().
The implementation of ResetToServerDefaults is supposed to take the following actions: clear all TrustLists, delete all assigned certificates, reset all Endpoints and ReverseEndpoints to defaults, set all UserTokenPolicies to defaults, delete all CertificateManagerEndpoints, and reset any passwords for built-in admin accounts. Finally, the ServerState needs to be set to SHUTDOWN.
Not all of these apply to what I'm doing at the moment, but TrustLists need to be cleared and certificates need to be deleted, including the application instance certificate which is expected to be regenerated when the server restarts.
What I'm doing to clear the TrustLists and certificates is to iterate the Application's TrustedStore and RejectedStore to get their thumbprints, then iterating the thumbprints calling the store's Remove() method for each one, then finally calling RequestServerStateChange() to shut down the server. This does result in the certificates being deleted from their folders. What is curious, however, is that if I don't shut the server process down but instead have Main() loop to restart the server, it seems like the trust relationships are still cached somewhere: I can reconnect to the server over the Basic256Sha256 endpoint with no certificates in trusted\certs.
I've tried inserting a GC.Collect() call just before looping back to recreate the server objects from scratch, thinking that might flush any cached data, but that also hasn't helped.
I suspect I'm just not doing the right things to properly and fully reset the TrustLists and certificates, but it's unclear to me exactly what I need to do with the SDK to accomplish this.
I'm also not sure what I should do to reset the server's own application instance certificate. Obviously, I can just delete certificates from their stores on disk, but deleting data out from under the server seems like it might not be the right way to go about it. Or is it?
Sorry if this is long-winded, but any advice on implementing ServerConfiguration's ResetToServerDefaults would be greatly appreciated.
Thanks,
Dave
One of the requirements I need to support for this server is the Push Management model as outlined in Section 12 of the spec. When I connect to my server with UaExpert with admin credentials on an encrypted endpoint, I can browse the ServerConfiguration object. As far as I can tell from poking at it with UaExpert, this mostly works as expected.
Where things start getting more difficult is that I also need to implement the optional ResetToServerDefaults method on the ServerConfiguration object. The IServerConfigurationMethods interface doesn't define any of the optional ServerConfiguration methods, but I eventually figured out how to create the method with the correct NodeId with CoreNodeManager.CreateMethod(), then attach it to the CoreNodeManager's list of dispatchers using CoreNodeManager.SetMethodDispatcher().
The implementation of ResetToServerDefaults is supposed to take the following actions: clear all TrustLists, delete all assigned certificates, reset all Endpoints and ReverseEndpoints to defaults, set all UserTokenPolicies to defaults, delete all CertificateManagerEndpoints, and reset any passwords for built-in admin accounts. Finally, the ServerState needs to be set to SHUTDOWN.
Not all of these apply to what I'm doing at the moment, but TrustLists need to be cleared and certificates need to be deleted, including the application instance certificate which is expected to be regenerated when the server restarts.
What I'm doing to clear the TrustLists and certificates is to iterate the Application's TrustedStore and RejectedStore to get their thumbprints, then iterating the thumbprints calling the store's Remove() method for each one, then finally calling RequestServerStateChange() to shut down the server. This does result in the certificates being deleted from their folders. What is curious, however, is that if I don't shut the server process down but instead have Main() loop to restart the server, it seems like the trust relationships are still cached somewhere: I can reconnect to the server over the Basic256Sha256 endpoint with no certificates in trusted\certs.
I've tried inserting a GC.Collect() call just before looping back to recreate the server objects from scratch, thinking that might flush any cached data, but that also hasn't helped.
I suspect I'm just not doing the right things to properly and fully reset the TrustLists and certificates, but it's unclear to me exactly what I need to do with the SDK to accomplish this.
I'm also not sure what I should do to reset the server's own application instance certificate. Obviously, I can just delete certificates from their stores on disk, but deleting data out from under the server seems like it might not be the right way to go about it. Or is it?
Sorry if this is long-winded, but any advice on implementing ServerConfiguration's ResetToServerDefaults would be greatly appreciated.
Thanks,
Dave