diff options
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java | 594 | ||||
| -rw-r--r-- | src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java | 9 | 
2 files changed, 382 insertions, 221 deletions
| diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java index 44a13a4..02b1cd1 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java @@ -36,16 +36,23 @@ import java.util.Comparator;  import java.util.Iterator;
  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.pdf.CaptionNotFoundException;
  import at.gv.egiz.pdfas.exceptions.pdf.KZSettingNotFoundException;
  import at.gv.egiz.pdfas.framework.input.PdfDataSource;
  import at.gv.egiz.pdfas.framework.output.DataSink;
 +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
  import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
  import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException;
  import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
  import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException;
 +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
 +import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException;
  import at.knowcenter.wag.egov.egiz.sig.SignatureFieldDefinition;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition;
  import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
  import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
  import at.knowcenter.wag.exactparser.ByteArrayUtils;
 @@ -81,6 +88,7 @@ import com.lowagie.text.pdf.PdfTemplate;   */
  public abstract class BinarySignature
  {
 +  protected static Log logger = LogFactory.getLog(BinarySignature.class);
    /**
     * The tolerance area of the line break algorithm.
     * 
 @@ -194,6 +202,11 @@ public abstract class BinarySignature    public static final PdfName EGIZ_CERTIFICATE_NAME = new PdfName("Cert");
    /**
 +   * The PdfName of the data array that contains various egiz-dict data.
 +   */
 +  public static final PdfName EGIZ_DATA_NAME = new PdfName("Data");
 +
 +  /**
     * The PDFName of the Signature XObject field in an Egiz Dictionary.
     * 
     * <p>
 @@ -410,175 +423,183 @@ public abstract class BinarySignature    }
    // TODO old code - remove
 -  //  /**
 -  //   * Extracts the binary 'text' of a document.
 -  //   * 
 -  //   * <p>
 -  //   * If the document contains an Egiz Dictionary, which means that it is already
 -  //   * signed, the binary text is the Base64 coded string of the original document
 -  //   * followed by the Ascii representation of the signature block.
 -  //   * </p>
 -  //   * <p>
 -  //   * If the document does not contain an Egiz Dictionary, which means that it is
 -  //   * unsigned, only the binary Base64 coded original document is returned as
 -  //   * binary text.
 -  //   * </p>
 -  //   * <p>
 -  //   * This function is intented for being used instead of the "text extraction"
 -  //   * mechanism used in the plain text Egiz project.
 -  //   * </p>
 -  //   * 
 -  //   * @param doc
 -  //   *          The file.
 -  //   * @return Returns the binary text of the document.
 -  //   * @throws PDFDocumentException
 -  //   *           Forwarded exception.
 -  //   */
 -  //  public static String extractTextBinary(File doc) throws PDFDocumentException
 -  //  {
 -  //    try
 -  //    {
 -  //      FileInputStream fis = new FileInputStream(doc);
 -  //      return extractTextBinary(fis);
 -  //    }
 -  //    catch (FileNotFoundException e)
 -  //    {
 -  //      throw new PDFDocumentException(202, e);
 -  //    }
 -  //  }
 +  // /**
 +  // * Extracts the binary 'text' of a document.
 +  // *
 +  // * <p>
 +  // * If the document contains an Egiz Dictionary, which means that it is
 +  // already
 +  // * signed, the binary text is the Base64 coded string of the original
 +  // document
 +  // * followed by the Ascii representation of the signature block.
 +  // * </p>
 +  // * <p>
 +  // * If the document does not contain an Egiz Dictionary, which means that it
 +  // is
 +  // * unsigned, only the binary Base64 coded original document is returned as
 +  // * binary text.
 +  // * </p>
 +  // * <p>
 +  // * This function is intented for being used instead of the "text extraction"
 +  // * mechanism used in the plain text Egiz project.
 +  // * </p>
 +  // *
 +  // * @param doc
 +  // * The file.
 +  // * @return Returns the binary text of the document.
 +  // * @throws PDFDocumentException
 +  // * Forwarded exception.
 +  // */
 +  // public static String extractTextBinary(File doc) throws
 +  // PDFDocumentException
 +  // {
 +  // try
 +  // {
 +  // FileInputStream fis = new FileInputStream(doc);
 +  // return extractTextBinary(fis);
 +  // }
 +  // catch (FileNotFoundException e)
 +  // {
 +  // throw new PDFDocumentException(202, e);
 +  // }
 +  // }
    //
 -  //  /**
 -  //   * Extracts the text binary.
 -  //   * 
 -  //   * @param is
 -  //   * @return Returns the binary text.
 -  //   * @throws PDFDocumentException
 -  //   */
 -  //  public static String extractTextBinary(InputStream is) throws PDFDocumentException
 -  //  {
 -  //    try
 -  //    {
 -  //      // for some stupid reason this produces a read error if the is comes from
 -  //      // a
 -  //      // multipart servlet form..???
 -  //      ByteArrayOutputStream baos = new ByteArrayOutputStream();
 -  //      int i = -1;
 -  //      int acc = 0;
 -  //      byte[] b = new byte[1000];
 -  //      while ((i = is.read(b)) > 0)
 -  //      {
 -  //        acc += i;
 -  //        System.out.print(" " + i);
 -  //        baos.write(b, 0, i);
 -  //      }
 -  //      System.out.println("acc = " + acc);
 -  //      byte[] pdf = baos.toByteArray();
 +  // /**
 +  // * Extracts the text binary.
 +  // *
 +  // * @param is
 +  // * @return Returns the binary text.
 +  // * @throws PDFDocumentException
 +  // */
 +  // public static String extractTextBinary(InputStream is) throws
 +  // PDFDocumentException
 +  // {
 +  // try
 +  // {
 +  // // for some stupid reason this produces a read error if the is comes from
 +  // // a
 +  // // multipart servlet form..???
 +  // ByteArrayOutputStream baos = new ByteArrayOutputStream();
 +  // int i = -1;
 +  // int acc = 0;
 +  // byte[] b = new byte[1000];
 +  // while ((i = is.read(b)) > 0)
 +  // {
 +  // acc += i;
 +  // System.out.print(" " + i);
 +  // baos.write(b, 0, i);
 +  // }
 +  // System.out.println("acc = " + acc);
 +  // byte[] pdf = baos.toByteArray();
    //
 -  //      return extractTextBinary(pdf);
 -  //    }
 -  //    catch (IOException e)
 -  //    {
 -  //      throw new PDFDocumentException(202, e);
 -  //    }
 -  //  }
 +  // return extractTextBinary(pdf);
 +  // }
 +  // catch (IOException e)
 +  // {
 +  // throw new PDFDocumentException(202, e);
 +  // }
 +  // }
    //
 -  //  /**
 -  //   * Extracts the signable text from a binary pdf document.
 -  //   * 
 -  //   * <p>
 -  //   * The signable text is the text that will be signed or verified afterwards.
 -  //   * </p>
 -  //   * 
 -  //   * @param pdf
 -  //   *          The pdf document.
 -  //   * @return Returns the extracted text String.
 -  //   * @throws PDFDocumentException
 -  //   *           Forwarded exception.
 -  //   */
 -  //  public static String extractTextBinary(final byte[] pdf) throws PDFDocumentException
 -  //  {
 -  //    try
 -  //    {
 -  //      PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf));
 -  //      PdfDictionary egiz_dict = getEgizDictFromReader(reader);
 -  //      if (egiz_dict == null)
 -  //      {
 -  //        System.out.println("NO Egiz Dict found - whole doc = original doc");
 +  // /**
 +  // * Extracts the signable text from a binary pdf document.
 +  // *
 +  // * <p>
 +  // * The signable text is the text that will be signed or verified afterwards.
 +  // * </p>
 +  // *
 +  // * @param pdf
 +  // * The pdf document.
 +  // * @return Returns the extracted text String.
 +  // * @throws PDFDocumentException
 +  // * Forwarded exception.
 +  // */
 +  // public static String extractTextBinary(final byte[] pdf) throws
 +  // PDFDocumentException
 +  // {
 +  // try
 +  // {
 +  // PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf));
 +  // PdfDictionary egiz_dict = getEgizDictFromReader(reader);
 +  // if (egiz_dict == null)
 +  // {
 +  // System.out.println("NO Egiz Dict found - whole doc = original doc");
    //
 -  //        int ods = pdf.length;
 -  //        return retrieveSignableTextFromData(pdf, ods);
 -  //      }
 +  // int ods = pdf.length;
 +  // return retrieveSignableTextFromData(pdf, ods);
 +  // }
    //
 -  //      String sig_text = extractSignatureTextOnly(egiz_dict);
 +  // String sig_text = extractSignatureTextOnly(egiz_dict);
    //
 -  //      int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict);
 +  // int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict);
    //
 -  //      String raw_text = retrieveSignableTextFromData(pdf, ods);
 -  //      raw_text += "\n";
 -  //      raw_text += sig_text;
 +  // String raw_text = retrieveSignableTextFromData(pdf, ods);
 +  // raw_text += "\n";
 +  // raw_text += sig_text;
    //
 -  //      return raw_text;
 -  //    }
 -  //    catch (IOException e)
 -  //    {
 -  //      throw new PDFDocumentException(202, e);
 -  //    }
 -  //  }
 +  // return raw_text;
 +  // }
 +  // catch (IOException e)
 +  // {
 +  // throw new PDFDocumentException(202, e);
 +  // }
 +  // }
    // TODO obsolete code - remove
 -  //  /**
 -  //   * Retrieves the List of SignatureHolders containing the information of all
 -  //   * digital signatures of the given document.
 -  //   * 
 -  //   * <p>
 -  //   * If the List of SignatureHolders is empty, the document is not signed
 -  //   * anyways.
 -  //   * </p>
 -  //   * 
 -  //   * @param pdf
 -  //   *          The complete pdf document.
 -  //   * @return Returns the List of SignatureHolders.
 -  //   * @throws PDFDocumentException
 -  //   * @throws SignatureTypesException
 -  //   * @throws SignatureException
 -  //   */
 -  //  public static List extractSignatureHoldersBinary(final byte[] pdf) throws PDFDocumentException, SignatureTypesException, SignatureException
 -  //  {
 -  //    try
 -  //    {
 -  //      PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf));
 -  //      List chain = getEgizDictChainFromReader(reader);
 +  // /**
 +  // * Retrieves the List of SignatureHolders containing the information of all
 +  // * digital signatures of the given document.
 +  // *
 +  // * <p>
 +  // * If the List of SignatureHolders is empty, the document is not signed
 +  // * anyways.
 +  // * </p>
 +  // *
 +  // * @param pdf
 +  // * The complete pdf document.
 +  // * @return Returns the List of SignatureHolders.
 +  // * @throws PDFDocumentException
 +  // * @throws SignatureTypesException
 +  // * @throws SignatureException
 +  // */
 +  // public static List extractSignatureHoldersBinary(final byte[] pdf) throws
 +  // PDFDocumentException, SignatureTypesException, SignatureException
 +  // {
 +  // try
 +  // {
 +  // PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf));
 +  // List chain = getEgizDictChainFromReader(reader);
    //
 -  //      List signatures = new ArrayList();
 -  //      Iterator it = chain.iterator();
 -  //      while (it.hasNext())
 -  //      {
 -  //        PdfDictionary dict = (PdfDictionary) it.next();
 +  // List signatures = new ArrayList();
 +  // Iterator it = chain.iterator();
 +  // while (it.hasNext())
 +  // {
 +  // PdfDictionary dict = (PdfDictionary) it.next();
    //
 -  //        int ods = getOriginalDocumentSizeFromEgizDict(dict);
 -  //        String signature_text = extractSignatureTextOnly(dict);
 +  // int ods = getOriginalDocumentSizeFromEgizDict(dict);
 +  // String signature_text = extractSignatureTextOnly(dict);
    //
 -  //        SignatureTypes sig_types = SignatureTypes.getInstance();
 -  //        List types = sig_types.getSignatureTypeDefinitions();
 -  //        SignatureBlock sig_block = new SignatureBlock(types);
 -  //        boolean could_separate = sig_block.separateBlockFromRawText(signature_text, false);
 +  // SignatureTypes sig_types = SignatureTypes.getInstance();
 +  // List types = sig_types.getSignatureTypeDefinitions();
 +  // SignatureBlock sig_block = new SignatureBlock(types);
 +  // boolean could_separate = sig_block.separateBlockFromRawText(signature_text,
 +  // false);
    //
 -  //        if (could_separate)
 -  //        {
 -  //          SignatureObject sig_object = sig_block.getSignatureObject();
 +  // if (could_separate)
 +  // {
 +  // SignatureObject sig_object = sig_block.getSignatureObject();
    //
 -  //          SignatureHolder holder = new BinarySignatureHolder(pdf, ods, sig_object);
 -  //          signatures.add(holder);
 -  //        }
 -  //      }
 +  // SignatureHolder holder = new BinarySignatureHolder(pdf, ods, sig_object);
 +  // signatures.add(holder);
 +  // }
 +  // }
    //
 -  //      return signatures;
 -  //    }
 -  //    catch (IOException e)
 -  //    {
 -  //      throw new PDFDocumentException(201, e);
 -  //    }
 -  //  }
 +  // return signatures;
 +  // }
 +  // catch (IOException e)
 +  // {
 +  // throw new PDFDocumentException(201, e);
 +  // }
 +  // }
    // /**
    // * Signs a document with the given signature table using the Incremental
 @@ -645,6 +666,26 @@ public abstract class BinarySignature    // throw new PresentableException(e);
    // }
    // }
 +  
 +  protected static int getCertificatePlaceholderLength(IncrementalUpdateInformation iui) throws SettingNotFoundException
 +  {
 +    SettingsReader settings;
 +    try
 +    {
 +      settings = SettingsReader.getInstance();
 +    }
 +    catch (SettingsException e)
 +    {
 +      throw new SettingNotFoundException(e);
 +    }
 +    String certPhLen = SignatureTypeDefinition.readPhLenStringFromSettings(settings, iui.signProfile, "certificate");
 +    int certLen = CERTIFICATE_PLACEHOLDER_LENGTH;
 +    if (certPhLen != null)
 +    {
 +      certLen = Integer.parseInt(certPhLen);
 +    }
 +    return certLen;
 +  }
    /**
     * Signs a document with the given signature table using the Incremental
 @@ -673,31 +714,38 @@ public abstract class BinarySignature     * @param pi
     *          The PositioningInstruction telling the algorithm where to place
     *          the signature block.
 +   * @param invisible_field_definitions
 +   *          List of invisible field definitions to be added to the egiz dict.
 +   *          May be null or empty, if there are no invisible fields.
 +   * @param invisibleKZString
 +   *          If not null, thins String is the KZ String to be written into the
 +   *          /Data array.
     * @return Returns the new document.
     * @throws PresentableException
     *           Forwarded exception.
     */
 -  public static IncrementalUpdateInformation writeIncrementalUpdate(PdfDataSource original_document, DataSink written_pdf, PdfPTable pdf_table, PositioningInstruction pi,
 -      List variable_field_definitions, List all_field_definitions) throws PresentableException
 +  public static IncrementalUpdateInformation writeIncrementalUpdate(PdfDataSource original_document, DataSink written_pdf, PdfPTable pdf_table, String profile, PositioningInstruction pi,
 +      List variable_field_definitions, List all_field_definitions, List invisible_field_definitions, String invisibleKZString) throws PresentableException
    {
      try
      {
        IncrementalUpdateInformation iui = new IncrementalUpdateInformation();
        iui.original_document = original_document;
        iui.start_index = original_document.getLength();
 +      iui.signProfile = profile;
        Document.compress = false;
        // System.out.println("wprinz: STAMPING PDF");
 -      //InputStream is = original_document.createInputStream();
 -      byte [] pdf_data = original_document.getAsByteArray();
 +      // InputStream is = original_document.createInputStream();
 +      byte[] pdf_data = original_document.getAsByteArray();
        PdfReader reader = new PdfReader(pdf_data);
 -      //is.close();
 +      // is.close();
        OutputStream baos = written_pdf.createOutputStream("application/pdf");
        // ByteArrayOutputStream baos = new ByteArrayOutputStream();
 -      
 +
        // IMPORTANT: append the new content to the original document using
        // incremental updated
        // The stamper allows this by setting append = true
 @@ -738,7 +786,7 @@ public abstract class BinarySignature        // table_position, content);
        content.addTemplate(table_template, pi.getX(), pi.getY() - pdf_table.getTotalHeight());
 -      
 +
        ActualTablePos atp = new ActualTablePos();
        atp.page = pi.getPage();
        atp.x = pi.getX();
 @@ -793,7 +841,7 @@ public abstract class BinarySignature        // add the EGIZ dict:
        if (variable_field_definitions != null)
        {
 -        createEgizDict(stamper, table_template, iui, variable_field_definitions, all_field_definitions);
 +        createEgizDict(stamper, table_template, iui, variable_field_definitions, all_field_definitions, invisible_field_definitions, invisibleKZString);
        }
        stamper.close();
 @@ -830,10 +878,10 @@ public abstract class BinarySignature     *          The field definitions.
     * @throws IOException
     * @throws SettingNotFoundException
 -   * @throws CaptionNotFoundException 
 +   * @throws CaptionNotFoundException
     */
 -  protected static void createEgizDict(PdfStamper stamper, PdfTemplate table_template, IncrementalUpdateInformation iui, List variable_field_definitions, List all_field_definitions)
 -      throws IOException, SettingNotFoundException, CaptionNotFoundException
 +  protected static void createEgizDict(PdfStamper stamper, PdfTemplate table_template, IncrementalUpdateInformation iui, List variable_field_definitions, List all_field_definitions,
 +      List invisible_field_definitions, String invisibleKZString) throws IOException, SettingNotFoundException, CaptionNotFoundException
    {
      // iui.temp_ir = table_template.getIndirectReference();
      iui.temp_ir_number = table_template.getIndirectReference().getNumber();
 @@ -843,7 +891,19 @@ public abstract class BinarySignature      iui.content_stream_length = content_stream.length;
      iui.replaces = determineReplacesInContentStream(content_stream, 0, content_stream.length, variable_field_definitions);
 -    iui.kz_list = determineKZ(content_stream, 0, content_stream.length, all_field_definitions);
 +    if (invisibleKZString == null)
 +    {
 +      iui.kz_list = determineKZ(content_stream, 0, content_stream.length, all_field_definitions);
 +    }
 +    else
 +    {
 +      StringInfo si = new StringInfo();
 +      si.string_start = -1;
 +      si.string_length = invisibleKZString.length();
 +
 +      iui.kz_list = new ArrayList();
 +      iui.kz_list.add(si);
 +    }
      // PdfIndirectReference previous_egiz_dict_ind_ref =
      // getEgizDictIndRefFromReader(reader);
 @@ -852,6 +912,7 @@ public abstract class BinarySignature      egiz_dict.put(EGIZ_XOBJ_NAME, table_template.getIndirectReference());
      egiz_dict.put(EGIZ_ODS_NAME, NUMBER_PLACEHOLDER);
 +    // /ID
      PdfArray kz_array = new PdfArray();
      for (int i = 0; i < iui.kz_list.size(); i++)
      {
 @@ -860,10 +921,16 @@ public abstract class BinarySignature      }
      egiz_dict.put(EGIZ_KZ_NAME, kz_array);
 +    // ByteRanges
      int num_replaces = calcNumReps(iui.replaces);
      int num_holes = num_replaces + 1 + 1;
      // +1 = the /encodings hole
      // +1 = the /Cert
 +    boolean has_hidden_variable_fields = invisible_field_definitions != null && !invisible_field_definitions.isEmpty();
 +    if (has_hidden_variable_fields)
 +    {
 +      num_holes += invisible_field_definitions.size();
 +    }
      int num_byte_ranges = num_holes + 1;
      PdfArray byte_ranges_array = new PdfArray();
 @@ -886,6 +953,36 @@ public abstract class BinarySignature      replaces_array.add(new PdfName(new String(BREV_NIL, "US-ASCII"))); // the
      // /Cert
 +    // hidden replaces
 +    List hidden_replaces = null;
 +    if (has_hidden_variable_fields)
 +    {
 +      hidden_replaces = new ArrayList();
 +
 +      Iterator it = invisible_field_definitions.iterator();
 +      while (it.hasNext())
 +      {
 +        SignatureFieldDefinition sfd = (SignatureFieldDefinition) it.next();
 +        byte[] brev = typeToBrev(sfd.field_name);
 +        encodings_array.add(new PdfName(new String(ENCODING_WIN, "US-ASCII")));
 +        replaces_array.add(new PdfName(new String(brev, "US-ASCII")));
 +
 +        ReplaceInfo ri = new ReplaceInfo();
 +        ri.brev = brev;
 +        ri.enc = ENCODING_WIN;
 +        ri.sfd = sfd;
 +        ri.replaces = new ArrayList();
 +
 +        StringInfo si = new StringInfo();
 +        si.string_start = -1; // to be determined later on
 +        si.string_length = sfd.placeholder_length;
 +        ri.replaces.add(si);
 +
 +        hidden_replaces.add(ri);
 +      }
 +    }
 +
 +    // content stream replaces
      Iterator it = iui.replaces.iterator();
      while (it.hasNext())
      {
 @@ -893,11 +990,8 @@ public abstract class BinarySignature        for (int i = 0; i < ri.replaces.size(); i++)
        {
          byte[] brev = typeToBrev(ri.sfd.field_name);
 -        String brev_string = new String(brev, "US-ASCII");
 -        PdfName brev_name = new PdfName(brev_string);
 -        replaces_array.add(brev_name);
 -
          encodings_array.add(new PdfName(new String(ENCODING_WIN, "US-ASCII")));
 +        replaces_array.add(new PdfName(new String(brev, "US-ASCII")));
        }
      }
      egiz_dict.put(EGIZ_REPLACES_NAME, replaces_array);
 @@ -905,20 +999,48 @@ public abstract class BinarySignature      egiz_dict.put(EGIZ_ENCODINGS_NAME, encodings_array);
      PdfArray cert_array = new PdfArray();
 -    byte[] cert_bytes = new byte[CERTIFICATE_PLACEHOLDER_LENGTH];
 +    iui.cert_length = getCertificatePlaceholderLength(iui);
 +    byte[] cert_bytes = new byte[iui.cert_length];
      for (int i = 0; i < cert_bytes.length; i++)
      {
        cert_bytes[i] = 0;
      }
      PdfString cert_placeholder = new PdfString(cert_bytes);
      cert_array.add(cert_placeholder);
 -    egiz_dict.put(EGIZ_CERTIFICATE_NAME, cert_array);
 +    egiz_dict.put(EGIZ_CERTIFICATE_NAME, cert_array); 
 +
 +    
 +    // /Data array with hidden information
 +    if (has_hidden_variable_fields || invisibleKZString != null)
 +    {
 +      PdfArray hidden_fields_array = new PdfArray();
 +
 +      if (invisibleKZString != null)
 +      {
 +        PdfString str = new PdfString(invisibleKZString);
 +        hidden_fields_array.add(str);
 +      }
 +
 +      if (has_hidden_variable_fields)
 +      {
 +        iui.replaces.addAll(0, hidden_replaces);
 +
 +        for (int i = 0; i < invisible_field_definitions.size(); i++)
 +        {
 +          SignatureFieldDefinition sfd = (SignatureFieldDefinition) invisible_field_definitions.get(i);
 +          byte[] placeholder = new byte[sfd.placeholder_length];
 +          for (int phIdx = 0; phIdx < placeholder.length; phIdx++)
 +          {
 +            placeholder[phIdx] = SIGN_PLACEHOLDER;
 +          }
 +          PdfString str = new PdfString(placeholder);
 +          hidden_fields_array.add(str);
 +        }
 +      }
 +
 +      egiz_dict.put(EGIZ_DATA_NAME, hidden_fields_array);
 +    }
 -    // if (previous_egiz_dict_ind_ref != null)
 -    // {
 -    // egiz_dict.put(PdfName.PREV, previous_egiz_dict_ind_ref);
 -    // }
 -    // no EGIZ chain
      PdfIndirectObject dict_ref = stamper.getWriter().addToBody(egiz_dict);
      // iui.egiz_dict_ir = dict_ref.getIndirectReference();
 @@ -1024,29 +1146,17 @@ public abstract class BinarySignature        replaceNumber(signed_pdf, ods_start, signed_pdf.length, num_digits);
 -      // update the Kennzeichnung byte ranges
 -      int cur_pos = kz_start;
 -      for (int i = 0; i < iui.kz_list.size(); i++)
 -      {
 -        StringInfo si = (StringInfo) iui.kz_list.get(i);
 -        replaceNumber(signed_pdf, cur_pos, si.string_start, num_digits);
 -        cur_pos += num_digits;
 -        cur_pos += 1;
 -        replaceNumber(signed_pdf, cur_pos, si.string_length, num_digits);
 -        cur_pos += num_digits;
 -        cur_pos += 1;
 -      }
 -
 -      int num_replaces = calcNumReps(iui.replaces);
 -      int num_holes = num_replaces + 1 + 1; // +1 = the /encodings hole
 -      // int num_byte_ranges = num_holes + 1;
 -
 -      cur_pos = array_start;
 +      int cur_pos = array_start;
        int cur_br_start = 0;
        // write the /encodings byte range
        {
 +        int num_replaces = calcNumReps(iui.replaces);
 +        int num_holes = num_replaces + 1 + 1;
 +        // +1 = the /encodings hole
 +        // +1 = the /Cert
 +
          int enc_length = (1 + 3) * num_holes;
          StringInfo byte_range = new StringInfo();
 @@ -1069,8 +1179,6 @@ public abstract class BinarySignature        // write the /Cert byte range
        {
 -        int cert_length = CERTIFICATE_PLACEHOLDER_LENGTH;
 -
          StringInfo byte_range = new StringInfo();
          byte_range.string_start = cur_br_start;
          byte_range.string_length = cert_start - cur_br_start;
 @@ -1083,10 +1191,39 @@ public abstract class BinarySignature          cur_pos += num_digits;
          cur_pos += 1;
 -        cur_br_start = cert_start + cert_length;
 +        cur_br_start = cert_start + iui.cert_length;
          iui.cert_start = cert_start;
 -        iui.cert_length = cert_length;
 +      }
 +
 +      // determine the /Data byte ranges if any
 +      List ifd = iui.invisible_field_definitions;
 +      if (!ifd.isEmpty() || iui.invisibleKZString != null)
 +      {
 +        String data_str = "/Data[(";
 +        byte[] data_bytes = data_str.getBytes("US-ASCII");
 +        int data_index = ByteArrayUtils.indexOf(signed_pdf, obj_start, data_bytes);
 +        int data_start = data_index + data_bytes.length;
 +
 +        int hole_start = data_start;
 +
 +        if (iui.invisibleKZString != null)
 +        {
 +          StringInfo si = (StringInfo) iui.kz_list.get(0);
 +          si.string_start = hole_start;
 +          
 +          hole_start += si.string_length + 2;
 +        }
 +
 +        for (int i = 0; i < ifd.size(); i++)
 +        {
 +          ReplaceInfo ri = (ReplaceInfo) iui.replaces.get(i);
 +          StringInfo si = (StringInfo) ri.replaces.get(0);
 +          si.string_start = hole_start;
 +
 +          hole_start += si.string_length + 2;
 +        }
 +
        }
        Iterator rit = iui.replaces.iterator();
 @@ -1131,6 +1268,21 @@ public abstract class BinarySignature        cur_pos += num_digits;
        cur_pos += 1;
 +      
 +      // update the Kennzeichnung byte ranges
 +      cur_pos = kz_start;
 +      for (int i = 0; i < iui.kz_list.size(); i++)
 +      {
 +        StringInfo si = (StringInfo) iui.kz_list.get(i);
 +
 +        replaceNumber(signed_pdf, cur_pos, si.string_start, num_digits);
 +        cur_pos += num_digits;
 +        cur_pos += 1;
 +        replaceNumber(signed_pdf, cur_pos, si.string_length, num_digits);
 +        cur_pos += num_digits;
 +        cur_pos += 1;
 +      }
 +
      }
      catch (IOException e)
      {
 @@ -1316,7 +1468,7 @@ public abstract class BinarySignature     *          where varaible strings are.
     * @return Returns the list of ReplaceInfo objects specifying the variable
     *         areas.
 -   * @throws CaptionNotFoundException 
 +   * @throws CaptionNotFoundException
     */
    protected static List determineReplacesInContentStream(final byte[] pdf, int begin, int end, List field_definitions) throws CaptionNotFoundException
    {
 @@ -1730,30 +1882,30 @@ public abstract class BinarySignature    }
    // TODO old code - remove
 -  //  /**
 -  //   * For debugging purposes.
 -  //   * 
 -  //   * @param args
 -  //   * @throws IOException
 -  //   */
 -  //  public static void main(String[] args) throws IOException
 -  //  {
 -  //    File signed_doc = new File("C:/wprinz/temp.pdf");
 +  // /**
 +  // * For debugging purposes.
 +  // *
 +  // * @param args
 +  // * @throws IOException
 +  // */
 +  // public static void main(String[] args) throws IOException
 +  // {
 +  // File signed_doc = new File("C:/wprinz/temp.pdf");
    //
 -  //    PdfReader reader = new PdfReader(new FileInputStream(signed_doc));
 -  //    PdfDictionary egiz_dict = getEgizDictFromReader(reader);
 -  //    if (egiz_dict == null)
 -  //    {
 -  //      System.out.println("NO Egiz Dict");
 -  //      return;
 -  //    }
 +  // PdfReader reader = new PdfReader(new FileInputStream(signed_doc));
 +  // PdfDictionary egiz_dict = getEgizDictFromReader(reader);
 +  // if (egiz_dict == null)
 +  // {
 +  // System.out.println("NO Egiz Dict");
 +  // return;
 +  // }
    //
 -  //    String sig_text = extractSignatureTextOnly(egiz_dict);
 -  //    System.out.println("Sig Text:");
 -  //    System.out.println(sig_text);
 +  // String sig_text = extractSignatureTextOnly(egiz_dict);
 +  // System.out.println("Sig Text:");
 +  // System.out.println(sig_text);
    //
 -  //    int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict);
 -  //    System.out.println("Original Document Size = " + ods);
 -  //  }
 +  // int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict);
 +  // System.out.println("Original Document Size = " + ods);
 +  // }
  }
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java index 77f1150..4352847 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java @@ -178,4 +178,13 @@ public class IncrementalUpdateInformation implements Serializable     */
    public ActualTablePos actualTablePos;
 +  /**
 +   * The field definitions of invisible fields, which data should be stored in /Data.
 +   */
 +  public List invisible_field_definitions;
 +  
 +  /**
 +   * The invisible KZ String, if KZ is invisible.
 +   */
 +  public String invisibleKZString = null;
  }
 | 
