Skip to content

Commit 7e76f09

Browse files
Mihkel Kivisildmrts
authored andcommitted
Use system time in OcspService.validateResponderCertificate()
WE2-868 Signed-off-by: Mihkel Kivisild [email protected]
1 parent 53d9d44 commit 7e76f09

File tree

5 files changed

+24
-12
lines changed

5 files changed

+24
-12
lines changed

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ public void WhenOcspResponseUnknownThenThrows()
225225
}
226226

227227
[Test]
228-
public void WhenOcspResponseCaNotTrustedThenThrows()
228+
public void WhenOcspResponseCaCertNotTrustedThenThrows()
229229
{
230230
using var _ = DateTimeProvider.OverrideUtcNow(new DateTime(2021, 3, 1));
231231
var validator = this.GetSubjectCertificateNotRevokedValidatorWithAiaOcsp(
@@ -239,6 +239,17 @@ public void WhenOcspResponseCaNotTrustedThenThrows()
239239
));
240240
}
241241

242+
[Test]
243+
public void WhenOcspResponseCACertExpiredThenThrows()
244+
{
245+
var validator = this.GetSubjectCertificateNotRevokedValidatorWithAiaOcsp(
246+
new OcspClientMock(Certificates.ResourceReader.ReadFromResource("ocsp_response_unknown.der")));
247+
var ex = Assert.ThrowsAsync<UserCertificateOcspCheckFailedException>(() =>
248+
validator.Validate(this.esteid2018Cert));
249+
Assert.That(ex.InnerException, Is.TypeOf<CertificateExpiredException>());
250+
Assert.That(ex.InnerException.Message,
251+
Does.StartWith("AIA OCSP responder certificate has expired"));
252+
}
242253

243254
private static byte[] BuildOcspResponseBodyWithInternalErrorStatus()
244255
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace WebEid.Security.Validator.CertValidators
3333
using Org.BouncyCastle.Asn1.Ocsp;
3434
using Org.BouncyCastle.Ocsp;
3535
using Org.BouncyCastle.Security;
36+
using WebEid.Security.Util;
3637

3738
internal sealed class SubjectCertificateNotRevokedValidator : ISubjectCertificateValidator
3839
{
@@ -154,8 +155,7 @@ private void VerifyOcspResponse(BasicOcspResp basicResponse,
154155
// 4. The signer is currently authorized to provide a response for the
155156
// certificate in question.
156157

157-
var producedAt = basicResponse.ProducedAt;
158-
ocspService.ValidateResponderCertificate(responderCert, producedAt);
158+
ocspService.ValidateResponderCertificate(responderCert, DateTimeProvider.UtcNow);
159159

160160
// 5. The time at which the status being indicated is known to be
161161
// correct (thisUpdate) is sufficiently recent.

src/WebEid.Security/Validator/Ocsp/Service/AiaOcspService.cs

Lines changed: 4 additions & 4 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
@@ -60,17 +60,17 @@ private Uri GetOcspAiaUrlFromCertificate(Org.BouncyCastle.X509.X509Certificate c
6060
"from the certificate failed");
6161
}
6262

63-
public void ValidateResponderCertificate(Org.BouncyCastle.X509.X509Certificate responderCertificate, DateTime producedAt)
63+
public void ValidateResponderCertificate(Org.BouncyCastle.X509.X509Certificate responderCertificate, DateTime now)
6464
{
6565
try
6666
{
67-
responderCertificate.ValidateCertificateExpiry(producedAt, "AIA OCSP responder");
67+
responderCertificate.ValidateCertificateExpiry(now, "AIA OCSP responder");
6868
// Trusted certificates validity has been already verified in ValidateCertificateExpiry().
6969
OcspResponseValidator.ValidateHasSigningExtension(responderCertificate);
7070
_ = new X509Certificate2(DotNetUtilities.ToX509Certificate(responderCertificate))
7171
.ValidateIsValidAndSignedByTrustedCa(this.trustedCaCertificates);
7272
}
73-
catch (Exception ex) when (!(ex is CertificateNotTrustedException))
73+
catch (Exception ex) when (!(ex is CertificateNotTrustedException) && !(ex is CertificateExpiredException))
7474
{
7575
throw new OcspCertificateException("Invalid certificate", ex);
7676
}

src/WebEid.Security/Validator/Ocsp/Service/DesignatedOcspService.cs

Lines changed: 3 additions & 3 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
@@ -44,7 +44,7 @@ public DesignatedOcspService(DesignatedOcspServiceConfiguration configuration)
4444

4545
public bool SupportsIssuerOf(X509Certificate certificate) => this.configuration.SupportsIssuerOf(certificate);
4646

47-
public void ValidateResponderCertificate(X509Certificate responderCertificate, DateTime producedAt)
47+
public void ValidateResponderCertificate(X509Certificate responderCertificate, DateTime now)
4848
{
4949
// Certificate pinning is implemented simply by comparing the certificates or their public keys,
5050
// see https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning.
@@ -53,7 +53,7 @@ public void ValidateResponderCertificate(X509Certificate responderCertificate, D
5353
throw new OcspCertificateException(
5454
"Responder certificate from the OCSP response is not equal to the configured designated OCSP responder certificate");
5555
}
56-
responderCertificate.ValidateCertificateExpiry(producedAt, "Designated OCSP responder");
56+
responderCertificate.ValidateCertificateExpiry(now, "Designated OCSP responder");
5757
}
5858
}
5959
}

src/WebEid.Security/Validator/Ocsp/Service/IOcspService.cs

Lines changed: 3 additions & 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
@@ -27,6 +27,7 @@ public interface IOcspService
2727
{
2828
bool DoesSupportNonce { get; }
2929
Uri AccessLocation { get; }
30-
void ValidateResponderCertificate(Org.BouncyCastle.X509.X509Certificate responderCertificate, DateTime producedAt);
30+
31+
void ValidateResponderCertificate(Org.BouncyCastle.X509.X509Certificate responderCertificate, DateTime now);
3132
}
3233
}

0 commit comments

Comments
 (0)