Skip to content

Commit 7bf6f0d

Browse files
AnhelinaMEugene Bochilo
authored andcommitted
Change revocation online fetching property behavior
DEVSIX-8401
1 parent 52d74b8 commit 7bf6f0d

File tree

2 files changed

+244
-87
lines changed

2 files changed

+244
-87
lines changed

sign/src/main/java/com/itextpdf/signatures/validation/v1/RevocationDataValidator.java

Lines changed: 86 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,62 @@ public void validate(ValidationReport report, ValidationContext context, X509Cer
172172
// Try to check responderCert for revocation using provided responder OCSP/CRL clients or
173173
// Authority Information Access for OCSP responses and CRL Distribution Points for CRL responses
174174
// using default clients.
175-
validateRevocationData(report, localContext, certificate, validationDate, ocspResponses, crlResponses);
175+
ValidationReport revDataValidationReport = new ValidationReport();
176+
validateRevocationData(revDataValidationReport, localContext, certificate, validationDate, ocspResponses,
177+
crlResponses);
178+
179+
if (ValidationReport.ValidationResult.INDETERMINATE == revDataValidationReport.getValidationResult()) {
180+
List<CrlValidationInfo> onlineCrlResponses = new ArrayList<>();
181+
List<OcspResponseValidationInfo> onlineOcspResponses = new ArrayList<>();
182+
tryToFetchRevInfoOnline(report, context, certificate, onlineCrlResponses, onlineOcspResponses);
183+
if (!onlineCrlResponses.isEmpty() || !onlineOcspResponses.isEmpty()) {
184+
// Merge the report excluding NO_REVOCATION_DATA message.
185+
for (ReportItem reportItem : revDataValidationReport.getLogs()) {
186+
if (!NO_REVOCATION_DATA.equals(reportItem.getMessage())) {
187+
report.addReportItem(reportItem);
188+
}
189+
}
190+
validateRevocationData(report, localContext, certificate, validationDate, onlineOcspResponses,
191+
onlineCrlResponses);
192+
return;
193+
}
194+
}
195+
report.merge(revDataValidationReport);
196+
}
197+
198+
private static void fillOcspResponses(List<OcspResponseValidationInfo> ocspResponses, IBasicOCSPResp basicOCSPResp,
199+
Date generationDate, TimeBasedContext timeBasedContext) {
200+
if (basicOCSPResp != null) {
201+
// Getting the responses.
202+
ISingleResp[] singleResponses = basicOCSPResp.getResponses();
203+
for (ISingleResp singleResponse : singleResponses) {
204+
ocspResponses.add(new OcspResponseValidationInfo(singleResponse, basicOCSPResp, generationDate,
205+
timeBasedContext));
206+
}
207+
}
208+
}
209+
210+
private static List<CrlValidationInfo> retrieveAllCRLResponsesUsingClient(ValidationReport report,
211+
X509Certificate certificate,
212+
ICrlClient crlClient) {
213+
List<CrlValidationInfo> crlResponses = new ArrayList<>();
214+
if (crlClient instanceof ValidationCrlClient) {
215+
ValidationCrlClient validationCrlClient = (ValidationCrlClient) crlClient;
216+
crlResponses.addAll(validationCrlClient.getCrls().values());
217+
} else {
218+
Collection<byte[]> crlBytesCollection = onExceptionLog(() ->
219+
crlClient.getEncoded(certificate, null), Collections.<byte[]>emptyList(), report, e ->
220+
new CertificateReportItem(certificate, REVOCATION_DATA_CHECK,
221+
MessageFormatUtil.format(CRL_CLIENT_FAILURE, crlClient), e, ReportItemStatus.INFO));
222+
for (byte[] crlBytes : crlBytesCollection) {
223+
onExceptionLog(() ->
224+
crlResponses.add(new CrlValidationInfo((X509CRL) CertificateUtil.parseCrlFromBytes(crlBytes),
225+
DateTimeUtil.getCurrentTimeDate(), TimeBasedContext.PRESENT)), report, e ->
226+
new CertificateReportItem(certificate, REVOCATION_DATA_CHECK,
227+
MessageFormatUtil.format(CANNOT_PARSE_CRL, crlClient), e, ReportItemStatus.INFO));
228+
}
229+
}
230+
return crlResponses;
176231
}
177232

