Skip to content

Commit e02a80e

Browse files
committed
AUT-2547 Add support for two fallbacks
1 parent 9350285 commit e02a80e

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/main/java/eu/webeid/ocsp/service/OcspServiceProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,7 @@ public OcspService getService(X509Certificate certificate) throws AuthTokenExcep
7676
return new AiaOcspService(aiaOcspServiceConfiguration, certificate, fallbackOcspService);
7777
}
7878

79+
public FallbackOcspService getFallbackService(URI ocspServiceUri) {
80+
return fallbackOcspServiceMap.get(ocspServiceUri);
81+
}
7982
}

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,34 @@ public List<RevocationInfo> validateCertificateNotRevoked(X509Certificate subjec
116116
List<RevocationInfo> revocationInfoList = new ArrayList<>();
117117

118118
CheckedFunction0<RevocationInfo> primarySupplier = () -> request(ocspService, subjectCertificate, issuerCertificate, false);
119-
CheckedFunction0<RevocationInfo> fallbackSupplier = () -> request(ocspService.getFallbackService(), subjectCertificate, issuerCertificate, true);
119+
OcspService firstFallbackService = ocspService.getFallbackService();
120+
CheckedFunction0<RevocationInfo> firstFallbackSupplier = () -> request(firstFallbackService, subjectCertificate, issuerCertificate, true);
121+
OcspService secondFallbackService = getOcspServiceProvider().getFallbackService(firstFallbackService.getAccessLocation());
122+
CheckedFunction0<RevocationInfo> fallbackSupplier;
123+
if (secondFallbackService == null) {
124+
fallbackSupplier = firstFallbackSupplier;
125+
} else {
126+
CheckedFunction0<RevocationInfo> secondFallbackSupplier = () -> request(secondFallbackService, subjectCertificate, issuerCertificate, true);
127+
fallbackSupplier = () -> {
128+
try {
129+
return firstFallbackSupplier.apply();
130+
} catch (ResilientUserCertificateRevokedException e) {
131+
// NOTE: ResilientUserCertificateRevokedException must be re-thrown before the generic
132+
// catch (Exception) block. Without this, a "revoked" verdict from the first fallback would
133+
// be swallowed, and the second fallback could silently override it with a "good" response.
134+
throw e;
135+
} catch (Exception e) {
136+
if (e instanceof ResilientUserCertificateOCSPCheckFailedException exception) {
137+
revocationInfoList.addAll((exception.getValidationInfo().revocationInfoList()));
138+
} else {
139+
revocationInfoList.add(new RevocationInfo(null, Map.ofEntries(
140+
Map.entry(RevocationInfo.KEY_OCSP_ERROR, e)
141+
)));
142+
}
143+
return secondFallbackSupplier.apply();
144+
}
145+
};
146+
}
120147
Decorators.DecorateCheckedSupplier<RevocationInfo> decorateCheckedSupplier = Decorators.ofCheckedSupplier(primarySupplier);
121148
if (retryRegistry != null) {
122149
Retry retry = retryRegistry.retry(ocspService.getAccessLocation().toASCIIString());

0 commit comments

Comments
 (0)