Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDS: add Method RevokeCertificate to Client and Server #2497

Merged
merged 6 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Libraries/Opc.Ua.Gds.Client.Common/GlobalDiscoveryServerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,25 @@
applicationId);
}

/// <summary>
/// Revokes a Certificate issued to the Application by the CertificateManager
/// </summary>
/// <param name="applicationId">The application id.</param>
/// <param name="certificate">The certificate to revoke</param>
public void RevokeCertificate(NodeId applicationId, byte[] certificate)
{
if (!IsConnected)
{
Connect();

Check warning on line 630 in Libraries/Opc.Ua.Gds.Client.Common/GlobalDiscoveryServerClient.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Client.Common/GlobalDiscoveryServerClient.cs#L630

Added line #L630 was not covered by tests
}

Session.Call(
ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory, Session.NamespaceUris),
ExpandedNodeId.ToNodeId(Opc.Ua.Gds.MethodIds.CertificateDirectoryType_RevokeCertificate, Session.NamespaceUris),
applicationId,
certificate);
}

Check warning on line 638 in Libraries/Opc.Ua.Gds.Client.Common/GlobalDiscoveryServerClient.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Client.Common/GlobalDiscoveryServerClient.cs#L633-L638

Added lines #L633 - L638 were not covered by tests

/// <summary>
/// Requests a new certificate.
/// </summary>
Expand Down
48 changes: 46 additions & 2 deletions Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,7 @@
activeNode.GetTrustList.OnCall = new GetTrustListMethodStateMethodCallHandler(OnGetTrustList);
activeNode.GetCertificateStatus.OnCall = new GetCertificateStatusMethodStateMethodCallHandler(OnGetCertificateStatus);
activeNode.StartSigningRequest.OnCall = new StartSigningRequestMethodStateMethodCallHandler(OnStartSigningRequest);
// TODO
//activeNode.RevokeCertificate.OnCall = new RevokeCertificateMethodStateMethodCallHandler(OnRevokeCertificate);
activeNode.RevokeCertificate.OnCall = new RevokeCertificateMethodStateMethodCallHandler(OnRevokeCertificate);
romanett marked this conversation as resolved.
Show resolved Hide resolved

activeNode.CertificateGroups.DefaultApplicationGroup.CertificateTypes.Value = new NodeId[] { Opc.Ua.ObjectTypeIds.RsaSha256ApplicationCertificateType };
activeNode.CertificateGroups.DefaultApplicationGroup.TrustList.LastUpdateTime.Value = DateTime.UtcNow;
Expand Down Expand Up @@ -580,6 +579,51 @@
return ServiceResult.Good;
}

private ServiceResult OnRevokeCertificate(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId applicationId,
byte[] certificate)
{
HasApplicationAdminAccess(context);

Check warning on line 589 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L589

Added line #L589 was not covered by tests

if (m_database.GetApplication(applicationId) == null)
{
return new ServiceResult(StatusCodes.BadNotFound, "The ApplicationId does not refer to a registered application.");

Check warning on line 593 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L593

Added line #L593 was not covered by tests
}

romanett marked this conversation as resolved.
Show resolved Hide resolved
bool revoked = false;
var certifcateToRevoke = new X509Certificate2(certificate);

Check warning on line 597 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L596-L597

Added lines #L596 - L597 were not covered by tests
foreach (var certType in m_certTypeMap)
{
try
{
byte[] applicationCertificate;
if (m_database.GetApplicationCertificate(applicationId, certType.Value, out applicationCertificate))
{
if (applicationCertificate != null)
{
if (new X509Certificate2(applicationCertificate).Equals(certifcateToRevoke))
{
RevokeCertificateAsync(certificate).Wait();
revoked = true;

Check warning on line 610 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L609-L610

Added lines #L609 - L610 were not covered by tests
}
}
}
}
catch

Check warning on line 615 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L614-L615

Added lines #L614 - L615 were not covered by tests
{
Utils.LogError("Failed to revoke: {0}", certType.Value);
}

Check warning on line 618 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L617-L618

Added lines #L617 - L618 were not covered by tests
}
if (!revoked)
{
throw new ServiceResultException(StatusCodes.BadInvalidArgument, "The certificate is not a Certificate for the specified Application that was issued by the CertificateManager.");

Check warning on line 622 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L622

Added line #L622 was not covered by tests
}
return ServiceResult.Good;

Check warning on line 624 in Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs

View check run for this annotation

Codecov / codecov/patch

Libraries/Opc.Ua.Gds.Server.Common/ApplicationsNodeManager.cs#L624

Added line #L624 was not covered by tests
}

private ServiceResult OnFindApplications(
ISystemContext context,
MethodState method,
Expand Down
16 changes: 16 additions & 0 deletions Tests/Opc.Ua.Gds.Tests/ClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,22 @@ public void GetInvalidCertificateStatus()
}
}

[Test, Order(895)]
public void RevokeGoodCertificates()
{
AssertIgnoreTestWithoutInvalidRegistration();
AssertIgnoreTestWithoutGoodNewKeyPairRequest();
ConnectGDS(true);
foreach (var application in m_goodApplicationTestSet)
{
m_gdsClient.GDSClient.RevokeCertificate(application.ApplicationRecord.ApplicationId, application.Certificate);

Assert.That(() => {
m_gdsClient.GDSClient.RevokeCertificate(application.ApplicationRecord.ApplicationId, application.Certificate);
}, Throws.Exception);
}
}

[Test, Order(900)]
public void UnregisterGoodApplications()
{
Expand Down
Loading