From 35a65bfdfeee48e03cb5dcfc72d45ac0b8a6c790 Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 21 Nov 2007 17:32:49 +0000 Subject: Config-parameter "check_document" introduced. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@224 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../at/gv/egiz/pdfas/exceptions/ErrorCode.java | 3 + .../pdfas/impl/vfilter/VerificationFilterImpl.java | 162 ++++++++++++++++++++- 2 files changed, 162 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java index 332974b..dcb5f30 100644 --- a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java @@ -36,6 +36,9 @@ public final class ErrorCode public static final int CERTIFICATE_NOT_FOUND = 313; public static final int NOT_SEMANTICALLY_EQUAL = 314; + + public static final int MODIFIED_AFTER_SIGNATION = 316; + public static final int NON_BINARY_SIGNATURES_PRESENT = 317; public static final int WEB_EXCEPTION = 330; diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java index 0c9e1f2..3fe17bf 100644 --- a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java @@ -10,6 +10,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.gv.egiz.pdfas.exceptions.framework.VerificationFilterException; import at.gv.egiz.pdfas.framework.SignatureHolderHelper; import at.gv.egiz.pdfas.framework.VerificatorFactory; @@ -26,9 +27,11 @@ import at.gv.egiz.pdfas.impl.vfilter.partition.BinaryPartition; import at.gv.egiz.pdfas.impl.vfilter.partition.TextPartition; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; import at.knowcenter.wag.egov.egiz.pdf.AbsoluteTextSignature; @@ -48,6 +51,10 @@ public class VerificationFilterImpl implements VerificationFilter */ private static final Log log = LogFactory.getLog(VerificationFilterImpl.class); + + // tzefferer: added + public static final String CHECK_DOCUMENT = "check_document"; + /** * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource, * java.util.List, @@ -62,9 +69,23 @@ public class VerificationFilterImpl implements VerificationFilter log.debug("Original IU blocks: " + blocks.size()); debugIUBlocks(blocks); } - + unrollLinearization(blocks); + // tzefferer: check document here + SettingsReader settings; + try { + settings = SettingsReader.getInstance(); + } catch (SettingsException e) { + throw new VerificationFilterException(e); + } + String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); + + if(check_doc.equalsIgnoreCase("true")) { + checkDocument(pdf, blocks, parameters); + } + // end add + if (log.isDebugEnabled()) { log.debug("IU blocks without linearization: " + blocks.size()); @@ -192,8 +213,10 @@ public class VerificationFilterImpl implements VerificationFilter protected List performSemiConservative(PdfDataSource pdf, boolean scanForOldSignatures, List blocks, List partitions) throws VerificationFilterException { + log.debug("perform semiConservative()..."); List binarySignatures = extractBinarySignaturesOnly(pdf, blocks); + log.debug("determining last partition..."); TextPartition lastTextPartition = VerificationFilterHelper.findLastTextPartition(partitions); List extractedSignatures = null; if (scanForOldSignatures) @@ -207,9 +230,11 @@ public class VerificationFilterImpl implements VerificationFilter } else { + log.debug("extracting signatures from last partition..."); extractedSignatures = extractSignaturesFromPartition(pdf, lastTextPartition); } - + + List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures); return signatureHolderChain; @@ -284,12 +309,16 @@ public class VerificationFilterImpl implements VerificationFilter } protected String extractText(PdfDataSource pdf, int endOfDocument) throws PresentableException + { + log.debug("EXTRACTING TEXT... end index = " + endOfDocument); + DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, endOfDocument); //DelimitedInputStream dis = new DelimitedInputStream(pdf.createInputStream(), endOfDocument); return PdfAS.extractNormalizedTextTextual(dds); } - + + protected List extractNewSignaturesFromText(String text) throws VerificationFilterException { try @@ -450,10 +479,12 @@ public class VerificationFilterImpl implements VerificationFilter log.debug("Extracting text from 0 to " + endOfDocument + " (total document size = " + pdf.getLength() + "):"); String extractedText = extractText(pdf, endOfDocument); log.debug("Extracting text finished."); + log.debug("extracted text: " + extractedText); log.debug("Extracting signatures:"); List extractedSignatures = extractNewSignaturesFromText(extractedText); log.debug("Extracting signatures finished."); + log.debug("Number of found signatures: " + extractedSignatures.size()); if (log.isDebugEnabled()) { @@ -519,6 +550,130 @@ public class VerificationFilterImpl implements VerificationFilter } } + // tzefferer: added method + protected void checkDocument(PdfDataSource pdf, List blocks, VerificationFilterParameters parameters) throws VerificationFilterException { + + boolean consider_old_sigs = parameters.scanForOldSignatures(); + boolean binary_only = parameters.extractBinarySignaturesOnly(); + boolean assume_sigs_only = parameters.assumeOnlySignatureUpdateBlocks(); + + if(binary_only) { + // check if document contains textual signatures + checkBinaryOnly(pdf, consider_old_sigs); + } + if(!assume_sigs_only) { + // check if document contains post-sign modifications + checkUpdateBlocks(pdf, blocks, consider_old_sigs); + } + } + // tzefferer: added method + protected void checkUpdateBlocks(PdfDataSource pdf, List blocks, boolean considerOldSigs) throws VerificationFilterException { + + boolean sig_detected = false; + + if(considerOldSigs) { + + DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength()); + String text = null; + try { + text = PdfAS.extractNormalizedTextTextual(dds); + } catch (PresentableException e) { + throw new VerificationFilterException(e); + } + + SignaturesAndOld sao = extractSignaturesAndOld(text); + + if((sao != null)&&(sao.oldSignature != null)) { + sig_detected = true; + } + } + + + Iterator it = blocks.iterator(); + String prev_text = null; + + while (it.hasNext()) + { + boolean sig_in_current_block = false; + + FooterParseResult fpr = (FooterParseResult) it.next(); + + DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, fpr.next_index); + + String text; + try { + text = PdfAS.extractNormalizedTextTextual(dds); + } catch (PresentableException e) { + throw new VerificationFilterException(e); + } + + if(prev_text == null) { + prev_text = text; + } else { + String texttmp = text.substring(prev_text.length()); + prev_text = text; + text = texttmp; + } + + List sig_holders = null; + try { + sig_holders = AbsoluteTextSignature.extractSignatureHoldersFromText(text); + } catch (SignatureException e) { + throw new VerificationFilterException(e); + } catch (SignatureTypesException e) { + throw new VerificationFilterException(e); + } + + if((sig_holders != null) && (sig_holders.size() > 0)) { + sig_detected = true; + sig_in_current_block = true; + } + + if((sig_detected) && (!sig_in_current_block)) { + throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed."); + } + } + } + // tzefferer: added method + protected void checkBinaryOnly(PdfDataSource pdf, boolean considerOldSigs) throws VerificationFilterException { + + DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength()); + String text = null; + try { + text = PdfAS.extractNormalizedTextTextual(dds); + } catch (PresentableException e) { + throw new VerificationFilterException(e); + } + + List sigs = new ArrayList(); + + if(considerOldSigs) { + SignaturesAndOld sao = extractSignaturesAndOld(text); + if(sao != null) { + if(sao.newSignatures != null) { + sigs.addAll(sao.newSignatures); + } + if(sao.oldSignature != null) { + sigs.add(sao.oldSignature); + } + } + } else { + List signatures = extractSignatures(pdf, pdf.getLength()); + if(signatures != null) { + sigs.addAll(signatures); + } + } + + Iterator it = sigs.iterator(); + while(it.hasNext()) { + SignatureHolder current = (SignatureHolder)it.next(); + if((current != null)&&(!current.getSignatureObject().isBinary())) { + throw new VerificationFilterException(ErrorCode.NON_BINARY_SIGNATURES_PRESENT, "The document contains non-binary signatures."); + } + } + } + + protected static class SignaturesAndOld { public List newSignatures = null; @@ -537,6 +692,7 @@ public class VerificationFilterImpl implements VerificationFilter log.debug("Extracting old signatures:"); SignatureHolder oldSignature = extractOldSignature(text, extractedSignatures); log.debug("Extracting old signatures finished."); + log.debug("oldSignature = null: " + (oldSignature==null)); SignaturesAndOld sao = new SignaturesAndOld(); sao.newSignatures = extractedSignatures; -- cgit v1.2.3