diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java | 272 | 
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 {
 | 
