Skip to content

Commit 6c0e8fa

Browse files
Unrelated expired trusted CA certificate should not throw an exception (#45)
Unrelated expired certificate should not throw an exception WE2-913 Signed-off-by: Mihkel Kivisild [email protected]
1 parent 085e75e commit 6c0e8fa

File tree

10 files changed

+61
-88
lines changed

10 files changed

+61
-88
lines changed

src/WebEid.Security.Tests/TestUtils/AuthTokenValidators.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ public static IAuthTokenValidator GetAuthTokenValidatorWithWrongTrustedCa() =>
5757
GetAuthTokenValidator(TokenOriginUrl,
5858
Certificates.CertificateLoader.LoadCertificatesFromResources("ESTEID2018.cer"));
5959

60+
public static IAuthTokenValidator GetAuthTokenValidatorWthJuly2024ExpiredUnrelatedTrustedCA() =>
61+
GetAuthTokenValidatorBuilder(TokenOriginUrl,
62+
Certificates.CertificateLoader
63+
.LoadCertificatesFromResources("TEST_of_ESTEID2018.cer", "TEST_of_SK_OCSP_RESPONDER_2020.cer"))
64+
.WithoutUserCertificateRevocationCheckWithOcsp()
65+
.Build();
66+
6067
public static IAuthTokenValidator GetAuthTokenValidatorWithDisallowedEsteidPolicy() =>
6168
GetAuthTokenValidatorBuilder(TokenOriginUrl, GetCaCertificates())
6269
.WithDisallowedCertificatePolicies(EstIdemiaPolicy)

src/WebEid.Security.Tests/Validator/AuthTokenCertificateTest.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright © 2020-2024 Estonian Information System Authority
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -45,6 +45,11 @@ public class AuthTokenCertificateTest : AbstractTestWithValidator
4545
private const string ExpiredEcdsaCert = "MIIF0TCCA7mgAwIBAgIQMBVFXroEt3hZ8FHcKKE65TANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEXMBUGA1UEYQwOTlRSRUUtMTA3NDcwMTMxFzAVBgNVBAMMDkVTVEVJRC1TSyAyMDE1MB4XDTE3MTAyNTA4NTcwMFoXDTIxMDIxMDIxNTk1OVowgYsxCzAJBgNVBAYTAkVFMQ8wDQYDVQQKDAZFU1RFSUQxFzAVBgNVBAsMDmF1dGhlbnRpY2F0aW9uMR4wHAYDVQQDDBVUT09NLE1BUlQsMzc2MDIwNDAzMzQxDTALBgNVBAQMBFRPT00xDTALBgNVBCoMBE1BUlQxFDASBgNVBAUTCzM3NjAyMDQwMzM0MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAExS1YQQBDLVvOi0a2GA5Y34AXODpx0AL8eKDOB7BjwBc/FAyVExhfb6O+lT5Tnaec3GnT4JNRyeV8d82L8cyOgFn4PWc+5cjFdmcZjJbtCvgyBOQQ831tteIDL2XSrvZEo4ICBDCCAgAwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCA4gwUwYDVR0gBEwwSjA+BgkrBgEEAc4fAQEwMTAvBggrBgEFBQcCARYjaHR0cHM6Ly93d3cuc2suZWUvcmVwb3NpdG9vcml1bS9DUFMwCAYGBACPegECMB8GA1UdEQQYMBaBFG1hcnQudG9vbS4zQGVlc3RpLmVlMB0GA1UdDgQWBBSzneoLqtqbvHvJ19cjhp2XR5ovQTAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHwYDVR0jBBgwFoAUs6uIvJnVYqSFKgjNtB1yO4NyR1EwYQYIKwYBBQUHAQMEVTBTMFEGBgQAjkYBBTBHMEUWP2h0dHBzOi8vc2suZWUvZW4vcmVwb3NpdG9yeS9jb25kaXRpb25zLWZvci11c2Utb2YtY2VydGlmaWNhdGVzLxMCRU4wagYIKwYBBQUHAQEEXjBcMCcGCCsGAQUFBzABhhtodHRwOi8vYWlhLnNrLmVlL2VzdGVpZDIwMTUwMQYIKwYBBQUHMAKGJWh0dHA6Ly9jLnNrLmVlL0VTVEVJRC1TS18yMDE1LmRlci5jcnQwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL3d3dy5zay5lZS9jcmxzL2VzdGVpZC9lc3RlaWQyMDE1LmNybDANBgkqhkiG9w0BAQsFAAOCAgEAOXTvktUXqPgaK/uxzgH0xSEYClBAWIQaNgpqY5lwsQtgQnpfKlsADqMZxCp7UuuMvQmpDbBxv1kIr0oG1uUXrUtPw81XOH1ClwPPXWpg9VRTAetNbHTBbHDyzuXQMNeDmrntChs+BteletejGD+aYG39HGMlrMbGQZOgvQrpYHMDek0ckCPEsZRXqUP0g7Ie7uBQhz5At7l4EDAeOW8xGoI6t+Ke4GedccXKef60w2ZIIDzvOFHPTc6POCsIlFtF/nCKwVi7GoQKjbUbM5OdBLZ0jyLq2LvzZuT86Jo8wObziuSzApGlBexHAqLrR83q+/Xl61yPnFf3w2kAfS9kBjeunzTH7Jm3pNT3Zq9JRLvEDqtpOPqr4zm9nG6OSghFU6tySkpQ5HiakGpMcnt5o5KuXhQ+Dg317tdXPyQkSiuJ9NfEBW0ijrwO12SVRzYo/jRl4ZQUkAEEUSMEsC6gTsZypPdIsLDVoQWTytHDU89s1xJDn4HulPl12dFnrhlLeX4RxOjDxppZxdjBU0FoJoDB0qwEAN2TMAPJWh+Pp9mFuS/u0dht9sKvAkpx+o0Z7v7QMz03XlzCHOLTIK+f81Rjokl8f+wiog5Ojj0wZkDe6DuQC9L5uDey3PJHv3naVovhs7jrEJu+yrsLue/OHhAgWRh2S75/wlVPHPEE44k=";
4646
private const string RevokedCert = "MIIERDCCA6agAwIBAgIQSs8/WoDixVxbKRhNnF/GEzAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTE4MDYxOTE0NTA1M1oXDTIwMDEwMjIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR/jopNG3KL0ZQUvO4OGSvcaqUtFDm3azOtsM2VRp666r0d36Zh0Zx/xej8f+SzEfWvvDT1HQLo3USiSbYn1FyNHTNxifV+Zvf6StXJAkdu24d1UvKbf+LylglO/yS7o4ijggIEMIICADAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIDiDBHBgNVHSAEQDA+MDIGCysGAQQBg5F/AQIBMCMwIQYIKwYBBQUHAgEWFWh0dHBzOi8vd3d3LnNrLmVlL0NQUzAIBgYEAI96AQIwHwYDVR0RBBgwFoEUMzgwMDEwODU3MThAZWVzdGkuZWUwHQYDVR0OBBYEFEQA6/1GXJtp+6czUzorhEJ7B95pMGEGCCsGAQUFBwEDBFUwUzBRBgYEAI5GAQUwRzBFFj9odHRwczovL3NrLmVlL2VuL3JlcG9zaXRvcnkvY29uZGl0aW9ucy1mb3ItdXNlLW9mLWNlcnRpZmljYXRlcy8TAkVOMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAfBgNVHSMEGDAWgBTAhJkpxE6fOwI09pnhClYACCk+ezB/BggrBgEFBQcBAQRzMHEwLAYIKwYBBQUHMAGGIGh0dHA6Ly9haWEuZGVtby5zay5lZS9lc3RlaWQyMDE4MEEGCCsGAQUFBzAChjVodHRwczovL3NrLmVlL3VwbG9hZC9maWxlcy9URVNUX29mX0VTVEVJRDIwMTguZGVyLmNydDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vYy5zay5lZS90ZXN0X2VzdGVpZDIwMTguY3JsMAoGCCqGSM49BAMEA4GLADCBhwJBcmcfLC+HcSJ6BuRrDGL+K+7BAW8BfAiiWWAuBV4ebLkbbAWmkc9dSKgr4BEGEt90xDTQ85yW4SjGulFXu9C3yQsCQgETaXTs3Hp6vDAcQYL8Bx4BO3DwJbDuD4BUJyT0+9HQiFCQmTQ4xrNjeaeOwRWyMOM9z5ORMeJCiQUyil1x4YPIbg==";
4747

48+
private const string ValidUntil2026TokenStr = "{\"algorithm\":\"ES384\"," +
49+
"\"unverifiedCertificate\":\"MIIEBDCCA2WgAwIBAgIQY5OGshxoPMFg+Wfc0gFEaTAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTIxMDcyMjEyNDMwOFoXDTI2MDcwOTIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQmwEKsJTjaMHSaZj19hb9EJaJlwbKc5VFzmlGMFSJVk4dDy+eUxa5KOA7tWXqzcmhh5SYdv+MxcaQKlKWLMa36pfgv20FpEDb03GCtLqjLTRZ7649PugAQ5EmAqIic29CjggHDMIIBvzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIDiDBHBgNVHSAEQDA+MDIGCysGAQQBg5EhAQIBMCMwIQYIKwYBBQUHAgEWFWh0dHBzOi8vd3d3LnNrLmVlL0NQUzAIBgYEAI96AQIwHwYDVR0RBBgwFoEUMzgwMDEwODU3MThAZWVzdGkuZWUwHQYDVR0OBBYEFPlp/ceABC52itoqppEmbf71TJz6MGEGCCsGAQUFBwEDBFUwUzBRBgYEAI5GAQUwRzBFFj9odHRwczovL3NrLmVlL2VuL3JlcG9zaXRvcnkvY29uZGl0aW9ucy1mb3ItdXNlLW9mLWNlcnRpZmljYXRlcy8TAkVOMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAfBgNVHSMEGDAWgBTAhJkpxE6fOwI09pnhClYACCk+ezBzBggrBgEFBQcBAQRnMGUwLAYIKwYBBQUHMAGGIGh0dHA6Ly9haWEuZGVtby5zay5lZS9lc3RlaWQyMDE4MDUGCCsGAQUFBzAChilodHRwOi8vYy5zay5lZS9UZXN0X29mX0VTVEVJRDIwMTguZGVyLmNydDAKBggqhkjOPQQDBAOBjAAwgYgCQgDCAgybz0u3W+tGI+AX+PiI5CrE9ptEHO5eezR1Jo4j7iGaO0i39xTGUB+NSC7P6AQbyE/ywqJjA1a62jTLcS9GHAJCARxN4NO4eVdWU3zVohCXm8WN3DWA7XUcn9TZiLGQ29P4xfQZOXJi/z4PNRRsR4plvSNB3dfyBvZn31HhC7my8woi\"," +
50+
"\"appVersion\":\"https://web-eid.eu/web-eid-app/releases/2.5.0+0\"," +
51+
"\"signature\":\"0Ov7ME6pTY1K2GXMj8Wxov/o2fGIMEds8OMY5dKdkB0nrqQX7fG1E5mnsbvyHpMDecMUH6Yg+p1HXdgB/lLqOcFZjt/OVXPjAAApC5d1YgRYATDcxsR1zqQwiNcHdmWn\"," +
52+
"\"format\":\"web-eid:1.0\"}";
4853

4954
[Test]
5055
public void WhenCertificateFieldIsMissingThenParsingFailsAsync()
@@ -164,30 +169,46 @@ public void WhenUserCertificateIsNotYetValidThenValidationFailsAsync()
164169
}
165170

