Skip to content

Commit

Permalink
TLS Check Certificate Revocation option (#287)
Browse files Browse the repository at this point in the history
* TLS Check Certificate Revocation option

Looks like OCSP must-staple support is implemented in .NET7 and should be in
.NET8. Not sure if .NET6 received a patch as well.
dotnet/runtime#33377

* Option for CertificateRevocationCheckMode

* Update src/NATS.Client.Core/NatsTlsOpts.cs

Co-authored-by: Caleb Lloyd <2414837+caleblloyd@users.noreply.github.com>

---------

Co-authored-by: Caleb Lloyd <2414837+caleblloyd@users.noreply.github.com>
  • Loading branch information
mtmk and caleblloyd authored Dec 15, 2023
1 parent 2d3711b commit f326e74
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/NATS.Client.Core/Internal/SslStreamConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ private SslClientAuthenticationOptions SslClientAuthenticationOptions(NatsUri ur
ClientCertificates = _tlsCerts?.ClientCerts,
LocalCertificateSelectionCallback = lcsCb,
RemoteCertificateValidationCallback = rcsCb,
CertificateRevocationCheckMode = _tlsOpts.CertificateRevocationCheckMode,
};

return options;
Expand Down
4 changes: 4 additions & 0 deletions src/NATS.Client.Core/NatsTlsOpts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public sealed record NatsTlsOpts
/// <summary>When true, skip remote certificate verification and accept any server certificate</summary>
public bool InsecureSkipVerify { get; init; }

/// <summary>Certificate revocation mode for certificate validation.</summary>
/// <value>One of the values in <see cref="T:System.Security.Cryptography.X509Certificates.X509RevocationMode" />. The default is <see langword="NoCheck" />.</value>
public X509RevocationMode CertificateRevocationCheckMode { get; init; }

/// <summary>TLS mode to use during connection</summary>
public TlsMode Mode { get; init; }

Expand Down
21 changes: 21 additions & 0 deletions tests/NATS.Client.Core.Tests/TlsClientTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Security.Cryptography.X509Certificates;

namespace NATS.Client.Core.Tests;

public class TlsClientTest
Expand All @@ -22,6 +24,25 @@ public async Task Client_connect_using_certificate()
Assert.True(rtt > TimeSpan.Zero);
}

[Fact]
public async Task Client_connect_using_certificate_and_revocation_check()
{
await using var server = NatsServer.Start(
new NullOutputHelper(),
new NatsServerOptsBuilder()
.UseTransport(TransportType.Tls, tlsVerify: true)
.Build());

var clientOpts = server.ClientOpts(NatsOpts.Default with { Name = "tls-test-client" });
clientOpts = clientOpts with { TlsOpts = clientOpts.TlsOpts with { CertificateRevocationCheckMode = X509RevocationMode.Online } };
await using var nats = new NatsConnection(clientOpts);

// At the moment I don't know of a good way of checking if the revocation check is working
// except to check if the connection fails. So we are expecting an exception here.
var exception = await Assert.ThrowsAnyAsync<Exception>(async () => await nats.ConnectAsync());
Assert.Contains("remote certificate was rejected", exception.InnerException!.InnerException!.Message);
}

[Fact]
public async Task Client_cannot_connect_without_certificate()
{
Expand Down

0 comments on commit f326e74

Please sign in to comment.