@@ -41,6 +41,9 @@ This file is part of the iText (R) project.
41
41
import java .util .Date ;
42
42
import java .util .List ;
43
43
44
+ import static com .itextpdf .signatures .validation .v1 .SafeCalling .onExceptionLog ;
45
+ import static com .itextpdf .signatures .validation .v1 .SafeCalling .onRuntimeExceptionLog ;
46
+
44
47
/**
45
48
* Validator class, which is expected to be used for certificates chain validation.
46
49
*/
@@ -60,6 +63,18 @@ public class CertificateChainValidator {
60
63
static final String ISSUER_CANNOT_BE_VERIFIED =
61
64
"Issuer certificate {0} for subject certificate {1} cannot be mathematically verified." ;
62
65
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
+
63
78
private final SignatureValidationProperties properties ;
64
79
private final IssuingCertificateRetriever certificateRetriever ;
65
80
private final RevocationDataValidator revocationDataValidator ;
@@ -102,15 +117,15 @@ public CertificateChainValidator addOcspClient(IOcspClient ocpsClient) {
102
117
/**
103
118
* Validate given certificate using provided validation date and required extensions.
104
119
*
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
109
124
*
110
125
* @return {@link ValidationReport} which contains detailed validation results
111
126
*/
112
127
public ValidationReport validateCertificate (ValidationContext context , X509Certificate certificate ,
113
- Date validationDate ) {
128
+ Date validationDate ) {
114
129
ValidationReport result = new ValidationReport ();
115
130
return validate (result , context , certificate , validationDate );
116
131
}
@@ -119,11 +134,11 @@ public ValidationReport validateCertificate(ValidationContext context, X509Certi
119
134
* Validate given certificate using provided validation date and required extensions.
120
135
* Result is added into provided report.
121
136
*
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
127
142
*
128
143
* @return {@link ValidationReport} which contains both provided and new validation results
129
144
*/
@@ -135,9 +150,12 @@ public ValidationReport validate(ValidationReport result, ValidationContext cont
135
150
if (stopValidation (result , localContext )) {
136
151
return result ;
137
152
}
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 ))) {
139
156
return result ;
140
157
}
158
+
141
159
validateRevocationData (result , localContext , certificate , validationDate );
142
160
if (stopValidation (result , localContext )) {
143
161
return result ;
@@ -230,6 +248,9 @@ private void validateValidityPeriod(ValidationReport result, X509Certificate cer
230
248
} catch (CertificateNotYetValidException e ) {
231
249
result .addReportItem (new CertificateReportItem (certificate , VALIDITY_CHECK , MessageFormatUtil .format (
232
250
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 ));
233
254
}
234
255
}
235
256
@@ -249,13 +270,23 @@ private void validateRequiredExtensions(ValidationReport result, ValidationConte
249
270
250
271
private void validateRevocationData (ValidationReport report , ValidationContext context , X509Certificate certificate ,
251
272
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 ));
253
277
}
254
278
255
279
private void validateChain (ValidationReport result , ValidationContext context , X509Certificate certificate ,
256
280
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
+ }
259
290
if (issuerCertificate == null ) {
260
291
result .addReportItem (new CertificateReportItem (certificate , CERTIFICATE_CHECK , MessageFormatUtil .format (
261
292
ISSUER_MISSING , certificate .getSubjectX500Principal ()), ReportItemStatus .INDETERMINATE ));
@@ -268,6 +299,11 @@ private void validateChain(ValidationReport result, ValidationContext context, X
268
299
MessageFormatUtil .format (ISSUER_CANNOT_BE_VERIFIED , issuerCertificate .getSubjectX500Principal (),
269
300
certificate .getSubjectX500Principal ()), e , ReportItemStatus .INVALID ));
270
301
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 ;
271
307
}
272
308
this .validate (result , context .setCertificateSource (CertificateSource .CERT_ISSUER ),
273
309
issuerCertificate , validationDate );
0 commit comments