166171
[Test]
167-
public void WhenTrustedCACertificateIsNotYetValidThenValidationFailsAsync()
172+
public void WhenTrustedCACertificateIsNotYetValidThenUserCertValidationFailsAsync()
168173
{
169174
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2018, 8, 17));
170-
Assert.ThrowsAsync<CertificateNotYetValidException>(() => this.Validator.Validate(this.ValidAuthToken, ValidChallengeNonce))
171-
.WithMessage("Trusted CA certificate is not yet valid");
175+
Assert.ThrowsAsync<CertificateNotYetValidException>(() => this.Validator
176+
.Validate(this.ValidAuthToken, ValidChallengeNonce))
177+
.WithMessage("User certificate is not yet valid");
172178
}
173179

174180
[Test]
175181
public void WhenUserCertificateIsNoLongerValidThenValidationFailsAsync()
176182
{
177-
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2024, 10, 17));
183+
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2026, 10, 19));
178184
Assert.ThrowsAsync<CertificateExpiredException>(() => this.Validator.Validate(this.ValidAuthToken, ValidChallengeNonce))
179185
.WithMessage("User certificate has expired");
180186
}
181187

188+
// In this case both CA and user certificate have expired, we expect the user certificate to be checked first.
182189
[Test]
183-
public void WhenTrustedCACertificateIsNoLongerValidThenValidationFailsAsync()
190+
public void WhenTrustedCACertificateIsNoLongerValidThenUserCertValidationFailsAsync()
184191
{
185-
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2033, 10, 17));
186-
Assert.ThrowsAsync<CertificateExpiredException>(() => this.Validator.Validate(this.ValidAuthToken, ValidChallengeNonce))
187-
.WithMessage("Trusted CA certificate has expired");
192+
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2033, 10, 19));
193+
Assert.ThrowsAsync<CertificateExpiredException>(() => this.Validator
194+
.Validate(this.ValidAuthToken, ValidChallengeNonce))
195+
.WithMessage("User certificate has expired");
196+
}
197+
198+
// The certificate validation process must only check the expiration of the CA certificate that is directly part of
199+
// the user's certificate chain. Expired but unrelated CA certificates must not cause exceptions.
200+
[Test]
201+
public void WhenUnrelatedCACertificateIsExpiredThenValidationSucceeds()
202+
{
203+
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2024, 7, 1));
204+
var authToken = this.Validator.Parse(ValidUntil2026TokenStr);
205+
var validatorWithExpiredUnrelatedTrustedCA = AuthTokenValidators.GetAuthTokenValidatorWthJuly2024ExpiredUnrelatedTrustedCA();
206+
207+
Assert.DoesNotThrowAsync(() => validatorWithExpiredUnrelatedTrustedCA.Validate(authToken, ValidChallengeNonce));
188208
}
189209

