@@ -41,6 +41,9 @@ This file is part of the iText (R) project.
4141import java .util .Date ;
4242import java .util .List ;
4343
44+ import static com .itextpdf .signatures .validation .v1 .SafeCalling .onExceptionLog ;
45+ import static com .itextpdf .signatures .validation .v1 .SafeCalling .onRuntimeExceptionLog ;
46+
4447/**
4548 * Validator class, which is expected to be used for certificates chain validation.
4649 */
@@ -60,6 +63,18 @@ public class CertificateChainValidator {
6063 static final String ISSUER_CANNOT_BE_VERIFIED =
6164 "Issuer certificate {0} for subject certificate {1} cannot be mathematically verified." ;
6265
66+ static final String ISSUER_VERIFICATION_FAILED =
67+ "Unexpected exception occurred while verifying issuer certificate." ;
68+ static final String ISSUER_RETRIEVAL_FAILED =
69+ "Unexpected exception occurred while retrieving certificate issuer from IssuingCertificateRetriever." ;
70+ static final String TRUSTSTORE_RETRIEVAL_FAILED =
71+ "Unexpected exception occurred while retrieving trust store from IssuingCertificateRetriever." ;
72+ static final String REVOCATION_VALIDATION_FAILED =
73+ "Unexpected exception occurred while validating certificate revocation." ;
74+ static final String VALIDITY_PERIOD_CHECK_FAILED =
75+ "Unexpected exception occurred while validating certificate validity period." ;
76+
77+
6378 private final SignatureValidationProperties properties ;
6479 private final IssuingCertificateRetriever certificateRetriever ;
6580 private final RevocationDataValidator revocationDataValidator ;
@@ -102,15 +117,15 @@ public CertificateChainValidator addOcspClient(IOcspClient ocpsClient) {
102117 /**
103118 * Validate given certificate using provided validation date and required extensions.
104119 *
105- * @param context the validation context in which to validate the certificate chain
106- * @param certificate {@link X509Certificate} to be validated
107- * @param validationDate {@link Date} against which certificate is expected to be validated. Usually signing
108- * date
120+ * @param context the validation context in which to validate the certificate chain
121+ * @param certificate {@link X509Certificate} to be validated
122+ * @param validationDate {@link Date} against which certificate is expected to be validated. Usually signing
123+ * date
109124 *
110125 * @return {@link ValidationReport} which contains detailed validation results
111126 */
112127 public ValidationReport validateCertificate (ValidationContext context , X509Certificate certificate ,
113- Date validationDate ) {
128+ Date validationDate ) {
114129 ValidationReport result = new ValidationReport ();
115130 return validate (result , context , certificate , validationDate );
116131 }
@@ -119,11 +134,11 @@ public ValidationReport validateCertificate(ValidationContext context, X509Certi
119134 * Validate given certificate using provided validation date and required extensions.
120135 * Result is added into provided report.
121136 *
122- * @param result {@link ValidationReport} which is populated with detailed validation results
123- * @param context the context in which to perform the validation
124- * @param certificate {@link X509Certificate} to be validated
125- * @param validationDate {@link Date} against which certificate is expected to be validated. Usually signing
126- * date
137+ * @param result {@link ValidationReport} which is populated with detailed validation results
138+ * @param context the context in which to perform the validation
139+ * @param certificate {@link X509Certificate} to be validated
140+ * @param validationDate {@link Date} against which certificate is expected to be validated. Usually signing
141+ * date
127142 *
128143 * @return {@link ValidationReport} which contains both provided and new validation results
129144 */
@@ -135,9 +150,12 @@ public ValidationReport validate(ValidationReport result, ValidationContext cont
135150 if (stopValidation (result , localContext )) {
136151 return result ;
137152 }
138- if (checkIfCertIsTrusted (result , localContext , certificate )) {
153+ if (onExceptionLog (() -> checkIfCertIsTrusted (result , localContext , certificate ), Boolean .FALSE , result ,
154+ e -> new CertificateReportItem (certificate , CERTIFICATE_CHECK , TRUSTSTORE_RETRIEVAL_FAILED ,
155+ e , ReportItemStatus .INFO ))) {
139156 return result ;
140157 }
158+
141159 validateRevocationData (result , localContext , certificate , validationDate );
142160 if (stopValidation (result , localContext )) {
143161 return result ;
@@ -230,6 +248,9 @@ private void validateValidityPeriod(ValidationReport result, X509Certificate cer
230248 } catch (CertificateNotYetValidException e ) {
231249 result .addReportItem (new CertificateReportItem (certificate , VALIDITY_CHECK , MessageFormatUtil .format (
232250 NOT_YET_VALID_CERTIFICATE , certificate .getSubjectX500Principal ()), e , ReportItemStatus .INVALID ));
251+ } catch (RuntimeException e ) {
252+ result .addReportItem (new CertificateReportItem (certificate , VALIDITY_CHECK , MessageFormatUtil .format (
253+ VALIDITY_PERIOD_CHECK_FAILED , certificate .getSubjectX500Principal ()), e , ReportItemStatus .INVALID ));
233254 }
234255 }
235256
@@ -249,13 +270,23 @@ private void validateRequiredExtensions(ValidationReport result, ValidationConte
249270
250271 private void validateRevocationData (ValidationReport report , ValidationContext context , X509Certificate certificate ,
251272 Date validationDate ) {
252- revocationDataValidator .validate (report , context , certificate , validationDate );
273+ onRuntimeExceptionLog (() ->
274+ revocationDataValidator .validate (report , context , certificate , validationDate ), report , e ->
275+ new CertificateReportItem (certificate , CERTIFICATE_CHECK ,
276+ REVOCATION_VALIDATION_FAILED , e , ReportItemStatus .INDETERMINATE ));
253277 }
254278
255279 private void validateChain (ValidationReport result , ValidationContext context , X509Certificate certificate ,
256280 Date validationDate ) {
257- X509Certificate issuerCertificate =
258- (X509Certificate ) certificateRetriever .retrieveIssuerCertificate (certificate );
281+ X509Certificate issuerCertificate = null ;
282+ try {
283+ issuerCertificate =
284+ (X509Certificate ) certificateRetriever .retrieveIssuerCertificate (certificate );
285+ } catch (RuntimeException e ) {
286+ result .addReportItem (new CertificateReportItem (certificate , CERTIFICATE_CHECK ,
287+ ISSUER_RETRIEVAL_FAILED , e , ReportItemStatus .INDETERMINATE ));
288+ return ;
289+ }
259290 if (issuerCertificate == null ) {
260291 result .addReportItem (new CertificateReportItem (certificate , CERTIFICATE_CHECK , MessageFormatUtil .format (
261292 ISSUER_MISSING , certificate .getSubjectX500Principal ()), ReportItemStatus .INDETERMINATE ));
@@ -268,6 +299,11 @@ private void validateChain(ValidationReport result, ValidationContext context, X
268299 MessageFormatUtil .format (ISSUER_CANNOT_BE_VERIFIED , issuerCertificate .getSubjectX500Principal (),
269300 certificate .getSubjectX500Principal ()), e , ReportItemStatus .INVALID ));
270301 return ;
302+ } catch (RuntimeException e ) {
303+ result .addReportItem (new CertificateReportItem (certificate , CERTIFICATE_CHECK ,
304+ MessageFormatUtil .format (ISSUER_VERIFICATION_FAILED , issuerCertificate .getSubjectX500Principal (),
305+ certificate .getSubjectX500Principal ()), e , ReportItemStatus .INVALID ));
306+ return ;
271307 }
272308 this .validate (result , context .setCertificateSource (CertificateSource .CERT_ISSUER ),
273309 issuerCertificate , validationDate );
0 commit comments