// Open the document for reading.
PdfReader reader = new PdfReader(documentFileName);
// Get the signatures in the document.
AcroFields fields = reader.getAcroFields();
ArrayList<String> signatures = fields.getSignatureNames();
if (signatures.size() == 0) {
throw new NoSignatureException(messages.getString(
"Document_has_no_signature."));
}
// Check if the last signature is a timestamp.
String lastSignature = signatures.get(signatures.size() - 1);
PdfPKCS7 pkcs7 = fields.verifySignature(lastSignature);
if (!pkcs7.isTsp()) {
throw new NoTimestampException(messages.getString(
"Document_has_no_document_level_timestamp."));
}
// Get the expiration date of the last timestamp.
Calendar expiration = Calendar.getInstance();
expiration.setTime(pkcs7.getSigningCertificate().getNotAfter());
// Validate last timestamp on the current date.
SignatureValidator.validate(lastSignature, reader, rootCertificates);
// Get OCSP responses and CRLs from DSS to validate old signatures.
PdfDictionary dictionary = reader.getCatalog().getAsDict(PdfName.DSS);
if (dictionary == null) {
throw new NoDSSException(messages.getString(
"Document_has_no_DSS_(Document_Security_Store)."));
}
PdfArray ocspArray = dictionary.getAsArray(PdfName.OCSPS);
ArrayList<BasicOCSPResp> ocsps = new ArrayList<BasicOCSPResp>();
if (ocspArray != null) {
for (int i = 0; i < ocspArray.size(); i++) {
PRStream stream = (PRStream) ocspArray.getAsStream(i);
OCSPResp response = new OCSPResp(PdfReader.getStreamBytes(stream));
BasicOCSPResp basicResponse = (BasicOCSPResp) response.getResponseObject();
ocsps.add(basicResponse);
}
}
PdfArray crlArray = dictionary.getAsArray(PdfName.CRLS);
ArrayList<X509CRL> crls = new ArrayList<X509CRL>();
if (crlArray != null) {
for (int i = 0; i < crlArray.size(); i++) {
PRStream stream = (PRStream) crlArray.getAsStream(i);
X509CRL crl = (X509CRL) factory.generateCRL(new ByteArrayInputStream(PdfReader.getStreamBytes(stream)));
crls.add(crl);
}
}
if (ocsps.size() == 0 && crls.size() == 0) {
throw new NoRevocationStatusException(messages.getString(
"Document_has_neither_OCSP_responses_nor_CRLs_for_offline_check_of_certificate_revocation_status."));
}
// Use date from last timestamp to validade next signature.
Calendar date = pkcs7.getTimeStampDate();
// Validate others signatures using date of the timestamp.
for (int i = signatures.size() - 2; i >= 0; i--) {
// Get next signature.
pkcs7 = fields.verifySignature(signatures.get(i));
// Validate next signature.
SignatureValidator.validate(
signatures.get(i), reader, rootCertificates, ocsps, crls, date);