Skip to content

Commit be477cb

Browse files
committed
Use system time in OcspService.validateResponderCertificate()
WE2-868 Signed-off-by: Mart Somermaa <mrts@users.noreply.github.com>
1 parent b57eaa2 commit be477cb

File tree

6 files changed

+30
-13
lines changed

6 files changed

+30
-13
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ CertificateData.getSubjectCN(userCertificate).orElseThrow(); // "JÕEORG\\,JAAK-
287287
CertificateData.getSubjectIdCode(userCertificate).orElseThrow(); // "PNOEE-38001085718"
288288
CertificateData.getSubjectCountryCode(userCertificate).orElseThrow(); // "EE"
289289
290-
toTitleCase(CertUtil.getSubjectGivenName(userCertificate)).orElseThrow(); // "Jaak-Kristjan"
291-
toTitleCase(CertUtil.getSubjectSurname(userCertificate)).orElseThrow(); // "Jõeorg"
290+
toTitleCase(CertificateData.getSubjectGivenName(userCertificate).orElseThrow()); // "Jaak-Kristjan"
291+
toTitleCase(CertificateData.getSubjectSurname(userCertificate).orElseThrow()); // "Jõeorg"
292292
```
293293
294294
## Extended configuration

src/main/java/eu/webeid/security/validator/certvalidators/SubjectCertificateNotRevokedValidator.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import eu.webeid.security.exceptions.AuthTokenException;
2626
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
27+
import eu.webeid.security.util.DateAndTime;
2728
import eu.webeid.security.validator.ocsp.DigestCalculatorImpl;
2829
import eu.webeid.security.validator.ocsp.OcspClient;
2930
import eu.webeid.security.validator.ocsp.OcspRequestBuilder;
@@ -163,8 +164,9 @@ private void verifyOcspResponse(BasicOCSPResp basicResponse, OcspService ocspSer
163164
// 4. The signer is currently authorized to provide a response for the
164165
// certificate in question.
165166

166-
final Date producedAt = basicResponse.getProducedAt();
167-
ocspService.validateResponderCertificate(responderCert, producedAt);
167+
// Use the clock instance so that the date can be mocked in tests.
168+
final Date now = DateAndTime.DefaultClock.getInstance().now();
169+
ocspService.validateResponderCertificate(responderCert, now);
168170

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

src/main/java/eu/webeid/security/validator/ocsp/service/AiaOcspService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ public URI getAccessLocation() {
7171
}
7272

7373
@Override
74-
public void validateResponderCertificate(X509CertificateHolder cert, Date producedAt) throws AuthTokenException {
74+
public void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException {
7575
try {
7676
final X509Certificate certificate = certificateConverter.getCertificate(cert);
77-
CertificateValidator.certificateIsValidOnDate(certificate, producedAt, "AIA OCSP responder");
77+
CertificateValidator.certificateIsValidOnDate(certificate, now, "AIA OCSP responder");
7878
// Trusted certificates' validity has been already verified in validateCertificateExpiry().
7979
OcspResponseValidator.validateHasSigningExtension(certificate);
80-
CertificateValidator.validateIsSignedByTrustedCA(certificate, trustedCACertificateAnchors, trustedCACertificateCertStore, producedAt);
80+
CertificateValidator.validateIsSignedByTrustedCA(certificate, trustedCACertificateAnchors, trustedCACertificateCertStore, now);
8181
} catch (CertificateException e) {
8282
throw new OCSPCertificateException("Invalid responder certificate", e);
8383
}

src/main/java/eu/webeid/security/validator/ocsp/service/DesignatedOcspService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public URI getAccessLocation() {
5959
}
6060

6161
@Override
62-
public void validateResponderCertificate(X509CertificateHolder cert, Date producedAt) throws AuthTokenException {
62+
public void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException {
6363
try {
6464
final X509Certificate responderCertificate = certificateConverter.getCertificate(cert);
6565
// Certificate pinning is implemented simply by comparing the certificates or their public keys,
@@ -68,7 +68,7 @@ public void validateResponderCertificate(X509CertificateHolder cert, Date produc
6868
throw new OCSPCertificateException("Responder certificate from the OCSP response is not equal to " +
6969
"the configured designated OCSP responder certificate");
7070
}
71-
certificateIsValidOnDate(responderCertificate, producedAt, "Designated OCSP responder");
71+
certificateIsValidOnDate(responderCertificate, now, "Designated OCSP responder");
7272
} catch (CertificateException e) {
7373
throw new OCSPCertificateException("X509CertificateHolder conversion to X509Certificate failed", e);
7474
}

src/main/java/eu/webeid/security/validator/ocsp/service/OcspService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ public interface OcspService {
3434

3535
URI getAccessLocation();
3636

37-
void validateResponderCertificate(X509CertificateHolder cert, Date date) throws AuthTokenException;
37+
void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException;
3838

3939
}

src/test/java/eu/webeid/security/validator/certvalidators/SubjectCertificateNotRevokedValidatorTest.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
package eu.webeid.security.validator.certvalidators;
2424

25+
import eu.webeid.security.exceptions.CertificateExpiredException;
2526
import eu.webeid.security.exceptions.CertificateNotTrustedException;
2627
import eu.webeid.security.exceptions.JceException;
2728
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
@@ -251,14 +252,28 @@ void whenOcspResponseUnknown_thenThrows() throws Exception {
251252
}
252253

253254
@Test
254-
void whenOcspResponseCANotTrusted_thenThrows() throws Exception {
255+
void whenOcspResponseCACertNotTrusted_thenThrows() throws Exception {
255256
final SubjectCertificateNotRevokedValidator validator = getSubjectCertificateNotRevokedValidatorWithAiaOcsp(
256257
getMockedResponse(getOcspResponseBytesFromResources("ocsp_response_unknown.der"))
257258
);
258-
assertThatExceptionOfType(CertificateNotTrustedException.class)
259+
try (var mockedClock = mockStatic(DateAndTime.DefaultClock.class)) {
260+
mockDate("2021-09-18T00:16:25", mockedClock);
261+
assertThatExceptionOfType(CertificateNotTrustedException.class)
262+
.isThrownBy(() ->
263+
validator.validateCertificateNotRevoked(estEid2018Cert))
264+
.withMessage("Certificate EMAILADDRESS=pki@sk.ee, CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE is not trusted");
265+
}
266+
}
267+
268+
@Test
269+
void whenOcspResponseCACertExpired_thenThrows() throws Exception {
270+
final SubjectCertificateNotRevokedValidator validator = getSubjectCertificateNotRevokedValidatorWithAiaOcsp(
271+
getMockedResponse(getOcspResponseBytesFromResources("ocsp_response_unknown.der"))
272+
);
273+
assertThatExceptionOfType(CertificateExpiredException.class)
259274
.isThrownBy(() ->
260275
validator.validateCertificateNotRevoked(estEid2018Cert))
261-
.withMessage("Certificate EMAILADDRESS=pki@sk.ee, CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE is not trusted");
276+
.withMessage("AIA OCSP responder certificate has expired");
262277
}
263278

264279
@Test

0 commit comments

Comments
 (0)