Skip to content

Commit 760bfd9

Browse files
authored
[Server] Fix: Return full CertificateChain after Certificate Update (#2861)
* simpler update process * update endpoint descriptions * adress review feedback * cleanup
1 parent 6038a69 commit 760bfd9

File tree

5 files changed

+31
-10
lines changed

5 files changed

+31
-10
lines changed

Libraries/Opc.Ua.Server/Configuration/ConfigurationNodeManager.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,15 @@ private ServiceResult ApplyChanges(
675675
// give the client some time to receive the response
676676
// before the certificate update may disconnect all sessions
677677
await Task.Delay(1000).ConfigureAwait(false);
678-
await m_configuration.CertificateValidator.UpdateCertificateAsync(m_configuration.SecurityConfiguration).ConfigureAwait(false);
678+
try
679+
{
680+
await m_configuration.CertificateValidator.UpdateCertificateAsync(m_configuration.SecurityConfiguration).ConfigureAwait(false);
681+
}
682+
catch (Exception ex)
683+
{
684+
Utils.LogCritical(ex, "Failed to sucessfully Apply Changes: Error updating application instance certificates. Server could be in faulted state.");
685+
throw;
686+
}
679687
}
680688
);
681689
}

Stack/Opc.Ua.Bindings.Https/Stack/Https/HttpsTransportListener.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,6 @@ public void CertificateUpdate(
499499
foreach (EndpointDescription description in m_descriptions)
500500
{
501501
ServerBase.SetServerCertificateInEndpointDescription(description,
502-
m_serverCertProvider.SendCertificateChain,
503502
certificateTypeProvider,
504503
false);
505504
}

Stack/Opc.Ua.Core/Security/Certificates/CertificateTypesProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public X509Certificate2 GetInstanceCertificate(string securityPolicyUri)
119119
}
120120

121121
/// <summary>
122-
/// Loads the cached certificate chain blob of a certificate for use in a secure channel as raw byte array.
122+
/// Loads the cached certificate chain blob of a certificate for use in a secure channel as raw byte array from cache.
123123
/// </summary>
124124
/// <param name="certificate">The application certificate.</param>
125125
public byte[] LoadCertificateChainRaw(X509Certificate2 certificate)
@@ -199,6 +199,7 @@ public X509Certificate2Collection LoadCertificateChain(X509Certificate2 certific
199199
public void Update(SecurityConfiguration securityConfiguration)
200200
{
201201
m_securityConfiguration = securityConfiguration;
202+
//ToDo intialize internal CertificateValidator after Certificate Update to clear cache of old application certificates
202203
}
203204

204205
CertificateValidator m_certificateValidator;

Stack/Opc.Ua.Core/Stack/Server/ServerBase.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -604,20 +604,18 @@ public static bool RequireEncryption(EndpointDescription description)
604604
/// Sets the Server Certificate in an Endpoint description if the description requires encryption.
605605
/// </summary>
606606
/// <param name="description">the endpoint Description to set the server certificate</param>
607-
/// <param name="sendCertificateChain">true if the certificate chain shall be sent</param>
608607
/// <param name="certificateTypesProvider">The provider to get the server certificate per certificate type.</param>
609608
/// <param name="checkRequireEncryption">only set certificate if the endpoint does require Encryption</param>
610609
public static void SetServerCertificateInEndpointDescription(
611610
EndpointDescription description,
612-
bool sendCertificateChain,
613611
CertificateTypesProvider certificateTypesProvider,
614612
bool checkRequireEncryption = true)
615613
{
616614
if (!checkRequireEncryption || RequireEncryption(description))
617615
{
618616
X509Certificate2 serverCertificate = certificateTypesProvider.GetInstanceCertificate(description.SecurityPolicyUri);
619617
// check if complete chain should be sent.
620-
if (sendCertificateChain)
618+
if (certificateTypesProvider.SendCertificateChain)
621619
{
622620
description.ServerCertificate = certificateTypesProvider.LoadCertificateChainRaw(serverCertificate);
623621
}
@@ -797,6 +795,22 @@ protected virtual EndpointBase GetEndpointInstance(ServerBase server)
797795
protected virtual void OnCertificateUpdate(object sender, CertificateUpdateEventArgs e)
798796
{
799797
InstanceCertificateTypesProvider.Update(e.SecurityConfiguration);
798+
799+
foreach (var certificateIdentifier in Configuration.SecurityConfiguration.ApplicationCertificates)
800+
{
801+
// preload chain
802+
X509Certificate2 certificate = certificateIdentifier.Find(false).GetAwaiter().GetResult();
803+
InstanceCertificateTypesProvider.LoadCertificateChainAsync(certificate).GetAwaiter().GetResult();
804+
}
805+
806+
//update certificate in the endpoint descriptions
807+
foreach (EndpointDescription endpointDescription in m_endpoints)
808+
{
809+
SetServerCertificateInEndpointDescription(
810+
endpointDescription,
811+
InstanceCertificateTypesProvider);
812+
}
813+
800814
foreach (var listener in TransportListeners)
801815
{
802816
listener.CertificateUpdate(e.CertificateValidator, InstanceCertificateTypesProvider);
@@ -1476,7 +1490,7 @@ protected virtual void ProcessRequest(IEndpointIncomingRequest request, object c
14761490
{
14771491
request.CallSynchronously();
14781492
}
1479-
#endregion
1493+
#endregion
14801494

14811495
#region RequestQueue Class
14821496
/// <summary>
@@ -1706,7 +1720,7 @@ private void OnProcessRequestQueue(object state)
17061720
}
17071721
}
17081722
#endif
1709-
#endregion
1723+
#endregion
17101724

17111725
#region Private Fields
17121726
private ServerBase m_server;
@@ -1720,7 +1734,7 @@ private void OnProcessRequestQueue(object state)
17201734
private Queue<IEndpointIncomingRequest> m_queue;
17211735
private int m_totalThreadCount;
17221736
#endif
1723-
#endregion
1737+
#endregion
17241738

17251739
}
17261740
#endregion

Stack/Opc.Ua.Core/Stack/Tcp/TcpServiceHost.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ public List<EndpointDescription> CreateServiceHost(
9898

9999
ServerBase.SetServerCertificateInEndpointDescription(
100100
description,
101-
sendCertificateChain,
102101
instanceCertificateTypesProvider);
103102

104103
listenerEndpoints.Add(description);

0 commit comments

Comments
 (0)