@Override public List<TimestampToken> getArchiveTimestamps() { final List<TimestampToken> archiveTimestampTokenList = new ArrayList<TimestampToken>(); final List<String> timestampedTimestamps = new ArrayList<String>(); final Set<PdfSignatureOrDocTimestampInfo> outerSignatures = pdfSignatureInfo.getOuterSignatures(); usedCertificatesDigestAlgorithms.add(DigestAlgorithm.SHA1); for (final PdfSignatureOrDocTimestampInfo outerSignature : outerSignatures) { if (outerSignature.isTimestamp()) { PdfDocTimestampInfo pdfBoxTimestampInfo = (PdfDocTimestampInfo) outerSignature; // return this timestamp if it's an archive timestamp final TimestampToken timestampToken = pdfBoxTimestampInfo.getTimestampToken(); if (timestampToken.getTimeStampType() == TimestampType.ARCHIVE_TIMESTAMP) { final List<TimestampReference> references = cadesSignature.getSignatureTimestampedReferences(); for (final String timestampId : timestampedTimestamps) { final TimestampReference signatureReference_ = new TimestampReference(timestampId); references.add(signatureReference_); } final List<CertificateToken> certificates = getCertificates(); for (final CertificateToken certificate : certificates) { references.add(createCertificateTimestampReference(certificate)); } timestampToken.setTimestampedReferences(references); archiveTimestampTokenList.add(timestampToken); } timestampedTimestamps.add(String.valueOf(timestampToken.getDSSId())); } } return Collections.unmodifiableList(archiveTimestampTokenList); }
/** * This method links previous signatures to the new one. This is useful to get revision number and * to know if a TSP is over the DSS dictionary */ private void linkSignatures(List<PdfSignatureOrDocTimestampInfo> signatures) { List<PdfSignatureOrDocTimestampInfo> previousList = new ArrayList<PdfSignatureOrDocTimestampInfo>(); for (PdfSignatureOrDocTimestampInfo sig : signatures) { if (CollectionUtils.isNotEmpty(previousList)) { for (PdfSignatureOrDocTimestampInfo previous : previousList) { previous.addOuterSignature(sig); } } previousList.add(sig); } }
@Override public List<TimestampToken> getSignatureTimestamps() { final List<TimestampToken> result = new ArrayList<TimestampToken>(); result.addAll(cadesSignatureTimestamps); final Set<PdfSignatureOrDocTimestampInfo> outerSignatures = pdfSignatureInfo.getOuterSignatures(); for (final PdfSignatureOrDocTimestampInfo outerSignature : outerSignatures) { if (outerSignature.isTimestamp() && (outerSignature instanceof PdfDocTimestampInfo)) { final PdfDocTimestampInfo pdfBoxTimestampInfo = (PdfDocTimestampInfo) outerSignature; // do not return this timestamp if it's an archive timestamp final TimestampToken timestampToken = pdfBoxTimestampInfo.getTimestampToken(); if (timestampToken.getTimeStampType() == TimestampType.SIGNATURE_TIMESTAMP) { timestampToken.setTimestampedReferences( cadesSignature.getSignatureTimestampedReferences()); result.add(timestampToken); } } } return Collections.unmodifiableList(result); }
private List<PdfSignatureOrDocTimestampInfo> getSignatures( CertificatePool validationCertPool, byte[] originalBytes) { List<PdfSignatureOrDocTimestampInfo> signatures = new ArrayList<PdfSignatureOrDocTimestampInfo>(); ByteArrayInputStream bais = null; PDDocument doc = null; try { bais = new ByteArrayInputStream(originalBytes); doc = PDDocument.load(bais); List<PDSignature> pdSignatures = doc.getSignatureDictionaries(); if (CollectionUtils.isNotEmpty(pdSignatures)) { logger.debug("{} signature(s) found", pdSignatures.size()); PdfDict catalog = new PdfBoxDict(doc.getDocumentCatalog().getCOSDictionary(), doc); PdfDssDict dssDictionary = PdfDssDict.extract(catalog); for (PDSignature signature : pdSignatures) { String subFilter = signature.getSubFilter(); byte[] cms = signature.getContents(originalBytes); if (StringUtils.isEmpty(subFilter) || ArrayUtils.isEmpty(cms)) { logger.warn("Wrong signature with empty subfilter or cms."); continue; } byte[] signedContent = signature.getSignedContent(originalBytes); int[] byteRange = signature.getByteRange(); PdfSignatureOrDocTimestampInfo signatureInfo = null; if (PdfBoxDocTimeStampService.SUB_FILTER_ETSI_RFC3161.getName().equals(subFilter)) { boolean isArchiveTimestamp = false; // LT or LTA if (dssDictionary != null) { // check is DSS dictionary already exist if (isDSSDictionaryPresentInPreviousRevision( getOriginalBytes(byteRange, signedContent))) { isArchiveTimestamp = true; } } signatureInfo = new PdfBoxDocTimestampInfo( validationCertPool, signature, dssDictionary, cms, signedContent, isArchiveTimestamp); } else { signatureInfo = new PdfBoxSignatureInfo( validationCertPool, signature, dssDictionary, cms, signedContent); } if (signatureInfo != null) { signatures.add(signatureInfo); } } Collections.sort(signatures, new PdfSignatureOrDocTimestampInfoComparator()); linkSignatures(signatures); for (PdfSignatureOrDocTimestampInfo sig : signatures) { logger.debug( "Signature " + sig.uniqueId() + " found with byteRange " + Arrays.toString(sig.getSignatureByteRange()) + " (" + sig.getSubFilter() + ")"); } } } catch (Exception e) { logger.warn("Cannot analyze signatures : " + e.getMessage(), e); } finally { IOUtils.closeQuietly(bais); IOUtils.closeQuietly(doc); } return signatures; }