Skip to content

Commit ed385dd

Browse files
committed
Use plaform OCSP implementation by default, move custom OCSP implementation to eu.webeid.ocsp and make it optional
WE2-1030 Signed-off-by: Mart Somermaa <[email protected]>
1 parent 4379d59 commit ed385dd

31 files changed

+402
-405
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<description>Web eID authentication token validation library for Java</description>
1212

1313
<properties>
14-
<java.version>11</java.version>
14+
<java.version>17</java.version>
1515
<jjwt.version>0.12.6</jjwt.version>
1616
<bouncycastle.version>1.81</bouncycastle.version>
1717
<jackson.version>2.19.1</jackson.version>

src/main/java/eu/webeid/security/validator/certvalidators/SubjectCertificateNotRevokedValidator.java renamed to src/main/java/eu/webeid/ocsp/DefaultOcspCertificateRevocationChecker.java

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,19 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.certvalidators;
23+
package eu.webeid.ocsp;
2424

25+
import eu.webeid.ocsp.client.OcspClient;
26+
import eu.webeid.ocsp.protocol.DigestCalculatorImpl;
27+
import eu.webeid.ocsp.protocol.OcspRequestBuilder;
28+
import eu.webeid.ocsp.protocol.OcspResponseValidator;
2529
import eu.webeid.security.exceptions.AuthTokenException;
2630
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
2731
import eu.webeid.security.util.DateAndTime;
28-
import eu.webeid.security.validator.ocsp.DigestCalculatorImpl;
29-
import eu.webeid.security.validator.ocsp.OcspClient;
30-
import eu.webeid.security.validator.ocsp.OcspRequestBuilder;
31-
import eu.webeid.security.validator.ocsp.OcspResponseValidator;
32-
import eu.webeid.security.validator.ocsp.OcspServiceProvider;
33-
import eu.webeid.security.validator.ocsp.service.OcspService;
32+
import eu.webeid.ocsp.service.OcspServiceProvider;
33+
import eu.webeid.ocsp.service.OcspService;
34+
import eu.webeid.security.validator.revocationcheck.OcspCertificateRevocationChecker;
35+
import eu.webeid.security.validator.revocationcheck.RevocationInfo;
3436
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
3537
import org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
3638
import org.bouncycastle.asn1.x509.Extension;
@@ -55,13 +57,15 @@
5557
import java.security.cert.X509Certificate;
5658
import java.time.Duration;
5759
import java.util.Date;
58-
import java.util.Objects;
60+
import java.util.Map;
5961

