-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved upgrade path for older TLS certificate generation versions.
- Loading branch information
Showing
7 changed files
with
181 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
src/Contrast.K8s.AgentOperator/Core/Tls/TlsCertificateChainValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Contrast Security, Inc licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Linq; | ||
|
||
namespace Contrast.K8s.AgentOperator.Core.Tls | ||
{ | ||
public interface ITlsCertificateChainValidator | ||
{ | ||
bool IsValid(TlsCertificateChain chain, out ValidationResultReason reason); | ||
} | ||
|
||
public class TlsCertificateChainValidator : ITlsCertificateChainValidator | ||
{ | ||
public bool IsValid(TlsCertificateChain chain, out ValidationResultReason reason) | ||
{ | ||
var renewThreshold = DateTime.Now + TimeSpan.FromDays(90); | ||
|
||
if (!chain.CaCertificate.HasPrivateKey | ||
|| !chain.ServerCertificate.HasPrivateKey) | ||
{ | ||
reason = ValidationResultReason.MissingPrivateKey; | ||
} | ||
else if (chain.CaCertificate.NotAfter < renewThreshold | ||
|| chain.ServerCertificate.NotAfter < renewThreshold) | ||
{ | ||
reason = ValidationResultReason.Expired; | ||
} | ||
else if (!TlsCertificateChainGenerator.GenerationVersion.SequenceEqual(chain.Version)) | ||
{ | ||
reason = ValidationResultReason.OldVersion; | ||
} | ||
else | ||
{ | ||
reason = ValidationResultReason.NoError; | ||
} | ||
|
||
return reason == ValidationResultReason.NoError; | ||
} | ||
} | ||
|
||
public enum ValidationResultReason | ||
{ | ||
NoError = 0, | ||
MissingPrivateKey, | ||
Expired, | ||
OldVersion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
tests/Contrast.K8s.AgentOperator.Tests/Core/Tls/TlsCertificateChainValidatorTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Contrast Security, Inc licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using AutoFixture; | ||
using CertificateManager; | ||
using Contrast.K8s.AgentOperator.Core.Tls; | ||
using Contrast.K8s.AgentOperator.Options; | ||
using FluentAssertions; | ||
using FluentAssertions.Execution; | ||
using Xunit; | ||
|
||
namespace Contrast.K8s.AgentOperator.Tests.Core.Tls | ||
{ | ||
public class TlsCertificateChainValidatorTests | ||
{ | ||
private static readonly Fixture AutoFixture = new(); | ||
|
||
[Fact] | ||
public void When_chain_expiration_is_valid_then_IsValid_should_return_true() | ||
{ | ||
using var chainFake = FakeCertificates(TimeSpan.FromDays(180)); | ||
|
||
var validator = new TlsCertificateChainValidator(); | ||
|
||
// Act | ||
var result = validator.IsValid(chainFake, out _); | ||
|
||
// Assert | ||
result.Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public void When_chain_expiration_is_expired_then_IsValid_should_return_expired() | ||
{ | ||
using var chainFake = FakeCertificates(TimeSpan.FromDays(45)); | ||
|
||
var validator = new TlsCertificateChainValidator(); | ||
|
||
// Act | ||
var result = validator.IsValid(chainFake, out var reason); | ||
|
||
// Assert | ||
using (new AssertionScope()) | ||
{ | ||
result.Should().BeFalse(); | ||
reason.Should().Be(ValidationResultReason.Expired); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void When_chain_version_differs_then_IsValid_should_return_old_version() | ||
{ | ||
using var chainFake = FakeCertificates(TimeSpan.FromDays(180)) with | ||
{ | ||
Version = AutoFixture.Create<byte[]>() | ||
}; | ||
|
||
var validator = new TlsCertificateChainValidator(); | ||
|
||
// Act | ||
var result = validator.IsValid(chainFake, out var reason); | ||
|
||
// Assert | ||
using (new AssertionScope()) | ||
{ | ||
result.Should().BeFalse(); | ||
reason.Should().Be(ValidationResultReason.OldVersion); | ||
} | ||
} | ||
|
||
private static TlsCertificateChain FakeCertificates(TimeSpan expiresAfter) | ||
{ | ||
var generator = new TlsCertificateChainGenerator( | ||
new CreateCertificates(new CertificateUtility()), | ||
AutoFixture.Create<TlsCertificateOptions>() with { ExpiresAfter = expiresAfter } | ||
); | ||
return generator.CreateTlsCertificateChain(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters