aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java272
1 files changed, 168 insertions, 104 deletions
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 {