178233
private void validateRevocationData(ValidationReport report, ValidationContext context, X509Certificate certificate,
@@ -264,9 +319,7 @@ private List<OcspResponseValidationInfo> retrieveAllOCSPResponses(ValidationRepo
264319
}
265320
SignatureValidationProperties.OnlineFetching onlineFetching = properties.getRevocationOnlineFetching(
266321
context.setValidatorContext(ValidatorContext.OCSP_VALIDATOR));
267-
if (SignatureValidationProperties.OnlineFetching.ALWAYS_FETCH == onlineFetching ||
268-
(SignatureValidationProperties.OnlineFetching.FETCH_IF_NO_OTHER_DATA_AVAILABLE == onlineFetching
269-
&& ocspResponses.isEmpty())) {
322+
if (SignatureValidationProperties.OnlineFetching.ALWAYS_FETCH == onlineFetching) {
270323
onRuntimeExceptionLog(() -> {
271324
IBasicOCSPResp basicOCSPResp = new OcspClientBouncyCastle().getBasicOCSPResp(certificate,
272325
issuerCert, null);
@@ -285,51 +338,45 @@ private List<CrlValidationInfo> retrieveAllCRLResponses(ValidationReport report,
285338
for (ICrlClient crlClient : crlClients) {
286339
crlResponses.addAll(retrieveAllCRLResponsesUsingClient(report, certificate, crlClient));
287340
}
288-
SignatureValidationProperties.OnlineFetching onLineFetching = properties.getRevocationOnlineFetching(
341+
SignatureValidationProperties.OnlineFetching onlineFetching = properties.getRevocationOnlineFetching(
289342
context.setValidatorContext(ValidatorContext.CRL_VALIDATOR));
290-
if (SignatureValidationProperties.OnlineFetching.ALWAYS_FETCH == onLineFetching ||
291-
(SignatureValidationProperties.OnlineFetching.FETCH_IF_NO_OTHER_DATA_AVAILABLE == onLineFetching &&
292-
crlResponses.isEmpty())) {
343+
if (SignatureValidationProperties.OnlineFetching.ALWAYS_FETCH == onlineFetching) {
293344
crlResponses.addAll(retrieveAllCRLResponsesUsingClient(report, certificate, new CrlClientOnline()));
294345
}
295346
// Sort all the CRL responses available based on the most recent revocation data.
296347
return crlResponses.stream().sorted((o1, o2) -> o2.crl.getThisUpdate().compareTo(o1.crl.getThisUpdate()))
297348
.collect(Collectors.toList());
298349
}
299350

300-
private static void fillOcspResponses(List<OcspResponseValidationInfo> ocspResponses, IBasicOCSPResp basicOCSPResp,
301-
Date generationDate, TimeBasedContext timeBasedContext) {
302-
if (basicOCSPResp != null) {
303-
// Getting the responses.
304-
ISingleResp[] singleResponses = basicOCSPResp.getResponses();
305-
for (ISingleResp singleResponse : singleResponses) {
306-
ocspResponses.add(new OcspResponseValidationInfo(singleResponse, basicOCSPResp, generationDate,
307-
timeBasedContext));
308-
}
351+
private void tryToFetchRevInfoOnline(ValidationReport report, ValidationContext context,
352+
X509Certificate certificate,
353+
List<CrlValidationInfo> onlineCrlResponses,
354+
List<OcspResponseValidationInfo> onlineOcspResponses) {
355+
SignatureValidationProperties.OnlineFetching crlOnlineFetching = properties.getRevocationOnlineFetching(
356+
context.setValidatorContext(ValidatorContext.CRL_VALIDATOR));
357+
if (SignatureValidationProperties.OnlineFetching.FETCH_IF_NO_OTHER_DATA_AVAILABLE == crlOnlineFetching) {
358+
// Sort all the CRL responses available based on the most recent revocation data.
359+
onlineCrlResponses.addAll(retrieveAllCRLResponsesUsingClient(report, certificate, new CrlClientOnline())
360+
.stream().sorted((o1, o2) ->
361+
o2.crl.getThisUpdate().compareTo(o1.crl.getThisUpdate())).collect(Collectors.toList()));
309362
}
310-
}
311-
312-
private static List<CrlValidationInfo> retrieveAllCRLResponsesUsingClient(ValidationReport report,
313-
X509Certificate certificate,
314-
ICrlClient crlClient) {
315-
List<CrlValidationInfo> crlResponses = new ArrayList<>();
316-
if (crlClient instanceof ValidationCrlClient) {
317-
ValidationCrlClient validationCrlClient = (ValidationCrlClient) crlClient;
318-
crlResponses.addAll(validationCrlClient.getCrls().values());
319-
} else {
320-
Collection<byte[]> crlBytesCollection = onExceptionLog(() ->
321-
crlClient.getEncoded(certificate, null), Collections.<byte[]>emptyList(), report, e ->
322-
new CertificateReportItem(certificate, REVOCATION_DATA_CHECK,
323-
MessageFormatUtil.format(CRL_CLIENT_FAILURE, crlClient), e, ReportItemStatus.INFO));
324-
for (byte[] crlBytes : crlBytesCollection) {
325-
onExceptionLog(() ->
326-
crlResponses.add(new CrlValidationInfo((X509CRL) CertificateUtil.parseCrlFromBytes(crlBytes),
327-
DateTimeUtil.getCurrentTimeDate(), TimeBasedContext.PRESENT)), report, e ->
328-
new CertificateReportItem(certificate, REVOCATION_DATA_CHECK,
329-
MessageFormatUtil.format(CANNOT_PARSE_CRL, crlClient), e, ReportItemStatus.INFO));
330-
}
363+
SignatureValidationProperties.OnlineFetching ocspOnlineFetching = properties.getRevocationOnlineFetching(
364+
context.setValidatorContext(ValidatorContext.OCSP_VALIDATOR));
365+
if (SignatureValidationProperties.OnlineFetching.FETCH_IF_NO_OTHER_DATA_AVAILABLE == ocspOnlineFetching) {
366+
onRuntimeExceptionLog(() -> {
367+
IBasicOCSPResp basicOCSPResp = new OcspClientBouncyCastle().getBasicOCSPResp(certificate,
368+
(X509Certificate) certificateRetriever.retrieveIssuerCertificate(certificate), null);
369+
List<OcspResponseValidationInfo> ocspResponses = new ArrayList<>();
370+
fillOcspResponses(ocspResponses, basicOCSPResp, DateTimeUtil.getCurrentTimeDate(),
371+
TimeBasedContext.PRESENT);
372+
// Sort all the OCSP responses available based on the most recent revocation data.
373+
onlineOcspResponses.addAll(ocspResponses.stream().sorted((o1, o2) ->
374+
o2.singleResp.getThisUpdate().compareTo(o1.singleResp.getThisUpdate()))
375+
.collect(Collectors.toList()));
376+
}, report, e -> new CertificateReportItem(certificate, REVOCATION_DATA_CHECK,
377+
MessageFormatUtil.format(OCSP_CLIENT_FAILURE, "OcspClientBouncyCastle"), e,
378+
ReportItemStatus.INDETERMINATE));
331379
}
332-
return crlResponses;
333380
}
334381

335382
/**

0 commit comments

Comments
 (0)