Skip to content

Commit

Permalink
Use system time in OcspService.validateResponderCertificate()
Browse files Browse the repository at this point in the history
WE2-868

Signed-off-by: Mart Somermaa <[email protected]>
  • Loading branch information
mrts committed Jul 25, 2024
1 parent b57eaa2 commit be477cb
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 13 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ CertificateData.getSubjectCN(userCertificate).orElseThrow(); // "JÕEORG\\,JAAK-
CertificateData.getSubjectIdCode(userCertificate).orElseThrow(); // "PNOEE-38001085718"
CertificateData.getSubjectCountryCode(userCertificate).orElseThrow(); // "EE"
toTitleCase(CertUtil.getSubjectGivenName(userCertificate)).orElseThrow(); // "Jaak-Kristjan"
toTitleCase(CertUtil.getSubjectSurname(userCertificate)).orElseThrow(); // "Jõeorg"
toTitleCase(CertificateData.getSubjectGivenName(userCertificate).orElseThrow()); // "Jaak-Kristjan"
toTitleCase(CertificateData.getSubjectSurname(userCertificate).orElseThrow()); // "Jõeorg"
```
## Extended configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

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

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

// 5. The time at which the status being indicated is known to be
// correct (thisUpdate) is sufficiently recent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ public URI getAccessLocation() {
}

@Override
public void validateResponderCertificate(X509CertificateHolder cert, Date producedAt) throws AuthTokenException {
public void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException {
try {
final X509Certificate certificate = certificateConverter.getCertificate(cert);
CertificateValidator.certificateIsValidOnDate(certificate, producedAt, "AIA OCSP responder");
CertificateValidator.certificateIsValidOnDate(certificate, now, "AIA OCSP responder");
// Trusted certificates' validity has been already verified in validateCertificateExpiry().
OcspResponseValidator.validateHasSigningExtension(certificate);
CertificateValidator.validateIsSignedByTrustedCA(certificate, trustedCACertificateAnchors, trustedCACertificateCertStore, producedAt);
CertificateValidator.validateIsSignedByTrustedCA(certificate, trustedCACertificateAnchors, trustedCACertificateCertStore, now);
} catch (CertificateException e) {
throw new OCSPCertificateException("Invalid responder certificate", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public URI getAccessLocation() {
}

@Override
public void validateResponderCertificate(X509CertificateHolder cert, Date producedAt) throws AuthTokenException {
public void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException {
try {
final X509Certificate responderCertificate = certificateConverter.getCertificate(cert);
// Certificate pinning is implemented simply by comparing the certificates or their public keys,
Expand All @@ -68,7 +68,7 @@ public void validateResponderCertificate(X509CertificateHolder cert, Date produc
throw new OCSPCertificateException("Responder certificate from the OCSP response is not equal to " +
"the configured designated OCSP responder certificate");
}
certificateIsValidOnDate(responderCertificate, producedAt, "Designated OCSP responder");
certificateIsValidOnDate(responderCertificate, now, "Designated OCSP responder");
} catch (CertificateException e) {
throw new OCSPCertificateException("X509CertificateHolder conversion to X509Certificate failed", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ public interface OcspService {

URI getAccessLocation();

void validateResponderCertificate(X509CertificateHolder cert, Date date) throws AuthTokenException;
void validateResponderCertificate(X509CertificateHolder cert, Date now) throws AuthTokenException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

package eu.webeid.security.validator.certvalidators;

import eu.webeid.security.exceptions.CertificateExpiredException;
import eu.webeid.security.exceptions.CertificateNotTrustedException;
import eu.webeid.security.exceptions.JceException;
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
Expand Down Expand Up @@ -251,14 +252,28 @@ void whenOcspResponseUnknown_thenThrows() throws Exception {
}

@Test
void whenOcspResponseCANotTrusted_thenThrows() throws Exception {
void whenOcspResponseCACertNotTrusted_thenThrows() throws Exception {
final SubjectCertificateNotRevokedValidator validator = getSubjectCertificateNotRevokedValidatorWithAiaOcsp(
getMockedResponse(getOcspResponseBytesFromResources("ocsp_response_unknown.der"))
);
assertThatExceptionOfType(CertificateNotTrustedException.class)
try (var mockedClock = mockStatic(DateAndTime.DefaultClock.class)) {
mockDate("2021-09-18T00:16:25", mockedClock);
assertThatExceptionOfType(CertificateNotTrustedException.class)
.isThrownBy(() ->
validator.validateCertificateNotRevoked(estEid2018Cert))
.withMessage("Certificate [email protected], CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE is not trusted");
}
}

@Test
void whenOcspResponseCACertExpired_thenThrows() throws Exception {
final SubjectCertificateNotRevokedValidator validator = getSubjectCertificateNotRevokedValidatorWithAiaOcsp(
getMockedResponse(getOcspResponseBytesFromResources("ocsp_response_unknown.der"))
);
assertThatExceptionOfType(CertificateExpiredException.class)
.isThrownBy(() ->
validator.validateCertificateNotRevoked(estEid2018Cert))
.withMessage("Certificate [email protected], CN=TEST of SK OCSP RESPONDER 2020, OU=OCSP, O=AS Sertifitseerimiskeskus, C=EE is not trusted");
.withMessage("AIA OCSP responder certificate has expired");
}

@Test
Expand Down

0 comments on commit be477cb

Please sign in to comment.