Skip to content

Commit 9764e74

Browse files
committed
AUT-2597 Reorganize code in ResilientOcspCertificateRevocationChecker
1 parent 4911414 commit 9764e74

File tree

1 file changed

+68
-48
lines changed

1 file changed

+68
-48
lines changed

src/main/java/eu/webeid/resilientocsp/ResilientOcspCertificateRevocationChecker.java

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -101,76 +101,99 @@ public ResilientOcspCertificateRevocationChecker(OcspClient ocspClient,
101101
@Override
102102
public List<RevocationInfo> validateCertificateNotRevoked(X509Certificate subjectCertificate,
103103
X509Certificate issuerCertificate) throws AuthTokenException {
104-
OcspService ocspService;
104+
OcspService primaryService = resolvePrimaryOcspService(subjectCertificate);
105+
106+
if (primaryService.getFallbackService() == null) {
107+
return List.of(request(primaryService, subjectCertificate, issuerCertificate, false));
108+
}
109+
110+
List<RevocationInfo> revocationInfoList = new ArrayList<>();
111+
CheckedSupplier<RevocationInfo> fallbackSupplier = buildFallbackSupplier(primaryService, subjectCertificate,
112+
issuerCertificate, revocationInfoList);
113+
CheckedSupplier<RevocationInfo> decoratedSupplier = decorateWithResilience(primaryService, subjectCertificate,
114+
issuerCertificate, revocationInfoList, fallbackSupplier);
115+
116+
RevocationInfo revocationInfo = processResult(Try.of(decoratedSupplier::get), subjectCertificate, revocationInfoList);
117+
revocationInfoList.add(revocationInfo);
118+
return revocationInfoList;
119+
}
120+
121+
private OcspService resolvePrimaryOcspService(X509Certificate subjectCertificate) throws AuthTokenException {
105122
try {
106-
ocspService = getOcspServiceProvider().getService(subjectCertificate);
123+
return getOcspServiceProvider().getService(subjectCertificate);
107124
} catch (CertificateException e) {
108125
throw new ResilientUserCertificateOCSPCheckFailedException(new ValidationInfo(subjectCertificate, List.of()));
109126
}
110-
final FallbackOcspService firstFallbackService = ocspService.getFallbackService();
111-
if (firstFallbackService == null) {
112-
return List.of(request(ocspService, subjectCertificate, issuerCertificate, false));
113-
}
114-
115-
CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker(ocspService.getAccessLocation().toASCIIString());
116-
117-
List<RevocationInfo> revocationInfoList = new ArrayList<>();
127+
}
118128

119-
CheckedSupplier<RevocationInfo> primarySupplier = () -> {
129+
private CheckedSupplier<RevocationInfo> buildFallbackSupplier(OcspService primaryService,
130+
X509Certificate subjectCertificate,
131+
X509Certificate issuerCertificate,
132+
List<RevocationInfo> revocationInfoList) {
133+
final FallbackOcspService firstFallbackService = primaryService.getFallbackService();
134+
CheckedSupplier<RevocationInfo> firstFallbackSupplier = () -> {
120135
try {
121-
return request(ocspService, subjectCertificate, issuerCertificate, false);
136+
return request(firstFallbackService, subjectCertificate, issuerCertificate, true);
122137
} catch (Exception e) {
123138
createAndAddRevocationInfoToList(e, revocationInfoList);
124139
throw e;
125140
}
126141
};
127-
CheckedSupplier<RevocationInfo> firstFallbackSupplier = () -> {
142+
OcspService secondFallbackService = firstFallbackService.getNextFallback();
143+
if (secondFallbackService == null) {
144+
return firstFallbackSupplier;
145+
}
146+
CheckedSupplier<RevocationInfo> secondFallbackSupplier = () -> {
128147
try {
129-
return request(firstFallbackService, subjectCertificate, issuerCertificate, true);
148+
return request(secondFallbackService, subjectCertificate, issuerCertificate, true);
149+
} catch (Exception e) {
150+
createAndAddRevocationInfoToList(e, revocationInfoList);
151+
throw e;
152+
}
153+
};
154+
return () -> {
155+
try {
156+
return firstFallbackSupplier.get();
157+
} catch (ResilientUserCertificateRevokedException e) {
158+
// NOTE: ResilientUserCertificateRevokedException must be re-thrown before the generic
159+
// catch (Exception) block. Without this, a "revoked" verdict from the first fallback would
160+
// be swallowed, and the second fallback could silently override it with a "good" response.
161+
throw e;
162+
} catch (Exception e) {
163+
return secondFallbackSupplier.get();
164+
}
165+
};
166+
}
167+
168+
private CheckedSupplier<RevocationInfo> decorateWithResilience(OcspService primaryService,
169+
X509Certificate subjectCertificate,
170+
X509Certificate issuerCertificate,
171+
List<RevocationInfo> revocationInfoList,
172+
CheckedSupplier<RevocationInfo> fallbackSupplier
173+
) {
174+
CheckedSupplier<RevocationInfo> primarySupplier = () -> {
175+
try {
176+
return request(primaryService, subjectCertificate, issuerCertificate, false);
130177
} catch (Exception e) {
131178
createAndAddRevocationInfoToList(e, revocationInfoList);
132179
throw e;
133180
}
134181
};
135-
OcspService secondFallbackService = firstFallbackService.getNextFallback();
136-
CheckedSupplier<RevocationInfo> fallbackSupplier;
137-
if (secondFallbackService == null) {
138-
fallbackSupplier = firstFallbackSupplier;
139-
} else {
140-
CheckedSupplier<RevocationInfo> secondFallbackSupplier = () -> {
141-
try {
142-
return request(secondFallbackService, subjectCertificate, issuerCertificate, true);
143-
} catch (Exception e) {
144-
createAndAddRevocationInfoToList(e, revocationInfoList);
145-
throw e;
146-
}
147-
};
148-
fallbackSupplier = () -> {
149-
try {
150-
return firstFallbackSupplier.get();
151-
} catch (ResilientUserCertificateRevokedException e) {
152-
// NOTE: ResilientUserCertificateRevokedException must be re-thrown before the generic
153-
// catch (Exception) block. Without this, a "revoked" verdict from the first fallback would
154-
// be swallowed, and the second fallback could silently override it with a "good" response.
155-
throw e;
156-
} catch (Exception e) {
157-
return secondFallbackSupplier.get();
158-
}
159-
};
160-
}
161182
Decorators.DecorateCheckedSupplier<RevocationInfo> decorateCheckedSupplier = Decorators.ofCheckedSupplier(primarySupplier);
162183
if (retryRegistry != null) {
163-
Retry retry = retryRegistry.retry(ocspService.getAccessLocation().toASCIIString());
184+
Retry retry = retryRegistry.retry(primaryService.getAccessLocation().toASCIIString());
164185
decorateCheckedSupplier.withRetry(retry);
165186
}
187+
CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker(primaryService.getAccessLocation().toASCIIString());
166188
decorateCheckedSupplier.withCircuitBreaker(circuitBreaker)
167189
.withFallback(List.of(ResilientUserCertificateOCSPCheckFailedException.class, CallNotPermittedException.class), e -> fallbackSupplier.get());
168190

169-
CheckedSupplier<RevocationInfo> decoratedSupplier = decorateCheckedSupplier.decorate();
170-
171-
Try<RevocationInfo> result = Try.of(decoratedSupplier::get);
191+
return decorateCheckedSupplier.decorate();
192+
}
172193

173-
RevocationInfo revocationInfo = result.getOrElseThrow(throwable -> {
194+
private RevocationInfo processResult(Try<RevocationInfo> result, X509Certificate subjectCertificate,
195+
List<RevocationInfo> revocationInfoList) throws AuthTokenException {
196+
return result.getOrElseThrow(throwable -> {
174197
if (throwable instanceof ResilientUserCertificateOCSPCheckFailedException exception) {
175198
exception.setValidationInfo(new ValidationInfo(subjectCertificate, revocationInfoList));
176199
return exception;
@@ -182,9 +205,6 @@ public List<RevocationInfo> validateCertificateNotRevoked(X509Certificate subjec
182205
// TODO This should always be TaraUserCertificateOCSPCheckFailedException when reached?
183206
return new ResilientUserCertificateOCSPCheckFailedException(new ValidationInfo(subjectCertificate, revocationInfoList));
184207
});
185-
186-
revocationInfoList.add(revocationInfo);
187-
return revocationInfoList;
188208
}
189209

190210
private void createAndAddRevocationInfoToList(Throwable throwable, List<RevocationInfo> revocationInfoList) {

0 commit comments

Comments
 (0)