Skip to content

Commit

Permalink
Make it easier to add certs to the extra store (dotnet#29828)
Browse files Browse the repository at this point in the history
  • Loading branch information
HaoK authored Feb 8, 2021
1 parent 0d981a0 commit ae6e9c8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ private X509ChainPolicy BuildChainPolicy(X509Certificate2 certificate)
chainPolicy.TrustMode = Options.ChainTrustValidationMode;
}

chainPolicy.ExtraStore.AddRange(Options.AdditionalChainCertificates);

if (!Options.ValidateValidityPeriod)
{
chainPolicy.VerificationFlags |= X509VerificationFlags.IgnoreNotTimeValid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public class CertificateAuthenticationOptions : AuthenticationSchemeOptions
/// Collection of X509 certificates which are trusted components of the certificate chain.
/// </summary>
public X509Certificate2Collection CustomTrustStore { get; set; } = new X509Certificate2Collection();

/// <summary>
/// Collection of X509 certificates which are added to the X509Chain.ChainPolicy.ExtraStore of the certificate chain.
/// </summary>
public X509Certificate2Collection AdditionalChainCertificates { get; set; } = new X509Certificate2Collection();

/// <summary>
/// Method used to validate certificate chains against <see cref="CustomTrustStore"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions.AdditionalChainCertificates.get -> System.Security.Cryptography.X509Certificates.X509Certificate2Collection!
Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions.AdditionalChainCertificates.set -> void
38 changes: 37 additions & 1 deletion src/Security/Authentication/test/CertificateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,41 @@ public async Task VerifyValidClientCertWithTrustedChainAuthenticates()
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

[Fact]
public async Task VerifyValidClientCertWithAdditionalCertificatesAuthenticates()
{
using var host = await CreateHost(
new CertificateAuthenticationOptions
{
Events = successfulValidationEvents,
ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust,
CustomTrustStore = new X509Certificate2Collection() { Certificates.SelfSignedPrimaryRoot, },
AdditionalChainCertificates = new X509Certificate2Collection() { Certificates.SignedSecondaryRoot },
RevocationMode = X509RevocationMode.NoCheck
}, Certificates.SignedClient);

using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

[Fact]
public async Task VerifyValidClientCertFailsWithoutAdditionalCertificatesAuthenticates()
{
using var host = await CreateHost(
new CertificateAuthenticationOptions
{
Events = successfulValidationEvents,
ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust,
CustomTrustStore = new X509Certificate2Collection() { Certificates.SelfSignedPrimaryRoot, },
RevocationMode = X509RevocationMode.NoCheck
}, Certificates.SignedClient);

using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
}

[Fact]
public async Task VerifyHeaderIsUsedIfCertIsNotPresent()
{
Expand Down Expand Up @@ -570,7 +605,7 @@ public async Task VerifyValidationResultCanBeCached(bool cache)
Assert.Equal(Expected, name.First().Value);
count = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == "ValidationCount");
Assert.Single(count);
var expected = cache ? "1" : "2";
var expected = cache ? "1" : "2";
Assert.Equal(expected, count.First().Value);
}

Expand Down Expand Up @@ -693,6 +728,7 @@ private static async Task<IHost> CreateHost(
options.RevocationFlag = configureOptions.RevocationFlag;
options.RevocationMode = configureOptions.RevocationMode;
options.ValidateValidityPeriod = configureOptions.ValidateValidityPeriod;
options.AdditionalChainCertificates = configureOptions.AdditionalChainCertificates;
});
}
else
Expand Down

0 comments on commit ae6e9c8

Please sign in to comment.