190210
[Test]
211+
[Ignore("A new designated test OCSP responder certificate was issued whose validity period no longer overlaps with the revoked certificate")]
191212
public void WhenCertificateIsRevokedThenOcspCheckFailsAsync()
192213
{
193214
var authTokenValidator = AuthTokenValidators.GetAuthTokenValidatorWithOcspCheck();

src/WebEid.Security.Tests/Validator/Validators/SubjectCertificateNotRevokedValidatorTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public sealed class SubjectCertificateNotRevokedValidatorTests : IDisposable
4646
private X509Certificate2 esteid2018Cert;
4747

4848
private AuthTokenValidationConfiguration configuration;
49-
private DateTimeProvider dateTimeProvider;
5049

5150
public SubjectCertificateNotRevokedValidatorTests() => this.ocspClient = new OcspClient(TimeSpan.FromSeconds(5));
5251

@@ -99,12 +98,12 @@ public void WhenOcspUrlIsInvalidThenThrows()
9998
public void WhenOcspRequestFailsThenThrows()
10099
{
101100
var ocspServiceProvider =
102-
OcspServiceMaker.GetDesignatedOcspServiceProvider("https://web-eid-test.free.beeceptor.com");
101+
OcspServiceMaker.GetDesignatedOcspServiceProvider("http://demo.sk.ee/ocsps");
103102
var validator = GetSubjectCertificateNotRevokedValidatior(ocspServiceProvider);
104103
Assert.ThrowsAsync<UserCertificateOcspCheckFailedException>(() =>
105104
validator.Validate(this.esteid2018Cert))
106105
.InnerException
107-
.HasMessageStartingWith("OCSP request was not successful, response:");
106+
.HasMessageStartingWith("OCSP request was not successful, response: StatusCode: 404");
108107
}
109108

110109
[Test]
@@ -198,7 +197,7 @@ public void WhenOcspResponseHas2ResponderCertsThenThrows()
198197
[Test]
199198
public void WhenOcspResponseRevokedThenThrows()
200199
{
201-
this.dateTimeProvider = DateTimeProvider.OverrideUtcNow(new DateTime(2021, 9, 18));
200+
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2021, 9, 18));
202201
var validator = this.GetSubjectCertificateNotRevokedValidatorWithAiaOcsp(
203202
new OcspClientMock(Certificates.ResourceReader.ReadFromResource("ocsp_response_revoked.der")));
204203
Assert.ThrowsAsync<UserCertificateOcspCheckFailedException>(() =>
@@ -228,6 +227,7 @@ public void WhenOcspResponseUnknownThenThrows()
228227
[Test]
229228
public void WhenOcspResponseCaNotTrustedThenThrows()
230229
{
230+
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2021, 3, 1));
231231
var validator = this.GetSubjectCertificateNotRevokedValidatorWithAiaOcsp(
232232
new OcspClientMock(Certificates.ResourceReader.ReadFromResource("ocsp_response_unknown.der")));
233233
var ex = Assert.ThrowsAsync<UserCertificateOcspCheckFailedException>(() =>

src/WebEid.Security/Util/DateTimeProvider.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright © 2020-2024 Estonian Information System Authority
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,7 +29,6 @@ namespace WebEid.Security.Util
2929
/// </summary>
3030
public sealed class DateTimeProvider : IDisposable
3131
{
32-
[ThreadStatic]
3332
private static DateTime? overridenUtcNow;
3433

3534
/// <summary>

src/WebEid.Security/Util/X509CertificateExtensions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ public static void ValidateCertificateExpiry(this Org.BouncyCastle.X509.X509Cert
6767
}
6868
}
6969

70-
public static X509Certificate2 ValidateIsSignedByTrustedCa(this X509Certificate2 certificate, ICollection<X509Certificate2> trustedCaCertificates)
70+
public static X509Certificate2 ValidateIsValidAndSignedByTrustedCa(this X509Certificate2 certificate, ICollection<X509Certificate2> trustedCaCertificates)
7171
{
72+
ValidateCertificateExpiry(certificate, DateTimeProvider.UtcNow, "User");
73+
7274
var chain = new X509Chain
7375
{
7476
ChainPolicy =
@@ -80,6 +82,7 @@ public static X509Certificate2 ValidateIsSignedByTrustedCa(this X509Certificate2
8082
UrlRetrievalTimeout = TimeSpan.Zero
8183
}
8284
};
85+
8386
foreach (var cert in trustedCaCertificates)
8487
{
8588
chain.ChainPolicy.ExtraStore.Add(cert);
@@ -110,6 +113,8 @@ public static X509Certificate2 ValidateIsSignedByTrustedCa(this X509Certificate2
110113
{
111114
throw new CertificateNotTrustedException(certificate);
112115
}
116+
// Verify that the trusted CA cert is presently valid before returning the result.
117+
ValidateCertificateExpiry(chainElement.Certificate, DateTimeProvider.UtcNow, "Trusted CA");
113118

114119
return chainElement.Certificate;
115120
}

src/WebEid.Security/Validator/AuthTokenValidator.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ public AuthTokenValidator(AuthTokenValidationConfiguration configuration, ILogge
5555
this.authTokenSignatureValidator = new AuthTokenSignatureValidator(configuration.SiteOrigin);
5656

5757
this.simpleSubjectCertificateValidators = SubjectCertificateValidatorBatch.CreateFrom(
58-
new SubjectCertificateExpiryValidator(configuration.TrustedCaCertificates, this.logger),
5958
new SubjectCertificatePurposeValidator(this.logger),
6059
new SubjectCertificatePolicyValidator(configuration.DisallowedSubjectCertificatePolicies
6160
.Select(policy => new Oid(policy))

src/WebEid.Security/Validator/CertValidators/SubjectCertificateExpiryValidator.cs

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/WebEid.Security/Validator/CertValidators/SubjectCertificateTrustedValidator.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright © 2020-2024 Estonian Information System Authority
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,6 +26,7 @@ namespace WebEid.Security.Validator.CertValidators
2626
using System.Threading.Tasks;
2727
using Microsoft.Extensions.Logging;
2828
using Util;
29+
using WebEid.Security.Exceptions;
2930

3031
internal sealed class SubjectCertificateTrustedValidator : ISubjectCertificateValidator
3132
{
@@ -39,14 +40,18 @@ public SubjectCertificateTrustedValidator(ICollection<X509Certificate2> trustedC
3940
}
4041

4142
/// <summary>
42-
/// Validates that the user certificate from the authentication token is signed by a trusted certificate authority.
43+
/// Checks that the user certificate from the authentication token is valid and signed by
44+
/// a trusted certificate authority. Also checks the validity of the user certificate's
45+
/// trusted CA certificate.
4346
/// </summary>
44-
/// <param name="subjectCertificate">the user certificate.</param>
45-
/// <exception cref="UserCertificateNotTrustedException">when user certificate is not signed by a trusted CA or is valid after CA certificate.</exception>
47+
/// <param name="subjectCertificate">the user certificate to be validated</param>
48+
/// <exception cref="CertificateNotTrustedException">when user certificate is not signed by a trusted CA</exception>
49+
/// <exception cref="CertificateNotYetValidException">when a CA certificate in the chain or the user certificate is not yet valid</exception>
50+
/// <exception cref="CertificateExpiredException">when a CA certificate in the chain or the user certificate is expired</exception>
4651
public Task Validate(X509Certificate2 subjectCertificate)
4752
{
48-
this.SubjectCertificateIssuerCertificate = subjectCertificate.ValidateIsSignedByTrustedCa(this.trustedCaCertificates);
49-
this.logger?.LogDebug("Subject certificate is signed by a trusted CA");
53+
this.SubjectCertificateIssuerCertificate = subjectCertificate.ValidateIsValidAndSignedByTrustedCa(this.trustedCaCertificates);
54+
this.logger?.LogDebug("Subject certificate is valid and signed by a trusted CA");
5055

5156
return Task.CompletedTask;
5257
}

0 commit comments

Comments
 (0)