Skip to content

Commit

Permalink
Merge branch 'master' into fork/Archie/Client_Durable_Subscription_Is…
Browse files Browse the repository at this point in the history
…olated
  • Loading branch information
Archie-Miller committed Sep 10, 2024
2 parents 80fd979 + 41363bd commit 4a76a03
Show file tree
Hide file tree
Showing 42 changed files with 1,066 additions and 460 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/rejected</StorePath>
</RejectedCertificateStore>

<MaxRejectedCertificates>5</MaxRejectedCertificates>

<!-- WARNING: The following setting (to automatically accept untrusted certificates) should be used
for easy debugging purposes ONLY and turned off for production deployments! -->
<AutoAcceptUntrustedCertificates>false</AutoAcceptUntrustedCertificates>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/rejected</StorePath>
</RejectedCertificateStore>
<MaxRejectedCertificates>5</MaxRejectedCertificates>

<!-- WARNING: The following setting (to automatically accept untrusted certificates) should be used
for easy debugging purposes ONLY and turned off for production deployments! -->
Expand Down
4 changes: 2 additions & 2 deletions Libraries/Opc.Ua.Client/Session/Session.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* ========================================================================
* Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
*
* OPC Foundation MIT License 1.00
* 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
Expand Down Expand Up @@ -4404,7 +4404,7 @@ private Node ProcessReadResponse(

value = attributes[Attributes.EventNotifier];

if (value == null)
if (value == null || value.Value is null)
{
throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Object does not support the EventNotifier attribute.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,13 @@ public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTok
return this;
}

/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetMaxRejectedCertificates(int maxRejectedCertificates)
{
ApplicationConfiguration.SecurityConfiguration.MaxRejectedCertificates = maxRejectedCertificates;
return this;
}

/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetAutoAcceptUntrustedCertificates(bool autoAccept)
{
Expand Down Expand Up @@ -1017,6 +1024,7 @@ private void SetSecureDefaults(SecurityConfiguration securityConfiguration)
securityConfiguration.SuppressNonceValidationErrors = false;
securityConfiguration.SendCertificateChain = true;
securityConfiguration.MinimumCertificateKeySize = CertificateFactory.DefaultKeySize;
securityConfiguration.MaxRejectedCertificates = 5;
}

/// <summary>
Expand Down
16 changes: 12 additions & 4 deletions Libraries/Opc.Ua.Configuration/ApplicationInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -892,12 +892,20 @@ private static async Task DeleteApplicationInstanceCertificateAsync(ApplicationC

if (!string.IsNullOrEmpty(thumbprint))
{
using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
if (store != null)
{
bool deleted = await store.Delete(thumbprint).ConfigureAwait(false);
if (deleted)
try
{
Utils.LogInfo(TraceMasks.Security, "Application Instance Certificate [{0}] deleted from trusted store.", thumbprint);
bool deleted = await store.Delete(thumbprint).ConfigureAwait(false);
if (deleted)
{
Utils.LogInfo(TraceMasks.Security, "Application Instance Certificate [{0}] deleted from trusted store.", thumbprint);
}
}
finally
{
store.Close();
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions Libraries/Opc.Ua.Configuration/IApplicationConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,16 @@ public interface IApplicationConfigurationBuilderSecurityOptions :
IApplicationConfigurationBuilderExtension,
IApplicationConfigurationBuilderCreate
{
/// <summary>
/// The number of rejected certificates to keep in the store.
/// </summary>
/// <param name="maxRejectedCertificates">
/// The number of certificates to keep in the rejected store before it is updated.
/// <see langword="0"/> to keep all rejected certificates.
/// A negative number to keep no history.
/// </param>
IApplicationConfigurationBuilderSecurityOptions SetMaxRejectedCertificates(int maxRejectedCertificates);

/// <summary>
/// Whether an unknown application certificate should be accepted
/// once all other security checks passed.
Expand Down
62 changes: 37 additions & 25 deletions Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ protected async Task<ICertificateGroup> InitializeCertificateGroup(CertificateGr
}

ICertificateGroup certificateGroup = m_certificateGroupFactory.Create(
m_globalDiscoveryServerConfiguration.AuthoritiesStorePath, certificateGroupConfiguration, m_configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath);
m_globalDiscoveryServerConfiguration.AuthoritiesStorePath,
certificateGroupConfiguration,
m_configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath);
SetCertificateGroupNodes(certificateGroup);
await certificateGroup.Init().ConfigureAwait(false);

Expand Down Expand Up @@ -654,12 +656,12 @@ private ServiceResult OnGetApplication(
}

private ServiceResult OnCheckRevocationStatus(
ISystemContext context,
MethodState method,
NodeId objectId,
byte[] certificate,
ref StatusCode certificateStatus,
ref DateTime validityTime)
ISystemContext context,
MethodState method,
NodeId objectId,
byte[] certificate,
ref StatusCode certificateStatus,
ref DateTime validityTime)
{
AuthorizationHelper.HasAuthenticatedSecureChannel(context);

Expand All @@ -673,11 +675,20 @@ private ServiceResult OnCheckRevocationStatus(
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;

//add GDS Issuer Cert Store Certificates to the Chain validation for consitent behaviour on all Platforms
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath))
//add GDS Issuer Cert Store Certificates to the Chain validation for consistent behaviour on all Platforms
ICertificateStore store = m_configuration.SecurityConfiguration.TrustedIssuerCertificates.OpenStore();
if (store != null)
{
chain.ChainPolicy.ExtraStore.AddRange(store.Enumerate().GetAwaiter().GetResult());
try
{
chain.ChainPolicy.ExtraStore.AddRange(store.Enumerate().GetAwaiter().GetResult());
}
finally
{
store.Close();
}
}

using (var x509 = new X509Certificate2(certificate))
{
if (chain.Build(x509))
Expand Down Expand Up @@ -747,13 +758,13 @@ private ServiceResult OnCheckRevocationStatus(
}

private ServiceResult OnGetCertificates(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId applicationId,
NodeId certificateGroupId,
ref NodeId[] certificateTypeIds,
ref byte[][] certificates)
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId applicationId,
NodeId certificateGroupId,
ref NodeId[] certificateTypeIds,
ref byte[][] certificates)
{
AuthorizationHelper.HasAuthorization(context, AuthorizationHelper.CertificateAuthorityAdminOrSelfAdmin);

Expand Down Expand Up @@ -797,7 +808,7 @@ private ServiceResult OnGetCertificates(

return ServiceResult.Good;
}

private ServiceResult CheckHttpsDomain(ApplicationRecordDataType application, string commonName)
{
if (application.ApplicationType == ApplicationType.Client)
Expand Down Expand Up @@ -1302,9 +1313,10 @@ out privateKeyPassword
issuerCertificates[0] = certificateGroup.Certificate.RawData;

// store new app certificate
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_globalDiscoveryServerConfiguration.ApplicationCertificatesStorePath))
var certificateStoreIdentifier = new CertificateStoreIdentifier(m_globalDiscoveryServerConfiguration.ApplicationCertificatesStorePath);
using (ICertificateStore store = certificateStoreIdentifier.OpenStore())
{
store.Add(certificate).Wait();
store?.Add(certificate).Wait();
}

m_database.SetApplicationCertificate(applicationId, m_certTypeMap[certificateGroup.CertificateType], signedCertificate);
Expand Down Expand Up @@ -1505,7 +1517,7 @@ protected override NodeState ValidateNode(
handle.Validated = true;
return handle.Node;
}
#endregion
#endregion

#region Overridden Methods
#endregion
Expand Down Expand Up @@ -1551,17 +1563,17 @@ protected void SetCertificateGroupNodes(ICertificateGroup certificateGroup)
{
certificateGroup.DefaultTrustList.Handle = new TrustList(
certificateGroup.DefaultTrustList,
certificateGroup.Configuration.TrustedListPath,
certificateGroup.Configuration.IssuerListPath,
new CertificateStoreIdentifier(certificateGroup.Configuration.TrustedListPath),
new CertificateStoreIdentifier(certificateGroup.Configuration.IssuerListPath),
new TrustList.SecureAccess(HasTrustListAccess),
new TrustList.SecureAccess(HasTrustListAccess));
}
}

#region AuthorizationHelpers
private void HasTrustListAccess(ISystemContext context, string trustedStorePath)
private void HasTrustListAccess(ISystemContext context, CertificateStoreIdentifier trustedStore)
{
AuthorizationHelper.HasTrustListAccess(context, trustedStorePath, m_certTypeMap, m_database);
AuthorizationHelper.HasTrustListAccess(context, trustedStore, m_certTypeMap, m_database);
}
#endregion

Expand Down
Loading

0 comments on commit 4a76a03

Please sign in to comment.