60-
public final class SubjectCertificateNotRevokedValidator {
62+
import static eu.webeid.security.util.DateAndTime.requirePositiveDuration;
63+
import static java.util.Objects.requireNonNull;
6164

62-
private static final Logger LOG = LoggerFactory.getLogger(SubjectCertificateNotRevokedValidator.class);
65+
public final class DefaultOcspCertificateRevocationChecker implements OcspCertificateRevocationChecker {
66+
67+
private static final Logger LOG = LoggerFactory.getLogger(DefaultOcspCertificateRevocationChecker.class);
6368

64-
private final SubjectCertificateTrustedValidator trustValidator;
6569
private final OcspClient ocspClient;
6670
private final OcspServiceProvider ocspServiceProvider;
6771
private final Duration allowedOcspResponseTimeSkew;
@@ -71,30 +75,30 @@ public final class SubjectCertificateNotRevokedValidator {
7175
Security.addProvider(new BouncyCastleProvider());
7276
}
7377

74-
public SubjectCertificateNotRevokedValidator(SubjectCertificateTrustedValidator trustValidator,
75-
OcspClient ocspClient,
76-
OcspServiceProvider ocspServiceProvider,
77-
Duration allowedOcspResponseTimeSkew,
78-
Duration maxOcspResponseThisUpdateAge) {
79-
this.trustValidator = trustValidator;
80-
this.ocspClient = ocspClient;
81-
this.ocspServiceProvider = ocspServiceProvider;
82-
this.allowedOcspResponseTimeSkew = allowedOcspResponseTimeSkew;
83-
this.maxOcspResponseThisUpdateAge = maxOcspResponseThisUpdateAge;
78+
public DefaultOcspCertificateRevocationChecker(OcspClient ocspClient,
79+
OcspServiceProvider ocspServiceProvider,
80+
Duration allowedOcspResponseTimeSkew,
81+
Duration maxOcspResponseThisUpdateAge) {
82+
this.ocspClient = requireNonNull(ocspClient, "ocspClient");
83+
this.ocspServiceProvider = requireNonNull(ocspServiceProvider, "ocspServiceProvider");
84+
this.allowedOcspResponseTimeSkew = requirePositiveDuration(allowedOcspResponseTimeSkew, "allowedOcspResponseTimeSkew");
85+
this.maxOcspResponseThisUpdateAge = requirePositiveDuration(maxOcspResponseThisUpdateAge, "maxOcspResponseThisUpdateAge");
8486
}
8587

8688
/**
87-
* Validates that the user certificate from the authentication token is not revoked with OCSP.
89+
* Validates with OCSP that the user certificate from the authentication token is not revoked.
8890
*
8991
* @param subjectCertificate user certificate to be validated
9092
* @throws AuthTokenException when user certificate is revoked or revocation check fails.
9193
*/
92-
public void validateCertificateNotRevoked(X509Certificate subjectCertificate) throws AuthTokenException {
94+
public RevocationInfo validateCertificateNotRevoked(X509Certificate subjectCertificate, X509Certificate issuerCertificate) throws AuthTokenException {
95+
requireNonNull(subjectCertificate, "subjectCertificate");
96+
requireNonNull(issuerCertificate, "issuerCertificate");
97+
9398
try {
9499
OcspService ocspService = ocspServiceProvider.getService(subjectCertificate);
95100

96-
final CertificateID certificateId = getCertificateId(subjectCertificate,
97-
Objects.requireNonNull(trustValidator.getSubjectCertificateIssuerCertificate()));
101+
final CertificateID certificateId = getCertificateId(subjectCertificate, issuerCertificate);
98102

99103
final OCSPReq request = new OcspRequestBuilder()
100104
.withCertificateId(certificateId)
@@ -106,7 +110,7 @@ public void validateCertificateNotRevoked(X509Certificate subjectCertificate) th
106110
}
107111

108112
LOG.debug("Sending OCSP request");
109-
final OCSPResp response = Objects.requireNonNull(ocspClient.request(ocspService.getAccessLocation(), request));
113+
final OCSPResp response = requireNonNull(ocspClient.request(ocspService.getAccessLocation(), request), "OCSPResp");
110114
if (response.getStatus() != OCSPResponseStatus.SUCCESSFUL) {
111115
throw new UserCertificateOCSPCheckFailedException("Response status: " + ocspStatusToString(response.getStatus()));
112116
}
@@ -119,6 +123,10 @@ public void validateCertificateNotRevoked(X509Certificate subjectCertificate) th
119123
if (ocspService.doesSupportNonce()) {
120124
checkNonce(request, basicResponse);
121125
}
126+
127+
// TODO: @madislm, just an example, please amend according to your requirements.
128+
return new RevocationInfo(ocspService.getAccessLocation(), Map.of("BasicOCSPResp", basicResponse));
129+
122130
} catch (OCSPException | CertificateException | OperatorCreationException | IOException e) {
123131
throw new UserCertificateOCSPCheckFailedException(e);
124132
}
@@ -202,20 +210,14 @@ private static CertificateID getCertificateId(X509Certificate subjectCertificate
202210
}
203211

204212
private static String ocspStatusToString(int status) {
205-
switch (status) {
206-
case OCSPResp.MALFORMED_REQUEST:
207-
return "malformed request";
208-
case OCSPResp.INTERNAL_ERROR:
209-
return "internal error";
210-
case OCSPResp.TRY_LATER:
211-
return "service unavailable";
212-
case OCSPResp.SIG_REQUIRED:
213-
return "request signature missing";
214-
case OCSPResp.UNAUTHORIZED:
215-
return "unauthorized";
216-
default:
217-
return "unknown";
218-
}
213+
return switch (status) {
214+
case OCSPResp.MALFORMED_REQUEST -> "malformed request";
215+
case OCSPResp.INTERNAL_ERROR -> "internal error";
216+
case OCSPResp.TRY_LATER -> "service unavailable";
217+
case OCSPResp.SIG_REQUIRED -> "request signature missing";
218+
case OCSPResp.UNAUTHORIZED -> "unauthorized";
219+
default -> "unknown";
220+
};
219221
}
220222

221223
}

src/main/java/eu/webeid/security/validator/ocsp/OcspClient.java renamed to src/main/java/eu/webeid/ocsp/client/OcspClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.client;
2424

2525
import org.bouncycastle.cert.ocsp.OCSPReq;
2626
import org.bouncycastle.cert.ocsp.OCSPResp;

src/main/java/eu/webeid/security/validator/ocsp/OcspClientImpl.java renamed to src/main/java/eu/webeid/ocsp/client/OcspClientImpl.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.client;
2424

2525
import org.bouncycastle.cert.ocsp.OCSPReq;
2626
import org.bouncycastle.cert.ocsp.OCSPResp;
@@ -34,6 +34,9 @@
3434
import java.net.http.HttpResponse;
3535
import java.time.Duration;
3636

37+
import static eu.webeid.security.util.DateAndTime.requirePositiveDuration;
38+
import static java.util.Objects.requireNonNull;
39+
3740
public class OcspClientImpl implements OcspClient {
3841

3942
private static final Logger LOG = LoggerFactory.getLogger(OcspClientImpl.class);
@@ -45,6 +48,7 @@ public class OcspClientImpl implements OcspClient {
4548
private final Duration ocspRequestTimeout;
4649

4750
public static OcspClient build(Duration ocspRequestTimeout) {
51+
requirePositiveDuration(ocspRequestTimeout, "ocspRequestTimeout");
4852
return new OcspClientImpl(
4953
HttpClient.newBuilder()
5054
.connectTimeout(ocspRequestTimeout)
@@ -91,8 +95,8 @@ public OCSPResp request(URI uri, OCSPReq ocspReq) throws IOException {
9195
}
9296

9397
public OcspClientImpl(HttpClient httpClient, Duration ocspRequestTimeout) {
94-
this.httpClient = httpClient;
95-
this.ocspRequestTimeout = ocspRequestTimeout;
98+
this.httpClient = requireNonNull(httpClient, "httpClient");
99+
this.ocspRequestTimeout = requirePositiveDuration(ocspRequestTimeout, "ocspRequestTimeout");
96100
}
97101

98102
}

src/main/java/eu/webeid/security/validator/ocsp/DigestCalculatorImpl.java renamed to src/main/java/eu/webeid/ocsp/protocol/DigestCalculatorImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.protocol;
2424

2525
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
2626
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;

src/main/java/eu/webeid/security/validator/ocsp/OcspRequestBuilder.java renamed to src/main/java/eu/webeid/ocsp/protocol/OcspRequestBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.protocol;
2424

2525
import org.bouncycastle.asn1.DEROctetString;
2626
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;

src/main/java/eu/webeid/security/validator/ocsp/OcspResponseValidator.java renamed to src/main/java/eu/webeid/ocsp/protocol/OcspResponseValidator.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.protocol;
2424

2525
import eu.webeid.security.exceptions.OCSPCertificateException;
2626
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
@@ -121,8 +121,7 @@ public static void validateSubjectCertificateStatus(SingleResp certStatusRespons
121121
if (status == null) {
122122
return;
123123
}
124-
if (status instanceof RevokedStatus) {
125-
RevokedStatus revokedStatus = (RevokedStatus) status;
124+
if (status instanceof RevokedStatus revokedStatus) {
126125
throw (revokedStatus.hasRevocationReason() ?
127126
new UserCertificateRevokedException("Revocation reason: " + revokedStatus.getRevocationReason()) :
128127
new UserCertificateRevokedException());

src/main/java/eu/webeid/security/validator/ocsp/OcspUrl.java renamed to src/main/java/eu/webeid/ocsp/protocol/OcspUrl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp;
23+
package eu.webeid.ocsp.protocol;
2424

2525
import org.bouncycastle.asn1.ASN1String;
2626
import org.bouncycastle.asn1.x509.AccessDescription;

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp.service;
23+
package eu.webeid.ocsp.service;
2424

2525
import eu.webeid.security.certificate.CertificateValidator;
2626
import eu.webeid.security.exceptions.AuthTokenException;
2727
import eu.webeid.security.exceptions.OCSPCertificateException;
2828
import eu.webeid.security.exceptions.UserCertificateOCSPCheckFailedException;
29-
import eu.webeid.security.validator.ocsp.OcspResponseValidator;
29+
import eu.webeid.ocsp.protocol.OcspResponseValidator;
30+
import eu.webeid.security.validator.revocationcheck.RevocationMode;
3031
import org.bouncycastle.cert.X509CertificateHolder;
3132
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
3233

@@ -39,7 +40,7 @@
3940
import java.util.Objects;
4041
import java.util.Set;
4142

42-
import static eu.webeid.security.validator.ocsp.OcspUrl.getOcspUri;
43+
import static eu.webeid.ocsp.protocol.OcspUrl.getOcspUri;
4344

4445
/**
4546
* An OCSP service that uses the responders from the Certificates' Authority Information Access (AIA) extension.
@@ -77,7 +78,15 @@ public void validateResponderCertificate(X509CertificateHolder cert, Date now) t
7778
CertificateValidator.certificateIsValidOnDate(certificate, now, "AIA OCSP responder");
7879
// Trusted certificates' validity has been already verified in validateCertificateExpiry().
7980
OcspResponseValidator.validateHasSigningExtension(certificate);
80-
CertificateValidator.validateIsSignedByTrustedCA(certificate, trustedCACertificateAnchors, trustedCACertificateCertStore, now);
81+
CertificateValidator.validateCertificateTrustAndRevocation(
82+
certificate,
83+
trustedCACertificateAnchors,
84+
trustedCACertificateCertStore,
85+
now,
86+
RevocationMode.DISABLED,
87+
null,
88+
null
89+
);
8190
} catch (CertificateException e) {
8291
throw new OCSPCertificateException("Invalid responder certificate", e);
8392
}

src/main/java/eu/webeid/security/validator/ocsp/service/AiaOcspServiceConfiguration.java renamed to src/main/java/eu/webeid/ocsp/service/AiaOcspServiceConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222

23-
package eu.webeid.security.validator.ocsp.service;
23+
package eu.webeid.ocsp.service;
2424

2525
import java.net.URI;
2626
import java.security.cert.CertStore;

0 commit comments

Comments
 (0)