From d29da544e84d36170b8befe992dba71b99f28ba2 Mon Sep 17 00:00:00 2001 From: tknall Date: Mon, 7 Jan 2008 13:09:41 +0000 Subject: incremental update check reintroduced git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@244 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../pdfas/impl/vfilter/VerificationFilterImpl.java | 272 +++++++++++++-------- 1 file changed, 168 insertions(+), 104 deletions(-) (limited to 'src/main/java/at/gv') 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 d192f7a..2aa5c28 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 @@ -55,6 +55,8 @@ public class VerificationFilterImpl implements VerificationFilter // tzefferer: added public static final String CHECK_DOCUMENT = "check_document"; + public static final String BINARY_ONLY = "binary_only"; + public static final String ASSUME_ONLY_SIGNATURE_BLOCKS = "assume_only_signature_blocks"; /** * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource, @@ -81,6 +83,26 @@ public class VerificationFilterImpl implements VerificationFilter debugIUBlocks(blocks); } + + SettingsReader settings; + try { + settings = SettingsReader.getInstance(); + } catch (SettingsException e) { + throw new VerificationFilterException(e); + } + String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); + + // tzefferer: check document for textual sigs here here if binary_only is set + if ("true".equalsIgnoreCase(check_doc) && + parameters.extractBinarySignaturesOnly()) { + + checkBinaryOnly(pdf, parameters.scanForOldSignatures()); + log.debug("checkDocument: " + sw.getTime() + "ms."); + } else { + log.debug("Skipping checkDocument for textual sigs."); + } + // end add + List signatureHolderChain = null; if (parameters.extractBinarySignaturesOnly()) @@ -116,26 +138,7 @@ public class VerificationFilterImpl implements VerificationFilter sw.stop(); log.debug("extractSignatureHolders: " + sw.getTime() + "ms."); - SettingsReader settings; - try { - settings = SettingsReader.getInstance(); - } catch (SettingsException e) { - throw new VerificationFilterException(e); - } - String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); - - // tzefferer: check document here - // check doesn't make sense if we don't have any signatures - if (signatureHolderChain != null && !signatureHolderChain.isEmpty() && "true".equalsIgnoreCase(check_doc)) { - sw.reset(); - sw.start(); - checkDocument(pdf, blocks, parameters); - sw.stop(); - log.debug("checkDocument: " + sw.getTime() + "ms."); - } else { - log.debug("Skipping checkDocument."); - } - // end add + return signatureHolderChain; } @@ -268,10 +271,23 @@ public class VerificationFilterImpl implements VerificationFilter List flattedOutPartitions = flattenOutTextPartitions(partitions, blocks); partitions = flattedOutPartitions; + SettingsReader settings; + try { + settings = SettingsReader.getInstance(); + } catch (SettingsException e) { + throw new VerificationFilterException(e); + } + String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); + + // flags for determination of illegal incremental update + int sigs_found = 0; + int sigs_found_prev = 0; + List partitionResults = new ArrayList(partitions.size()); for (int i = 0; i < partitions.size(); i++) { Partition p = (Partition) partitions.get(i); + if (p instanceof TextPartition) { @@ -290,9 +306,27 @@ public class VerificationFilterImpl implements VerificationFilter { partitionResult = extractSignaturesFromPartition(pdf, tp); } - + + sigs_found_prev = sigs_found; + sigs_found = partitionResult.size(); partitionResults.add(partitionResult); + } else { + // should be binary partition + if(p instanceof BinaryPartition) { + BinaryPartition binpart = (BinaryPartition)p; + // add number (n) of found binary signatures - if there is a subsequent textual partition, + // at least n+1 sigs have to be found (note: sig-blocks of binary signatures are also extracted and detected) + sigs_found = sigs_found + binpart.blocks.size(); + + } } + + // throw an Exception if there were already signatures, but current block does not contain any signatures + if((check_doc.equalsIgnoreCase("true"))&& ((sigs_found_prev > 0) && !(sigs_found > sigs_found_prev)) ) { + log.error("Illegal document modification!"); + throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed."); + } + } List extractedSignatures = new ArrayList(); @@ -493,6 +527,16 @@ public class VerificationFilterImpl implements VerificationFilter */ protected List extractBinarySignaturesOnly(PdfDataSource pdf, List blocks) throws VerificationFilterException { + SettingsReader settings; + try { + settings = SettingsReader.getInstance(); + } catch (SettingsException e) { + throw new VerificationFilterException(e); + } + String check_doc = settings.getSetting(CHECK_DOCUMENT, "false"); + String binary_only = settings.getSetting(BINARY_ONLY, "false"); + String assume_sigs_only = settings.getSetting(ASSUME_ONLY_SIGNATURE_BLOCKS, "false"); + try { // PERF: extract binary signatures needs byte array @@ -502,6 +546,7 @@ public class VerificationFilterImpl implements VerificationFilter Iterator it = blocks.iterator(); int prev_end = 0; + boolean sig_detected = false; while (it.hasNext()) { FooterParseResult fpr = (FooterParseResult) it.next(); @@ -515,6 +560,24 @@ public class VerificationFilterImpl implements VerificationFilter List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end); binarySignatures.addAll(binary_holders); + if(binary_holders.size() > 0) { + sig_detected = true; + } + } else { + // an Exception is thrown here if: + // 1) check_document is activated + // 2) assume_only_signature_blocks is false - otherwise we permit updates + // 3) binary_only is true - otherwise updates are handled in method performFullConservative(). + // when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual + // signature either but an illegal update, otherwise an Exception (doc contains textual sig) would have been thrown before + // 4) a binary signature has been detected in a previous block + if(check_doc.equalsIgnoreCase("true") && + binary_only.equalsIgnoreCase("true") && + assume_sigs_only.equalsIgnoreCase("false") && + sig_detected) { + + throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed."); + } } prev_end = fpr.next_index; @@ -595,6 +658,7 @@ 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); SignaturesAndOld sao = extractSignaturesAndOld(extractedText); @@ -606,90 +670,90 @@ 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 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."); - } - } - } +// 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 { -- cgit v1.2.3