diff --git a/Libraries/Opc.Ua.Client/Session/Session.cs b/Libraries/Opc.Ua.Client/Session/Session.cs
index 73670373b..21d014100 100644
--- a/Libraries/Opc.Ua.Client/Session/Session.cs
+++ b/Libraries/Opc.Ua.Client/Session/Session.cs
@@ -1196,8 +1196,6 @@ await m_configuration
byte[] serverCertificateData = response.ServerCertificate;
SignatureData serverSignature = response.ServerSignature;
EndpointDescriptionCollection serverEndpoints = response.ServerEndpoints;
- SignedSoftwareCertificateCollection serverSoftwareCertificates = response
- .ServerSoftwareCertificates;
m_sessionTimeout = response.RevisedSessionTimeout;
m_maxRequestMessageSize = response.MaxRequestMessageSize;
@@ -1232,8 +1230,6 @@ await m_configuration
clientCertificateChainData,
clientNonce);
- HandleSignedSoftwareCertificates(serverSoftwareCertificates);
-
// process additional header
ProcessResponseAdditionalHeader(response.ResponseHeader, serverCertificate);
@@ -1280,10 +1276,6 @@ await m_configuration
m_instanceCertificateChain,
m_endpoint.Description.SecurityMode != MessageSecurityMode.None);
- // send the software certificates assigned to the client.
- SignedSoftwareCertificateCollection clientSoftwareCertificates
- = GetSoftwareCertificates();
-
// copy the preferred locales if provided.
if (preferredLocales != null && preferredLocales.Count > 0)
{
@@ -1294,7 +1286,7 @@ SignedSoftwareCertificateCollection clientSoftwareCertificates
ActivateSessionResponse activateResponse = await ActivateSessionAsync(
null,
clientSignature,
- clientSoftwareCertificates,
+ null,
m_preferredLocales,
new ExtensionObject(identityToken),
userTokenSignature,
@@ -1320,12 +1312,6 @@ SignedSoftwareCertificateCollection clientSoftwareCertificates
}
}
- if (clientSoftwareCertificates?.Count > 0 &&
- (certificateResults == null || certificateResults.Count == 0))
- {
- m_logger.LogInformation("Empty results were received for the ActivateSession call.");
- }
-
// fetch namespaces.
await FetchNamespaceTablesAsync(ct).ConfigureAwait(false);
@@ -1487,14 +1473,10 @@ public async Task UpdateSessionAsync(
m_instanceCertificateChain,
m_endpoint.Description.SecurityMode != MessageSecurityMode.None);
- // send the software certificates assigned to the client.
- SignedSoftwareCertificateCollection clientSoftwareCertificates
- = GetSoftwareCertificates();
-
ActivateSessionResponse response = await ActivateSessionAsync(
null,
clientSignature,
- clientSoftwareCertificates,
+ null,
preferredLocales,
new ExtensionObject(identityToken),
userTokenSignature,
@@ -2339,10 +2321,6 @@ public async Task ReconnectAsync(
m_instanceCertificateChain,
m_endpoint.Description.SecurityMode != MessageSecurityMode.None);
- // send the software certificates assigned to the client.
- SignedSoftwareCertificateCollection clientSoftwareCertificates
- = GetSoftwareCertificates();
-
m_logger.LogInformation("Session REPLACING channel for {SessionId}.", SessionId);
if (connection != null)
@@ -2640,14 +2618,6 @@ public bool RemoveTransferredSubscription(Subscription subscription)
return true;
}
- ///
- /// Returns the software certificates assigned to the application.
- ///
- protected virtual SignedSoftwareCertificateCollection GetSoftwareCertificates()
- {
- return [];
- }
-
///
/// Handles an error when validating the application instance certificate provided by the server.
///
@@ -2659,26 +2629,6 @@ protected virtual void OnApplicationCertificateError(
throw new ServiceResultException(result);
}
- ///
- /// Handles an error when validating software certificates provided by the server.
- ///
- ///
- protected virtual void OnSoftwareCertificateError(
- SignedSoftwareCertificate signedCertificate,
- ServiceResult result)
- {
- throw new ServiceResultException(result);
- }
-
- ///
- /// Inspects the software certificates provided by the server.
- ///
- protected virtual void ValidateSoftwareCertificates(
- List softwareCertificates)
- {
- // always accept valid certificates.
- }
-
///
/// Starts a timer to check that the connection to the server is still available.
///
@@ -4175,38 +4125,6 @@ private static void UpdateDescription(
return currentToken?.ServerNonce;
}
- ///
- /// Handles the validation of server software certificates and application callback.
- ///
- private void HandleSignedSoftwareCertificates(
- SignedSoftwareCertificateCollection serverSoftwareCertificates)
- {
- // get a validator to check certificates provided by server.
- CertificateValidator validator = m_configuration.CertificateValidator;
-
- // validate software certificates.
- var softwareCertificates = new List();
-
- foreach (SignedSoftwareCertificate signedCertificate in serverSoftwareCertificates)
- {
- ServiceResult result = SoftwareCertificate.Validate(
- validator,
- signedCertificate.CertificateData,
- m_telemetry,
- out SoftwareCertificate softwareCertificate);
-
- if (ServiceResult.IsBad(result))
- {
- OnSoftwareCertificateError(signedCertificate, result);
- }
-
- softwareCertificates.Add(softwareCertificate);
- }
-
- // check if software certificates meet application requirements.
- ValidateSoftwareCertificates(softwareCertificates);
- }
-
///
/// Processes the response from a publish request.
///
diff --git a/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs b/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs
index 73ff4e8a7..a3d0d17df 100644
--- a/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs
+++ b/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs
@@ -1021,14 +1021,12 @@ public static void ReportAuditCreateSessionEvent(
/// A contextual logger to log to
/// The audit entry id.
/// The session that is activated.
- /// The software certificates
/// The exception received during activate session request
public static void ReportAuditActivateSessionEvent(
this IAuditEventServer server,
ILogger logger,
string auditEntryId,
ISession session,
- IList softwareCertificates,
Exception exception = null)
{
if (server?.Auditing != true)
@@ -1078,25 +1076,6 @@ public static void ReportAuditActivateSessionEvent(
Utils.Clone(session?.IdentityToken),
false);
- if (softwareCertificates != null)
- {
- // build the list of SignedSoftwareCertificate
- var signedSoftwareCertificates = new List();
- foreach (SoftwareCertificate softwareCertificate in softwareCertificates)
- {
- var item = new SignedSoftwareCertificate
- {
- CertificateData = softwareCertificate.SignedCertificate.RawData
- };
- signedSoftwareCertificates.Add(item);
- }
- e.SetChildValue(
- systemContext,
- BrowseNames.ClientSoftwareCertificates,
- signedSoftwareCertificates.ToArray(),
- false);
- }
-
server.ReportAuditEvent(systemContext, e);
}
catch (Exception e)
diff --git a/Libraries/Opc.Ua.Server/Server/StandardServer.cs b/Libraries/Opc.Ua.Server/Server/StandardServer.cs
index 834e47ea4..6a0511729 100644
--- a/Libraries/Opc.Ua.Server/Server/StandardServer.cs
+++ b/Libraries/Opc.Ua.Server/Server/StandardServer.cs
@@ -346,7 +346,6 @@ public override async Task CreateSessionAsync(
byte[] serverNonce;
byte[] serverCertificate = null;
EndpointDescriptionCollection serverEndpoints = null;
- SignedSoftwareCertificateCollection serverSoftwareCertificates = null;
SignatureData serverSignature = null;
uint maxRequestMessageSize = (uint)MessageContext.MaxMessageSize;
@@ -528,9 +527,6 @@ X509Certificate2Collection clientCertificateChain
// return the endpoints supported by the server.
serverEndpoints = GetEndpointDescriptions(endpointUrl, BaseAddresses, null);
- // return the software certificates assigned to the server.
- serverSoftwareCertificates = [.. ServerProperties.SoftwareCertificates];
-
// sign the nonce provided by the client.
serverSignature = null;
@@ -580,7 +576,6 @@ X509Certificate2Collection clientCertificateChain
ServerNonce = serverNonce,
ServerCertificate = serverCertificate,
ServerEndpoints = serverEndpoints,
- ServerSoftwareCertificates = serverSoftwareCertificates,
ServerSignature = serverSignature,
MaxRequestMessageSize = maxRequestMessageSize
};
@@ -724,75 +719,14 @@ public override async Task ActivateSessionAsync(
DiagnosticInfoCollection diagnosticInfos = null;
OperationContext context = ValidateRequest(secureChannelContext, requestHeader, RequestType.ActivateSession);
- // validate client's software certificates.
- var softwareCertificates = new List();
try
{
- if (context?.SecurityPolicyUri != SecurityPolicies.None)
- {
- bool diagnosticsExist = false;
-
- if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
- {
- diagnosticInfos = [];
- }
-
- results = [];
- diagnosticInfos = [];
-
- foreach (SignedSoftwareCertificate signedCertificate in clientSoftwareCertificates)
- {
- ServiceResult result = SoftwareCertificate.Validate(
- CertificateValidator,
- signedCertificate.CertificateData,
- m_serverInternal.Telemetry,
- out SoftwareCertificate softwareCertificate);
-
- if (ServiceResult.IsBad(result))
- {
- results.Add(result.Code);
-
- // add diagnostics if requested.
- if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
- {
- DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(
- ServerInternal,
- context,
- result,
- m_logger);
- diagnosticInfos.Add(diagnosticInfo);
- diagnosticsExist = true;
- }
- }
- else
- {
- softwareCertificates.Add(softwareCertificate);
- results.Add(StatusCodes.Good);
-
- // add diagnostics if requested.
- if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
- {
- diagnosticInfos.Add(null);
- }
- }
- }
-
- if (!diagnosticsExist && diagnosticInfos != null)
- {
- diagnosticInfos.Clear();
- }
- }
-
- // check if certificates meet the server's requirements.
- ValidateSoftwareCertificates(softwareCertificates);
-
// activate the session.
(bool identityChanged, serverNonce) = await ServerInternal.SessionManager.ActivateSessionAsync(
context,
requestHeader.AuthenticationToken,
clientSignature,
- softwareCertificates,
userIdentityToken,
userTokenSignature,
localeIds,
@@ -817,8 +751,7 @@ public override async Task ActivateSessionAsync(
ServerInternal.ReportAuditActivateSessionEvent(
m_logger,
context?.AuditEntryId,
- session,
- softwareCertificates);
+ session);
ResponseHeader responseHeader = CreateResponse(requestHeader, StatusCodes.Good);
@@ -845,7 +778,6 @@ public override async Task ActivateSessionAsync(
m_logger,
context?.AuditEntryId,
session,
- softwareCertificates,
e);
lock (ServerInternal.DiagnosticsWriteLock)
@@ -2728,16 +2660,6 @@ protected virtual void OnApplicationCertificateError(
throw new ServiceResultException(result);
}
- ///
- /// Inspects the software certificates provided by the server.
- ///
- /// The software certificates.
- protected virtual void ValidateSoftwareCertificates(
- List softwareCertificates)
- {
- // always accept valid certificates.
- }
-
///
/// Verifies that the request header is valid.
///
diff --git a/Libraries/Opc.Ua.Server/Session/ISession.cs b/Libraries/Opc.Ua.Server/Session/ISession.cs
index 020ae48e6..b4681d8a5 100644
--- a/Libraries/Opc.Ua.Server/Session/ISession.cs
+++ b/Libraries/Opc.Ua.Server/Session/ISession.cs
@@ -113,7 +113,6 @@ public interface ISession : IDisposable
///
bool Activate(
OperationContext context,
- List clientSoftwareCertificates,
UserIdentityToken identityToken,
IUserIdentity identity,
IUserIdentity effectiveIdentity,
@@ -187,7 +186,6 @@ bool Activate(
void ValidateBeforeActivate(
OperationContext context,
SignatureData clientSignature,
- List clientSoftwareCertificates,
ExtensionObject userIdentityToken,
SignatureData userTokenSignature,
out UserIdentityToken identityToken,
diff --git a/Libraries/Opc.Ua.Server/Session/ISessionManager.cs b/Libraries/Opc.Ua.Server/Session/ISessionManager.cs
index 29ee3ac84..a090db803 100644
--- a/Libraries/Opc.Ua.Server/Session/ISessionManager.cs
+++ b/Libraries/Opc.Ua.Server/Session/ISessionManager.cs
@@ -123,7 +123,6 @@ ValueTask CreateSessionAsync(
OperationContext context,
NodeId authenticationToken,
SignatureData clientSignature,
- List clientSoftwareCertificates,
ExtensionObject userIdentityToken,
SignatureData userTokenSignature,
StringCollection localeIds,
diff --git a/Libraries/Opc.Ua.Server/Session/Session.cs b/Libraries/Opc.Ua.Server/Session/Session.cs
index fb348f74e..bc18ce119 100644
--- a/Libraries/Opc.Ua.Server/Session/Session.cs
+++ b/Libraries/Opc.Ua.Server/Session/Session.cs
@@ -438,7 +438,6 @@ public bool UpdateLocaleIds(StringCollection localeIds)
public void ValidateBeforeActivate(
OperationContext context,
SignatureData clientSignature,
- List clientSoftwareCertificates,
ExtensionObject userIdentityToken,
SignatureData userTokenSignature,
out UserIdentityToken identityToken,
@@ -531,14 +530,6 @@ public void ValidateBeforeActivate(
throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
}
}
- else
- {
- // cannot change the certificates after activation.
- if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
- {
- throw new ServiceResultException(StatusCodes.BadInvalidArgument);
- }
- }
// validate the user identity token.
identityToken = ValidateUserIdentityToken(
@@ -555,7 +546,6 @@ public void ValidateBeforeActivate(
///
public bool Activate(
OperationContext context,
- List clientSoftwareCertificates,
UserIdentityToken identityToken,
IUserIdentity identity,
IUserIdentity effectiveIdentity,
@@ -597,21 +587,6 @@ public bool Activate(
// update server nonce.
m_serverNonce = serverNonce;
- // build list of signed certificates for audit event.
- var signedSoftwareCertificates = new List();
-
- if (clientSoftwareCertificates != null)
- {
- foreach (SoftwareCertificate softwareCertificate in clientSoftwareCertificates)
- {
- var item = new SignedSoftwareCertificate
- {
- CertificateData = softwareCertificate.SignedCertificate.RawData
- };
- signedSoftwareCertificates.Add(item);
- }
- }
-
// update the contact time.
lock (DiagnosticsLock)
{
diff --git a/Libraries/Opc.Ua.Server/Session/SessionManager.cs b/Libraries/Opc.Ua.Server/Session/SessionManager.cs
index a087b3bf8..b725e6a2d 100644
--- a/Libraries/Opc.Ua.Server/Session/SessionManager.cs
+++ b/Libraries/Opc.Ua.Server/Session/SessionManager.cs
@@ -283,7 +283,6 @@ public virtual async ValueTask CreateSessionAsync(
OperationContext context,
NodeId authenticationToken,
SignatureData clientSignature,
- List clientSoftwareCertificates,
ExtensionObject userIdentityToken,
SignatureData userTokenSignature,
StringCollection localeIds,
@@ -332,7 +331,6 @@ await m_semaphoreSlim.WaitAsync(cancellationToken)
session.ValidateBeforeActivate(
context,
clientSignature,
- clientSoftwareCertificates,
userIdentityToken,
userTokenSignature,
out newIdentity,
@@ -400,7 +398,6 @@ await m_semaphoreSlim.WaitAsync(cancellationToken)
bool contextChanged = session.Activate(
context,
- clientSoftwareCertificates,
newIdentity,
identity,
effectiveIdentity,
diff --git a/Stack/Opc.Ua.Core/Stack/Configuration/ServerProperties.cs b/Stack/Opc.Ua.Core/Stack/Configuration/ServerProperties.cs
index e019ca018..18b1aca96 100644
--- a/Stack/Opc.Ua.Core/Stack/Configuration/ServerProperties.cs
+++ b/Stack/Opc.Ua.Core/Stack/Configuration/ServerProperties.cs
@@ -48,7 +48,6 @@ public ServerProperties()
BuildNumber = string.Empty;
BuildDate = DateTime.MinValue;
DatatypeAssemblies = [];
- SoftwareCertificates = [];
}
///
@@ -85,10 +84,5 @@ public ServerProperties()
/// The assemblies that contain encodeable types that could be uses a variable values.
///
public StringCollection DatatypeAssemblies { get; }
-
- ///
- /// The software certificates granted to the server.
- ///
- public SignedSoftwareCertificateCollection SoftwareCertificates { get; }
}
}
diff --git a/Stack/Opc.Ua.Core/Stack/Types/SoftwareCertificate.cs b/Stack/Opc.Ua.Core/Stack/Types/SoftwareCertificate.cs
deleted file mode 100644
index 7a8144b03..000000000
--- a/Stack/Opc.Ua.Core/Stack/Types/SoftwareCertificate.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ========================================================================
- * Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved.
- *
- * OPC Foundation MIT License 1.00
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * The complete license agreement can be found here:
- * http://opcfoundation.org/License/MIT/1.00/
- * ======================================================================*/
-
-using System;
-using System.IO;
-using System.Runtime.Serialization;
-using System.Security.Cryptography.X509Certificates;
-
-namespace Opc.Ua
-{
- ///
- /// The SoftwareCertificate class.
- ///
- public class SoftwareCertificate
- {
- ///
- /// The SignedSoftwareCertificate that contains the SoftwareCertificate
- ///
- public X509Certificate2 SignedCertificate { get; set; }
-
- ///
- /// Validates a software certificate.
- ///
- public static ServiceResult Validate(
- CertificateValidator validator,
- byte[] signedCertificate,
- ITelemetryContext telemetry,
- out SoftwareCertificate softwareCertificate)
- {
- softwareCertificate = null;
-
- // validate the certificate.
- X509Certificate2 certificate;
- try
- {
- certificate = CertificateFactory.Create(signedCertificate);
- validator.ValidateAsync(certificate, default).GetAwaiter().GetResult();
- }
- catch (Exception e)
- {
- return ServiceResult.Create(
- e,
- StatusCodes.BadDecodingError,
- "Could not decode software certificate body.");
- }
-
- // certificate is valid.
- return ServiceResult.Good;
- }
- }
-}
diff --git a/Tests/Opc.Ua.Client.Tests/SessionClientBatchTests.cs b/Tests/Opc.Ua.Client.Tests/SessionClientBatchTests.cs
index 443c4f0ee..9635885e7 100644
--- a/Tests/Opc.Ua.Client.Tests/SessionClientBatchTests.cs
+++ b/Tests/Opc.Ua.Client.Tests/SessionClientBatchTests.cs
@@ -64,7 +64,6 @@ public async Task ActivateSessionAsyncShouldSimplyCallBaseMethodWhenNoLimitsSetA
RequestHeader requestHeader)
{
var clientSignature = new SignatureData();
- var clientSoftwareCertificates = new SignedSoftwareCertificateCollection();
var localeIds = new StringCollection();
var userIdentityToken = new ExtensionObject();
var userTokenSignature = new SignatureData();
@@ -81,7 +80,7 @@ public async Task ActivateSessionAsyncShouldSimplyCallBaseMethodWhenNoLimitsSetA
ActivateSessionResponse response = await sessionMock.ActivateSessionAsync(
requestHeader,
clientSignature,
- clientSoftwareCertificates,
+ null,
localeIds,
userIdentityToken,
userTokenSignature,
@@ -100,7 +99,6 @@ public void ActivateSessionAsyncShouldThrowExceptionWhenResponseContainsBadStatu
RequestHeader requestHeader)
{
var clientSignature = new SignatureData();
- var clientSoftwareCertificates = new SignedSoftwareCertificateCollection();
var localeIds = new StringCollection();
var userIdentityToken = new ExtensionObject();
var userTokenSignature = new SignatureData();
@@ -124,7 +122,7 @@ public void ActivateSessionAsyncShouldThrowExceptionWhenResponseContainsBadStatu
async () => await sessionMock.ActivateSessionAsync(
requestHeader,
clientSignature,
- clientSoftwareCertificates,
+ null,
localeIds,
userIdentityToken,
userTokenSignature,
@@ -138,7 +136,6 @@ public void ActivateSessionAsyncShouldThrowExceptionWhenSendRequestAsyncThrows(
RequestHeader requestHeader)
{
var clientSignature = new SignatureData();
- var clientSoftwareCertificates = new SignedSoftwareCertificateCollection();
var localeIds = new StringCollection();
var userIdentityToken = new ExtensionObject();
var userTokenSignature = new SignatureData();
@@ -156,7 +153,7 @@ public void ActivateSessionAsyncShouldThrowExceptionWhenSendRequestAsyncThrows(
async () => await sessionMock.ActivateSessionAsync(
requestHeader,
clientSignature,
- clientSoftwareCertificates,
+ null,
localeIds,
userIdentityToken,
userTokenSignature,