aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/knowcenter/wag
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-lib/src/main/java/at/knowcenter/wag')
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java245
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/CircularIncludeException.java44
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/NestedProperties.java255
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/PropertyTree.java82
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java207
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java116
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java29
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java11
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java15
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java4
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java215
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java249
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java70
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java25
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java47
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java56
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java62
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java43
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java68
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java85
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java82
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java84
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java71
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java73
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java59
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java60
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java60
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java68
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java71
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java70
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java171
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java167
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java32
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java81
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java47
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java75
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java122
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java68
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java48
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java104
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java108
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java53
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/signaturelayout/mocca/MoccaXades14SignatureLayoutHandler.java53
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java34
48 files changed, 2989 insertions, 1088 deletions
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
index fa9d4c1..2681f80 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
@@ -115,7 +115,7 @@ public abstract class PdfAS
* The current version of the pdf-as library. This version string is logged on every invocation
* of the api or the web application.
*/
- public static final String PDFAS_VERSION = "3.3-SNAPSHOT";
+ public static final String PDFAS_VERSION = "3.3";
/**
* The key of the strict mode setting.
@@ -1306,122 +1306,135 @@ public abstract class PdfAS
*/
public static PositioningInstruction adjustSignatureTableandCalculatePosition(final PdfDataSource pdfDataSource, PdfPTable pdf_table, TablePos pos) throws PDFDocumentException
{
- // first check pageinstruction in TablePos-object
- // new,auto,absolut
- PdfReader reader = readInPdfDocument(pdfDataSource);
- PDFASUtils.checkReaderPermissions(reader);
- // get pages of currentdocument
- int doc_pages = reader.getNumberOfPages();
- int page = doc_pages;
- boolean make_new_page = pos.isNewPage();
- if (!(pos.isNewPage() || pos.isPauto()))
- {
- // we should posit signaturtable on this page
-
- page = pos.getPage();
- // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages);
- if (page > doc_pages)
- {
- make_new_page = true;
- page = doc_pages;
- // throw new PDFDocumentException(227, "Page number is to big(=" + page+
- // ") cannot be parsed.");
- }
- }
-
- // getPagedimensions
- Rectangle psize = reader.getPageSizeWithRotation(page);
- int page_rotation = reader.getPageRotation(page);
-
- float page_width = psize.getWidth();
- float page_height = psize.getHeight();
- // now we can calculate x-position
- float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL;
- if (!pos.isXauto())
- {
- // we do have absolute x
- pre_pos_x = pos.getPosX();
- }
- // calculate width
- // center
- float pre_width = page_width - 2*pre_pos_x;
- if (!pos.isWauto())
- {
- // we do have absolute width
- pre_width = pos.getWidth();
- if (pos.isXauto())
- { // center x
- pre_pos_x = (page_width - pre_width) / 2;
- }
- }
- final float pos_x = pre_pos_x;
- final float width = pre_width;
- // Signatur table dimensions are complete
- pdf_table.setTotalWidth(width);
- pdf_table.setLockedWidth(true);
-
- final float table_height = pdf_table.getTotalHeight();
- // now check pos_y
- float pos_y = pos.getPosY();
- if (!pos.isYauto())
- {
- // we do have y-position too --> all parameters but page ok
- if (make_new_page)
- {
- page++;
- }
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
- }
- // pos_y is auto
- if (make_new_page)
- {
- // ignore footer in new page
- page++;
- pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
- }
- // up to here no checks have to be made if Tablesize and Pagesize are fit
- // Now we have to getfreespace in page and reguard footerline
- float footer_line = pos.getFooterLine();
- float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, page_rotation);
- if (pre_page_length == Float.NEGATIVE_INFINITY)
- {
- // we do have an empty page or nothing in area above footerline
- pre_page_length = page_height;
- // no text --> SIGNATURE_BORDER
- pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
- if (pos_y - footer_line <= table_height)
- {
- make_new_page = true;
- if (!pos.isPauto())
- {
- // we have to correct pagenumber
- page = reader.getNumberOfPages();
- }
- page++;
- // no text --> SIGNATURE_BORDER
- pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
- }
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
- }
- final float page_length = pre_page_length;
- // we do have text take SIGNATURE_MARGIN
- pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL;
- if (pos_y - footer_line <= table_height)
- {
- make_new_page = true;
- if (!pos.isPauto())
- {
- // we have to correct pagenumber in case of absolute page and not enough
- // space
- page = reader.getNumberOfPages();
- }
- page++;
- // no text --> SIGNATURE_BORDER
- pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
- }
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ PdfReader reader = null;
+ try {
+ reader = PDFASUtils.createPdfReaderCheckingPermissions(pdfDataSource);
+ // get pages of currentdocument
+ int doc_pages = reader.getNumberOfPages();
+ int page = doc_pages;
+ boolean make_new_page = pos.isNewPage();
+ if (!(pos.isNewPage() || pos.isPauto()))
+ {
+ // we should posit signaturtable on this page
+
+ page = pos.getPage();
+ // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages);
+ if (page > doc_pages)
+ {
+ make_new_page = true;
+ page = doc_pages;
+ // throw new PDFDocumentException(227, "Page number is to big(=" + page+
+ // ") cannot be parsed.");
+ }
+ }
+
+ // getPagedimensions
+ Rectangle psize = reader.getPageSizeWithRotation(page);
+ int page_rotation = reader.getPageRotation(page);
+
+ float page_width = psize.getWidth();
+ float page_height = psize.getHeight();
+
+ // now we can calculate x-position
+ float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL;
+ if (!pos.isXauto())
+ {
+ // we do have absolute x
+ pre_pos_x = pos.getPosX();
+ }
+ // calculate width
+ // center
+ float pre_width = page_width - 2*pre_pos_x;
+ if (!pos.isWauto())
+ {
+ // we do have absolute width
+ pre_width = pos.getWidth();
+ if (pos.isXauto())
+ { // center x
+ pre_pos_x = (page_width - pre_width) / 2;
+ }
+ }
+ final float pos_x = pre_pos_x;
+ final float width = pre_width;
+ // Signatur table dimensions are complete
+ pdf_table.setTotalWidth(width);
+ pdf_table.setLockedWidth(true);
+
+ final float table_height = pdf_table.getTotalHeight();
+ // now check pos_y
+ float pos_y = pos.getPosY();
+
+ // in case an absolute y position is already given OR
+ // if the table is related to an invisible signature
+ // there is no need for further calculations
+ // (fixed adding new page in case of invisible signatures)
+ if (!pos.isYauto() || table_height == 0)
+ {
+ // we do have y-position too --> all parameters but page ok
+ if (make_new_page)
+ {
+ page++;
+ }
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
+ // pos_y is auto
+ if (make_new_page)
+ {
+ // ignore footer in new page
+ page++;
+ pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
+ // up to here no checks have to be made if Tablesize and Pagesize are fit
+ // Now we have to getfreespace in page and reguard footerline
+ float footer_line = pos.getFooterLine();
+ float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, page_rotation);
+ if (pre_page_length == Float.NEGATIVE_INFINITY)
+ {
+ // we do have an empty page or nothing in area above footerline
+ pre_page_length = page_height;
+ // no text --> SIGNATURE_BORDER
+ pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+ if (pos_y - footer_line <= table_height)
+ {
+ make_new_page = true;
+ if (!pos.isPauto())
+ {
+ // we have to correct pagenumber
+ page = reader.getNumberOfPages();
+ }
+ page++;
+ // no text --> SIGNATURE_BORDER
+ pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+ }
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
+ final float page_length = pre_page_length;
+ // we do have text take SIGNATURE_MARGIN
+ pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL;
+ if (pos_y - footer_line <= table_height)
+ {
+ make_new_page = true;
+ if (!pos.isPauto())
+ {
+ // we have to correct pagenumber in case of absolute page and not enough
+ // space
+ page = reader.getNumberOfPages();
+ }
+ page++;
+ // no text --> SIGNATURE_BORDER
+ pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+ }
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ }
+ }
+ }
}
// /**
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/CircularIncludeException.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/CircularIncludeException.java
new file mode 100644
index 0000000..6ff7d3a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/CircularIncludeException.java
@@ -0,0 +1,44 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.cfg;
+
+/**
+ * Exception indicating that circular includes were detected.
+ *
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public class CircularIncludeException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public CircularIncludeException() {
+ super();
+ }
+
+ public CircularIncludeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/NestedProperties.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/NestedProperties.java
new file mode 100644
index 0000000..259a1dc
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/NestedProperties.java
@@ -0,0 +1,255 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.cfg;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOCase;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Enhanced Java Properties allowing nested include instructions.<br/>
+ * In order to include further Properties use the following instruction:
+ * <p/>
+ * <code>include = [path/to/]foo.properties</code>
+ * <p/>
+ * Note that wildcard imports are allowed, e.g.
+ * <p/>
+ * <code>include = [path/to/]profile.*.properties</code>
+ * <p/>
+ * In order to use more than one include instruction within a file append an arbitary postfix to <code>include.</code>
+ * in order to make each include key unique within a properties file, e.g.
+ * <p/>
+ * <code>include = profile.SIGNATURBLOCK*.properties</code><br/>
+ * <code>include.amtssignaturen = profile.AMTSSIGNATURBLOCK*.properties</code><br/>
+ * <code>include.1 = myProfiles1/*.properties</code><br/>
+ * <code>include.2 = myProfiles2/*.properties</code>
+ * <p/>
+ * Note that
+ * <ul>
+ * <li>all include instructions of a certain properties file are sorted alphabetically by their key name before being
+ * executed,</li>
+ * <li>include instructions can be used within any properties files being loaded (even within other includes) and that</li>
+ * <li>(wildcard) path/file declarations are always case <b>insensitive</b>, regardless of the underlying operating
+ * system.</li>
+ * <li>included properties always override locally defined properties</li>
+ * </ul>
+ * <p/>
+ * <b>Mind creating circular includes!</b>
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public class NestedProperties extends Properties {
+
+ private static final long serialVersionUID = 1L;
+
+ private Log log = LogFactory.getLog(getClass());
+
+ /**
+ * Creates an empty property list with no default values.
+ */
+ public NestedProperties() {
+ super();
+ }
+
+ /**
+ * Creates an empty property list with the specified defaults.
+ * @param defaults The defaults.
+ */
+ public NestedProperties(Properties defaults) {
+ super(defaults);
+ }
+
+ /**
+ * The name of the key that triggers including of other properties.
+ */
+ private final String INCLUDE_KEY_NAME = "include";
+
+ /**
+ * Defines the default behaviour of the file matching filter.
+ */
+ private final IOCase DEFAULT_IOCASE = IOCase.SENSITIVE;
+
+ /**
+ * The maximum depth of includes before being regarded as circular (throwing a {@link CircularIncludeException}).
+ */
+ private final int MAX_NESTED_INCLUDE_DEPTH = 25;
+
+ @Override
+ /**
+ * Warning: When Properties are loaded using InputStreams include instructions are not supported.
+ */
+ public synchronized void load(InputStream inStream) throws IOException {
+ log.debug("Loading properties from input stream. Include instructions are not supported.");
+ super.load(inStream);
+ }
+
+ @Override
+ public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException {
+ // Loading from InputStream is not supported since including further property files that have been declared
+ // using relative paths need a context directory which cannot be retrieved from InputStreams.
+ throw new UnsupportedOperationException("Imports from XML files are not supported.");
+ }
+
+ /**
+ * Reads a property list from a certain file including other properties files if include instructions are present.
+ * Note that include instructions that do not match any files do not result in an exception. A respective message at
+ * WARN level is logged.
+ *
+ * @param file
+ * The file to be read.
+ * @throws IOException
+ * Thrown in case of an I/O error.
+ * @throws CircularIncludeException
+ * Thrown if circular includes have been detected (@link {@link RuntimeException}).
+ */
+ public synchronized void load(File file) throws IOException, CircularIncludeException {
+ load(file, 0);
+ }
+
+ /**
+ * Reads a property list from a certain file including other properties files if include instructions are present.
+ * Note that include instructions that do not match any files do not result in an exception. A respective message at
+ * WARN level is logged.
+ *
+ * @param file
+ * The file to be read.
+ * @param currentDepth
+ * The current include depth.
+ * @throws IOException
+ * Thrown in case of an I/O error.
+ * @throws CircularIncludeException
+ * Thrown if circular includes have been detected (@link {@link RuntimeException}).
+ */
+ private synchronized void load(File file, int currentDepth) throws IOException, CircularIncludeException {
+ if (currentDepth > MAX_NESTED_INCLUDE_DEPTH) {
+ throw new CircularIncludeException("Circular include instruction(s) detected.");
+ }
+ InputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ log.debug("Loading '" + file.getCanonicalPath() + "'.");
+ super.load(in);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ // Properties have been loaded. Apply preprocessing step in order to process include instructions.
+ // Provide a context directory in order to be able to resolve relative path instructions.
+ processIncludes(file.getParentFile(), currentDepth);
+ }
+
+ /**
+ * Resolves all include instructions as part of a postprocessing step.
+ *
+ * @param contextFolder
+ * The folder that should be assumed as starting folder for relative include instructions.
+ * @param currentDepth
+ * The current include depth.
+ * @throws IOException
+ * Thrown in case of error.
+ */
+ private void processIncludes(File contextFolder, int currentDepth) throws IOException {
+ SortedMap<String, String> sortedIncludeInstructions = new TreeMap<String, String>();
+
+ // Walk through properties, collecting include instructions.
+ // Since the backing Hashtable does not guarantee any order, import instructions need to be sorted according to
+ // their keys (natural order -> alphabetically).
+ // This allows for defining a pseudo load order: include.1=path/to/settings.propertes,
+ // include.2=other/path/to/settings.properties
+ @SuppressWarnings("unchecked")
+ Enumeration<String> propertyNames = (Enumeration<String>) propertyNames();
+ while (propertyNames.hasMoreElements()) {
+ String key = propertyNames.nextElement();
+ // valid include instructions: include=xxx, include.foo=xxx, include.foo.foo=xxx... (keys are case
+ // insensitive)
+ if (INCLUDE_KEY_NAME.equalsIgnoreCase(key) || StringUtils.startsWithIgnoreCase(key, INCLUDE_KEY_NAME + ".")) {
+ String includeValue = StringUtils.trimToNull(getProperty(key));
+ if (includeValue != null) {
+ sortedIncludeInstructions.put(key, includeValue);
+ }
+ }
+ }
+
+ // performing imports
+ Iterator<String> includeIt = sortedIncludeInstructions.keySet().iterator();
+ while (includeIt.hasNext()) {
+ String includeInstructionKey = includeIt.next();
+ String includePath = getProperty(includeInstructionKey);
+ processInclude(contextFolder, includePath, currentDepth);
+ // remove import instruction from properties
+ remove(includeInstructionKey);
+ }
+ }
+
+ /**
+ * Processes a single include instruction (which may lead to several imports due to wildcard support).
+ *
+ * @param contextFolder
+ * The folder that should be assumed as starting folder for relative include instructions.
+ * @param includePath
+ * The include path instruction.
+ * @param currentDepth
+ * The current include depth.
+ * @throws IOException
+ * Thrown in case of error.
+ */
+ private void processInclude(File contextFolder, String includePath, int currentDepth) throws IOException {
+ // Combine contextFolder with relative path instructions from includePath.
+ File includeInstruction = new File(contextFolder, includePath);
+ contextFolder = includeInstruction.getParentFile();
+ String includeName = includeInstruction.getName();
+
+ WildcardFileFilter fileFilter = new WildcardFileFilter(includeName, DEFAULT_IOCASE);
+ Collection<File> includeFiles = null;
+ if (contextFolder != null && contextFolder.exists() && contextFolder.isDirectory()) {
+ includeFiles = FileUtils.listFiles(contextFolder, fileFilter, null);
+ }
+ if (includeFiles != null && !includeFiles.isEmpty()) {
+ log.info("Including '" + includePath + "'.");
+ for (File includeFile : includeFiles) {
+ NestedProperties includeProperties = new NestedProperties();
+ includeProperties.load(includeFile, currentDepth + 1);
+ putAll(includeProperties);
+ }
+ } else {
+ log.warn("Unable to find '" + includeName + "' in folder '" + contextFolder.getCanonicalPath() + "'.");
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/PropertyTree.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/PropertyTree.java
index 49ba003..e9276b8 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/PropertyTree.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/PropertyTree.java
@@ -38,7 +38,7 @@ import java.util.Vector;
* the values of a configuration is stored in nested hashes. The keys in an area are stored in a
* HashMap. The values of a key are stored in a Vector to overload some keys. The property tree can
* be used to extract sub nodes and sub keys of different tree levels.
- *
+ *
* @author wlackner
* @see java.util.HashMap
* @see java.util.Vector
@@ -49,7 +49,7 @@ public class PropertyTree implements Serializable {
* SVUID.
*/
private static final long serialVersionUID = -1686170519955886222L;
-
+
/**
* The key split string. A key can be a complex key. Sub keys are separated from each other with
* the split string. This string is used to devide the complex key.
@@ -77,7 +77,7 @@ public class PropertyTree implements Serializable {
* the tree will be created. The last part of the key (last splitted element) adds the value to
* there own value data structure (Vector). <br />
* <strong>Example: </strong> <code>setKeyValue("key.1_level.2_level","the value for k_1_2")</code
- *
+ *
* @param splitKey the key that has to be store the value
* @param value only String values can be stored
*/
@@ -97,7 +97,7 @@ public class PropertyTree implements Serializable {
/**
* Adds a String value to the current key
- *
+ *
* @param value
*/
private void addValue(String value) {
@@ -108,7 +108,7 @@ public class PropertyTree implements Serializable {
* This method takes a key as input value, split them into subnodes and return the sub tree of the
* last node of the key. If the key or a sub node not found, the method return null. This means
* the key is not part of the sub property tree.
- *
+ *
* @param splitKey the key that has to be found as sub node of the current node
* @return the sub tree (PropertyTree) or <code>null</code> if the key is not a subtree referece
*/
@@ -129,7 +129,7 @@ public class PropertyTree implements Serializable {
* This method return the subtree that corresponds to a particular key. The key does not split.
* Therefore the key must be a children of the current node. Search only in the key map of the
* current node.
- *
+ *
* @param key the key that has to be a sub node
* @return a sub tree (PropertyTree) or <code>null</code> if the key is not a children of the
* current node
@@ -142,7 +142,7 @@ public class PropertyTree implements Serializable {
* Returns the last value (keys can be overloaded) of a key. The key are splitted into subnodes
* and the last node of the key is the current value holder. If a key or subnode is not in the sub
* tree the return value is <code>null.</code>
- *
+ *
* @param key the key that holds the value (can be a nested key like <code>"key.1.2.3"</code>)
* @return the value of the key (last node of the key) or <code>null</code> otherwise
*/
@@ -162,7 +162,7 @@ public class PropertyTree implements Serializable {
* Returns the first value (keys can be overloaded) of a key. The key are splitted into subnodes
* and the last node of the key is the current value holder. If a key or subnode is not in the sub
* tree the return value is <code>null</code>.
- *
+ *
* @param key the key that holds the value (can be a nested key like <code>"key.1.2.3"</code>)
* @return the value of the key (last node of the key) or <code>null</code> otherwise
*/
@@ -180,7 +180,7 @@ public class PropertyTree implements Serializable {
/**
* This method return all values of the current node. The values are stored as String values.
- *
+ *
* @return the values (type String) of the current node
* @see Vector
*/
@@ -191,7 +191,7 @@ public class PropertyTree implements Serializable {
/**
* This method return all keys (sub tree references) of the current node as a Map. The keys are
* stored as String values.
- *
+ *
* @return the keys (type String) of the current node
* @see Map
*/
@@ -202,7 +202,7 @@ public class PropertyTree implements Serializable {
/**
* This method return all keys (sub tree references) of the current node as an ArrayList. The keys
* are stored as String values.
- *
+ *
* @return the keys (type String) of the current node
* @see ArrayList
*/
@@ -219,10 +219,10 @@ public class PropertyTree implements Serializable {
}
/**
- *
+ *
* This method return all sub tree references of a key as an ArrayList. The keys are stored as
* String values.
- *
+ *
* @param key (can be a nested key like <code>"key.1.2.3"</code>)
* @return the keys (type String) of the current node
* @see ArrayList
@@ -237,7 +237,7 @@ public class PropertyTree implements Serializable {
/**
* This method return all values of a key. The values are stored as String values.
- *
+ *
* @param key (can be a nested key like <code>"key.1.2.3"</code>)
* @return the values (type Vector) of the key or <code>null</code> if the key is not in the sub
* tree of the current node
@@ -254,7 +254,7 @@ public class PropertyTree implements Serializable {
/**
* Store a sub tree (type PropertyTree) in the current node. The key and it's sub tree are stored
* in a HashMap.
- *
+ *
* @param key the reference of the sub tree
* @param tree the sub tree of the key
* @see HashMap
@@ -270,7 +270,7 @@ public class PropertyTree implements Serializable {
* Extracts a sub tree of a nested key. The Method returns the last sub tree of the nested key.
* <strong>Example: </strong>if the key is like: <code>key.1.2.3</code> the sub tree of the last
* node <code>3</code> is returned.
- *
+ *
* @param key the reference of the sub tree
* @return a sub tree of the key or <code>null</code> if the key can not be found
*/
@@ -280,7 +280,7 @@ public class PropertyTree implements Serializable {
/**
* This method checks if a key is a reference to a sub tree in the current node.
- *
+ *
* @param key a simple key that is a parent reference of a sub tree
* @return true if the key is found, false otherwise
*/
@@ -291,7 +291,7 @@ public class PropertyTree implements Serializable {
/**
* The default toString method. It starts with the current node recursively downwards and return
* the String representation of the node.
- *
+ *
* @return the string representation of the node
*/
public String toString() {
@@ -300,9 +300,9 @@ public class PropertyTree implements Serializable {
/**
* This is a helper function to define the prefix for different levels in the toString method, not
- * realy nice ;-).
- * It replaces all "." chars with " ".
- *
+ * realy nice ;-).<p/>
+ * In other words: Fills {@code key} with spaces (of same length).
+ *
* @param key
* @return a replaces prefix string
*/
@@ -312,7 +312,7 @@ public class PropertyTree implements Serializable {
/**
* This method concatenates all values of the current node and return them as a combinded string.
- *
+ *
* @param prefix
* @param tree
* @return the string representation of the node values
@@ -330,7 +330,7 @@ public class PropertyTree implements Serializable {
/**
* The toString method. It starts with a special level prefix, sub tree and recursively adds all
* sub trees.
- *
+ *
* @param prefix the prefix for this node
* @param tree the current node
* @return the string representation of the node
@@ -351,8 +351,40 @@ public class PropertyTree implements Serializable {
}
return os;
}
-
+
public void removeEntry(String key) {
- this.keys_.remove(key);
+ this.keys_.remove(key);
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((keys_ == null) ? 0 : keys_.hashCode());
+ result = prime * result + ((values_ == null) ? 0 : values_.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ PropertyTree other = (PropertyTree) obj;
+ if (keys_ == null) {
+ if (other.keys_ != null)
+ return false;
+ } else if (!keys_.equals(other.keys_))
+ return false;
+ if (values_ == null) {
+ if (other.values_ != null)
+ return false;
+ } else if (!values_.equals(other.values_))
+ return false;
+ return true;
+ }
+
} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java
index 352c594..832f952 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java
@@ -32,7 +32,6 @@ import iaik.security.provider.IAIK;
import iaik.utils.RFC2253NameParser;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@@ -42,6 +41,7 @@ import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.commons.logging.Log;
@@ -49,6 +49,7 @@ import org.apache.commons.logging.LogFactory;
import at.gv.egiz.pdfas.api.commons.Constants;
import at.gv.egiz.pdfas.api.exceptions.ConfigUtilsException;
+import at.gv.egiz.pdfas.exceptions.ErrorCode;
import at.gv.egiz.pdfas.utils.ConfigUtils;
import at.gv.egiz.pdfas.utils.TempDirHelper;
import at.knowcenter.wag.egov.egiz.PdfAS;
@@ -61,36 +62,36 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper;
* The SettingsReader reads the <code>settings.txt</code> file. The
* <code>settings.txt</code> is a simple java property file that collects all
* parameters used in different modules.
- *
+ *
* The SettingsReader provides methods to get the property keys and the
* corresponding values. The keys could be defined as combinations of single
* keys. Therefore it is possible to combine differen classes of keys. An
* example could be:
- *
+ *
* <pre>
- *
+ *
* #SettingNotFoundException
* error.code.100=Interner Fehler
* error.code.101=Die Konfigurationsdatei konnte nicht geladen werden
- *
+ *
* #PDFDocumentException
* error.code.200=Das Dokument konnte nicht geladen werden
- *
+ *
* #SignatureException
* error.code.300=Die Signatur ist ungültig
- *
+ *
* #NormalizeException
* error.code.400=Die angegebene Version ist nicht bekannt
- *
+ *
* normalizer.version=V01
- *
+ *
* </pre>
- *
+ *
* The internal representation of the example above is:
- *
+ *
* <pre>
- *
+ *
* .error|
* |.code|
@@ -100,10 +101,10 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper;
* | |.101=Die Konfigurationsdatei konnte nicht geladen werden
* | |.300=Die Signatur ist ungueltig
* .normalizer|
- * |.version=V01
- *
+ * |.version=V01
+ *
* </pre>
- *
+ *
* @author wlackner
*/
public class SettingsReader implements Serializable
@@ -145,17 +146,22 @@ public class SettingsReader implements Serializable
* The file path postfix where certificates are stored
*/
private static final String CERT = "certificates";
-
+
/**
* pdf-as internal properties resource path
*/
private static final String PDF_AS_PROP_RESOURCE = "/config/pdf-as.properties";
-
+
+ /**
+ * The default configuration properties. These settings can be overridden by any local configuration.
+ */
+ private static final String DEFAULT_CFG_PROPERTIES_RESOURCE = "/config/defaultconfig.properties";
+
/**
* internal help file
*/
private static final String HELP_TEXT_PROP_RESOURCE = "/config/help_text.properties";
-
+
public static final boolean REGISTER_IAIK_PROVIDERS_ON_DEFAULT = true;
// /**
@@ -165,14 +171,14 @@ public class SettingsReader implements Serializable
/**
* The path of the resources repository.
- *
+ *
* <p>
* This usually contains sub directories for the templates, the configuration
* files, etc.
* </p>
*/
public static String RESOURCES_PATH = null;
-
+
/**
* The path for temporary files.
*/
@@ -237,7 +243,7 @@ public class SettingsReader implements Serializable
/**
* The reference to the settings file.
*/
- private static String settingsFile_ = null;
+ private static File settingsFile_ = null;
/**
* The reference to the property representation of the settings file.
@@ -258,7 +264,7 @@ public class SettingsReader implements Serializable
* The only cause to do this is that the definition file should only be read
* once while getting often this instance. The method throws an IOException if
* the settings file could not be read.
- *
+ *
* @param settingsFile
* load this file, if the <code>settingsFile == null</code> the
* default settings ({@link SettingsReader#CONFIG_FILE_DEFAULT_NAME})
@@ -271,39 +277,45 @@ public class SettingsReader implements Serializable
try
{
String cfg_path = CONFIG_PATH;
- properties_ = new Properties();
if (settingsFile == null)
{
settingsFile = cfg_path + CONFIG_FILE_DEFAULT_NAME;
}
- settingsFile_ = settingsFile;
- if (logger_.isInfoEnabled())
- {
- File file = new File(settingsFile_);
- logger_.debug("load Settings:" + file.getAbsolutePath());
- // Properties sys_prop = System.getProperties();
- // Enumeration prop_keys = sys_prop.propertyNames();
- // while (prop_keys.hasMoreElements()) {
- // String key = (String) prop_keys.nextElement();
- // String value = sys_prop.getProperty(key);
- // logger_.info(key + "=" + value);
- // }
- }
- FileInputStream sfs = new FileInputStream(settingsFile_);
- properties_.load(sfs);
-
+ settingsFile_ = new File(settingsFile);
+ logger_.debug("load Settings:" + settingsFile_.getAbsolutePath());
+
+ // DTI
+ // (1) first load default properties which may be overloaded by local configurations
+ Properties defaultConfiguration = new Properties();
+ InputStream in = null;
+ try {
+ defaultConfiguration.load(in = getClass().getResourceAsStream(DEFAULT_CFG_PROPERTIES_RESOURCE));
+ } catch (Exception e) {
+ throw new SettingsException(ErrorCode.UNABLE_TO_LOAD_DEFAULT_CONFIG,
+ "Unable to load default configuration.", e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+
+ // (2) then load main configuration (considers include instructions)
+ NestedProperties includeAwareProperties = new NestedProperties(defaultConfiguration);
+ try {
+ includeAwareProperties.load(settingsFile_);
+ properties_ = includeAwareProperties;
+ } catch (CircularIncludeException e) {
+ throw new SettingsException(ErrorCode.CIRCULAR_INCLUDE_INSTRUCTION_DETECTED, e);
+ }
+
+ // (3) then forcedly overwrite some system settings
// dferbas override with system props
properties_.load(SettingsReader.class.getResourceAsStream(PDF_AS_PROP_RESOURCE));
+ // (4) and finally add help texts.
Properties help_prop = new Properties();
-// FileInputStream hfs = new FileInputStream(cfg_path + HELP_TEXT_FILE_DEFAULT_NAME);
-// help_prop.load(hfs);
help_prop.load(SettingsReader.class.getResourceAsStream(HELP_TEXT_PROP_RESOURCE));
- // load properties from current package!
- // properties_.load(getClass().getResourceAsStream(settingsFile_));
+ // (5) Build PropertyTree configuration.
Enumeration prop_keys = properties_.propertyNames();
-
while (prop_keys.hasMoreElements())
{
String key = (String) prop_keys.nextElement();
@@ -319,10 +331,12 @@ public class SettingsReader implements Serializable
pTree_.setKeyValue(key, value);
}
}
+
catch (IOException e)
{
throw new SettingsException("Couldn't load settings from file " + settingsFile, e);
}
+
}
/**
@@ -331,7 +345,7 @@ public class SettingsReader implements Serializable
* holding the definitions of the default settings file. Default file:
* {@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}: "settings.txt".
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* @return an instance of the SettingsReader
* @throws SettingsException
* if the default settings file could not be read
@@ -340,15 +354,15 @@ public class SettingsReader implements Serializable
{
return getInstance(null);
}
-
+
/**
* Reloads the Settings file.
- *
+ *
* <p>
* Subsequent calls to getInstance will return the new settings.
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
* </p>
- *
+ *
* @throws SettingsException f.e.
*/
public synchronized static void createInstance() throws SettingsException
@@ -356,16 +370,16 @@ public class SettingsReader implements Serializable
instance_ = null;
getInstance();
}
-
+
/**
* Reloads the Settings file.
- *
+ *
* <p>
* Subsequent calls to getInstance will return the new settings.
* </p>
* @param registerProvider <code>true</code>: automatically registers IAIK JCE and ECC Provider;
* <code>false</code>: providers will NOT be automatically registered, providers
- * needed have to be registered by the API user
+ * needed have to be registered by the API user
* @throws SettingsException f.e.
*/
public synchronized static void createInstance(boolean registerProvider) throws SettingsException
@@ -381,18 +395,18 @@ public class SettingsReader implements Serializable
* <code>settingsFile == null</code> the default settings file will be load.
* Default file: {@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}:
* "settings.txt"
- *
+ *
* If an instance of this class exist, the input param is ignored! The
* SettingsReader is singleton and therefore the first
* {@link SettingsReader#getInstance()}defines the settings file that has to
* be loaded. This means changes between a application lifecyle can not be
* done!
- *
+ *
* @param settingsFile
* the settings file that should be load.
* @param registerProvider <code>true</code>: automatically registers IAIK JCE and ECC Provider;
* <code>false</code>: providers will NOT be automatically registered, providers
- * needed have to be registered by the API user
+ * needed have to be registered by the API user
* @return an instance of the SettingsReader
* @throws SettingsException
* if the settings file could not be read
@@ -402,7 +416,7 @@ public class SettingsReader implements Serializable
if (instance_ == null)
{
int length = Utils.max(new int[] { RESOURCES_PATH.length(), TMP_PATH.length(), CONFIG_PATH.length(), CERT_PATH.length() });
-
+
logger_.info(StringUtils.repeat("*", length + 25));
logger_.info(" resources path = \"" + RESOURCES_PATH + "\"");
logger_.info(" configuration path = \"" + CONFIG_PATH + "\"");
@@ -410,7 +424,7 @@ public class SettingsReader implements Serializable
logger_.info(" temporary path = \"" + TMP_PATH + "\"");
logger_.debug(" file.encoding = \"" + System.getProperty("file.encoding") + "\"");
logger_.info(StringUtils.repeat("*", length + 25));
-
+
if (registerProvider) {
IAIK.addAsProvider();
ECCProvider.addAsProvider();
@@ -429,12 +443,12 @@ public class SettingsReader implements Serializable
// Does not conform with PKIX, but is used by belgium citizen card
// log.info("Registering RDN \"SERIALNUMBER\" as " + ObjectID.serialNumber + ".");
RFC2253NameParser.register("SERIALNUMBER", ObjectID.serialNumber);
-
+
instance_ = new SettingsReader(settingsFile);
}
return instance_;
}
-
+
/**
* This method returns an synchronized instance of this class. The settings
* file is read only once using this class. This method returns the instance
@@ -443,13 +457,13 @@ public class SettingsReader implements Serializable
* Default file: {@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}:
* "settings.txt".
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* If an instance of this class exist, the input param is ignored! The
* SettingsReader is singleton and therefore the first
* {@link SettingsReader#getInstance()}defines the settings file that has to
* be loaded. This means changes between a application lifecyle can not be
* done!
- *
+ *
* @param settingsFile
* the settings file that should be load.
* @return an instance of the SettingsReader
@@ -464,7 +478,7 @@ public class SettingsReader implements Serializable
/**
* This method returns a property value to the corresponding key. If the key
* is not found in the property file a SettingNotFoundException is thrown.
- *
+ *
* @param key
* get the value for that key in the property file
* @return the value of the property key.
@@ -490,17 +504,10 @@ public class SettingsReader implements Serializable
return result;
}
-
- // TODO in the next change request, the Setting system will be refactored
- // this is just for testing purposes.
- public void setSetting(String key, String value)
- {
- properties_.setProperty(key, value);
- }
/**
* Relocates the relative file.
- *
+ *
* @param file
* The relative file.
* @return Returns the usable file.
@@ -519,7 +526,7 @@ public class SettingsReader implements Serializable
/**
* This method returns a property value to the corresponding key. If the key
* is not found in the property file the input param defaultValue is returned.
- *
+ *
* @param key
* get the value for that key in the property file
* @param defaultValue
@@ -545,7 +552,7 @@ public class SettingsReader implements Serializable
* This method returns a property value to the corresponding key. If the key
* is not found in the property file the input param defaultKey is searched.
* If the default key is not found the input param defaultValue is returned.
- *
+ *
* @param primaryKey
* get the value for that key in the property file
* @param defaultKey
@@ -580,7 +587,7 @@ public class SettingsReader implements Serializable
* keyPrefix. The method search all keys in the property file that has the
* keyPrefix as leading substring. The <code>Object[]</code> collects all
* sub keys without the keyPrefix.
- *
+ *
* @param keyPrefix
* to search for sub keys
* @return alls keys starting with the keyPrefix
@@ -604,7 +611,7 @@ public class SettingsReader implements Serializable
* If a property value is number (interger) this method extracts the value and
* convert it to an int. If the key ist not found or the conversion fails, the
* defaultValue is returned.
- *
+ *
* @param key
* get the value for that key in the property file
* @param defaultValue
@@ -641,7 +648,7 @@ public class SettingsReader implements Serializable
* This method returns an array of sub keys (children references) of the key.
* The method is a wrapper calling the method
* {@link PropertyTree#getKeys(String key)}.
- *
+ *
* @param key
* get all sub keys for that key in the property file
* @return an list of sub keys (type String)
@@ -659,7 +666,7 @@ public class SettingsReader implements Serializable
* not overload keys. If a key is defined more than one times the last
* definition is stored it the property list. The method is a wrapper calling
* the method {@link PropertyTree#getFirstValue(String key)}.
- *
+ *
* @param key
* get the value for that key in the property file
* @return the value of the property key
@@ -678,7 +685,7 @@ public class SettingsReader implements Serializable
/**
* This method returns the PropertyTree representation of the configuration
* file.
- *
+ *
* @return Returns the pTree.
* @see PropertyTree
*/
@@ -686,20 +693,20 @@ public class SettingsReader implements Serializable
{
return pTree_;
}
-
+
/**
* Reads internal resource as string.
* @param relativePath
* @return null in case of error
*/
public String readInternalResourceAsString(String relativePath) {
-// return readAsString(getInternalResource(relativePath));
- return FileHelper.readFromInputStream(getInternalResource(relativePath));
+// return readAsString(getInternalResource(relativePath));
+ return FileHelper.readFromInputStream(getInternalResource(relativePath));
}
-
+
/**
* Get resource as stream, relative to internal resource path {@value #INTERNAL_RESOURCE_PATH}
- *
+ *
* @param relativePath
* @return
*/
@@ -717,9 +724,9 @@ public class SettingsReader implements Serializable
}
return stream;
}
-
+
/**
- * Read resource as utf8 string.
+ * Read resource as utf8 string.
* @param is
* @return <code>null</code> in case of error
*/
@@ -730,7 +737,7 @@ public class SettingsReader implements Serializable
return IOUtils.toString(is, "utf-8");
} catch (IOException e) {
logger_.info("error reading stream to string ", e);
- }
+ }
return null;
}
*/
@@ -758,11 +765,11 @@ public class SettingsReader implements Serializable
/**
* Returns the directory where temporary files should be stored.
- *
+ *
* <p>
* If the directory doesn't exist, it is created.
* </p>
- *
+ *
* @return Returns the directory where temporary files should be stored.
* @see TempDirHelper#getTemporaryDirectory()
*/
@@ -773,7 +780,7 @@ public class SettingsReader implements Serializable
/**
* Deletes all files in the temporary directory, if it exists.
- *
+ *
* <p>
* This should be used to clear temporary files when the application shuts
* down.
@@ -784,19 +791,19 @@ public class SettingsReader implements Serializable
{
TempDirHelper.clearTemporaryDirectory();
}
-
+
public static synchronized void initialize(String configdir, String tmpdir) {
-
+
String defaultConfigDeployedTo = null;
// resolve work directory
// configuration explicitely given ?
if (configdir == null) {
-
+
// configuration via system property ?
logger_.debug("No configuration directory given. Looking for system property \"" + Constants.CONFIG_DIR_SYSTEM_PROPERTY + "\".");
configdir = System.getProperty(Constants.CONFIG_DIR_SYSTEM_PROPERTY);
if (configdir == null) {
-
+
// configuration via user's home directory ?
logger_.debug("System property not set. Trying to locate configuration within the user's home directory.");
String userHome = System.getProperty("user.home");
@@ -808,7 +815,7 @@ public class SettingsReader implements Serializable
defaultConfigDeployedTo = ConfigUtils.deployDefaultConfiguration(configdir, false);
} catch (ConfigUtilsException e) {
throw new RuntimeException(e);
- }
+ }
if (defaultConfigDeployedTo != null) {
logger_.info("** Default configuration successfully deployed to \"" + defaultConfigDeployedTo + "\" **");
} else {
@@ -833,7 +840,7 @@ public class SettingsReader implements Serializable
{
throw new IllegalArgumentException("The config directory \"" + configdir + "\" does not exist or is not a directory.");
}
-
+
// resolve temporary dir
if (tmpdir == null) {
logger_.debug("Temporary directory not explicitely set. Looking for user's temp directory.");
@@ -851,14 +858,14 @@ public class SettingsReader implements Serializable
} catch (IOException e) {
tmpdir = ConfigUtils.assertFileSeparator(tmpdirFile.getPath());
}
-
+
RESOURCES_PATH = configdir;
TMP_PATH = tmpdir;
CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
// ConfigUtils.printConfigInfo(logger_);
-
+
if (defaultConfigDeployedTo != null) {
logger_.debug("** Default configuration successfully deployed to \"" + defaultConfigDeployedTo + "\" **");
}
@@ -870,10 +877,10 @@ public class SettingsReader implements Serializable
{
initialize(base_dir, null);
}
-
+
/**
* Initializes the paths of the SettingsReader for web application usage.
- *
+ *
* @param base_dir
* The base directory of this web application. E.g.
* TOMCAT_HOME/webapps/pdf-as
@@ -890,14 +897,14 @@ public class SettingsReader implements Serializable
{
initialize(null);
}
-
+
static {
-
+
String versionString = "* PDF-AS library version " + PdfAS.PDFAS_VERSION + " *";
String paddingString = StringUtils.repeat("*", versionString.length());
logger_.info("PDF-AS info\n" + paddingString + "\n" + versionString + "\n" + paddingString);
}
-
+
public Properties getProperties() {
return this.properties_;
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
index 1b66f53..0468160 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
@@ -73,7 +73,7 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
/**
* The main program entry point of the commandline tool.
- *
+ *
* @author wprinz
*/
public abstract class Main
@@ -156,18 +156,18 @@ public abstract class Main
/**
* Main program entry point.
- *
+ *
* @param args
* The commandline arguments.
* @throws IOException
- *
+ *
* @deprecated use {@link at.gv.egiz.pdfas.commandline.Main} instead
*/
public static void main(String[] args) throws IOException {
System.out.println("\nWarning: The entry point at.knowcenter.wag.egov.egiz.commandline.Main is deprecated. Use at.gv.egiz.pdfas.commandline.Main instead.\n");
at.gv.egiz.pdfas.commandline.Main.main(args);
}
-
+
/*
public static void main(String[] args) throws IOException
{
@@ -413,7 +413,7 @@ public abstract class Main
catch (PresentableException e)
{
printPresentableException(e);
-
+
if (output != null)
{
logger_.debug("Deleting output file on error.");
@@ -451,10 +451,10 @@ public abstract class Main
// }
PrintWriter messageOutput = new PrintWriter(System.out);
-
-
+
+
if (mode.equals(VALUE_MODE_SIGN))
- {
+ {
carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput);
}
else
@@ -468,22 +468,12 @@ public abstract class Main
PrintWriter messageOutput) throws PresentableException
{
messageOutput.println("Signing...");
-
- // for performance measurement
- long startTime = 0;
- long fileSize = 0;
- if (logger_.isInfoEnabled()) {
- startTime = System.currentTimeMillis();
- }
PdfDataSource pdfDataSource;
try
{
File file = new File(input);
pdfDataSource = new FileBasedPdfDataSourceImpl(file, (int)file.length());
- if (logger_.isDebugEnabled())
- fileSize = file.length();
-
}
catch (IOException e)
{
@@ -495,7 +485,7 @@ public abstract class Main
try
{
outputFile = new File(output);
-
+
dataSink = new FileBasedDataSink(outputFile);
}
catch (IOException e)
@@ -523,39 +513,23 @@ public abstract class Main
}
}
- // for performance measurement
- if (logger_.isInfoEnabled()) {
- long endTime = System.currentTimeMillis();
- String toReport = "SIGN;" + signature_mode + ";" + input + ";"+ fileSize + ";" + (endTime - startTime);
- logger_.info(toReport);
- }
-
messageOutput.println("Signing was successful.");
}
public static void carryOutVerify(String input, String connector, int verify_which, PrintWriter messageOutput) throws PresentableException
{
messageOutput.println("Verifying...");
-
- // for performance measurement
- long startTime = 0;
- long fileSize = 0;
- if (logger_.isInfoEnabled()) {
- startTime = System.currentTimeMillis();
- }
-
+
DataSource dataSource = null;
try
{
File file = new File(input);
- if (logger_.isDebugEnabled())
- fileSize = file.length();
String extension = extractExtension(input);
if (extension != null && extension.equals("txt"))
{
try
{
- FileInputStream fis = new FileInputStream(file);
+ FileInputStream fis = new FileInputStream(file);
byte[] input_bytes = new byte[(int) file.length()];
fis.read(input_bytes);
fis.close();
@@ -582,24 +556,16 @@ public abstract class Main
messageOutput.println("Verification results:");
formatVerifyResults(results, messageOutput);
-
- // for performance measurement
- if (logger_.isInfoEnabled()) {
- long endTime = System.currentTimeMillis();
- String toReport = "VERIFY;"+ input + ";"+ fileSize + ";" + (endTime - startTime) + ";" + debugVerifyResults(results);
- logger_.info(toReport);
- }
-
-
+
}
/**
* Extracts the extension from a file name string.
- *
+ *
* <p>
* The extension of a file name is whatever text follows the last '.'.
* </p>
- *
+ *
* @param file_name
* The file name.
* @return Returns the extension. If the file name ends with the '.', then an
@@ -664,14 +630,14 @@ public abstract class Main
// }
}
// logger_.debug("Finally used sign algorithm = " + signatorId);
-
+
String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(connector);
PdfAS.signCommandline(pdfDataSource, dataSink, signatorId, connectorId, signature_type, null, pos, null, null);
// PdfAS.sign(algorithm, pdfDataSource, dataSink, signature_type, connector, pos);
}
-
+
public static List processVerify(DataSourceHolder dataSource, String connector, int verify_which) throws PresentableException
{
VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings();
@@ -698,7 +664,7 @@ public abstract class Main
holders_to_verify = new ArrayList();
holders_to_verify.add(holder);
}
-
+
List results = PdfAS.verifySignatureHolders(holders_to_verify, connector, false, null);
return results;
@@ -749,7 +715,7 @@ public abstract class Main
/**
* Prints that the provided option was unrecognized.
- *
+ *
* @param option
* The unrecognized option.
* @throws PresentableException
@@ -763,7 +729,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param parameter
* The parameter, which is missing a value.
* @throws PresentableException
@@ -777,7 +743,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param value
* The unrecognized value.
* @throws PresentableException
@@ -791,7 +757,7 @@ public abstract class Main
/**
* Prints that the provided additional commandline argument was unrecognized.
- *
+ *
* @param argument
* The unrecognized argument.
* @throws PresentableException
@@ -805,7 +771,7 @@ public abstract class Main
/**
* Prints that a certain parameter was missing.
- *
+ *
* @param missing_term
* A description of the missing parameter ("e.g. a mode").
* @param parameter
@@ -820,7 +786,7 @@ public abstract class Main
/**
* Prints that something is missing.
- *
+ *
* @param missing_term
* A descriptive message of the missing thing.
* @throws PresentableException
@@ -834,7 +800,7 @@ public abstract class Main
/**
* Prints out the ErrorCodeException in a descriptive form.
- *
+ *
* @param ece
* The ErrorCodeException to be printed.
*/
@@ -868,7 +834,7 @@ public abstract class Main
/**
* Prints the usage text.
- *
+ *
* @param writer
* The writer to print the text to.
* @throws PresentableException
@@ -920,7 +886,9 @@ public abstract class Main
writer.print(" " + PARAMETER_SIGNATURE_TYPE + " <");
SignatureTypes sig_types = SignatureTypes.getInstance();
SettingsReader settings = SettingsReader.getInstance();
- Set types_array = sig_types.getSignatureTypes();
+ // show only signature profiles that can be used for signature
+// Set types_array = sig_types.getSignatureTypes();
+ Set types_array = sig_types.getSignatureTypesForSignature();
Iterator it = types_array.iterator();
while (it.hasNext())
{
@@ -973,7 +941,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param mode
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -985,7 +953,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param signature_mode
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -998,7 +966,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param connector
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1012,7 +980,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param signature_type
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1020,8 +988,8 @@ public abstract class Main
protected static boolean checkSignatureType(String signature_type) throws SignatureTypesException
{
return SignatureTypes.getInstance().getSignatureTypes().contains(signature_type);
-
- // exthex: uuuaaaahhhhh WHY??? wprinz again?, dont do that. Use List.contains(o), please
+
+ // exthex: uuuaaaahhhhh WHY??? wprinz again?, dont do that. Use List.contains(o), please
// take a java course and read: http://www.amazon.de/Java-f%C3%BCr-Dummies-Barry-Burd/dp/382662999X
// List types_array = sig_types.getSignatureTypes();
// Iterator it = types_array.iterator();
@@ -1038,7 +1006,7 @@ public abstract class Main
/**
* Translates the commandline argument to a PDF-AS-ID.
- *
+ *
* @param signature_mode
* The signator mode commandline argument.
* @return Returns the corresponding PDFASID.
@@ -1066,7 +1034,7 @@ public abstract class Main
/**
* Formats the verification results.
- *
+ *
* @param results
* The List of SignatureResponse verification results.
* @param writer
@@ -1088,12 +1056,12 @@ public abstract class Main
}
}
}
-
+
/**
* Formats the verification results for debugging. Returns 0 if no error occurs or the sum of all error-codes.
- *
+ *
* @param results
- *
+ *
* @param writer
* The output sink to write the formatted text to.
* @throws SettingNotFoundException
@@ -1106,16 +1074,16 @@ public abstract class Main
while (it.hasNext())
{
SignatureResponse result = (SignatureResponse) it.next();
-
+
toreturn += Integer.valueOf(result.getSignatureCheckCode()).intValue();
}
return toreturn;
}
-
+
/**
* Formats the SignatureResponse.
- *
+ *
* @param result
* The SignatureResponse to be printed.
* @param writer
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
index 46245d2..de94527 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
@@ -60,7 +60,7 @@ import com.lowagie.text.pdf.PdfPTable;
/**
* Signs the document binary.
- *
+ *
* <p>
* In prepareSign, an Incremental Update is created that contains the Signature
* block and the egiz dictionary. For formatting the layout, variable values are
@@ -72,9 +72,9 @@ import com.lowagie.text.pdf.PdfPTable;
* In finishSign, the variable fields (values, /Cert) are replaced with the
* values according to the encoding.
* </p>
- *
+ *
* @deprecated moved to new-framework
- *
+ *
* @author wprinz
*/
public class BinarySignator_1_0_0 implements Signator
@@ -131,18 +131,6 @@ public class BinarySignator_1_0_0 implements Signator
variable_field_definitions.add(sfd);
}
}
-
- //check if signature block is invisible, and if so and if also signature block is positioned
- //on a new page, prevent pdf-as to do that, because why should make a new page just for an invisible block
- //added by rpiazzi
- if (signature_object.getSignatureTypeDefinition().getInvisibleFieldDefinitions().size()==SignatureTypes.REQUIRED_SIG_KEYS.length) {
- if (pi.isMakeNewPage()) {
- int pageNumber = pi.getPage();
- pi = new PositioningInstruction(false, pageNumber-1, 0, 0);
- }
- }
- //end added
-
IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdf, pdf_table, signature_type, pi, variable_field_definitions, all_field_definitions, null, null, null);
String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$
@@ -187,7 +175,6 @@ public class BinarySignator_1_0_0 implements Signator
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new PDFDocumentException(201, e);
}
}
@@ -198,10 +185,10 @@ public class BinarySignator_1_0_0 implements Signator
public SignResult finishSign(IncrementalUpdateInformation iui) throws PresentableException
{
restoreSignedPdf(iui);
-
+
// PdfAS.prefixID(iui.signed_signature_object, PdfAS.BINARY_ID);
fillReplacesWithValues(iui);
-
+
BinarySignature.replaceCertificate(iui);
BinarySignature.replacePlaceholders(iui);
@@ -212,7 +199,7 @@ public class BinarySignator_1_0_0 implements Signator
/**
* Reads the signature values from the signed signature object and fills the
* corresponding value in the Replaces array.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
*/
@@ -222,7 +209,7 @@ public class BinarySignator_1_0_0 implements Signator
while (it.hasNext())
{
ReplaceInfo ri = (ReplaceInfo) it.next();
-
+
ri.value = iui.signed_signature_object.retrieveStringValue(ri.sfd.field_name);
}
}
@@ -256,7 +243,7 @@ public class BinarySignator_1_0_0 implements Signator
/**
* Forms the SignatureData to be used for signing.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @return Returns the SignatureData to be used for signing.
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
index 9ffeefe..492c5f1 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
@@ -44,12 +44,12 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* This signator is just for testing purposes.
- *
+ *
* <p>
* It doesn't modify the original document, but simply returns the XML signature
* response as the signed document.
* </p>
- *
+ *
* @author wprinz
*/
public class DetachedSignator_1_0_0 implements Signator
@@ -58,7 +58,7 @@ public class DetachedSignator_1_0_0 implements Signator
* The Pdf-AS ID of this Signator.
*/
public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_TEST, SignatorFactory.VERSION_1_0_0);
-
+
/**
* @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
*/
@@ -90,12 +90,12 @@ public class DetachedSignator_1_0_0 implements Signator
IncrementalUpdateInformation iui = new IncrementalUpdateInformation();
iui.original_document = pdf;
iui.signature_type = signature_type;
- iui.pos = pos;
+ iui.pos = pos;
String document_text = PdfAS.extractNormalizedTextTextual(pdf);
iui.nonTextObjectInfos = PdfAS.extractNonTextualObjects(pdf);
// logger_.debug("signed_text = " + document_text);
-
+
DataSource ds = new TextDataSourceImpl(document_text);
iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -117,7 +117,6 @@ public class DetachedSignator_1_0_0 implements Signator
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new PDFDocumentException(300, e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
index 1559246..73e6afb 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
@@ -44,7 +44,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* Signs a document textually.
- *
+ *
* <p>
* In prepareSign, the document text is extracted and normalized.
* </p>
@@ -52,7 +52,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
* In finishSign, the signed SignatureObject is transformed into a Signature
* block, which is then written as an Incremental Update.
* </p>
- *
+ *
* @author wprinz
*/
public class DetachedfTextualSignator_1_0_0 implements Signator
@@ -61,12 +61,12 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
* The Mime Type.
*/
public static final String MIME_TYPE = "text/xml"; //$NON-NLS-1$
-
+
/**
* The Pdf-AS ID of this Signator.
*/
public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_DETACHED_TEXTUAL, SignatorFactory.VERSION_1_0_0);
-
+
/**
* @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
*/
@@ -88,7 +88,7 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
* The parameter has_SIG_ID is not used by this Signator because it doesn't
* pre-format the signature block.
* </p>
- *
+ *
* @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[],
* String, TablePos, boolean)
*/
@@ -98,12 +98,12 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
IncrementalUpdateInformation iui = new IncrementalUpdateInformation();
iui.original_document = pdf;
iui.signature_type = signature_type;
- iui.pos = pos;
+ iui.pos = pos;
String document_text = PdfAS.extractNormalizedTextTextual(pdf, "cp1252");
iui.nonTextObjectInfos = PdfAS.extractNonTextualObjects(pdf);
// logger_.debug("signed_text = " + document_text);
-
+
DataSource ds = new TextDataSourceImpl(document_text);
iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -125,7 +125,6 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new PDFDocumentException(300, e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
index fd59d34..7b5a968 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
@@ -73,7 +73,9 @@ public class AbsoluteTextSignature
public static List getSignatureTypesForTextAnalysis() throws SignatureTypesException
{
SignatureTypes sig_types = SignatureTypes.getInstance();
- List allSignatureTypes = sig_types.getSignatureTypeDefinitions();
+ // use only those profiles that are allowed to be used for verification
+// List allSignatureTypes = sig_types.getSignatureTypeDefinitions();
+ List<SignatureTypeDefinition> allSignatureTypes = sig_types.getSignatureTypeDefinitionsForVerification();
List textSignatureTypes = new ArrayList(allSignatureTypes.size());
Iterator it = allSignatureTypes.iterator();
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
index ece9525..75a64f1 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
@@ -40,6 +40,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -89,25 +90,46 @@ import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfStamperImp;
import com.lowagie.text.pdf.PdfString;
import com.lowagie.text.pdf.PdfTemplate;
+import com.lowagie.text.pdf.PdfWriter;
/**
* Contains various extension functions to digitally sign documents.
- *
+ *
* <p>
* These functions are used to replace parts of the original Egiz plain text
* signature mechanism.
* </p>
- *
+ *
* @author wprinz
*/
public abstract class BinarySignature
{
//23.11.2010 changed by exthex - added replacePlaceholder(PdfStamper stamper, int pageNr, String placeholderName) method
-
+
protected static Log logger = LogFactory.getLog(BinarySignature.class);
+
+ /**
+ * The resource path of the srgb profile to be embedded in case of PDF/A-1b.
+ */
+ private static final String srgbProfileResource = "/at/gv/egiz/pdfas/itext/srgb.profile";
+
+ /**
+ * The color profile to be embedded in case of PDF/A-1b.
+ */
+ private static final byte[] SRGB_PROFILE;
+
+ static {
+ try {
+ logger.debug("Preloading srgb color profile '" + srgbProfileResource + ".");
+ SRGB_PROFILE = IOUtils.toByteArray(BinarySignature.class.getResourceAsStream(srgbProfileResource));
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to preload srgb color profile.", e);
+ }
+ }
+
/**
* The tolerance area of the line break algorithm.
- *
+ *
* @see Placeholder#replacePlaceholderWithTolerance(byte[], List, byte[], int)
*/
public static final int LINE_BREAK_TOLERANCE = 10;
@@ -116,11 +138,11 @@ public abstract class BinarySignature
* The number of bytes left out for the certificate placeholder.
*/
public static final int CERTIFICATE_PLACEHOLDER_LENGTH = 10000;
-
+
/**
* The number of bytes left out for the timestamp placeholder.
*/
- public static final int TIMESTAMP_PLACEHOLDER_LENGTH = 5000;
+ public static final int TIMESTAMP_PLACEHOLDER_LENGTH = 5000;
/**
* The placeholder character used to fill out Strings in the layout process.
@@ -162,11 +184,11 @@ public abstract class BinarySignature
* The SIG_ID brev.
*/
public static final byte[] BREV_SID = { 's', 'i', 'd' };
-
+
/**
* The SIG_ALG brev.
*/
- public static final byte[] BREV_ALG = { 'a', 'l', 'g' };
+ public static final byte[] BREV_ALG = { 'a', 'l', 'g' };
/**
* No explicit encoding.
@@ -185,7 +207,7 @@ public abstract class BinarySignature
/**
* The PDFName of the Egiz Dictionary.
- *
+ *
* <p>
* Used to locate and identify the Egiz Dictionary in the document.
* </p>
@@ -195,7 +217,7 @@ public abstract class BinarySignature
/**
* The PDFName of the Original Document Size (ODS) field in an Egiz
* Dictionary.
- *
+ *
* <p>
* The ODS must be a positive integral number.
* </p>
@@ -226,7 +248,7 @@ public abstract class BinarySignature
* The PdfName of the certificate array.
*/
public static final PdfName EGIZ_CERTIFICATE_NAME = new PdfName("Cert");
-
+
/**
* The PdfName of the Timestamp
*/
@@ -239,7 +261,7 @@ public abstract class BinarySignature
/**
* The PDFName of the Signature XObject field in an Egiz Dictionary.
- *
+ *
* <p>
* This must be an indirect reference to the XObject containing the Signature
* table.
@@ -251,17 +273,17 @@ public abstract class BinarySignature
* The number placeholder that is used to give numbers a fixed length.
*/
protected static final PdfNumber NUMBER_PLACEHOLDER = new PdfNumber(999999999);
-
+
/**
* Extracts the signature text only.
- *
+ *
* <p>
* The signature text is the text of the Signature XObject.
* </p>
- *
+ *
* @param egiz_dict
* The Egiz Dictionary.
- *
+ *
* @return Returns the signature text.
*/
public static String extractSignatureTextOnly(PdfDictionary egiz_dict) throws IOException
@@ -276,7 +298,7 @@ public abstract class BinarySignature
/**
* Retrieves the size of the original document from the Egiz Dictionary.
- *
+ *
* @param egiz_dict
* The Egiz Dictionary.
* @return Returns the size (in bytes) of the original document.
@@ -292,7 +314,7 @@ public abstract class BinarySignature
/**
* Retrieves the previous Egiz dictionary from the given one, if a previous
* dictionary exists.
- *
+ *
* @param egiz_dict
* The Egiz Dictionary.
* @return Returns the previous Egiz Dictionary, or null if there is none.
@@ -306,7 +328,7 @@ public abstract class BinarySignature
/**
* Retrieves the Egiz Dictionary from the document if present.
- *
+ *
* @param reader
* The reader to retrieve the dictionary from.
* @return Returns the Egiz Dictionary, if present, or returns null, if no
@@ -327,7 +349,7 @@ public abstract class BinarySignature
/**
* Retrieves the Egiz Dictionary's indirect reference from the reader.
- *
+ *
* @param reader
* The reader.
* @return Returns the indirect reference of the Egiz Dictionary, or null, if
@@ -342,14 +364,14 @@ public abstract class BinarySignature
/**
* Retrieves the chain of Egiz Dictionaries from the reader.
- *
+ *
* <p>
* The first element in the List will be the top most (oldest) Egiz
* Dictionary. The last element in the List will be the bottom most (latest)
* Egiz Dictionary. If the list is empty, no dictionary could be found at all,
* which means that the document is not digitally signed.
* </p>
- *
+ *
* @param reader
* The reader.
* @return Returns the List of PdfDictionaries from the document.
@@ -374,7 +396,7 @@ public abstract class BinarySignature
/**
* Builds a digest of the given data.
- *
+ *
* @param data
* The data to be digested.
* @param length
@@ -393,7 +415,6 @@ public abstract class BinarySignature
}
catch (NoSuchAlgorithmException e)
{
- e.printStackTrace();
throw new PDFDocumentException(202, "Digest algorithm not supported - NoSuchAlgorithmException", e);
}
@@ -406,7 +427,7 @@ public abstract class BinarySignature
/**
* Retrieves the signable text from the given document.
- *
+ *
* @param data
* The data.
* @param ods
@@ -423,7 +444,7 @@ public abstract class BinarySignature
/**
* Fills the holes in the byte ranges with the SIGN_PLACEHOLDER.
- *
+ *
* @param data
* The given byte ranged data.
* @param byte_ranges
@@ -697,7 +718,7 @@ public abstract class BinarySignature
// throw new PresentableException(e);
// }
// }
-
+
protected static int getLineBreakTolerance(IncrementalUpdateInformation iui) throws PDFDocumentException
{
SettingsReader settings;
@@ -717,7 +738,7 @@ public abstract class BinarySignature
}
return lineBreakTolerance;
}
-
+
protected static int getCertificatePlaceholderLength(IncrementalUpdateInformation iui) throws SettingNotFoundException
{
SettingsReader settings;
@@ -737,7 +758,7 @@ public abstract class BinarySignature
}
return certLen;
}
-
+
protected static int getTimestampPlaceholderLength(IncrementalUpdateInformation iui) throws SettingNotFoundException
{
SettingsReader settings;
@@ -761,7 +782,7 @@ public abstract class BinarySignature
/**
* Signs a document with the given signature table using the Incremental
* Update method.
- *
+ *
* <p>
* The table containing the signature text will be appended. As specified by
* the parameters, the signature will be appended to the last page, or a plain
@@ -777,7 +798,7 @@ public abstract class BinarySignature
* information about the signature. Basically the size of the original
* document and the reference of the signature table.
* </p>
- *
+ *
* @param original_document
* The original document.
* @param pdf_table
@@ -811,10 +832,7 @@ public abstract class BinarySignature
// System.out.println("wprinz: STAMPING PDF");
// InputStream is = original_document.createInputStream();
- byte[] pdf_data = original_document.getAsByteArray();
- PdfReader reader = new PdfReader(pdf_data);
- PDFASUtils.checkReaderPermissions(reader);
- // is.close();
+ PdfReader reader = PDFASUtils.createPdfReaderCheckingPermissions(original_document);
OutputStream baos = written_pdf.createOutputStream("application/pdf");
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -823,7 +841,7 @@ public abstract class BinarySignature
// incremental updated
// The stamper allows this by setting append = true
boolean adobeSigField = AdobeSignatureHelper.isAdobeSignatureFieldEnabled(so.getSignatureTypeDefinition().getType());
- PdfStamper stamper = null;
+ PdfStamper stamper = null;
if (adobeSigField) {
stamper = PdfStamper.createSignature(reader, baos, '\0', null, true);
} else {
@@ -843,13 +861,13 @@ public abstract class BinarySignature
{
throw new PDFDocumentException(224, "The provided page (=" + pi.getPage() + ") is out of range.");
}
-
+
if (SignaturePlaceholderContext.isSignaturePlaceholderDataSet() &&
SignaturePlaceholderContext.getSignaturePlaceholderData().getPlaceholderName() != null)
{
replacePlaceholder(stamper, pi.getPage(), SignaturePlaceholderContext.getSignaturePlaceholderData().getPlaceholderName());
}
-
+
PdfContentByte content = stamper.getOverContent(pi.getPage());
// content = StampContent einer PageStamp.
@@ -857,12 +875,12 @@ public abstract class BinarySignature
// table_height = " + pdf_table.getTotalHeight());
PdfTemplate table_template = content.createTemplate(pdf_table.getTotalWidth(), pdf_table.getTotalHeight());
- table_template.setCompress(Boolean.FALSE); // do not compress sigblock because we rewrite it afterwards for bin sig
+ table_template.setCompress(Boolean.FALSE); // do not compress sigblock because we rewrite it afterwards for bin sig
// exthex
StructContentHelper structHelper = new StructContentHelper(stamper, content, pi.getPage());
structHelper.prepareStructData(table_template);
-
+
pdf_table.writeSelectedRows(0, -1, 0, pdf_table.getTotalHeight(), table_template);
// table_template.moveTo(0, 0);
@@ -876,13 +894,13 @@ public abstract class BinarySignature
// pdf_table.writeSelectedRows(0, -1, SIGNATURE_BORDER / 2,
// table_position, content);
-
+
structHelper.beginSigBlockContent();
-
+
content.addTemplate(table_template, pi.getX(), pi.getY() - pdf_table.getTotalHeight());
-
- structHelper.endSigBlockContent();
-
+
+ structHelper.endSigBlockContent();
+
ActualTablePos atp = new ActualTablePos();
atp.page = pi.getPage();
@@ -891,13 +909,13 @@ public abstract class BinarySignature
atp.width = pdf_table.getTotalWidth();
atp.height = pdf_table.getTotalHeight();
iui.actualTablePos = atp;
-
+
structHelper.buildFigureStructData(so, table_template);
structHelper.buildSigBlockStructData();
structHelper.finishMainStructData();
-
+
structHelper.buildVerifyLinkStructData(table_template, atp);
-
+
// For debugging print a 100x100 grid
// {
// Rectangle psize = reader.getPageSizeWithRotation(pos.page);
@@ -940,7 +958,22 @@ public abstract class BinarySignature
// PdfObject value = resources.get(key);
// System.out.println(" " + key + " = " + value);
// }
-
+
+ // added by dti: fixing PDF/A-1b
+ if (PDFASUtils.isPdfAEnabled(profile)) {
+ logger.debug("Adding sRGB IEC61966-2.1 color profile (output intent) in order to satisfy PDF/A-1b requirements.");
+ PdfWriter writer = stamper.getWriter();
+ writer.setOutputIntents("Custom", "sRGB", "", "sRGB IEC61966-2.1", SRGB_PROFILE);
+ PdfArray a = writer.getExtraCatalog().getAsArray(PdfName.OUTPUTINTENTS);
+ if (a != null) {
+ PdfDictionary d = a.getAsDict(0);
+ if (d != null) {
+ // overwrite PDF/X entry with PDF/A entry
+ d.put(PdfName.S, PdfName.GTS_PDFA1);
+ }
+ }
+ }
+
// add the EGIZ dict:
if (variable_field_definitions != null)
{
@@ -964,22 +997,20 @@ public abstract class BinarySignature
}
catch (IOException e)
{
- e.printStackTrace();
throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF, e);
}
catch (DocumentException e)
{
- e.printStackTrace();
throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF, e);
}
}
-
+
private static void replacePlaceholder(PdfStamper stamper, int pageNr, String placeholderName) throws BadElementException, MalformedURLException, IOException, BadPdfFormatException, PresentableException {
Image img = Image.getInstance(SignaturePlaceholderData.class.getResource("empty.jpg"));
PdfImage pImg = new PdfImage(img, "Imwurscht", null);
PdfStamperImp stamperImp = (PdfStamperImp)stamper.getWriter();
PdfIndirectObject ind = stamperImp.addToBody(pImg);
-
+
PdfDictionary resources = stamper.getReader().getPageN(pageNr).getAsDict(PdfName.RESOURCES);
if (ind != null && resources != null)
{
@@ -999,11 +1030,11 @@ public abstract class BinarySignature
throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF, new NullPointerException("Resource dictionary not found in document structure!"));
}
}
-
+
/**
* Creates the EGIZ Dictionary and adds it to the document.
- *
+ *
* @param stamper
* The PdfStamper.
* @param table_template
@@ -1092,11 +1123,11 @@ public abstract class BinarySignature
// /encodings
replaces_array.add(new PdfName(new String(BREV_NIL, "US-ASCII"))); // the
// /Cert
-
+
if (iui.timeStamper != null) {
encodings_array.add(new PdfName(new String(ENCODING_NIL))); // the /Timestamp
replaces_array.add(new PdfName(new String(BREV_NIL, "US-ASCII"))); // the /timestamp
-
+
}
// hidden replaces
@@ -1153,9 +1184,9 @@ public abstract class BinarySignature
}
PdfString cert_placeholder = new PdfString(cert_bytes);
cert_array.add(cert_placeholder);
- egiz_dict.put(EGIZ_CERTIFICATE_NAME, cert_array);
-
- // Timestamp
+ egiz_dict.put(EGIZ_CERTIFICATE_NAME, cert_array);
+
+ // Timestamp
if (iui.timeStamper != null) {
// only if handler is available
PdfArray timestamp_array = new PdfArray();
@@ -1167,10 +1198,10 @@ public abstract class BinarySignature
}
PdfString timestamp_placeholder = new PdfString(timestamp_bytes);
timestamp_array.add(timestamp_placeholder);
- egiz_dict.put(EGIZ_TIMESTAMP_NAME, timestamp_array);
+ egiz_dict.put(EGIZ_TIMESTAMP_NAME, timestamp_array);
}
-
+
// /Data array with hidden information
if (has_hidden_variable_fields || invisibleKZString != null)
{
@@ -1221,7 +1252,7 @@ public abstract class BinarySignature
/**
* Converts a field name (type) to the corresponding BREV.
- *
+ *
* @param type
* The field name (type).
* @return Returns the corresponding BREV, or BREV_NIL if the type is not
@@ -1261,12 +1292,12 @@ public abstract class BinarySignature
/**
* Updates the information in the egiz dictionary to reflect the real offsets
* of the byte ranges.
- *
+ *
* <p>
* This replaces the "dummy numbers" in the egiz dictionary with the correct
* values.
* </p>
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @throws PDFDocumentException
@@ -1309,7 +1340,7 @@ public abstract class BinarySignature
byte[] cert_bytes = cert_str.getBytes("US-ASCII");
int cert_index = ByteArrayUtils.indexOf(signed_pdf, obj_start, cert_bytes);
int cert_start = cert_index + cert_bytes.length;
-
+
//Timestamp
int timestamp_index = 0;
int timestamp_start = 0;
@@ -1325,14 +1356,14 @@ public abstract class BinarySignature
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;
+ int num_holes = num_replaces + 1 + 1;
// +1 = the /encodings hole
- // +1 = the /Cert
+ // +1 = the /Cert
// +1 = the /Timestamp
if (iui.timeStamper != null) {
num_holes += 1;
@@ -1376,7 +1407,7 @@ public abstract class BinarySignature
iui.cert_start = cert_start;
}
-
+
// write the /Timestamp byte range
if (iui.timeStamper != null) {
StringInfo byte_range = new StringInfo();
@@ -1394,7 +1425,7 @@ public abstract class BinarySignature
cur_br_start = timestamp_start + iui.timestamp_length;
iui.timestamp_start = timestamp_start;
- }
+ }
// determine the /Data byte ranges if any
List ifd = iui.invisible_field_definitions;
@@ -1411,7 +1442,7 @@ public abstract class BinarySignature
{
StringInfo si = (StringInfo) iui.kz_list.get(0);
si.string_start = hole_start;
-
+
hole_start += si.string_length + 2;
}
@@ -1468,7 +1499,7 @@ 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++)
@@ -1494,7 +1525,7 @@ public abstract class BinarySignature
/**
* Replaces the certificate placeholder with the certificate from the signed
* Signature Object.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @throws PDFDocumentException
@@ -1550,7 +1581,7 @@ public abstract class BinarySignature
/**
* Replaces the timestam placeholder with the timestamp from the signed
* Signature Object.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @throws PDFDocumentException
@@ -1558,27 +1589,27 @@ public abstract class BinarySignature
public static void replaceTimestamp(IncrementalUpdateInformation iui) throws PDFDocumentException
{
String timestamp = iui.signed_signature_object.getSigTimeStamp();
- if (timestamp != null) {
+ if (timestamp != null) {
byte[] escaped = Placeholder.escapePDFString(timestamp.getBytes());
if (escaped.length > iui.timestamp_length)
{
throw new PlaceholderException("timestamp", escaped.length - iui.timestamp_length);
}
- System.arraycopy(escaped, 0, iui.signed_pdf, iui.timestamp_start, escaped.length);
+ System.arraycopy(escaped, 0, iui.signed_pdf, iui.timestamp_start, escaped.length);
}
}
-
+
/**
* Replaces the placeholders with values from the signed SignatureObject.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @throws PDFDocumentException
*/
public static void replacePlaceholders(IncrementalUpdateInformation iui) throws PDFDocumentException
{
- final int lineBreakTolerance = getLineBreakTolerance(iui);
-
+ final int lineBreakTolerance = getLineBreakTolerance(iui);
+
final byte[] signed_pdf = iui.signed_pdf;
// int num_replaces = calcNumReps(iui.replaces);
@@ -1661,7 +1692,7 @@ public abstract class BinarySignature
* carried out. Accordingly to this number, entries in the dictionary are
* created.
* </p>
- *
+ *
* @param replaces
* The ReplaceInfo list.
* @return Returns the number of string replaces.
@@ -1681,12 +1712,12 @@ public abstract class BinarySignature
/**
* Determines the List of ReplaceInfo objects of replaces in the content
* stream regarding the given field definitions.
- *
+ *
* <p>
* This method collects all variable String fields in a content stream and
* orders them according to their start offset.
* </p>
- *
+ *
* @param pdf
* The PDF.
* @param begin
@@ -1760,7 +1791,7 @@ public abstract class BinarySignature
/**
* Determines the Kennzeichnug in the content stream.
- *
+ *
* @param pdf
* The PDF.
* @param begin
@@ -1819,7 +1850,7 @@ public abstract class BinarySignature
/**
* Finds the index of the StringInfo within the StringInfo list that has the
* given content (caption).
- *
+ *
* @param strings
* The list of StringInfos.
* @param caption
@@ -1886,7 +1917,7 @@ public abstract class BinarySignature
/**
* Tells, if the given StringInfo contains only placeholder characters.
- *
+ *
* @param si
* The StringInfo.
* @param placeholder
@@ -1935,7 +1966,7 @@ public abstract class BinarySignature
/**
* Finds the first string after and at the given index not being a placeholder
* string.
- *
+ *
* @param strings
* The list of StringInfos.
* @param start
@@ -1958,7 +1989,7 @@ public abstract class BinarySignature
/**
* Restores the given String to its placeholder.
- *
+ *
* @param pdf
* The PDF.
* @param si
@@ -1978,7 +2009,7 @@ public abstract class BinarySignature
/**
* Reconstructs the replaces from the PDF and forms suitable value strings.
- *
+ *
* @param pdf
* The PDF.
* @param brevs
@@ -2044,7 +2075,7 @@ public abstract class BinarySignature
/**
* Reads an unsigned integer number.
- *
+ *
* @param pdf
* The PDF.
* @param start_index
@@ -2073,7 +2104,7 @@ public abstract class BinarySignature
/**
* Replaces a number by the new value.
- *
+ *
* @param pdf
* The PDF.
* @param start_index
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
index 7de89d2..1a89b7b 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
@@ -25,15 +25,19 @@
*/
package at.knowcenter.wag.egov.egiz.pdf;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger;
import org.pdfbox.cos.COSName;
import org.pdfbox.cos.COSStream;
import org.pdfbox.pdmodel.PDPage;
import org.pdfbox.pdmodel.PDResources;
+import org.pdfbox.pdmodel.common.PDRectangle;
import org.pdfbox.pdmodel.common.PDStream;
import org.pdfbox.pdmodel.graphics.xobject.PDXObject;
import org.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
@@ -44,6 +48,21 @@ import org.pdfbox.util.TextPosition;
import org.pdfbox.util.operator.OperatorProcessor;
import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.ClosePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveToReplicateFinalPoint;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveToReplicateInitialPoint;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.LineTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.MoveTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseFillEvenOddAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseFillNonZeroAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.EndPath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillEvenOddAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillNonZeroAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillPathEvenOddRule;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillPathNonZeroWindingNumberRule;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.StrokePath;
/**
* PDFPage is an inner class that is used to calculate the page length of a PDF
@@ -52,7 +71,7 @@ import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
* This method is called when processing the FileStream. By calling the method
* {@link org.pdfbox.util.PDFStreamEngine#processStream(org.pdfbox.pdmodel.PDPage, org.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)}
* the implemented method showCharacter is called.
- *
+ *
* @author wlackner
* @see PDFTextStripper
*/
@@ -67,41 +86,167 @@ public class PDFPage extends PDFTextStripper
* The maximum (lowest) y position of a character.
*/
protected float max_character_ypos = Float.NEGATIVE_INFINITY;
-
+
/**
* The maximum (lowest y position of an image.
*/
protected float max_image_ypos = Float.NEGATIVE_INFINITY;
-
+
/**
* The effective page height.
*/
protected float effectivePageHeight;
-
+
+ /**
+ * The path currently being constructed.
+ */
+ private GeneralPath currentPath = new GeneralPath();
+
+ /**
+ * The lowest position of a drawn path (originating from top).
+ */
+ private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
+
/**
* Constructor.
- *
+ *
* @param effectivePageHeight The height of the page to be evaluated. PDF elements outside this height will not be considered.
- *
+ *
* @throws IOException
*/
public PDFPage(float effectivePageHeight) throws IOException
{
super();
-
+
this.effectivePageHeight = effectivePageHeight;
-
+
OperatorProcessor newInvoke = new MyInvoke();
newInvoke.setContext(this);
operators.put("Do", newInvoke);
+
+ registerCustomPathOperators();
}
+ /**
+ * Registers operators responsible for path construction and painting in order to fix auto positioning on pages with
+ * path elements.
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+ @SuppressWarnings("unchecked")
+ private void registerCustomPathOperators() {
+
+ // *** path construction
+
+ operators.put("m", new MoveTo(this));
+ operators.put("l", new LineTo(this));
+ operators.put("c", new CurveTo(this));
+ operators.put("y", new CurveToReplicateFinalPoint(this));
+ operators.put("v", new CurveToReplicateInitialPoint(this));
+ operators.put("h", new ClosePath(this));
+
+ // *** path painting
+
+ // "S": stroke path
+ operators.put("S", new StrokePath(this));
+ operators.put("s", new CloseAndStrokePath(this));
+ operators.put("f", new FillPathNonZeroWindingNumberRule(this));
+ operators.put("F", new FillPathNonZeroWindingNumberRule(this));
+ operators.put("f*", new FillPathEvenOddRule(this));
+ operators.put("b", new CloseFillNonZeroAndStrokePath(this));
+ operators.put("B", new FillNonZeroAndStrokePath(this));
+ operators.put("b*", new CloseFillEvenOddAndStrokePath(this));
+ operators.put("B*", new FillEvenOddAndStrokePath(this));
+ operators.put("n", new EndPath(this));
+
+ // Note: The graphic context (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying pdfbox library does
+ // not yet support clipping. This prevents feasible usage of clipping operators (W, W*).
+// operators.put("W", new ...(this));
+// operators.put("W*", new ...(this));
+
+ }
+
+ /**
+ * Returns the path currently being constructed.
+ *
+ * @return The path currently being constructed.
+ */
+ public GeneralPath getCurrentPath() {
+ return currentPath;
+ }
+
+ /**
+ * Sets the current path.
+ * @param currentPath The new current path.
+ */
+ public void setCurrentPath(GeneralPath currentPath) {
+ this.currentPath = currentPath;
+ }
+
+ /**
+ * Registers a rectangle that bounds the path currently being drawn.
+ *
+ * @param bounds
+ * A rectangle depicting the bounds (coordinates originating from bottom left).
+ * @author Datentechnik Innovation GmbH
+ */
+ public void registerPathBounds(Rectangle bounds) {
+ if (!bounds.isEmpty()) {
+ logger_.trace("Registering path bounds: " + bounds);
+
+ // vertical start of rectangle (counting from top of page)
+ float upperBoundYPositionFromTop;
+
+ // vertical end of rectangle (counting from top of page)
+ // this depicts the current end of path-related page content
+ float lowerBoundYPositionFromTop;
+
+ PDRectangle boundaryBox = page.findMediaBox();
+ float pageHeight;
+
+ switch (page.findRotation()) {
+ case 90: // CW
+ pageHeight = boundaryBox.getWidth();
+ upperBoundYPositionFromTop = (float) bounds.getMinX();
+ lowerBoundYPositionFromTop = (float) bounds.getMaxX();
+ break;
+ case 180:
+ pageHeight = boundaryBox.getHeight();
+ upperBoundYPositionFromTop = (float) bounds.getMinY();
+ lowerBoundYPositionFromTop = (float) bounds.getMaxY();
+ break;
+ case 270: // CCW
+ pageHeight = boundaryBox.getWidth();
+ upperBoundYPositionFromTop = pageHeight - (float) bounds.getMaxX();
+ lowerBoundYPositionFromTop = pageHeight - (float) bounds.getMinX();
+ break;
+ default:
+ pageHeight = boundaryBox.getHeight();
+ upperBoundYPositionFromTop = pageHeight - (float) bounds.getMaxY();
+ lowerBoundYPositionFromTop = pageHeight - (float) bounds.getMinY();
+ break;
+ }
+
+ // new maximum ?
+ if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) {
+ // Is the rectangle (at least partly) located above the footer line?
+ // (effective page height := page height - footer line)
+ if (upperBoundYPositionFromTop <= effectivePageHeight) {
+ // yes: update current end of path-related page content
+ maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop;
+ logger_.trace("New max path related y position (from top): " + maxPathRelatedYPositionFromTop);
+ } else {
+ // no: rectangle is fully located below the footer line -> ignore
+ logger_.trace("Ignoring path bound below the footer line.");
+ }
+ }
+ }
+ }
protected void processOperator(PDFOperator operator, List arguments) throws IOException
{
- //logger_.debug("operator = " + operator);
-
- super.processOperator(operator, arguments);
+// logger_.debug("operator = " + operator);
+ super.processOperator(operator, arguments);
}
// exthex
@@ -111,7 +256,7 @@ public class PDFPage extends PDFTextStripper
* is used to calculate the latest position of a text in the page. Sorry for
* this missinterpretation of the method, but it is the only way to do this
* (provided by PDFBox)!!!
- *
+ *
* @param text
* the character to be displayed -> calculate there y position.
*/
@@ -119,7 +264,7 @@ public class PDFPage extends PDFTextStripper
{
float current_y = text.getY();
final String character = text.getCharacter();
-
+
int pageRotation = page.findRotation();
//logger_.debug("PageRotation = " + pageRotation);
if (pageRotation == 0)
@@ -146,7 +291,7 @@ public class PDFPage extends PDFTextStripper
//logger_.debug("character is below footer_line. footer_line = " + this.footer_line + ", text.character=" + character + ", y=" + current_y);
return;
}
-
+
// store ypos of the char if it is not empty
if (!character.equals(" ") && current_y > this.max_character_ypos)
{
@@ -160,26 +305,18 @@ public class PDFPage extends PDFTextStripper
// logger_.debug(new String(string));
// }
- /**
- * Returns the calculated page length.
- *
- * @return the max page length value
- */
- public float getMaxPageLength()
- {
- float max_ypos = Float.NEGATIVE_INFINITY;
-
- if (this.max_character_ypos > this.max_image_ypos)
- {
- max_ypos = this.max_character_ypos;
- }
- else
- {
- max_ypos = this.max_image_ypos;
- }
-
- return max_ypos;
- }
+ /**
+ * Returns the calculated page length.
+ *
+ * @return the max page length value
+ */
+ public float getMaxPageLength() {
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Determining page content length: text=" + max_character_ypos + ", image=" + max_image_ypos
+ + ", path=" + maxPathRelatedYPositionFromTop);
+ }
+ return NumberUtils.max(max_character_ypos, max_image_ypos, maxPathRelatedYPositionFromTop);
+ }
public class MyInvoke extends OperatorProcessor
{
@@ -192,26 +329,26 @@ public class PDFPage extends PDFTextStripper
Map xobjects = context.getXObjects();
PDXObject xobject = (PDXObject) xobjects.get(name.getName());
-
+
PDStream stream = xobject.getPDStream();
COSStream cos_stream = stream.getStream();
-
+
COSName subtype = (COSName) cos_stream.getDictionaryObject(COSName.SUBTYPE);
if (subtype.equals(COSName.IMAGE))
{
logger_.debug("XObject Image");
-
+
Matrix ctm = context.getGraphicsState().getCurrentTransformationMatrix();
logger_.debug("ctm = " + ctm);
-
+
Pos [] coordinates = new Pos [] {
new Pos(0, 0, 1),
new Pos(1, 0, 1),
new Pos(0, 1, 1),
new Pos(1, 1, 1) };
-
+
Pos [] transformed_coordinates = transtormCoordinates(coordinates, ctm);
-
+
/**********************************************************
* pdf-as fix:
* calculating min and max point of an image to look where
@@ -219,10 +356,10 @@ public class PDFPage extends PDFTextStripper
* fix solves problems with footer and images and
* placement of the signature in an image only pdf document
**********************************************************/
-
+
float actual_lowest_point = Float.NaN;
float actual_starting_point = Float.NaN;
-
+
int pageRotation = page.findRotation();
logger_.debug("PageRotation = " + pageRotation);
if (pageRotation == 0)
@@ -231,7 +368,7 @@ public class PDFPage extends PDFTextStripper
logger_.debug("min_y = " + min_y);
float page_height = page.findMediaBox().getHeight();
logger_.debug("page_height = " + page_height);
-
+
actual_lowest_point = page_height - min_y;
actual_starting_point = page_height - findMaxY(transformed_coordinates);
}
@@ -243,7 +380,7 @@ public class PDFPage extends PDFTextStripper
logger_.debug("page_width = " + page_width);
actual_lowest_point = max_x;
- actual_starting_point = findMinX(transformed_coordinates);
+ actual_starting_point = findMinX(transformed_coordinates);
}
if (pageRotation == 180)
{
@@ -257,17 +394,17 @@ public class PDFPage extends PDFTextStripper
{
float min_x = findMinX(transformed_coordinates);
logger_.debug("min_x = " + min_x);
-
+
float page_width = page.findMediaBox().getWidth();
logger_.debug("page_width = " + page_width);
-
+
actual_lowest_point = page_width - min_x;
- actual_starting_point = page_width - findMaxX(transformed_coordinates);
+ actual_starting_point = page_width - findMaxX(transformed_coordinates);
}
-
+
logger_.debug("actual_lowest_point = " + actual_lowest_point);
-
+
if (actual_lowest_point > PDFPage.this.effectivePageHeight && actual_starting_point > PDFPage.this.effectivePageHeight)
{
logger_.debug("image is below footer_line");
@@ -278,7 +415,7 @@ public class PDFPage extends PDFTextStripper
{
PDFPage.this.max_image_ypos = actual_lowest_point;
}
-
+
return;
}
@@ -297,7 +434,7 @@ public class PDFPage extends PDFTextStripper
}
}
}
-
+
public static Pos [] transtormCoordinates (Pos [] coordinates, Matrix m)
{
Pos [] transformed = new Pos [coordinates.length];
@@ -307,18 +444,18 @@ public class PDFPage extends PDFTextStripper
}
return transformed;
}
-
+
public static Pos transtormCoordinate (Pos pos, Matrix m)
{
Pos transformed = new Pos();
transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0) + pos.z * m.getValue(2, 0);
transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1) + pos.z * m.getValue(2, 1);
transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2) + pos.z * m.getValue(2, 2);
-
+
logger_.debug(" transformed " + pos + " --> " + transformed);
return transformed;
}
-
+
public static float findMinY (Pos [] coordinates)
{
float min = Float.POSITIVE_INFINITY;
@@ -331,7 +468,7 @@ public class PDFPage extends PDFTextStripper
}
return min;
}
-
+
public static float findMaxY(Pos[] coordinates) {
float max = 0;
for (int i = 0; i < coordinates.length; i++) {
@@ -341,7 +478,7 @@ public class PDFPage extends PDFTextStripper
}
return max;
}
-
+
public static float findMaxX (Pos [] coordinates)
{
float max = Float.NEGATIVE_INFINITY;
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java
index a8a150e..3b9909f 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java
@@ -35,6 +35,7 @@ import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.gv.egiz.pdfas.utils.PDFASUtils;
import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
@@ -59,7 +60,7 @@ import com.lowagie.text.pdf.SubsetLocal;
* This class is the IText implementation of the PDFSignatureObject interface.
* The class takes an abstract definition of a signature object and convert them
* into a pdf table that is used to sign a pdf document.
- *
+ *
* @author wlackner
* @see at.knowcenter.wag.egov.egiz.sig.SignatureObject
* @see at.knowcenter.wag.egov.egiz.table.Table
@@ -76,8 +77,6 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
// Also fixed a minor bug which prevented proper style inheritment (Bug Nr. #534).
// 04.11.2010 changed by exthex - allow setting separate hAlign and vAlign for image cells analog to value cells.
- private static final String SIG_PDFA1_B_VALID = "SIG_PDFA1B_VALID";
-
/**
* The default font definition
*/
@@ -116,7 +115,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* The empty constructor. It loads the ui definitions from signature tables
* and init the align map.
- *
+ *
* @throws PDFDocumentException
*/
public PDFSignatureObjectIText() throws PDFDocumentException
@@ -127,7 +126,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* load the class settings
- *
+ *
* @throws PDFDocumentException
* @see SettingsReader
*/
@@ -174,7 +173,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* Set the abstract signature definition.
- *
+ *
* @param signatorObject
* the abstract signator object
* @see at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject#setSignatorObject(at.knowcenter.wag.egov.egiz.sig.SignatureObject)
@@ -186,7 +185,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* This method maps the table cell definitions to the pdfCell element.
- *
+ *
* @param pdfCell
* the pdf cell to be styled
* @param cellStyle
@@ -226,7 +225,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
align = ((Integer) alignMap_.get(cellStyle.getVAlign())).intValue();
if (align != -1)
pdfCell.setVerticalAlignment(align);
-
+
align = -1;
if (type == Entry.TYPE_VALUE && cellStyle.getValueHAlign() != null)
align = ((Integer) alignMap_.get(cellStyle.getValueHAlign())).intValue();
@@ -242,7 +241,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* This method maps the cell font definition to the iText Font Object
- *
+ *
* @param fontString
* @return the corresponding iText Font Object
* @see com.lowagie.text.Font
@@ -277,12 +276,12 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
int face = ((Integer) font_face).intValue();
float height = Float.parseFloat(font_arr[1]);
int weight = ((Integer) font_weight).intValue();
-
+
font = new Font(face, height, weight);
fontMap_.put(fontString, font);
return font;
}
-
+
/**
* Creates a custom
* @param fontString
@@ -305,15 +304,15 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
}
}
logger_.debug("TrueType Font detected:"+fontName +" ("+fontSize+")");
-
+
try {
Font font = (Font) fontMap_.get(fontString);
-
+
if (font == null) {
logger_.debug("Font \"" + fontString + "\" not in cache. Instantiating font.");
String fontPath = SettingsReader.RESOURCES_PATH + "fonts" + File.separator + fontName;
logger_.debug("Instantiating \"" + fontPath + "\".");
-
+
font = new Font(BaseFont.createFont(fontPath, BaseFont.WINANSI, true), fontSize);
fontMap_.put(fontString, font);
}
@@ -334,7 +333,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
* <li>images</li>
* <li>tables</li>
* </ul>
- *
+ *
* @param abstractCell
* the abstract cell definition
* @return the new redererd pdf table cell
@@ -345,27 +344,8 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
*/
private PdfPCell renderCell(Entry abstractCell) throws PDFDocumentException
{
- boolean pdfaValid =false;
- try
- {
- String profileid = sigObject_.getSignatureTypeDefinition().getType();
- String pdfa = SettingsReader.getInstance().getSetting("sig_obj." +profileid+".key."+SIG_PDFA1_B_VALID, "default."+SIG_PDFA1_B_VALID, "false");
- pdfaValid= "true".equalsIgnoreCase(pdfa);
-
-// exthex test
- //SubsetLocal.set(!pdfaValid);
-
-// boolean forceSubset = true; // get this from config, default to false
- //String
-
- //SubsetLocal.set(true); // exthex
-
- logger_.trace("Sign PDF/A compliant:"+pdfa);
- } catch (SettingsException e1)
- {
- logger_.error(e1);
- }
-
+ boolean pdfaValid = PDFASUtils.isPdfAEnabled(sigObject_.getSignatureTypeDefinition().getType());
+
PdfPCell pdf_cell = null;
Style cell_style = abstractCell.getStyle();
boolean isValue = true;
@@ -384,7 +364,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
{
font_string = cell_style.getValueFont();
}
-
+
logger_.trace("using cell font: "+font_string);
Font cell_font;
@@ -402,7 +382,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
}
// exthex
if (pdfaValid && abstractCell.getType() == Entry.TYPE_VALUE) {
- SubsetLocal.addNonSubsetFont(cell_font.getBaseFont());
+ SubsetLocal.addNonSubsetFont(cell_font.getBaseFont());
}
Phrase text_phrase = new Phrase(text, cell_font);
pdf_cell = new PdfPCell(text_phrase);
@@ -429,9 +409,9 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
}
Image image = Image.getInstance(img_file.getCanonicalPath());
logger_.debug("Using image file \"" + img_file.getCanonicalPath() + "\".");
-
+
image.scaleToFit(80.0f, 80.0f);
- boolean fit = true;
+ boolean fit = true;
Style.ImageScaleToFit istf = cell_style.getImageScaleToFit();
if (istf != null)
{
@@ -490,7 +470,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
* This method visualize an abstract table into a corresponding pdf table. The
* new pdf table is redered and get the style information from the abstract
* cell.
- *
+ *
* @param abstractTable
* the abstract table definition
* @return the new redererd pdf table cell
@@ -558,7 +538,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* This method creates the pdf table object. It takes the abstract table
* definition from the signature object and render the abstract table.
- *
+ *
* @param sigObject
* the signature object, the base for the abstract table definition
* @return R
@@ -587,7 +567,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* Converts the current abstract signature object in a pdf signature object
* implementation
- *
+ *
* @return the converted pdf signature object
* @see at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject#getSignatureObject()
*/
@@ -603,11 +583,11 @@ public class PDFSignatureObjectIText implements PDFSignatureObject
/**
* Converts a abstract signature object in a pdf signature object
* implementation
- *
+ *
* @param sigObject
* the abstract signatorObject to convert
* @return the converted pdf signature object
- * @throws PDFDocumentException
+ * @throws PDFDocumentException
* @see at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject#getSignatureObject(at.knowcenter.wag.egov.egiz.sig.SignatureObject)
*/
public Object getSignatureObject(SignatureObject sigObject) throws PDFDocumentException
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
index bdc1078..b3adb71 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
@@ -32,6 +32,7 @@ import java.util.List;
import at.gv.egiz.pdfas.framework.input.PdfDataSource;
import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl;
+import at.gv.egiz.pdfas.utils.PDFASUtils;
import org.pdfbox.pdfparser.PDFParser;
import org.pdfbox.pdmodel.PDDocument;
@@ -44,7 +45,7 @@ import com.lowagie.text.DocumentException;
/**
* Contains useful helpers for accessing PDF documents.
- *
+ *
* @author wprinz
* @author mruhmer
*/
@@ -52,12 +53,13 @@ public abstract class PDFUtilities
{
public static float calculatePageLength(final PdfDataSource pdfDataSource, int page, float effectivePageHeight, int pagerotation) throws PDFDocumentException
{
+ PDDocument pdfDocument_ = null;
try
{
//ByteArrayInputStream original_bais = new ByteArrayInputStream(pdf);
//byte [] normalized_pdf = TextualSignature.normalizePDF(original_bais);
byte [] normalized_pdf = TextualSignature.normalizePDF(pdfDataSource);
-
+
// PERF: The whole PDF normalization process is costy
ByteArrayInputStream bais = new ByteArrayInputStream(normalized_pdf);
@@ -66,9 +68,8 @@ public abstract class PDFUtilities
parser.setTempDirectory(temporary_dir);
parser.parse();
- PDDocument pdfDocument_ = parser.getPDDocument();
+ pdfDocument_ = parser.getPDDocument();
float page_length = calculatePageLength(pdfDocument_, page, effectivePageHeight, pagerotation);
- pdfDocument_.close();
return page_length;
}
catch (IOException e)
@@ -78,8 +79,10 @@ public abstract class PDFUtilities
catch (DocumentException e)
{
throw new PDFDocumentException(201, e);
+ } finally {
+ PDFASUtils.closeQuietly(pdfDocument_);
}
- }
+ }
public static float calculatePageLength(PDDocument document, int page, float effectivePageHeight, int pagerotation) throws IOException
{
//int last_page_id = document.getNumberOfPages();
@@ -87,8 +90,8 @@ public abstract class PDFUtilities
PDPage pdpage = (PDPage) allPages.get(page);
pdpage.setRotation(pagerotation);
return calculatePageLength(pdpage, effectivePageHeight);
- }
-
+ }
+
/**
* @deprecated
* @param pdf
@@ -98,12 +101,13 @@ public abstract class PDFUtilities
*/
public static float calculateLastPageLength(final byte[] pdf, float effectivePageHeight) throws PDFDocumentException
{
+ PDDocument pdfDocument_ = null;
try
{
//ByteArrayInputStream original_bais = new ByteArrayInputStream(pdf);
PdfDataSource dataSource = new ByteArrayPdfDataSourceImpl(pdf);
byte [] normalized_pdf = TextualSignature.normalizePDF(dataSource);
-
+
ByteArrayInputStream bais = new ByteArrayInputStream(normalized_pdf);
PDFParser parser = new PDFParser(bais);
@@ -111,9 +115,8 @@ public abstract class PDFUtilities
parser.setTempDirectory(temporary_dir);
parser.parse();
- PDDocument pdfDocument_ = parser.getPDDocument();
+ pdfDocument_ = parser.getPDDocument();
float last_page_length = calculateLastPageLength(pdfDocument_, effectivePageHeight);
- pdfDocument_.close();
return last_page_length;
}
@@ -124,6 +127,8 @@ public abstract class PDFUtilities
catch (DocumentException e)
{
throw new PDFDocumentException(201, e);
+ } finally {
+ PDFASUtils.closeQuietly(pdfDocument_);
}
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
index a9c1c54..deb5fed 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/StructContentHelper.java
@@ -173,9 +173,8 @@ public class StructContentHelper implements StructContentWriter {
}
} catch (Exception ex) {
- logger.error("error", ex);
- throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF,
- "error writing structured signature content", ex);
+ logger.warn("Unable to process structured document data. Going to write untagged signature block.", ex);
+ isTagged = false;
}
}
@@ -471,16 +470,38 @@ public class StructContentHelper implements StructContentWriter {
}
}
- private void checkTagging() {
- PdfDictionary markDict = stamper.getReader().getCatalog().getAsDict(PdfName.MARKINFO);
- if (markDict != null) {
- isTagged = markDict.getAsBoolean(PdfName.MARKED).booleanValue();
- }
- if (!isTagged) {
- logger.debug("input document is not tagged. no structure/wai information is written");
- }
- logger.debug("Input is tagged. Writing structure/WAI data.");
- }
+ private void checkTagging() {
+ PdfDictionary markDict = stamper.getReader().getCatalog().getAsDict(PdfName.MARKINFO);
+ if (markDict != null) {
+ isTagged = markDict.getAsBoolean(PdfName.MARKED).booleanValue();
+ }
+ if (!isTagged) {
+ logger.debug("Input document is not tagged. No structure data will be attached to signature block.");
+ } else {
+ logger.trace("Document claims to be tagged. Checking availability of structured tree root.");
+ PdfDictionary structTreeRoot;
+ if ((structTreeRoot = getStructTreeRoot()) == null) {
+ // document claimed to be tagged but document does not contain structural information
+ isTagged = false;
+ logger.debug("Document claims to be tagged structured tree root was not found.");
+ } else if (getParentTreeNums() == null) {
+ // document claimed to be tagged but document does not contain structural information
+ isTagged = false;
+ logger.debug("Document claims to be tagged but required information is missing.");
+ } else if (structTreeRoot.getDirectObject(PdfName.K) == null) {
+ // structured content
+ isTagged = false;
+ logger.debug("Document claims to be tagged but required information is missing.");
+ } else {
+ logger.debug("Input is tagged and required structure data seems to be available. Going to write structured signature block.");
+ }
+ if (!isTagged) {
+ logger.info("Unable to process structured document data. Going to write untagged signature block.");
+ }
+ }
+ }
+
+
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java
index 35a0768..3ce690b 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java
@@ -53,7 +53,7 @@ import com.lowagie.text.pdf.PdfWriter;
/**
* Contains helper function for textual signatures.
- *
+ *
* @author wprinz
*/
public class TextualSignature
@@ -62,21 +62,22 @@ public class TextualSignature
* The logger definition.
*/
private static final Logger logger_ = ConfigLogger.getLogger(TextualSignature.class);
-
+
/**
* Extracts the document text from a given pdf.
- *
+ *
* @param pdf_stream
* The pdf_input stream.
* @return Returns the extracted document text.
- * @throws PDFDocumentException
+ * @throws PDFDocumentException
* @throws TextExtractionException
* Forwarded exception.
*/
- public static String extractTextTextual(PdfDataSource pdfDataSource, String encoding) throws PDFDocumentException
+ public static String extractTextTextual(PdfDataSource pdfDataSource, String encoding) throws PDFDocumentException
{
PerformanceCounters.textExtractions.increment();
-
+ PDDocument doc = null;
+ Document document = null;
try
{
int first_page_rotation = 0;
@@ -90,12 +91,8 @@ public class TextualSignature
// byte[] bytes = normalizePDF(pdf_stream);
- //iText
-
- byte [] pdf_data = pdfDataSource.getAsByteArray();
- PdfReader reader = new PdfReader(pdf_data);
- PDFASUtils.checkReaderPermissions(reader);
- //pdf_stream.close();
+
+ PdfReader reader = PDFASUtils.createPdfReaderCheckingPermissions(pdfDataSource);
// PERF: PDF normalization needs byte array - this is costy
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
@@ -108,7 +105,7 @@ public class TextualSignature
// this method (although it works when a Table is appended)... very
// fragile.
- Document document = new Document();
+ document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
@@ -126,7 +123,7 @@ public class TextualSignature
first_page_rotation = new_size_withrot.getRotation();
//logger_.info("iText first_page_rotation="+new_size_withrot.getRotation());
}
- //logger_.info("iText set PageSize of page:"+page_num+" to: "+new_size_withrot);
+ //logger_.info("iText set PageSize of page:"+page_num+" to: "+new_size_withrot);
//document.setPageSize(new_size);
document.setPageSize(new_size_withrot);
document.newPage();
@@ -163,15 +160,15 @@ public class TextualSignature
//logger_.info("temporary_dir="+temporary_dir.getAbsolutePath());
parser.setTempDirectory(temporary_dir);
parser.parse();
-
- PDDocument doc = parser.getPDDocument();
+
+ doc = parser.getPDDocument();
//System.out.println("pdfBox.getNumberOfPages()"+doc.getNumberOfPages());
-
+
PDFTextStripper stripper = new PDFTextStripper();
stripper.setSortByPosition(false);
stripper.setGetFirstPageRotationFromThis(true);
stripper.setFirstPageRotation(first_page_rotation);
-
+
// stripper.setStartPage(4);
// stripper.setEndPage(4);
logger_.debug("TextualSignator extractTextTextual: Begin stripping text");
@@ -182,8 +179,7 @@ public class TextualSignature
throw new PDFDocumentException(ErrorCode.TEXT_EXTRACTION_EXCEPTION, "Unable to extract textual content.", e);
}
logger_.debug("TextualSignator extractTextTextual: Stripping text ended");
-
- doc.close();
+
//logger_.debug("TextualSignator extractTextTextual="+text);
return text;
@@ -199,39 +195,39 @@ public class TextualSignature
catch (DocumentException e)
{
throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e);
+ } finally {
+ PDFASUtils.closeQuietly(doc);
+ PDFASUtils.closeQuietly(document);
}
}
-
+
/**
* Normalizes a given binary PDF to a version PDFbox can handle correctly.
- *
+ *
* <p>
* PDFbox has serious problems with documents that use incremental updates or
* XObject forms. Therefor use this to remove incremental updates and create a
* streamlined document.
* </p>
- *
+ *
* <p>
* Note that this has nothing to do with text normalization. It just unifies
* the PDF documents that are fed into PDFbox for text extraction and page
* length determination.
* </p>
- *
+ *
* @param input_pdf
* The input pdf to be normalized.
* @return Returns the normalized pdf.
* @throws IOException
* @throws DocumentException
- * @throws PDFDocumentException
+ * @throws PDFDocumentException
*/
public static byte[] normalizePDF(PdfDataSource pdfDataSource) throws IOException, DocumentException, PDFDocumentException
{
//iText
- byte [] pdf_data = pdfDataSource.getAsByteArray();
- PdfReader reader = new PdfReader(pdf_data);
- PDFASUtils.checkReaderPermissions(reader);
- //input_pdf.close();
-
+ PdfReader reader = PDFASUtils.createPdfReaderCheckingPermissions(pdfDataSource);
+
// PERF: PDF Normalization needs byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// For some reason the Reader -> ImportPage -> Writer mechanism produces
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
new file mode 100644
index 0000000..143a6b6
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
@@ -0,0 +1,62 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import java.awt.geom.Point2D;
+
+import org.pdfbox.util.operator.OperatorProcessor;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+
+/**
+ * Provides functions for path construction operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathConstructionOperatorProcessor extends OperatorProcessor {
+
+ public PathConstructionOperatorProcessor(PDFPage context) {
+ setContext(context);
+ }
+
+ /**
+ * Transforms the given point from user space coordinates to device space coordinates based on the current
+ * transition matrix.
+ *
+ * @param x
+ * The x axis value of the user space coordinates.
+ * @param y
+ * The y axis value of the user space coordinates.
+ * @return The transformed point.
+ */
+ public Point2D transform(double x, double y) {
+ double[] position = { x, y };
+ context.getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
+ .transform(position, 0, position, 0, 1);
+ return new Point2D.Double(position[0], position[1]);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
new file mode 100644
index 0000000..9a76f87
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
@@ -0,0 +1,43 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import org.pdfbox.util.operator.OperatorProcessor;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+
+/**
+ * Provides functions for path painting operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathPaintingOperatorProcessor extends OperatorProcessor {
+
+ public PathPaintingOperatorProcessor(PDFPage context) {
+ setContext(context);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
new file mode 100644
index 0000000..ea87887
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
@@ -0,0 +1,68 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Close the current subpath by appending a straight line segment from the current point to the starting point of the
+ * subpath. If the current subpath is already closed, h shall donothing. This operator terminates the current subpath.
+ * Appending another segment to the current path shall begin a new subpath, even if the new segment begins at the
+ * endpoint reached by the h operation.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class ClosePath extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public ClosePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().closePath();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Closing current path.");
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'h'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
new file mode 100644
index 0000000..a2fc8de
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
@@ -0,0 +1,85 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x1 = (COSNumber) operands.get(0);
+ COSNumber y1 = (COSNumber) operands.get(1);
+ COSNumber x2 = (COSNumber) operands.get(2);
+ COSNumber y2 = (COSNumber) operands.get(3);
+ COSNumber x3 = (COSNumber) operands.get(4);
+ COSNumber y3 = (COSNumber) operands.get(5);
+
+ Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+ Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float) p1.getX(), (float) p1.getY(),
+ (float) p2.getX(), (float) p2.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x2:"
+ + p2.getX() + ",y2:" + p2.getY() + ", x3:" + p3.getX() + ",y3:" + p3.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'c'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
new file mode 100644
index 0000000..bb5c86c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
@@ -0,0 +1,82 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x3, y3) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateFinalPoint extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveToReplicateFinalPoint(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x1 = (COSNumber) operands.get(0);
+ COSNumber y1 = (COSNumber) operands.get(1);
+ COSNumber x3 = (COSNumber) operands.get(2);
+ COSNumber y3 = (COSNumber) operands.get(3);
+
+ Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float) p1.getX(), (float) p1.getY(),
+ (float) p3.getX(), (float) p3.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x3:"
+ + p3.getX() + ",y3:" + p3.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'y'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
new file mode 100644
index 0000000..b35bcaf
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
@@ -0,0 +1,84 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using the current point and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new
+ * current point shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateInitialPoint extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveToReplicateInitialPoint(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x2 = (COSNumber) operands.get(0);
+ COSNumber y2 = (COSNumber) operands.get(1);
+ COSNumber x3 = (COSNumber) operands.get(2);
+ COSNumber y3 = (COSNumber) operands.get(3);
+
+ Point2D currentPoint = pdfPage.getCurrentPath().getCurrentPoint();
+ Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float)currentPoint.getX(), (float)currentPoint.getY(),
+ (float) p2.getX(), (float) p2.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x2:" + p2.getX() + ",y2:" + p2.getY() + ", x3:"
+ + p3.getX() + ",y3:" + p3.getY() + ", using current point x:" + currentPoint.getX() + ",y:"
+ + currentPoint.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'v'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
new file mode 100644
index 0000000..ae5894d
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
@@ -0,0 +1,71 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Append a straight line segment from the current point to the point (x, y). The new current point shall be (x, y).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class LineTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public LineTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x = (COSNumber) operands.get(0);
+ COSNumber y = (COSNumber) operands.get(1);
+ Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+ pdfPage.getCurrentPath().lineTo((float) p.getX(), (float) p.getY());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Adding line to x:" + p.getX() + ",y:" + p.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'l'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
new file mode 100644
index 0000000..b43de2e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
@@ -0,0 +1,73 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.cos.COSNumber;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+
+/**
+ * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. If the
+ * previous path construction operator in the current path was also m, the new m overrides it; no vestige of the
+ * previous m operation remains in the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class MoveTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public MoveTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x = (COSNumber) operands.get(0);
+ COSNumber y = (COSNumber) operands.get(1);
+ Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+ pdfPage.getCurrentPath().moveTo((float) p.getX(), (float) p.getY());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Moving current path to x:" + p.getX() + ",y:" + p.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'm'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
new file mode 100644
index 0000000..54f4af8
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
@@ -0,0 +1,59 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Close and stroke the path. This operator shall have the same effect as the sequence <code>h S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("S", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
new file mode 100644
index 0000000..6a84cf4
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
@@ -0,0 +1,60 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall
+ * have the same effect as the sequence <code>h B*</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseFillEvenOddAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing, filling (even odd rule) and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("B*", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
new file mode 100644
index 0000000..f8db567
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
@@ -0,0 +1,60 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill. This
+ * operator shall have the same effect as the sequence <code>h B</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseFillNonZeroAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing, filling (non zero rule) and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("B", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
new file mode 100644
index 0000000..4448a1e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
@@ -0,0 +1,68 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * End the path object without filling or stroking it. This operator shall be a path-painting no-op, used primarily for
+ * the side effect of changing the current clipping path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class EndPath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public EndPath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ log.debug("Ending path " + pdfPage.getCurrentPath());
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("End path without filling or stroking.");
+ }
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'n'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
new file mode 100644
index 0000000..8a42dff
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
@@ -0,0 +1,72 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Fill and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall produce
+ * the same result as <code>B</code>, except that the path is filled as if with <code>f*</code> instead of
+ * <code>f</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillEvenOddAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling (even odd rule) and stroking path.");
+ }
+
+ GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+ context.processOperator("f*", operands);
+ pdfPage.setCurrentPath(currentPath);
+ context.processOperator("S", operands);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'B*'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
new file mode 100644
index 0000000..96025ed
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
@@ -0,0 +1,72 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill. This operator
+ * shall produce the same result as constructing two identical path objects, painting the first with <code>f</code> and
+ * the second with <code>S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillNonZeroAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling (non zero rule) and stroking path.");
+ }
+
+ GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+ context.processOperator("f", operands);
+ pdfPage.setCurrentPath(currentPath);
+ context.processOperator("S", operands);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'B'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
new file mode 100644
index 0000000..c6417ea
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
@@ -0,0 +1,71 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Fill the path, using the even-odd rule to determine the region to fill.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathEvenOddRule extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillPathEvenOddRule(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling path, using even-odd rule.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'f*'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
new file mode 100644
index 0000000..b350009
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
@@ -0,0 +1,72 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Fill the path, using the nonzero winding number rule to determine the region to fill. Any subpaths that are open
+ * shall be implicitly closed before being filled.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathNonZeroWindingNumberRule extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillPathNonZeroWindingNumberRule(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_NON_ZERO);
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling path, using nonzero winding number rule.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'f/F'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
new file mode 100644
index 0000000..9dfce7e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
@@ -0,0 +1,70 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.pdfbox.util.PDFOperator;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+
+/**
+ * Strokes the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class StrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public StrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Stroking path.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'S'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
index 9e28213..b5a05ed 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
@@ -77,7 +77,7 @@ import at.knowcenter.wag.egov.egiz.tools.Normalizer;
* All values that build or used by the signation creation process, call the
* external services, can read or set separately. All other values are defined
* in the settings file.
- *
+ *
* @author wlackner
* @author modified by <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas Knall</a>
*/
@@ -138,7 +138,7 @@ public class SignatureObject implements Serializable
public static final String SIG_CER_DIG = "SIG_CER_DIG";
private X509Cert x509Cert_ = null;
-
+
private String timeStamp = null;
// public static final String SIG_RES = "SIG_RES";
@@ -194,7 +194,7 @@ public class SignatureObject implements Serializable
/**
* The raw xml response from the connector that was used to set the values in
* this SignatureObject.
- *
+ *
* <p>
* This is set by the Connector so that signing Applications can use the
* returned XML values.
@@ -222,7 +222,7 @@ public class SignatureObject implements Serializable
/**
* The empty constructor. It initilize the normlizer, load the settings and
* set the default styles.
- *
+ *
* @throws SignatureException
* ErrorCode:101, 400
*/
@@ -235,7 +235,7 @@ public class SignatureObject implements Serializable
/**
* This method initialize the normalizer
- *
+ *
* @throws SignatureException
* ErrorCode:400
*/
@@ -254,7 +254,7 @@ public class SignatureObject implements Serializable
/**
* This method load the signature definitions
- *
+ *
* @throws SignatureException
* ErrorCode:101
*/
@@ -296,7 +296,7 @@ public class SignatureObject implements Serializable
/**
* Dummy getter Method for debugging only
- *
+ *
* @return response string
*/
public String getSigResponse()
@@ -306,7 +306,7 @@ public class SignatureObject implements Serializable
/**
* Dummy setter Method for debugging only
- *
+ *
* @param sigRespone
* store the response string
*/
@@ -317,7 +317,7 @@ public class SignatureObject implements Serializable
/**
* This method set the signature type.
- *
+ *
* @param sigType
* the signature type to be set
* @throws SignatureTypesException
@@ -331,7 +331,7 @@ public class SignatureObject implements Serializable
/**
* Returns the default signation type
- *
+ *
* @return the key for the default signature definition, if the key is not
* found it returns null
*/
@@ -343,7 +343,7 @@ public class SignatureObject implements Serializable
/**
* This method checks if a given signature key is realy a defined signature
* key.
- *
+ *
* @param sigKey
* the key to check
* @return true if the key is correct, false if the given key is not defined
@@ -360,7 +360,7 @@ public class SignatureObject implements Serializable
* The value that has to be set would be normalized! <br>
* <b>If the key equals to <code>SIG_VALUE</code> all whitespaces are
* removed! </b> <br>
- *
+ *
* @param key
* the key to be set
* @param value
@@ -371,7 +371,7 @@ public class SignatureObject implements Serializable
public boolean setSigValue(String key, String value) {
return setSigValue(key, value, false);
}
-
+
public boolean setSigValue(String key, String value, boolean placeholder)
{
SignatureEntry sig_entry = null;
@@ -416,7 +416,7 @@ public class SignatureObject implements Serializable
/**
* Set the value and the caption to given key.
- *
+ *
* @param key
* the key of the signature object
* @param value
@@ -435,14 +435,14 @@ public class SignatureObject implements Serializable
* This method returns a value for a given signature key. If the key equals to
* <code>SIG_NORM</code> and the value is <code>null</code> the version
* string of the current normalizer is returned!
- *
+ *
* @param key
* the key to get the value for
* @return a value for the given key
*/
public String getSigValue(String key)
{
-
+
String value = null;
SignatureEntry sigEntry = null;
if (sigEntries_.containsKey(key))
@@ -462,13 +462,13 @@ public class SignatureObject implements Serializable
logger_.debug("Using override property for key '" + key + "' = " + value);
}
}
-
+
return value;
}
/**
* Sets the "Kennzeichnung".
- *
+ *
* @param kz
* The "Kennzeichnung" to be set.
*/
@@ -479,7 +479,7 @@ public class SignatureObject implements Serializable
/**
* Returns the "Kennzeichnung" of this signature.
- *
+ *
* @return Returns the "Kennzeichnung" of this signature. Returns null if
* there is no "Kennzeichnung" or it is not recognized by this
* application.
@@ -508,14 +508,14 @@ public class SignatureObject implements Serializable
* and the coresponding value is <code>null</code> the key itself is
* returned as caption! If the key does not exist the method returns
* <code>null</code>.
- *
+ *
* @param key
* the key to get the caption for
* @return a caption for the given key
*/
private String getSigCaption(String key)
{
-
+
String caption = null;
if (sigEntries_.containsKey(key))
{
@@ -667,15 +667,15 @@ public class SignatureObject implements Serializable
if (StringUtils.equals(nameFromText, nameFromCertificate)) {
return nameFromText;
}
-
+
logger_.debug("Checking RFC2253 name.");
-
+
// if we do not have a name from certificate just return the name from text
if (nameFromCertificate == null) {
logger_.debug("No certificate RFC2253 name provided. Applying less sophisticated workaround (does not cover all cases) without certificate usage.");
return prepareRFC2253Name(nameFromText);
}
-
+
// no name from text extraction available, just return name from certificate
if (nameFromText == null) {
logger_.debug("No extracted/reconstructed name available. Just returning the name from certificate: \"" + nameFromCertificate + "\".");
@@ -762,13 +762,13 @@ public class SignatureObject implements Serializable
result.append(rdnVP.getValue());
} else {
// no BER encoding -> take value from certificate
- // also take RDN from certificate if possible
+ // also take RDN from certificate if possible
String certValue = values[values.length - 1 - i].getAVA()
.getValueAsString();
String rdn = resolveRDN(nameFromCertificate, certValue, rdnVP.getRdn());
result.append(rdn + "=").append(certValue);
}
-
+
}
String merged = result.toString();
if (logger_.isDebugEnabled()) {
@@ -785,15 +785,15 @@ public class SignatureObject implements Serializable
}
return merged;
}
-
+
/**
* This method tries to resolve the RDN corresponding to a given value from the certificate String.
- * As values might occur multiple times for different RDNs, an unambiguous resolving cannot be assured.
+ * As values might occur multiple times for different RDNs, an unambiguous resolving cannot be assured.
* In case of ambiguity, the RDN extracted from text is returned by default.
- *
+ *
* This method is a bug fix for a problem that caused the verification of ZID documents to fail as the RDN
* from the extracted text ("EMAILADDRESS") was different to the RDN in the certificate ("EMAIL")
- *
+ *
* @param certString
* The String obtained from the certificate
* @param value
@@ -804,42 +804,42 @@ public class SignatureObject implements Serializable
* The resolved RDN from the certificate, or the RDN from text extraction
*/
private static String resolveRDN(String certString, String value, String extractedRDN) {
-
+
if (!certString.contains(value)) {
-
+
// given value cannot be found in certificate string
return extractedRDN;
}
-
+
if (certString.indexOf(value) != certString.lastIndexOf(value)) {
-
+
// given value is ambiguous - cannot resolve RDN from certificate string
return extractedRDN;
}
-
+
String[] parts = certString.split(",|;");
String val = value.trim();
-
+
for (int i = 0; i < parts.length; i++) {
-
+
String part = parts[i].trim();
-
+
if (part.endsWith(val)) {
-
+
// found entry - extract RDN
- String[] components = part.split("=");
+ String[] components = part.split("=");
if (components.length != 2) {
// unexpected format - return default
- return extractedRDN;
- }
+ return extractedRDN;
+ }
String rdn = components[0].trim();
- return rdn;
- }
- }
+ return rdn;
+ }
+ }
// default
return extractedRDN;
}
-
+
/**
* @return Returns the SignationIssuer.
*/
@@ -920,10 +920,10 @@ public class SignatureObject implements Serializable
}
// dferbas baik
-
+
/**
* signature algorithm if embedded
- * @param sigAlg
+ * @param sigAlg
*/
public void setSigAlg(String sigAlg)
{
@@ -937,7 +937,7 @@ public class SignatureObject implements Serializable
public String getSigAlg()
{
return getSigValue(SignatureTypes.SIG_ALG);
- }
+ }
/**
* @param certDigest
@@ -1016,7 +1016,7 @@ public class SignatureObject implements Serializable
setSigValue(SIG_CER, x509Certificate);
storeCertificate(getSignationSerialNumber(), getSignationIssuer(), x509Certificate);
}
-
+
public void setX509Certificate(X509Certificate cert)
{
try
@@ -1037,7 +1037,7 @@ public class SignatureObject implements Serializable
/**
* return the 509v3 certificate of the given serialNumber and the given issuer
* string
- *
+ *
* @param serialNumber
* the serialNumber which the certificates should load
* @param issuer
@@ -1070,7 +1070,7 @@ public class SignatureObject implements Serializable
/**
* Set the signation id's build by a BKU signated SignatureObject.
- *
+ *
* @param sigIds
* the string to store.
*/
@@ -1152,7 +1152,7 @@ public class SignatureObject implements Serializable
String productVersion = response_properties.getProperty("productVersion");
logger_.debug("productVersion = " + productVersion);
- boolean new_etsi = decideNewEtsiByBKUVersion(productVersion);
+ boolean new_etsi = decideNewEtsiByBKUVersion(productVersion);
logger_.debug("verwende neue etsi properties = " + new_etsi);
String etsi_prefix = "";
@@ -1183,7 +1183,7 @@ public class SignatureObject implements Serializable
/**
* Checks if the current SignatureObject is siganted by MOA. It checks if the
* current SignatureObject has a signation id value.
- *
+ *
* @return true if no signation id value is found, false otherwise
*/
public boolean isMOASigned()
@@ -1204,7 +1204,7 @@ public class SignatureObject implements Serializable
/**
* Tells if this SignatureObject is textual.
- *
+ *
* @return Returns true, if it is textual.
*/
public boolean isTextual()
@@ -1223,7 +1223,7 @@ public class SignatureObject implements Serializable
/**
* Tells, if this SignatureObject is binary.
- *
+ *
* @return Returns true, if it is binary.
*/
public boolean isBinary()
@@ -1237,14 +1237,14 @@ public class SignatureObject implements Serializable
{
logger_.error(e.getMessage(), e);
}
-
+
return SigKZIDHelper.isBinary(kz);
}
/**
* Takes the signation id value of the current SignatureObject and split them
* into the corresponding id array added with the id-base.
- *
+ *
* @return the id array
*/
// TODO hotifx
@@ -1328,7 +1328,7 @@ public class SignatureObject implements Serializable
real_ids[3] = "0-" + base + "-" + ids[3];
real_ids[4] = "0-" + base + "-" + ids[4];
real_ids[5] = etsi_string;
-
+
if (logger_.isDebugEnabled())
{
for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
@@ -1345,7 +1345,7 @@ public class SignatureObject implements Serializable
* for equition. Used to store and find corresponting certificates.
* Normalzing: normalizing the string using the normalizer, remove all white
* spaces, encode as base64 and replace all "/" chars with "_".
- *
+ *
* @param issuer
* the issuer string to normalize
* @return the normalized issuer string
@@ -1357,7 +1357,7 @@ public class SignatureObject implements Serializable
{
if (issuer != null)
{
- // use explicit method for normalization
+ // use explicit method for normalization
issuer = normalizeIssuer(issuer);
/* this block may be used to enhance normalization (tknall)
try {
@@ -1375,7 +1375,6 @@ public class SignatureObject implements Serializable
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -1443,7 +1442,7 @@ public class SignatureObject implements Serializable
}
}
}
-
+
private X509Cert loadCertificateFromCertstore(String serialNumber, String issuer) {
String iss_hash = getIssuerFileHash(issuer);
String cert_store_path = certPath_ + iss_hash;
@@ -1476,10 +1475,10 @@ public class SignatureObject implements Serializable
* <li>add the <code>.txt</code> extension to get the meta information of
* the certificate</li>
* </ol>
- *
+ *
* The certificate meta file is build by the base64 coded issuer string and
* the cert digest value devided by the <code>@</code> char.
- *
+ *
* @param serialNumber
* the file name of the certificate .der|.txt
* @param issuer
@@ -1541,7 +1540,7 @@ public class SignatureObject implements Serializable
/**
* Writes the certificate data to a file and stores the file in the local
* certificate store.
- *
+ *
* @param cert_data
* The binary certificate data.
*/
@@ -1580,17 +1579,17 @@ public class SignatureObject implements Serializable
/**
* Connects to the LDAP server to look for the certificate.
- *
+ *
* @param serialNumber
* The serial number String of the certificate being sought. E.g.
* "123455676744123432".
* @param issuer
* The issuer String of the certificate being sought.
- *
+ *
* @return Returns the DER certificate file as can be stored in the local
* repository. Returns null, if the document wasn't found on the
* server.
- * @throws ClassNotFoundException
+ * @throws ClassNotFoundException
*/
protected byte[] loadCertificateFromLDAP(String serialNumber, String issuer) {
// START modification by TK
@@ -1629,10 +1628,10 @@ public class SignatureObject implements Serializable
* <li>add the <code>.txt</code> extension to get the meta information of
* the certificate</li>
* </ol>
- *
+ *
* The certificate meta file is build by the base64 coded issuer string and
* the cert digest value devided by the <code>@</code> char.
- *
+ *
* @param serialNumber
* the file name of the certificate .der|.txt
* @param issuer
@@ -1650,7 +1649,7 @@ public class SignatureObject implements Serializable
{
return storeCertificate(serialNumber, issuer, x509Certificate);
}
-
+
/**
* This method stores a X509v3 certificate to the filesystem. The reference to
* the stored certificate is build by the serialNumber and the issuer string.
@@ -1673,10 +1672,10 @@ public class SignatureObject implements Serializable
* <li>add the <code>.txt</code> extension to get the meta information of
* the certificate</li>
* </ol>
- *
+ *
* The certificate meta file is build by the base64 coded issuer string and
* the cert digest value devided by the <code>@</code> char.
- *
+ *
* @param serialNumber
* the file name of the certificate .der|.txt
* @param issuer
@@ -1723,7 +1722,7 @@ public class SignatureObject implements Serializable
}
return store_complete;
}
-
+
/**
* @return Returns the AbstractTable.
* @see at.knowcenter.wag.egov.egiz.table.Table
@@ -1739,7 +1738,7 @@ public class SignatureObject implements Serializable
/**
* This method read the style definitions from the settings file.
- *
+ *
* @param styleKey
* the key to read the style definitions
* @return the defined style informations
@@ -1762,7 +1761,7 @@ public class SignatureObject implements Serializable
* This method creates an abstract signature table object. It takes all keys
* and values set by the signature object to create the corresponding abstract
* table object. The table definition is read from the settings file.
- *
+ *
* @param tableKey
* is the name of the table definition in the settings file
* @return a new abstract signature table
@@ -1964,7 +1963,7 @@ public class SignatureObject implements Serializable
/**
* This method returns a signature entry object.
- *
+ *
* @param key
* the corresponding key
* @return the signature entry object of the given key, null if the key does
@@ -1977,7 +1976,7 @@ public class SignatureObject implements Serializable
/**
* This method is a helper function to remove all white spaces from a text.
- *
+ *
* @param text
* the white spaces should remove from
* @return a text without white spaces
@@ -1993,7 +1992,7 @@ public class SignatureObject implements Serializable
}
/**
- *
+ *
* @param placeholder
* @return Returns the list of SignatureFieldDefinitions that's values in the
* SignatureObject have been filled out with placeholders.
@@ -2015,7 +2014,7 @@ public class SignatureObject implements Serializable
setValueBruteForce(SignatureTypes.SIG_ID, null);
continue;
}
-
+
if (sfd.field_name.equals(SignatureTypes.SIG_ALG) && !baikEnabled) {
setValueBruteForce(SignatureTypes.SIG_ID, null);
continue;
@@ -2040,7 +2039,7 @@ public class SignatureObject implements Serializable
/**
* Returns the raw signature response XML string as set by the signing
* Connector.
- *
+ *
* @return Returns the XML response String.
*/
public String getRawSignatureResponse()
@@ -2050,12 +2049,12 @@ public class SignatureObject implements Serializable
/**
* Sets the raw signature response XML string.
- *
+ *
* <p>
* This should be used by the Connector to pass the response String to the
* signer.
* </p>
- *
+ *
* @param raw_response_string
* The new raw signature response string.
*/
@@ -2063,8 +2062,8 @@ public class SignatureObject implements Serializable
{
this.raw_signature_response = raw_response_string;
}
-
-
+
+
/**
* get timestamp if available
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java
index 783512c..a4d71fd 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java
@@ -26,7 +26,9 @@
package at.knowcenter.wag.egov.egiz.sig;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -45,6 +47,118 @@ import at.knowcenter.wag.exactparser.ByteArrayUtils;
public class SignatureTypes
{
+ /**
+ * Defines all supported states for {@link SignatureTypes} (signature profiles). Signature types can be enabled
+ * ("on"), can be set to support signature only ("sign_only"), to verification only ("verify_only") or can be
+ * disabled ("off" or any other value not covered by other enum values).
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+ public enum State {
+
+ /**
+ * Enables a signature profile.
+ */
+ ON ("on", "yes", "true", "enabled"),
+
+ /**
+ * Disables a signature profile.
+ */
+ OFF (),
+
+ /**
+ * Restricts the signature profile so that is can only be used for verification purposes and not for signature.
+ */
+ VERIFY_ONLY ("verify_only", "verify-only", "verifyonly", "verify only", "verify"),
+
+ /**
+ * Allows the signature profile to be used for signature but not for verification.
+ */
+ SIGN_ONLY ("sign_only", "sign-only", "signonly", "sign only", "sign");
+
+ /**
+ * Sets the default state when no valid value was provided.
+ */
+ private static final State DEFAULT = OFF;
+
+ /**
+ * States that allow signatures.
+ */
+ private static final State[] CAN_SIGN = { ON, SIGN_ONLY };
+
+ /**
+ * States that allow verification.
+ */
+ private static final State[] CAN_VERIFY = { ON, VERIFY_ONLY };
+
+ private String[] keyWords;
+
+ private State(String... keyWords) {
+ this.keyWords = keyWords;
+ }
+
+ /**
+ * Returns a valid State from a given {@code keyWord}. If the {@code keyWord} cannot be matched to a certain
+ * state, the default State {@link #OFF} is returned.
+ *
+ * @param keyWord
+ * A valid keyword like "on", "sign_only"...
+ * @return The enum State.
+ */
+ public static State fromString(String keyWord) {
+ if (keyWord == null) {
+ return DEFAULT;
+ }
+ try {
+ return valueOf(keyWord.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ for (State candidate : values()) {
+ for (String candidateKeyWord : candidate.keyWords) {
+ if (keyWord.equalsIgnoreCase(candidateKeyWord)) {
+ return candidate;
+ }
+ }
+ }
+ return DEFAULT;
+ }
+ }
+
+ /**
+ * Returns {@code true} when the current state is one of the given candidate {@code states}.
+ *
+ * @param states
+ * The candidate states.
+ * @return {@code true} when the current state is one of the given candidate states, {@code false} if not.
+ */
+ public boolean in(State... states) {
+ if (states != null) {
+ for (State state : states) {
+ if (this == state) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns if the respective state allows signatures.
+ * @return {@code true} if signatures are allowed, {@code false} if not.
+ */
+ public boolean canSign() {
+ return in(CAN_SIGN);
+ }
+
+ /**
+ * Returns if the respective state allows verification.
+ * @return {@code true} if verification is allowed, {@code false} if not.
+ */
+ public boolean canVerify() {
+ return in(CAN_VERIFY);
+ }
+
+ }
+
// 03.11.2010 changed by exthex - commented unneeded setDefaultStyles method to reduce confusion
/**
@@ -70,8 +184,8 @@ public class SignatureTypes
/**
* The state value activating an signature definition
*/
- private static final String STATE_ON = "on";
-
+// public static final String STATE_ON = "on";
+
// /**
// * The state value de activating an signature definition
// */
@@ -403,10 +517,12 @@ public class SignatureTypes
if (settings_ != null)
{
ArrayList types = settings_.getKeys(TYPES);
- for (int type_idx = 0; type_idx < types.size(); type_idx++)
- {
- String type = (String) types.get(type_idx);
- addSignatureType(type);
+ if (types != null) {
+ for (int type_idx = 0; type_idx < types.size(); type_idx++)
+ {
+ String type = (String) types.get(type_idx);
+ addSignatureType(type);
+ }
}
}
}
@@ -420,8 +536,9 @@ public class SignatureTypes
* @param typeName
*/
public void addSignatureType(String typeName) {
-
- if (STATE_ON.equals(settings_.getSetting(TYPES + "." + typeName, null)))
+
+// if (STATE_ON.equals(settings_.getSetting(TYPES + "." + typeName, null)))
+ if (State.fromString(settings_.getSetting(TYPES + "." + typeName, null)) != State.OFF)
{
SignatureTypeDefinition sig_type_def;
try
@@ -446,6 +563,23 @@ public class SignatureTypes
return this.typeDefMap_.keySet();
}
+ /**
+ * Returns a set of identifiers for profiles than can be used for signature, i.e. profiles that are either enabled
+ * ("on") or set to "sign_only").
+ *
+ * @return A set of signature profile/type identifiers.
+ */
+ @SuppressWarnings("unchecked")
+ public Set<String> getSignatureTypesForSignature() {
+ Set<String> filteredResult = new HashSet<String>();
+ for (String signatureProfileId : (Set<String>) typeDefMap_.keySet()) {
+ if (State.fromString(settings_.getSetting(TYPES + "." + signatureProfileId, null)).canSign()) {
+ filteredResult.add(signatureProfileId);
+ }
+ }
+ return filteredResult;
+ }
+
/**
* @return a list of signature type definitions
*/
@@ -453,6 +587,23 @@ public class SignatureTypes
{
return new ArrayList(this.typeDefMap_.values());
}
+
+ /**
+ * Returns a (filtered) list of signature type definitions useable for verification. Those definitions for profiles
+ * that are not allowed to be used for verification are filtered.
+ *
+ * @return A filtered list of signature type definitions.
+ */
+ @SuppressWarnings("unchecked")
+ public List<SignatureTypeDefinition> getSignatureTypeDefinitionsForVerification() {
+ List<SignatureTypeDefinition> filteredResult = new ArrayList<SignatureTypeDefinition>(typeDefMap_.size());
+ for (String signatureProfileId : (Set<String>) typeDefMap_.keySet()) {
+ if (State.fromString(settings_.getSetting(TYPES + "." + signatureProfileId, null)).canVerify()) {
+ filteredResult.add((SignatureTypeDefinition) typeDefMap_.get(signatureProfileId));
+ }
+ }
+ return filteredResult;
+ }
/**
* This method returns the corresponding signature type definition to a given
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java
index 7b4e463..e11a38c 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java
@@ -99,7 +99,7 @@ public class X509Cert implements Serializable
* statement and remove all whitespaces in the string. The result string
* (base64) is used by reconstructing the certiface sign by the verification
* process.
- *
+ *
* @param certString
* the string to normalize
* @return the normalized cert string
@@ -115,7 +115,7 @@ public class X509Cert implements Serializable
/**
* This method initialzes a X509Certificate by a string value. It must be
* coded Base64 or as plain binary stream.
- *
+ *
* @param certString
* the certificate string to analyse
* @return the X509Cert object
@@ -150,7 +150,9 @@ public class X509Cert implements Serializable
String serial_num = cert.getSerialNumber().toString();
String issuer = cert.getIssuerDN().getName();
- issuer = issuer.replaceAll(", ", ",");
+ // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
+// issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
String subject_name = cert.getSubjectDN().toString();
x509_cert.setSerialNumber(serial_num);
x509_cert.setIssuerName(issuer);
@@ -174,7 +176,7 @@ public class X509Cert implements Serializable
}
return x509_cert;
}
-
+
public static X509Cert initByX509Certificate(X509Certificate cert) throws CertificateEncodingException {
X509Cert x509_cert = new X509Cert();
x509_cert.setX509Cert(cert);
@@ -182,7 +184,9 @@ public class X509Cert implements Serializable
String serial_num = cert.getSerialNumber().toString();
String issuer = cert.getIssuerDN().getName();
- issuer = issuer.replaceAll(", ", ",");
+ // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
+// issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
String subject_name = cert.getSubjectDN().toString();
x509_cert.setSerialNumber(serial_num);
x509_cert.setIssuerName(issuer);
@@ -210,7 +214,9 @@ public class X509Cert implements Serializable
String serial_num = cert.getSerialNumber().toString();
String issuer = cert.getIssuerDN().getName();
- issuer = issuer.replaceAll(", ", ",");
+ // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
+// issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
String subject_name = cert.getSubjectDN().toString();
x509_cert.setSerialNumber(serial_num);
x509_cert.setIssuerName(issuer);
@@ -226,7 +232,7 @@ public class X509Cert implements Serializable
{
// nothing to do, cause certString is not X509 conformc
logger_.error(ce.getMessage(), ce);
-
+
}
catch (IOException ioe)
{
@@ -240,7 +246,7 @@ public class X509Cert implements Serializable
/**
* This method initialzes a X509Certificate by a file path value. The file
* must be a plain binary file like .cer format.
- *
+ *
* @param filePath
* the certificate file to analyse
* @return the X509Cert object
@@ -276,7 +282,9 @@ public class X509Cert implements Serializable
String serial_num = cert.getSerialNumber().toString();
String issuer = cert.getIssuerDN().getName();
- issuer = issuer.replaceAll(", ", ",");
+ // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
+// issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
String subject_name = cert.getSubjectDN().toString();
x509_cert.setSerialNumber(serial_num);
x509_cert.setIssuerName(issuer);
@@ -300,7 +308,7 @@ public class X509Cert implements Serializable
/**
* This method initialzes a X509Certificate by a file value. The file must be
* a plain binary file like .cer format.
- *
+ *
* @param certFile
* the certificate file to analyse
* @return the X509Cert object
@@ -314,7 +322,7 @@ public class X509Cert implements Serializable
/**
* This method checks if a certificate file is X509 conform.
- *
+ *
* @return true if a certificate file is X509 conform, false otherwise
*/
public boolean isX509Cert()
@@ -480,7 +488,7 @@ public class X509Cert implements Serializable
/**
* This method checks, if a X509Certificate has a public key with the rsa
* algorithm.
- *
+ *
* @return true if the public key is produced with rsa, false otherwise
*/
public boolean isRSA()
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
index c3b6421..e4d78c3 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
@@ -49,9 +49,9 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* Connector for communicating with BKU.
- *
+ *
* @deprecated use the new connectors.
- *
+ *
* @author wlackner
* @author wprinz
*/
@@ -59,7 +59,7 @@ public class BKUConnector implements LocalConnector
{
/**
* ConnectorInformation that identifies this Connector to the system.
- *
+ *
* @see at.knowcenter.wag.egov.egiz.sig.ConnectorFactory
* @see ConnectorInformation
*/
@@ -85,7 +85,7 @@ public class BKUConnector implements LocalConnector
/**
* load the inital signature settings
- *
+ *
* @see SettingsReader
*/
public void loadSettings() throws SignatureException
@@ -111,7 +111,7 @@ public class BKUConnector implements LocalConnector
* SignatureObject is filled out by the parsed BKU-Response. <br>
* If an error request is send back from BKU, an error message is generated an
* an exception is thrown.
- *
+ *
* @param sigType
* the type of the SignatureObject that should be returned
* @param userName
@@ -137,7 +137,7 @@ public class BKUConnector implements LocalConnector
* This method generates the BKU verify prozess. It checks if the given
* SignatureObject is signed by MOA or BKU. The verify template string is
* filled out by the corresponding method.
- *
+ *
* @param normalizedText
* the normalized text to verify
* @param sigObject
@@ -163,7 +163,7 @@ public class BKUConnector implements LocalConnector
* X509Certificate, CertDigest, DigestValue and the signation id-s. If the
* X509Certificate is extracted it would be stored in the certificates
* directory.
- *
+ *
* @param xmlResponse
* the response string from the BKU sign-request
* @param sigObj
@@ -177,7 +177,7 @@ public class BKUConnector implements LocalConnector
private void parseCreateXMLResponse(Properties response_properties, SignatureObject sigObj) throws SignatureException
{
String xmlResponse = response_properties.getProperty("response_string");
-
+
Pattern sig_val_p_s = Pattern.compile("<[\\w]*:?SignatureValue>");
Pattern sig_val_p_e = Pattern.compile("</[\\w]*:?SignatureValue>");
Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>");
@@ -280,7 +280,7 @@ public class BKUConnector implements LocalConnector
ids[2] = extractId(xmlResponse, "signed-data-object-");
ids[3] = extractId(xmlResponse, "etsi-data-reference-");
ids[4] = extractId(xmlResponse, "etsi-data-object-");
-
+
//TODO hotfix - already deprecated
String final_ids =SignatureObject.formatSigIds(response_properties, ids);
//sigObj.setSignationIDs(ids);
@@ -289,7 +289,7 @@ public class BKUConnector implements LocalConnector
/**
* This emthod extracts id-values from a text. The id is given by the name.
- *
+ *
* @param text
* the id-value that should extract from
* @param name
@@ -301,13 +301,13 @@ public class BKUConnector implements LocalConnector
String id = null;
int start_idx = text.indexOf(name) + name.length();
int end_idx = text.indexOf("\"", start_idx);
-
+
// TODO hotfix! - already deprecated
- final int quot_end_idx = end_idx;
+ final int quot_end_idx = end_idx;
final int squot_end_idx = text.indexOf("'", start_idx);
end_idx = Math.min(quot_end_idx, squot_end_idx);
// TODO hotfix end! - already deprecated
-
+
id = text.substring(start_idx, end_idx);
if (logger_.isDebugEnabled())
{
@@ -319,7 +319,7 @@ public class BKUConnector implements LocalConnector
/**
* This method reads the verify template from the file system and fills out
* the template with the SignatureObject values.
- *
+ *
* @param normalizedText
* the normalized text to veryfied
* @param sigObject
@@ -362,7 +362,7 @@ public class BKUConnector implements LocalConnector
verify_template = getConnectorValueFromProfile(sigObject.getSignationType(), "bku.verify.template2"); //"./templates/BKUVerifyTemplateB64_neueBKU.xml";
sig_prop_filename = getConnectorValueFromProfile(sigObject.getSignationType(), "bku.verify.template2.SP"); //"./templates/BKUVerifyTemplateSP_neueBKU.xml";
}
-
+
//String ver_temp_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_template));
String ver_temp_str = this.settings_.readInternalResourceAsString(verify_template);
@@ -388,13 +388,18 @@ public class BKUConnector implements LocalConnector
}
sig_prop_str = sig_prop_str.replaceFirst("SigningTimeReplace", sigObject.getSignationDate());
-
+
String issuer_name = sigObject.getSignationIssuer();
// The issuer is already unicode, so it mustn't be encoded again.
//byte[] issuer_name = CodingHelper.encodeUTF8(sigObject.getSignationIssuer());
// new String(issuer_name); // this would double encode the String, not to mention the missing encoding
- sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", issuer_name);
-
+
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", issuer_name);
+ sig_prop_str = sig_prop_str.replace("X509IssuerNameReplace", issuer_name);
+
sig_prop_str = sig_prop_str.replaceFirst("X509SerialNumberReplace", sigObject.getSignationSerialNumber());
sig_prop_str = sig_prop_str.replaceFirst("DigestValueX509CertificateReplace", sigObject.getX509CertificateDigest());
sig_prop_str = sig_prop_str.replaceFirst("SigIdReplace", ids[0]);
@@ -403,30 +408,30 @@ public class BKUConnector implements LocalConnector
ver_temp_str = ver_temp_str.replaceFirst("CertAlgReplace", cert_alg);
ver_temp_str = ver_temp_str.replaceFirst("TemplateQualifyingPropertiesReplace", sig_prop_str);
byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8"), "sha1");
-
+
// TODO hotfix - already deprecated
if (neue_bku)
{
final String ETSI_SIGNED_PROPERTIES_START_TAG = "<etsi:SignedProperties"; // xml name spaces follow, so this is not a complete tag...
final String ETSI_SIGNED_PROPERTIES_END_TAG = "</etsi:SignedProperties>";
-
+
final int hash_start = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_START_TAG);
assert hash_start >= 0;
final int hash_end = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_END_TAG, hash_start) + ETSI_SIGNED_PROPERTIES_END_TAG.length();
assert hash_end - ETSI_SIGNED_PROPERTIES_END_TAG.length() >= 0;
assert hash_end > hash_start;
-
+
final String string_to_be_hashed = sig_prop_str.substring(hash_start, hash_end);
logger_.debug("etsi:SignedProperties string to be hashed: " + string_to_be_hashed);
-
+
logger_.debug("\n--------------------- ETSI properties string to be hashed: start ---------------------");
logger_.debug(string_to_be_hashed);
logger_.debug("\n--------------------- ETSI properties string to be hashed: stop ---------------------");
-
+
final byte [] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
sig_prop_code = CodingHelper.buildDigest(bytes_to_be_hashed, "sha1");
}
-
+
String sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
ver_temp_str = ver_temp_str.replaceFirst("DigestValueSignedPropertiesReplace", sig_prop_hash);
if (logger_.isDebugEnabled())
@@ -453,7 +458,7 @@ public class BKUConnector implements LocalConnector
//String raw_b64 = CodingHelper.encodeUTF8AsBase64(normalizedText);
String raw_b64 = CodingHelper.encodeBase64(data_value);
-
+
ver_temp_str = ver_temp_str.replaceFirst("Base64ContentReplace", raw_b64);
ver_temp_str = ver_temp_str.replaceFirst("DigestValueSignedDataReplace", object_data_hash);
@@ -479,7 +484,7 @@ public class BKUConnector implements LocalConnector
* This method parses the verify response string and return a
* SignatureResponse object. The SignatureResponse object is filled out by the
* response values from the BKU-response.
- *
+ *
* @param xmlResponse
* the response values from the BKU-verify request
* @return SignatureResponse object
@@ -621,8 +626,8 @@ public class BKUConnector implements LocalConnector
return sig_res;
}
-
-
+
+
public String prepareSignRequest(String userName, String signText,
String signType) throws SignatureException
@@ -636,7 +641,7 @@ public class BKUConnector implements LocalConnector
//String sign_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
String sign_req_str = this.settings_.readInternalResourceAsString(sign_request_filename);
- //this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
+ //this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
if (logger_.isDebugEnabled())
{
//logger_.debug(sign_request_filename + "_signText.xml :" + signText);
@@ -660,7 +665,7 @@ public class BKUConnector implements LocalConnector
SignatureObject sigObject) throws SignatureException
{
String verify_request = getVerifyRequestTemplateFileName(sigObject.getSignationType());
-
+
//String verify_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request));
String verify_req_str = this.settings_.readInternalResourceAsString(verify_request);
@@ -681,7 +686,11 @@ public class BKUConnector implements LocalConnector
// get the BKU-template
verify_template_str = getVerifyTemplate(normalizedText, sigObject);
}
- verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+ verify_req_str = verify_req_str.replace("XMLContentReplace", verify_template_str);
if (logger_.isDebugEnabled())
{
logger_.debug("verify_req_str.xml : " + verify_req_str);
@@ -692,7 +701,7 @@ public class BKUConnector implements LocalConnector
/**
* Sends the request to the given URL.
- *
+ *
* @param url
* The URL.
* @param request_string
@@ -722,7 +731,7 @@ public class BKUConnector implements LocalConnector
// TODO hotfix - already deprecated
String response_string = response_properties.getProperty("response_string");
-
+
SignatureObject sig_obj = new SignatureObject();
sig_obj.setRawSignatureResponse(response_string);
try
@@ -783,7 +792,7 @@ public class BKUConnector implements LocalConnector
public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException
{
String response_string = response_properties.getProperty("response_string");
-
+
if (!response_string.equals(""))
{
Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>");
@@ -880,13 +889,13 @@ public class BKUConnector implements LocalConnector
/**
* Returns the type of this BKU-like connector.
- *
+ *
* <p>
* All settings keys will be prefixed by this type. So to reuse the BKU
* connector, a deriving class has to implement this method specifying an own
* type.
* </p>
- *
+ *
* @return Returns the type of this BKU-like connector.
*/
protected String getType()
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java
index ef355a0..d413a29 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java
@@ -63,7 +63,7 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* Connector to access the MOA service.
- *
+ *
* @deprecated
* @author wlackner
* @author wprinz
@@ -72,7 +72,7 @@ public class MOAConnector implements Connector
{
/**
* ConnectorInformation that identifies this Connector to the system.
- *
+ *
* @see at.knowcenter.wag.egov.egiz.sig.ConnectorFactory
* @see ConnectorInformation
*/
@@ -80,7 +80,7 @@ public class MOAConnector implements Connector
/**
* The class type value.
- *
+ *
* <p>
* Just for convenience.
* </p>
@@ -122,7 +122,7 @@ public class MOAConnector implements Connector
/**
* load the inital signature settings
- *
+ *
* @see SettingsReader
*/
private void loadSettings() throws SignatureException
@@ -148,7 +148,7 @@ public class MOAConnector implements Connector
* SignatureObject is filled out by the parsed MOA-Response. <br>
* If an error request is send back from MOA, an error message is generated an
* an exception is thrown.
- *
+ *
* @param sigType
* the type of the SignatureObject that should be returned
* @param userName
@@ -282,7 +282,7 @@ public class MOAConnector implements Connector
* SignatureValue, X509IssuerName, SigningTime, X509SerialNumber,
* X509Certificate, CertDigest and DigestValues. If the X509Certificate is
* extracted it would be stored in the certificates directory.
- *
+ *
* @param xmlResponse
* the response string from the MOA sign-request
* @param sigObj
@@ -393,7 +393,7 @@ public class MOAConnector implements Connector
/**
* This method reads the verify template from the file system and fills out
* the template with the SignatureObject values.
- *
+ *
* @param normalizedText
* the normalized text to veryfied
* @param sigObject
@@ -453,12 +453,18 @@ public class MOAConnector implements Connector
// byte[] issuer_name =
// CodingHelper.encodeUTF8(sigObject.getSignationIssuer());
// new String(issuer_name)
- sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", sigObject.getSignationIssuer());
+
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", sigObject.getSignationIssuer());
+ sig_prop_str = sig_prop_str.replace("X509IssuerNameReplace", sigObject.getSignationIssuer());
sig_prop_str = sig_prop_str.replaceFirst("X509SerialNumberReplace", sigObject.getSignationSerialNumber());
sig_prop_str = sig_prop_str.replaceFirst("DigestValueX509CertificateReplace", sigObject.getX509CertificateDigest());
verify_req_str = verify_req_str.replaceFirst("CertAlgReplace", cert_alg);
- verify_req_str = verify_req_str.replaceFirst("TemplateSignedPropertiesReplace", sig_prop_str);
+// verify_req_str = verify_req_str.replaceFirst("TemplateSignedPropertiesReplace", sig_prop_str);
+ verify_req_str = verify_req_str.replace("TemplateSignedPropertiesReplace", sig_prop_str);
byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8"), "sha1"); // added
// the
// ("UTF-8")
@@ -509,7 +515,7 @@ public class MOAConnector implements Connector
* This method generates the MOA verify prozess. It checks if the given
* SignatureObject is signed by MOA or BKU. The verify template string is
* filled out by the corresponding method.
- *
+ *
* @param normalizedText
* the normalized text to verify
* @param sigObject
@@ -548,7 +554,12 @@ public class MOAConnector implements Connector
BKUConnector bku_conn = new BKUConnector();
verify_template_str = bku_conn.getVerifyTemplate(normalizedText, sigObject);
}
- verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+ verify_req_str = verify_req_str.replace("XMLContentReplace", verify_template_str);
verify_req_str = verify_req_str.replaceFirst("TrustProfileIDReplace", trust_profile);
if (logger_.isDebugEnabled())
@@ -564,10 +575,6 @@ public class MOAConnector implements Connector
}
catch (WebException we)
{
- if (logger_.isDebugEnabled())
- {
- we.printStackTrace();
- }
SignatureException se = new SignatureException(we.getErrorCode(), we);
throw se;
}
@@ -616,7 +623,7 @@ public class MOAConnector implements Connector
* This method parses the verify response string and return a
* SignatureResponse object. The SignatureResponse object is filled out by the
* response values from the BKU-response.
- *
+ *
* @param xmlResponse
* the response values from the MOA-verify request
* @return SignatureResponse object
@@ -639,7 +646,7 @@ public class MOAConnector implements Connector
Pattern cert_qualified_p = Pattern.compile("<QualifiedCertificate/>");
Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse);
// [tknall] stop qualified certificate
-
+
Pattern sig_chk_p_s = Pattern.compile("<SignatureCheck>");
Pattern sig_chk_p_e = Pattern.compile("</SignatureCheck>");
Pattern man_chk_p_s = Pattern.compile("<SignatureManifestCheck>");
@@ -671,11 +678,11 @@ public class MOAConnector implements Connector
Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
SignatureResponse sig_res = new SignatureResponse();
-
+
// [tknall] start qualified certificate
sig_res.setQualifiedCertificate(cert_qualified_m.find());
// [tknall] stop qualified certificate
-
+
// public authority
Pattern publicAuthority_p = Pattern.compile("<PublicAuthority/>");
Matcher publicAuthority_m = publicAuthority_p.matcher(xmlResponse);
@@ -821,7 +828,7 @@ public class MOAConnector implements Connector
* SOAP Message send and recieve by the AXIS module. The Response SOAP message
* of the MOA server is parsed by AXIS and the message envelope is send back
* to the calling method.
- *
+ *
* @param requestString
* the request string (XML) to send.
* @param serviceMode
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java
index ee250ff..908ed57 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java
@@ -60,14 +60,14 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* Contains static helper methods used by the BKU Connectors.
- *
+ *
* @author wprinz
*/
public final class BKUHelper
{
private static final Pattern ALLOWED_SL_RESPONSE_PATTERN = Pattern.compile("^.*<[\\w]*:?(CreateXMLSignatureResponse|VerifyXMLSignatureResponse)[^>]*>(.*)</[\\w]*:?(CreateXMLSignatureResponse|VerifyXMLSignatureResponse)>.*$", Pattern.DOTALL);
-
+
/**
* The log.
*/
@@ -75,21 +75,21 @@ public final class BKUHelper
/**
* Encodes the given SignatureData to a valid Base64Content.
- *
+ *
* <p>
* The data is Base64 encoded. If the mime-type suggests that the data is
* binary, it is Base64 encoded for a second time.
* </p>
- *
+ *
* @param data
* The data to be converted to a valid Base64 content.
* @return Returns the Base64 content.
*/
public static String prepareBase64Content(SignatureData data)
{
- // PERF: base64 encoding needs byte array
+ // PERF: base64 encoding needs byte array
byte [] d = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource());
-
+
String base64 = CodingHelper.encodeBase64(d);
if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$
{
@@ -105,7 +105,7 @@ public final class BKUHelper
* <p>
* This is useful for building the hash.
* </p>
- *
+ *
* @param data
* The data to be prepared.
* @return Returns the prepared data.
@@ -114,7 +114,7 @@ public final class BKUHelper
{
// PERF: prepareEnvelopingData needs byte array
byte[] enc = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource());
-
+
if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$
{
log.debug("The data is application/pdf - so the binary data is Base64 encoded."); //$NON-NLS-1$
@@ -125,7 +125,6 @@ public final class BKUHelper
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException("Very Strange: US-ASCII encoding not supported???", e); //$NON-NLS-1$
}
}
@@ -135,7 +134,7 @@ public final class BKUHelper
/**
* Checks the response xml for an error description and if found throws an
* appropriate exception.
- *
+ *
* @param response_string
* The response xml.
* @throws ConnectorException
@@ -169,29 +168,29 @@ public final class BKUHelper
throw new ExternalErrorException(error_code, error_mess);
}
log.debug("No error found. Assuring that CreateXMLSignatureResponse or VerifyXMLSignatureResponse elements are available.");
-
+
// assure that a CreateXMLSignatureResponse or a VerifyXMLSignatureResponse is available
Matcher slMatcher = ALLOWED_SL_RESPONSE_PATTERN.matcher(response_string);
if (!slMatcher.matches()) {
throw new ConnectorException(ErrorCode.UNABLE_TO_RECEIVE_SUITABLE_RESPONSE, "No suitable response received: " + response_string);
}
-
+
}
/**
* This method parses the BKU-Response string.
- *
+ *
* <p>
* It separates the SignatureValue, X509IssuerName, SigningTime,
* X509SerialNumber, X509Certificate, CertDigest, DigestValue and the
* signation id-s. If the X509Certificate is extracted it would be stored in
* the certificates directory.
* </p>
- *
+ *
* @param xmlResponse
* The response string.
* @return Returns the parsed signature object holding the data.
- *
+ *
* @throws ConnectorException
* ErrorCode (303, 304)
* @see SignatureObject
@@ -355,7 +354,7 @@ public final class BKUHelper
ids[2] = extractId(xmlResponse, "signed-data-object-"); //$NON-NLS-1$
ids[3] = extractId(xmlResponse, "etsi-data-reference-"); //$NON-NLS-1$
ids[4] = extractId(xmlResponse, "etsi-data-object-"); //$NON-NLS-1$
-
+
String algs = AlgorithmSuiteUtil.extractAlgorithmSuiteString(xmlResponse);
SignSignatureObject so = new SignSignatureObject();
@@ -363,26 +362,26 @@ public final class BKUHelper
so.issuer = iss_nam;
so.signatureValue = sig_val;
so.x509Certificate = cert;
-
+
AlgorithmSuiteObject suite = new AlgorithmSuiteObject(algs, false);
so.sigAlgorithm = AlgorithmMapper.getUri(suite.getSignatureMethod());
-
+
String defaultCertAlg = environment.getDefaultAlgForCert(cert);
if (AlgorithmSuiteUtil.isDefaultCertAlg(algs, defaultCertAlg)) {
// do not embed default alg
algs = null;
- }
+ }
String final_ids = id_formatter.formatIds(ids, algs);
so.id = final_ids;
-
+
return so;
}
/**
* Removes all whitespaces ("\\s") from the String.
- *
+ *
* @param str
* The String.
* @return The String with all whitespaces removed.
@@ -394,7 +393,7 @@ public final class BKUHelper
/**
* This emthod extracts id-values from a text. The id is given by the name.
- *
+ *
* @param text
* the id-value that should extract from
* @param name
@@ -411,7 +410,7 @@ public final class BKUHelper
return "";
}
// stop
-
+
int start_idx = startOfName + name.length();
int end_idx = text.indexOf("\"", start_idx); //$NON-NLS-1$
@@ -430,7 +429,7 @@ public final class BKUHelper
* This method parses the verify response string and return a
* SignatureResponse object. The SignatureResponse object is filled out by the
* response values from the BKU-response.
- *
+ *
* @param xmlResponse
* the response values from the BKU-verify request
* @return SignatureResponse object
@@ -521,14 +520,14 @@ public final class BKUHelper
if (hash_data_m_s.find() && hash_data_m_e.find())
{
String hashInputData = xmlResponse.substring(hash_data_m_s.end(), hash_data_m_e.start());
-
+
Pattern b64_p_s = Pattern.compile("<Base64Content>"); //$NON-NLS-1$
Pattern b64_p_e = Pattern.compile("</Base64Content>"); //$NON-NLS-1$
Matcher b64_m_s = b64_p_s.matcher(hashInputData);
Matcher b64_m_e = b64_p_e.matcher(hashInputData);
boolean hashInputDataFound = b64_m_s.find() && b64_m_e.find();
-
+
String b64 = hashInputDataFound ? hashInputData.substring(b64_m_s.end(), b64_m_e.start()) : "";
sig_res.setHashInputData(b64);
@@ -623,7 +622,7 @@ public final class BKUHelper
public static String formDateTimeElement(Date verificationTime, String namespace)
{
String nsPrefix = StringUtils.isBlank(namespace) ? "" : (namespace + ":");
-
+
String dateTimeElement = "";
if (verificationTime != null)
{
@@ -633,25 +632,25 @@ public final class BKUHelper
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateTime = df.format(verificationTime) + "Z";
log.debug("DateTime (VerificationTime in UTC) = " + dateTime);
-
+
dateTimeElement = "<" + nsPrefix + "DateTime>" + dateTime + "</" + nsPrefix + "DateTime>";
};
return dateTimeElement;
}
-
+
public static String getBKUIdentifier(Properties parsedResponseProperties) {
-
+
// http://www.buergerkarte.at/konzept/securitylayer/spezifikation/aktuell/bindings/bindings.html#http.kodierung.response.browser
String bkuServerHeader = parsedResponseProperties.getProperty(BKUPostConnection.BKU_SERVER_HEADER_KEY);
// http://www.buergerkarte.at/konzept/securitylayer/spezifikation/aktuell/bindings/bindings.html#http.kodierung.response.dataurl
String bkuUserAgentHeader = parsedResponseProperties.getProperty(BKUPostConnection.BKU_USER_AGENT_HEADER_KEY);
-
+
String bkuSignatureLayout = parsedResponseProperties.getProperty(BKUPostConnection.BKU_SIGNATURE_LAYOUT_HEADER_KEY);
-
+
return getBKUIdentifier(bkuServerHeader, bkuUserAgentHeader, bkuSignatureLayout);
}
-
+
public static String getBKUIdentifier(String bkuServerHeader, String bkuUserAgentHeader, String bkuSignatureLayout) {
log.debug("BKU response header \"user-agent\": " + bkuUserAgentHeader);
@@ -659,7 +658,7 @@ public final class BKUHelper
log.trace("BKU response header \"" + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "\": " + bkuSignatureLayout);
String result = null;
-
+
if (bkuServerHeader != null) {
result = bkuServerHeader;
} else if (bkuUserAgentHeader != null) {
@@ -667,7 +666,7 @@ public final class BKUHelper
} else {
log.warn("Unable to find any BKU identifier (neither header value \"user-agent\" nor \"server\".)");
}
-
+
if (bkuSignatureLayout != null && result != null) {
log.debug("BKU response header \"" + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "\" found.");
String signatureLayoutData = " " + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "/" + bkuSignatureLayout;
@@ -678,18 +677,18 @@ public final class BKUHelper
log.debug("Signature layout already encoded in server/user-agent header.");
}
}
-
+
if (result != null) {
log.debug("Returning BKU identifier \"" + result + "\"");
} else {
log.debug("Returning null BKU identifier.");
}
-
+
return result;
}
public static String getBKUIdentifier(LocalBKUParams bkuParams) {
return getBKUIdentifier(bkuParams.getServer(), bkuParams.getUserAgent(), bkuParams.getSignatureLayout());
}
-
+
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java
index a8de41e..6926d2b 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java
@@ -55,11 +55,11 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* Connects to the BKU using the detached multipart/formdata requests.
- *
+ *
* <p>
* This feature is available since BKU version 2.7.4.
* </p>
- *
+ *
* @author wprinz
*/
public class DetachedBKUConnector implements Connector, LocalConnector
@@ -85,12 +85,12 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Constructor that builds the configuration environment for this connector
* according to the given profile.
- *
+ *
* <p>
* If confuguration parameters are not defined on that profile, the default
* parameters defined in the configuration are used.
* </p>
- *
+ *
* @param connectorParameters
* The connectot parameters.
* @throws ConnectorException
@@ -101,10 +101,10 @@ public class DetachedBKUConnector implements Connector, LocalConnector
this.params = connectorParameters;
this.environment = new Environment(this.params.getProfileId(), loc_ref_content);
}
-
+
/**
* Prepares the sign request xml to be sent using the sign request template.
- *
+ *
* @param data
* The SignatureData.
* @return Returns the sign request xml to be sent.
@@ -120,7 +120,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
String sign_keybox_identifier = this.environment.getSignKeyboxIdentifier();
String mime_type = data.getMimeType();
String loc_ref_content = this.environment.getLocRefContent();
-
+
if (log.isDebugEnabled())
{
log.debug("sign keybox identifier = " + sign_keybox_identifier); //$NON-NLS-1$
@@ -139,7 +139,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Analyzes the sign response xml and extracts the signature data.
- *
+ *
* @param response_properties
* The response properties containing the response String and
* transport related information.
@@ -155,14 +155,14 @@ public class DetachedBKUConnector implements Connector, LocalConnector
String bkuIdentifier = BKUHelper.getBKUIdentifier(response_properties);
log.debug("BKU identifier: " + (bkuIdentifier != null ? ("\"" + bkuIdentifier + "\"") : "n/a"));
-
+
SignatureLayoutHandler sigLayout;
try {
sigLayout = SignatureLayoutHandlerFactory.getSignatureLayoutHandlerInstance(bkuIdentifier);
} catch (SettingsException e) {
throw new ConnectorException(e.getErrorCode(), e.getMessage());
}
-
+
BKUHelper.checkResponseForError(response_string);
SignSignatureObject so = sigLayout.parseCreateXMLSignatureResponse(response_string, this.environment);
@@ -225,15 +225,15 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Sends the request and data to the given URL.
- *
+ *
* <p>
* This method mainly handles communication exceptions. The actual send work
* is done by doPostRequestMultipart.
* </p>
- *
+ *
* @see BKUPostConnection#doPostRequestMultipart(String, String,
* SignatureData)
- *
+ *
* @param url
* The URL to send the request to.
* @param request_string
@@ -262,7 +262,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Performs a sign.
- *
+ *
* @param data
* The data to be signed.
* @return Returns the signature object containing the signature data.
@@ -289,7 +289,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Performs a verification.
- *
+ *
* @param data
* The data to be verified.
* @param so
@@ -331,7 +331,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Prepares the verify request xml to be sent using the verify request
* template.
- *
+ *
* @param data
* The SignatureData.
* @param so
@@ -345,7 +345,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
String verify_request_template = this.environment.getVerifyRequestTemplate();
String xml_content = null;
-
+
if (dsigData != null && dsigData.getXmlDsig() != null)
{
xml_content = dsigData.getXmlDsig();
@@ -355,16 +355,18 @@ public class DetachedBKUConnector implements Connector, LocalConnector
xml_content = chooseAndCreateXMLDsig(data, so);
}
-
-
- String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ String verify_request_xml = verify_request_template.replace(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getLocRefContent());
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.DATE_TIME_REPLACE, BKUHelper.formDateTimeElement(this.params.getVerificationTime(), "sl"));
return verify_request_xml;
}
-
- private String chooseAndCreateXMLDsig(SignatureData data, SignSignatureObject so) throws ConnectorException {
+
+ private String chooseAndCreateXMLDsig(SignatureData data, SignSignatureObject so) throws ConnectorException {
// MOA
if (SigKZIDHelper.isMOASigned(so))
{
@@ -379,7 +381,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
log.debug("Algorithm = " + algorithmId);
LocRefDetachedMOCCAConnector mocca_connector = new LocRefDetachedMOCCAConnector(this.params, "not needed here", algorithmId);
return mocca_connector.prepareXMLContent(data, so);
-
+
// ATRUST
} else if (SigKZIDHelper.isATrustSigned(so)) {
log.debug("ATrust signature detected");
@@ -391,20 +393,20 @@ public class DetachedBKUConnector implements Connector, LocalConnector
else if (SigKZIDHelper.isBKUSigned(so)) {
log.debug("TD signature signature detected.");
return prepareXMLContent(data, so);
- }
+ }
// unknown
else {
throw new ConnectorException(ErrorCode.UNSUPPORTED_SIGNATURE, "Unsupported signature (" + so.id + ", " +so.kz + "). Please get a new version of PDF-AS. Your version is: " + PdfAS.PDFAS_VERSION);
}
- }
+ }
/**
* Prepares the XML content the holds the actual signature data.
- *
+ *
* <p>
* This strongly rebuilds the XML content as retuned from a sign request.
* </p>
- *
+ *
* @param data
* The data.
* @param so
@@ -421,13 +423,13 @@ public class DetachedBKUConnector implements Connector, LocalConnector
String ids_string = so.getSigID();
String[] ids = SignatureObject.parseSigIds(ids_string);
-
+
X509Certificate cert = so.getX509Certificate();
-
+
// dferbas
AlgorithmSuiteObject algSuite = new AlgorithmSuiteObject();
String verify_xml = AlgorithmSuiteUtil.evaluateReplaceAlgs(algSuite, this.environment, so);
-
+
// data digest replace
{
// byte[] data_value = data.getData();
@@ -457,7 +459,11 @@ public class DetachedBKUConnector implements Connector, LocalConnector
verify_xml = verify_xml.replaceAll(TemplateReplaces.SIG_ID_REPLACE, ids[0]);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
verify_xml = verify_xml.replaceFirst(TemplateReplaces.MIME_TYPE_REPLACE, data.getMimeType());
@@ -495,7 +501,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Analyzes the verify response string.
- *
+ *
* @param response_properties
* The response properties containing the response XML.
* @return Returns the SignatureResponse containing the verification result.
@@ -518,7 +524,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Holds environment configuration information like templates.
- *
+ *
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment
@@ -537,27 +543,27 @@ public class DetachedBKUConnector implements Connector, LocalConnector
* The configuration key of the sign URL.
*/
protected static final String SIGN_URL_KEY = "bku.sign.url"; //$NON-NLS-1$
-
+
/**
* BKU template file prefix
*/
protected static final String TEMPLATE_FILE_PREFIX = "/templates/bku.";
-
+
/**
* signing file template sufix
*/
protected static final String SIGN_TEMPLATE_FILE_SUFIX = ".sign.xml";
-
+
/**
* verifing template file sufix
*/
- protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml";
+ protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml";
/**
* verifing file template key sufix
*/
protected static final String VERIFY_TEMPLATE_SUFIX = ".verify.template.xml";
-
+
/**
* The configuration key of the verify request template.
*/
@@ -605,7 +611,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Initializes the environment with a given profile.
- *
+ *
* @param profile
* The configuration profile.
* @throws ConnectorException
@@ -614,7 +620,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
public Environment(String profile, String loc_ref_content) throws ConnectorException
{
this.profile = profile;
-
+
this.loc_ref_content = loc_ref_content;
SettingsReader settings = null;
@@ -626,7 +632,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
{
throw new ConnectorException(300, e);
}
-
+
this.sign_keybox_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEYBOX_IDENTIFIER_KEY);
String sign_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + SIGN_TEMPLATE_FILE_SUFIX;
@@ -634,7 +640,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
// try to load template from file
//this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
this.sign_request_template = settings.readInternalResourceAsString(sign_request_filename);
-
+
// when first load failed (the template file does'nt exist), load it from default template file
if(this.sign_request_template == null)
{
@@ -642,7 +648,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
//this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
this.sign_request_template = settings.readInternalResourceAsString(sign_request_filename);
}
-
+
if (this.sign_request_template == null)
{
throw new ConnectorException(300, "Can not read the create xml request template"); //$NON-NLS-1$
@@ -651,20 +657,20 @@ public class DetachedBKUConnector implements Connector, LocalConnector
this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY);
// verify
-
+
String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX;
-
+
// try to load template file for verifing
//this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
this.verify_request_template = settings.readInternalResourceAsString(verify_request_filename);
-
+
if(this.verify_request_template == null)
{
verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY);
//this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
this.verify_request_template = settings.readInternalResourceAsString(verify_request_filename);
}
-
+
if (this.verify_request_template == null)
{
throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template"); //$NON-NLS-1$
@@ -674,7 +680,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
String verify_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + VERIFY_TEMPLATE_SUFIX;
//this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename));
this.verify_template = settings.readInternalResourceAsString(verify_filename);
-
+
if(this.verify_template == null)
{
verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY);
@@ -702,7 +708,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the LocRef content.
- *
+ *
* @return Returns the LocRef content.
*/
public String getLocRefContent()
@@ -712,7 +718,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the sign keybox identifier.
- *
+ *
* @return Returns the sign keybox identifier.
*/
public String getSignKeyboxIdentifier()
@@ -722,7 +728,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate()
@@ -732,7 +738,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL()
@@ -742,7 +748,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
public String getVerifyRequestTemplate()
@@ -752,7 +758,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate()
@@ -762,7 +768,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
public String getVerifyURL()
@@ -772,7 +778,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa()
@@ -782,7 +788,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa()
@@ -793,7 +799,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java
index 170cc45..22318a2 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java
@@ -52,7 +52,7 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* @author wprinz
- *
+ *
*/
public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
{
@@ -72,16 +72,16 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Constructor that builds the configuration environment for this connector
* according to the given profile.
- *
+ *
* <p>
* If confuguration parameters are not defined on that profile, the default
* parameters defined in the configuration are used.
* </p>
- *
+ *
* <p>
* This is the new "hotfix" base64 connector.
* </p>
- *
+ *
* @param profile
* The profile from which the Environment should be assembled.
* @throws ConnectorException
@@ -137,7 +137,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
// /**
// * This emthod extracts id-values from a text. The id is given by the name.
-// *
+// *
// * @param text
// * the id-value that should extract from
// * @param name
@@ -166,11 +166,11 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Prepares the XML content the holds the actual signature data.
- *
+ *
* <p>
* This strongly rebuilds the XML content as retuned from a sign request.
* </p>
- *
+ *
* @param data
* The data.
* @param so
@@ -186,13 +186,13 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
{
String ids_string = so.getSigID();
String[] ids = SignatureObject.parseSigIds(ids_string);
-
+
X509Certificate cert = so.getX509Certificate();
-
+
// dferbas
AlgorithmSuiteObject algSuite = new AlgorithmSuiteObject();
String verify_xml = AlgorithmSuiteUtil.evaluateReplaceAlgs(algSuite, this.environment, so);
-
+
// data digest replace
byte[] data_value = BKUHelper.prepareEnvelopingData(data);
{
@@ -225,7 +225,11 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
verify_xml = verify_xml.replaceAll(TemplateReplaces.SIG_ID_REPLACE, ids[0]);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
@@ -276,7 +280,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Prepares the sign request xml to be sent using the sign request template.
- *
+ *
* @param data
* The SignatureData.
* @return Returns the sign request xml to be sent.
@@ -302,7 +306,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Prepares the verify request xml to be sent using the verify request
* template.
- *
+ *
* @param data
* The SignatureData.
* @param so
@@ -325,7 +329,11 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
xml_content = chooseAndCreateXMLDsig(data, so);
}
- String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ String verify_request_xml = verify_request_template.replace(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
// log.debug("\r\n\r\n" + verify_request_xml + "\r\n\r\n");
@@ -349,7 +357,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Sends the request to the given URL.
- *
+ *
* @param url
* The URL.
* @param request_string
@@ -373,7 +381,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Analyzes the sign response xml and extracts the signature data.
- *
+ *
* @param response_properties
* The response properties containing the response String and
* transport related information.
@@ -391,7 +399,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
String bkuIdentifier = BKUHelper.getBKUIdentifier(response_properties);
log.debug("BKU identifier: \"" + bkuIdentifier + "\"");
-
+
SignSignatureObject so = BKUHelper.parseCreateXMLResponse(response_string, new HotfixIdFormatter(), this.environment);
log.debug("analyzeSignResponse finished."); //$NON-NLS-1$
@@ -400,7 +408,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Analyzes the verify response string.
- *
+ *
* @param response_properties
* The response properties containing the response XML.
* @return Returns the SignatureResponse containing the verification result.
@@ -423,7 +431,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Holds environment configuration information like templates.
- *
+ *
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment
@@ -488,7 +496,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Initializes the environment with a given profile.
- *
+ *
* @param profile
* The configuration profile.
* @throws ConnectorException
@@ -524,7 +532,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
//this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
this.verify_request_template = settings.readInternalResourceAsString(verify_request_filename);
log.debug("Verify request template filename = " + verify_request_filename);
-
+
if (this.verify_request_template == null)
{
throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template"); //$NON-NLS-1$
@@ -555,7 +563,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the sign keybox identifier.
- *
+ *
* @return Returns the sign keybox identifier.
*/
public String getSignKeyboxIdentifier()
@@ -565,7 +573,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate()
@@ -575,7 +583,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL()
@@ -585,7 +593,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
public String getVerifyRequestTemplate()
@@ -595,7 +603,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate()
@@ -605,7 +613,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
public String getVerifyURL()
@@ -615,7 +623,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa()
@@ -625,7 +633,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa()
@@ -636,7 +644,7 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java
index ea90841..07e9ccd 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java
@@ -55,7 +55,7 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper;
/**
* Connects to MOA providing the Data detached as LocRef on a local resource.
- *
+ *
* @author wprinz
*/
public class DetachedLocRefMOAConnector implements Connector
@@ -79,12 +79,12 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Constructor that builds the configuration environment for this connector
* according to the given profile.
- *
+ *
* <p>
* If confuguration parameters are not defined on that profile, the default
* parameters defined in the configuration are used.
* </p>
- *
+ *
* @param profile
* The profile from which the Environment should be assembled.
* @throws SettingsException
@@ -183,7 +183,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Prepares the verify request xml to be sent using the verify request
* template.
- *
+ *
* @param data
* The SignatureData.
* @param so
@@ -206,7 +206,11 @@ public class DetachedLocRefMOAConnector implements Connector
xml_content = chooseAndCreateXMLDsig(data, so);
}
- String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ String verify_request_xml = verify_request_template.replace(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.TRUST_PROFILE_ID_REPLACE, this.environment.getVerifyTrustProfileId());
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getSignatureDataUrl());
@@ -217,7 +221,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Analyzes the verify response string.
- *
+ *
* @param response_properties
* The response properties containing the response XML.
* @return Returns the SignatureResponse containing the verification result.
@@ -272,7 +276,11 @@ public class DetachedLocRefMOAConnector implements Connector
// Qualified Properties replaces
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
verify_xml = verify_xml.replaceFirst(TemplateReplaces.MIME_TYPE_REPLACE, data.getMimeType());
@@ -323,7 +331,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Holds environment configuration information like templates.
- *
+ *
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment
@@ -417,7 +425,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Initializes the environment with a given profile.
- *
+ *
* @param profile
* The configuration profile.
* @throws SettingsException
@@ -516,7 +524,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the URL where to load the detached data from.
- *
+ *
* @return Returns the URL where to load the detached data from.
*/
public String getSignatureDataUrl()
@@ -526,7 +534,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the sign key identifier.
- *
+ *
* @return Returns the sign key identifier.
*/
public String getSignKeyIdentifier()
@@ -536,7 +544,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate()
@@ -546,7 +554,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL()
@@ -556,7 +564,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
public String getVerifyRequestTemplate()
@@ -566,7 +574,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate()
@@ -576,7 +584,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
public String getVerifyURL()
@@ -586,7 +594,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the verify trust profile id.
- *
+ *
* @return Returns the verify trust profile id.
*/
public String getVerifyTrustProfileId()
@@ -596,7 +604,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa()
@@ -606,7 +614,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa()
@@ -617,7 +625,7 @@ public class DetachedLocRefMOAConnector implements Connector
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java
index 6f2d171..4a33fc8 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java
@@ -54,7 +54,7 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper;
/**
* @author wprinz
- *
+ *
*/
public class EnvelopingBase64MOAConnector implements Connector
{
@@ -69,18 +69,18 @@ public class EnvelopingBase64MOAConnector implements Connector
* other configurable elements.
*/
protected Environment environment = null;
-
+
protected ConnectorParameters params = null;
/**
* Constructor that builds the configuration environment for this connector
* according to the given profile.
- *
+ *
* <p>
* If confuguration parameters are not defined on that profile, the default
* parameters defined in the configuration are used.
* </p>
- *
+ *
* @param profile
* The profile from which the Environment should be assembled.
* @throws ConnectorException
@@ -150,7 +150,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Prepares the sign request xml to be sent using the sign request template.
- *
+ *
* @param data
* The SignatureData.
* @return Returns the sign request xml to be sent.
@@ -176,7 +176,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Prepares the verify request xml to be sent using the verify request
* template.
- *
+ *
* @param data
* The SignatureData.
* @param so
@@ -199,7 +199,11 @@ public class EnvelopingBase64MOAConnector implements Connector
xml_content = chooseAndCreateXMLDsig(data, so);
}
- String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ String verify_request_xml = verify_request_template.replace(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.TRUST_PROFILE_ID_REPLACE, this.environment.getVerifyTrustProfileId());
String returnHashInputDataElement = "";
@@ -208,10 +212,10 @@ public class EnvelopingBase64MOAConnector implements Connector
returnHashInputDataElement = MOASoapWithAttachmentConnector.RETURN_HASH_INPUT_DATA;
}
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.RETURN_HASH_INPUT_DATA_REPLACE, returnHashInputDataElement);
-
+
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.DATE_TIME_REPLACE, BKUHelper.formDateTimeElement(this.params.getVerificationTime()));
-
+
log.debug("\r\n\r\n" + verify_request_xml + "\r\n\r\n");
return verify_request_xml;
@@ -219,7 +223,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Analyzes the sign response xml and extracts the signature data.
- *
+ *
* @param response_properties
* The response properties containing the response String and
* transport related information.
@@ -243,7 +247,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Analyzes the verify response string.
- *
+ *
* @param response_properties
* The response properties containing the response XML.
* @return Returns the SignatureResponse containing the verification result.
@@ -266,11 +270,11 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Prepares the XML content the holds the actual signature data.
- *
+ *
* <p>
* This strongly rebuilds the XML content as retuned from a sign request.
* </p>
- *
+ *
* @param data
* The data.
* @param so
@@ -285,7 +289,7 @@ public class EnvelopingBase64MOAConnector implements Connector
try
{
X509Certificate cert = so.getX509Certificate();
-
+
// dferbas
AlgorithmSuiteObject algSuite = new AlgorithmSuiteObject();
String verify_xml = AlgorithmSuiteUtil.evaluateReplaceAlgs(algSuite, this.environment, so);
@@ -311,7 +315,11 @@ public class EnvelopingBase64MOAConnector implements Connector
// Qualified Properties replaces
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
@@ -339,7 +347,7 @@ public class EnvelopingBase64MOAConnector implements Connector
// Base64 content replace -> do this at last for performance
String base64 = CodingHelper.encodeBase64(data_value);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.BASE64_CONTENT_REPLACE, base64);
-
+
log.debug("prepareXMLContent finished."); //$NON-NLS-1$
return verify_xml;
}
@@ -352,7 +360,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Holds environment configuration information like templates.
- *
+ *
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment
@@ -401,7 +409,7 @@ public class EnvelopingBase64MOAConnector implements Connector
* The configuration key for the RSA cert alg property.
*/
protected static final String RSA_CERT_ALG_KEY = "cert.alg.rsa"; //$NON-NLS-1$
-
+
protected String profile = null;
protected String sign_key_identifier = null;
@@ -424,7 +432,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Initializes the environment with a given profile.
- *
+ *
* @param profile
* The configuration profile.
* @throws ConnectorException
@@ -433,7 +441,7 @@ public class EnvelopingBase64MOAConnector implements Connector
public Environment(String profile, String signKeyIdentifier) throws ConnectorException
{
this.profile = profile;
-
+
SettingsReader settings = null;
try
{
@@ -449,7 +457,7 @@ public class EnvelopingBase64MOAConnector implements Connector
this.sign_key_identifier = signKeyIdentifier;
}
else
- {
+ {
this.sign_key_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEY_IDENTIFIER_KEY);
}
@@ -488,7 +496,7 @@ public class EnvelopingBase64MOAConnector implements Connector
this.cert_alg_rsa = settings.getValueFromKey(RSA_CERT_ALG_KEY);
}
-
+
public String getProfile()
{
return this.profile;
@@ -496,7 +504,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the sign key identifier.
- *
+ *
* @return Returns the sign key identifier.
*/
public String getSignKeyIdentifier()
@@ -506,7 +514,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate()
@@ -516,7 +524,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL()
@@ -526,7 +534,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
public String getVerifyRequestTemplate()
@@ -536,7 +544,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate()
@@ -546,7 +554,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
public String getVerifyURL()
@@ -556,7 +564,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the verify trust profile id.
- *
+ *
* @return Returns the verify trust profile id.
*/
public String getVerifyTrustProfileId()
@@ -566,7 +574,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa()
@@ -576,7 +584,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa()
@@ -587,7 +595,7 @@ public class EnvelopingBase64MOAConnector implements Connector
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
index db0a04f..401921b 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
@@ -54,7 +54,7 @@ import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
/**
* Connects to MOA providing the Data detached as LocRef on a local resource.
- *
+ *
* @author wprinz
*/
public class MOASoapWithAttachmentConnector implements Connector
@@ -72,9 +72,9 @@ public class MOASoapWithAttachmentConnector implements Connector
private static Log log = LogFactory.getLog(MOASoapWithAttachmentConnector.class);
protected static final String MULTIPART_LOC_REF_CONTENT = "formdata:fileupload"; //$NON-NLS-1$
-
+
protected static final String RETURN_HASH_INPUT_DATA = "<ReturnHashInputData/>"; //$NON-NLS-1$
-
+
/**
* The connector parameters.
*/
@@ -85,17 +85,17 @@ public class MOASoapWithAttachmentConnector implements Connector
* other configurable elements.
*/
protected Environment environment = null;
-
-
+
+
/**
* Constructor that builds the configuration environment for this connector
* according to the given profile.
- *
+ *
* <p>
* If confuguration parameters are not defined on that profile, the default
* parameters defined in the configuration are used.
* </p>
- *
+ *
* @param connectorParameters
* The parameters for this connector.
* @throws ConnectorException
@@ -193,7 +193,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Prepares the verify request xml to be sent using the verify request
* template.
- *
+ *
* @param data
* The SignatureData.
* @param so
@@ -216,32 +216,36 @@ public class MOASoapWithAttachmentConnector implements Connector
xml_content = chooseAndCreateXMLDsig(data, so);
}
- String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+ String verify_request_xml = verify_request_template.replace(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.TRUST_PROFILE_ID_REPLACE, this.environment.getVerifyTrustProfileId());
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getSignatureDataUrl());
-
+
String returnHashInputDataElement = "";
if (this.params.isReturnHashInputData())
{
returnHashInputDataElement = RETURN_HASH_INPUT_DATA;
}
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.RETURN_HASH_INPUT_DATA_REPLACE, returnHashInputDataElement);
-
+
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.DATE_TIME_REPLACE, BKUHelper.formDateTimeElement(this.params.getVerificationTime()));
-
+
log.debug("\r\n\r\n" + verify_request_xml + "\r\n\r\n");
return verify_request_xml;
}
-
+
private String chooseAndCreateXMLDsig(SignatureData data, SignSignatureObject so) throws ConnectorException {
-
+
// MOA
if (SigKZIDHelper.isMOASigned(so)) {
log.debug("MOA signature detected.");
return prepareXMLContent(data, so);
-
+
// MOCCA
} else if (SigKZIDHelper.isMOCCASigned(so)) {
log.debug("MOCCA signature detected.");
@@ -255,7 +259,7 @@ public class MOASoapWithAttachmentConnector implements Connector
log.debug("A-Trust signature detected.");
this.environment.reInitVerifyTemplate(ATRUST_VERIFY_TEMPLATE_KEY);
return prepareXMLContent(data, so);
-
+
// TD bku
} else if (SigKZIDHelper.isBKUSigned(so)) {
log.debug("TD bku signature detected.");
@@ -263,13 +267,13 @@ public class MOASoapWithAttachmentConnector implements Connector
return bku_connector.prepareXMLContent(data, so);
} else {
throw new ConnectorException(ErrorCode.UNSUPPORTED_SIGNATURE, "Unsupported signature (" + so.id + ", " +so.kz + "). Please get a new version of PDF-AS. Your version is: " + PdfAS.PDFAS_VERSION);
-
+
}
}
-
+
/**
* Analyzes the verify response string.
- *
+ *
* @param response_properties
* The response properties containing the response XML.
* @return Returns the SignatureResponse containing the verification result.
@@ -298,7 +302,7 @@ public class MOASoapWithAttachmentConnector implements Connector
String verify_xml = null;
X509Certificate cert = so.getX509Certificate();
-
+
// dferbas
AlgorithmSuiteObject algSuite = new AlgorithmSuiteObject();
verify_xml = AlgorithmSuiteUtil.evaluateReplaceAlgs(algSuite, this.environment, so);
@@ -326,7 +330,11 @@ public class MOASoapWithAttachmentConnector implements Connector
// Qualified Properties replaces
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
verify_xml = verify_xml.replaceFirst(TemplateReplaces.MIME_TYPE_REPLACE, data.getMimeType());
@@ -367,23 +375,11 @@ public class MOASoapWithAttachmentConnector implements Connector
{
try
{
- // for performance measurement
-// long startTime = 0;
-// if (log.isInfoEnabled()) {
-// startTime = System.currentTimeMillis();
-// }
-
+
// Properties response_properties = MOASoapConnection.connectMOA(request_string, MOASoapConnection.SERVICE_SIGN, url);
log.debug("Connecting to " + url);
Properties response_properties = MOASoapConnection.doPostRequestMultipart(url,mode, request_string, data );
-
- // for performance measurement
-// if (log.isInfoEnabled()) {
-// long endTime = System.currentTimeMillis();
-// String toReport = "MOA-PROCESSING;-;-;" + (endTime - startTime) + ";";
-// log.info(toReport);
-// }
-
+
return response_properties;
}
catch (Exception e)
@@ -391,14 +387,14 @@ public class MOASoapWithAttachmentConnector implements Connector
throw new ConnectorException(330, e);
}
}
-
+
public void reInitVerifyTemplate(String templatePropKey) throws ConnectorException {
this.environment.reInitVerifyTemplate(templatePropKey);
}
/**
* Holds environment configuration information like templates.
- *
+ *
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment
@@ -490,7 +486,7 @@ public class MOASoapWithAttachmentConnector implements Connector
protected String cert_alg_rsa = null;
-
+
public void reInitVerifyTemplate(String templatePropKey) throws ConnectorException {
SettingsReader settings = null;
try
@@ -501,14 +497,14 @@ public class MOASoapWithAttachmentConnector implements Connector
{
throw new ConnectorException(300, e);
}
-
+
String verify_request_filename = getConnectorValueFromProfile(settings, this.profile, templatePropKey);
this.verify_template = settings.readInternalResourceAsString(verify_request_filename);
-
+
}
/**
* Initializes the environment with a given profile.
- *
+ *
* @param profile
* The configuration profile.
* @throws SettingsException
@@ -537,7 +533,7 @@ public class MOASoapWithAttachmentConnector implements Connector
this.sign_key_identifier = signKeyIdentifier;
}
else
- {
+ {
this.sign_key_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEY_IDENTIFIER_KEY);
}
@@ -570,7 +566,7 @@ public class MOASoapWithAttachmentConnector implements Connector
if (this.verify_request_template == null)
{
- verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY);
+ verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY);
//this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
this.verify_request_template = settings.readInternalResourceAsString(verify_request_filename);
}
@@ -614,7 +610,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the URL where to load the detached data from.
- *
+ *
* @return Returns the URL where to load the detached data from.
*/
public String getSignatureDataUrl()
@@ -624,7 +620,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the sign key identifier.
- *
+ *
* @return Returns the sign key identifier.
*/
public String getSignKeyIdentifier()
@@ -634,7 +630,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate()
@@ -644,7 +640,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL()
@@ -654,7 +650,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
public String getVerifyRequestTemplate()
@@ -664,7 +660,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate()
@@ -674,7 +670,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
public String getVerifyURL()
@@ -684,7 +680,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the verify trust profile id.
- *
+ *
* @return Returns the verify trust profile id.
*/
public String getVerifyTrustProfileId()
@@ -694,7 +690,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa()
@@ -704,7 +700,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa()
@@ -715,7 +711,7 @@ public class MOASoapWithAttachmentConnector implements Connector
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java
index 12fc709..f9fe70b 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java
@@ -120,10 +120,10 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
* @throws ConnectorException Thrown in case of an error.
*/
public SignSignatureObject doSign(SignatureData data) throws ConnectorException {
- log.debug("doSign:");
+ log.debug("doSign:");
String sign_request_xml = prepareSignRequest(data);
- log.debug("sign_request_xml = " + sign_request_xml);
+ log.debug("sign_request_xml = " + sign_request_xml);
String url = this.environment.getSignURL();
Properties response_properties = sendRequest(url, sign_request_xml, data);
@@ -132,7 +132,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
sso.response_properties = response_properties;
- log.debug("doSign finished.");
+ log.debug("doSign finished.");
return sso;
}
@@ -148,12 +148,12 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
* This method analyzes a signature response of the signature device.
* @param response_properties The response elements of the signature device.
* @return The parsed signed signature object.
- * @throws ConnectorException Thrown in case of an error.
+ * @throws ConnectorException Thrown in case of an error.
*/
public SignSignatureObject analyzeSignResponse(Properties response_properties) throws ConnectorException {
- log.debug("analyzeSignResponse:");
+ log.debug("analyzeSignResponse:");
String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
-
+
String bkuIdentifier = BKUHelper.getBKUIdentifier(response_properties);
log.debug("BKU identifier: \"" + bkuIdentifier + "\"");
SignatureLayoutHandler sigLayout;
@@ -162,13 +162,13 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
} catch (SettingsException e) {
throw new ConnectorException(e.getErrorCode(), e.getMessage());
}
-
+
BKUHelper.checkResponseForError(response_string);
-
+
// SignSignatureObject so = MOCCAHelper.parseCreateXMLResponse(response_string, new DetachedMOCIdFormatter());
SignSignatureObject so = sigLayout.parseCreateXMLSignatureResponse(response_string, this.environment);
so.response_properties = response_properties;
- log.debug("analyzeSignResponse finished.");
+ log.debug("analyzeSignResponse finished.");
return so;
}
@@ -187,7 +187,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
* @throws ConnectorException Thrown in case of an error.
*/
public String prepareSignRequest(SignatureData data) throws ConnectorException {
- log.debug("prepareSignRequestDetached:");
+ log.debug("prepareSignRequestDetached:");
String sign_request_template = this.environment.getSignRequestTemplate();
@@ -196,9 +196,9 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
String loc_ref_content = this.environment.getLocRefContent();
if (log.isDebugEnabled()) {
- log.debug("sign keybox identifier = " + sign_keybox_identifier);
- log.debug("mime type = " + mime_type);
- log.debug("loc_ref_content = " + loc_ref_content);
+ log.debug("sign keybox identifier = " + sign_keybox_identifier);
+ log.debug("mime type = " + mime_type);
+ log.debug("loc_ref_content = " + loc_ref_content);
}
String sign_request_xml = sign_request_template.replaceFirst(TemplateReplaces.KEYBOX_IDENTIFIER_REPLACE, sign_keybox_identifier);
@@ -206,7 +206,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
sign_request_xml = sign_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, loc_ref_content);
log.debug("sign_request_xml = " + sign_request_xml);
- log.debug("prepareSignRequestDetached finished.");
+ log.debug("prepareSignRequestDetached finished.");
return sign_request_xml;
}
@@ -226,15 +226,15 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
* @throws ConnectorException Thrown in case of an error.
*/
public String prepareXMLContent(SignatureData data, SignSignatureObject so) throws ConnectorException {
- log.debug("prepareXMLContent:");
+ log.debug("prepareXMLContent:");
try {
-
+
String ids_string = so.getSigID();
String sigId = this.parseSigId(ids_string);
X509Certificate cert = so.getX509Certificate();
-
-
+
+
// dferbas
AlgorithmSuiteObject algSuite = new AlgorithmSuiteObject();
String verify_xml = AlgorithmSuiteUtil.evaluateReplaceAlgs(algSuite, this.environment, so);
@@ -244,7 +244,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
String object_data_hash = CodingHelper.encodeBase64(data_value_hash);
// template replacements
-
+
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_SIGNED_DATA_REPLACE, object_data_hash);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNATURE_VALUE_REPLACE, so.getSignatureValue());
@@ -259,7 +259,11 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
verify_xml = verify_xml.replaceAll(TemplateReplaces.SIG_ID_REPLACE, sigId);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
- verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ // fixed by dti: Issuer names may contain escapted commas ("\,"). As far as replaceFirst (and replaceAll)
+ // methods are regarded, backslashes in the replacement string may cause the results to be different than
+ // if it were being treated as a literal replacement string.
+// verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ verify_xml = verify_xml.replace(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber());
// SigDataRefReplace already done above
verify_xml = verify_xml.replaceFirst(TemplateReplaces.MIME_TYPE_REPLACE, data.getMimeType());
@@ -270,15 +274,15 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
if (matcher.find()) {
log.debug("SignedProperties found.");
String string_to_be_hashed = matcher.group(1);
- log.debug("SignedProperties string to be hashed: " + string_to_be_hashed);
- final byte[] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
+ log.debug("SignedProperties string to be hashed: " + string_to_be_hashed);
+ final byte[] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
byte[] sig_prop_code = CodingHelper.buildDigest(bytes_to_be_hashed, algSuite.getPropertiesDigestMethod());
String sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_SIGNED_PROPERTIES_REPLACE, sig_prop_hash);
}
- log.debug("prepareXMLContent finished.");
+ log.debug("prepareXMLContent finished.");
return verify_xml;
} catch (Exception e) {
log.debug(e);
@@ -291,21 +295,21 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
* @author wprinz
*/
public static class Environment extends ConnectorEnvironment {
-
+
/**
* The configuration key of the sign keybox identifier.
*/
- protected static final String SIGN_KEYBOX_IDENTIFIER_KEY = "moc.sign.KeyboxIdentifier";
+ protected static final String SIGN_KEYBOX_IDENTIFIER_KEY = "moc.sign.KeyboxIdentifier";
/**
* The configuration key of the sign request template.
*/
- protected static final String SIGN_REQUEST_TEMPLATE_KEY = "moc.sign.request.detached";
+ protected static final String SIGN_REQUEST_TEMPLATE_KEY = "moc.sign.request.detached";
/**
* The configuration key of the sign URL.
*/
- protected static final String SIGN_URL_KEY = "moc.sign.url";
+ protected static final String SIGN_URL_KEY = "moc.sign.url";
/**
* BKU template file prefix
@@ -334,29 +338,29 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
*/
/* signature verification is not supported by mocca
protected static final String VERIFY_REQUEST_TEMPLATE_KEY = "moc.verify.request.detached";
- */
+ */
/**
* The configuration key of the verify template.
*/
- protected static final String VERIFY_TEMPLATE_KEY = "moc.verify.template.detached";
+ protected static final String VERIFY_TEMPLATE_KEY = "moc.verify.template.detached";
/**
* The configuration key of the verify URL.
*/
/* signature verification is not supported by mocca
protected static final String xxxVERIFY_URL_KEY = "moc.verify.url";
- */
+ */
/**
* The configuration key for the ECDSA cert alg property.
*/
- protected static final String ECDSA_CERT_ALG_KEY = "cert.alg.ecdsa";
+ protected static final String ECDSA_CERT_ALG_KEY = "cert.alg.ecdsa";
/**
* The configuration key for the RSA cert alg property.
*/
- protected static final String RSA_CERT_ALG_KEY = "cert.alg.rsa";
+ protected static final String RSA_CERT_ALG_KEY = "cert.alg.rsa";
protected String profile = null;
@@ -381,7 +385,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
protected String cert_alg_ecdsa = null;
protected String cert_alg_rsa = null;
-
+
protected String algorithmId = null;
/**
@@ -411,7 +415,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
}
// SIGN REQUEST
-
+
// try specific file
String sign_request_filename = TEMPLATE_FILE_PREFIX + this.algorithmId + SIGN_TEMPLATE_FILE_SUFFIX;
log.debug("Trying to load specific sign request file " + sign_request_filename);
@@ -428,15 +432,15 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
// request file is needed !!!
if (this.sign_request_template == null) {
- throw new ConnectorException(300, "Can not read the create xml request template");
+ throw new ConnectorException(300, "Can not read the create xml request template");
}
this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY);
-
+
// VERIFY REQUEST
/* signature verification is not supported by mocca
-
+
// try specific file
String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moc.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX;
log.debug("Trying to load specific verify request file " + verify_request_filename);
@@ -451,11 +455,11 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
// request file is needed !!!
if (this.verify_request_template == null) {
- throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template");
+ throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template");
}
-
+
*/
-
+
// load template file
// try specific file
String verify_filename = TEMPLATE_FILE_PREFIX + this.algorithmId + VERIFY_TEMPLATE_SUFFIX;
@@ -473,7 +477,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
// signature template is needed !!!
if (this.verify_template == null) {
- throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template");
+ throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template");
}
/* signature verification is not supported by mocca
@@ -496,7 +500,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the LocRef content.
- *
+ *
* @return Returns the LocRef content.
*/
public String getLocRefContent() {
@@ -505,7 +509,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the sign keybox identifier.
- *
+ *
* @return Returns the sign keybox identifier.
*/
public String getSignKeyboxIdentifier() {
@@ -514,7 +518,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the sign request template.
- *
+ *
* @return Returns the sign request template.
*/
public String getSignRequestTemplate() {
@@ -523,7 +527,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the sign URL.
- *
+ *
* @return Returns the sign URL.
*/
public String getSignURL() {
@@ -532,7 +536,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the verify request template.
- *
+ *
* @return Returns the verify request template.
*/
/* signature verification is not supported by mocca
@@ -543,7 +547,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the verify template.
- *
+ *
* @return Returns the verify template.
*/
public String getVerifyTemplate() {
@@ -552,7 +556,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the verify URL.
- *
+ *
* @return Returns the verify URL.
*/
/* signature verification is not supported by mocca
@@ -563,7 +567,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the ecdsa cert alg property.
- *
+ *
* @return Returns the ecdsa cert alg property.
*/
public String getCertAlgEcdsa() {
@@ -572,7 +576,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Returns the rsa cert alg property.
- *
+ *
* @return Returns the rsa cert alg property.
*/
public String getCertAlgRsa() {
@@ -582,7 +586,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
/**
* Reads the configuration entry given by the key, first from the given
* profile, if not found from the defaults.
- *
+ *
* @param settings
* The settings.
* @param profile
@@ -599,7 +603,7 @@ public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
return value;
}
}
-
+
/**
* Parses the common part for all id attributes from a given signature parameter string.
* @param sigIdString The given signature parameter string.
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
index 094880d..03bf931 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
@@ -50,49 +50,52 @@ import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter;
*/
public final class SigKZIDHelper
{
-
+
/**
* The Logger.
*/
protected static Log logger = LogFactory.getLog(SigKZIDHelper.class);
-
+
public static boolean isTextual(PdfASID sig_kz)
{
if (sig_kz == null)
{
// Old signature -> must be textual.
-
+
return true;
}
-
+
// new signauture -> sig_kz decides
return sig_kz.getType().equals(SignatorFactory.TYPE_TEXTUAL);
}
-
+
public static boolean isBinary(PdfASID sig_kz)
{
return ! isTextual(sig_kz);
}
-
-
+
+
public static boolean isMOASigned(PdfASID sig_kz, String sig_id)
{
if (sig_kz == null || sig_kz.getVersion().equals(SignatorFactory.VERSION_1_0_0))
{
// old signature - if sig_id is null this means MOA
-
+
return sig_id == null;
}
-
- if(sig_id == null)
+
+ // According to the specification no signature parameter means MOA signature.
+ // Fixed: empty ("") or blank (" "), non-null signature parameter should also be regarded as "no signature parameter"
+// if (sig_id != null)
+ if (StringUtils.isBlank(sig_id))
return true;
-
+
// new signature - sig_id decides
String [] ids = sig_id.split("@");
// dferbas
String prefix = (ids[0].split(":"))[0];
-
-
+
+
if (prefix.equals(DetachedLocRefMOAIdFormatter.SIG_ID_PREFIX))
{
return true;
@@ -116,10 +119,10 @@ public final class SigKZIDHelper
logger.error(e.getMessage(), e);
}
}
-
+
return isMOASigned(kz, sig_id);
}
-
+
/**
* @author tknall
*/
@@ -128,7 +131,7 @@ public final class SigKZIDHelper
if (StringUtils.isEmpty(sig_id)) {
return false;
}
- String[] ids = sig_id.split("@");
+ String[] ids = sig_id.split("@");
if (ArrayUtils.isEmpty(ids)) {
return false;
}
@@ -136,7 +139,7 @@ public final class SigKZIDHelper
if (algorithmId == null) {
return false;
} else {
- return algorithmId.startsWith("etsi-moc-1.0") || algorithmId.startsWith("etsi-moc-1.1");
+ return algorithmId.startsWith("etsi-moc-1.0") || algorithmId.startsWith("etsi-moc-1.1") || algorithmId.startsWith("etsi-moc-1.2");
}
}
@@ -203,16 +206,16 @@ public final class SigKZIDHelper
logger.error(e.getMessage(), e);
}
}
-
+
return isOldBKU(kz, sig_id);
}
-
+
public static String getAlgorithmId(String bkuIdentifier) throws SettingsException, SettingNotFoundException, ConnectorException {
SettingsReader sr = SettingsReader.getInstance();
String base = "signaturelayout.pattern";
Vector v = sr.getSettingKeys(base);
-
+
Iterator it = v.iterator();
while (it.hasNext()) {
String subKey = (String) it.next();
@@ -225,7 +228,7 @@ public final class SigKZIDHelper
return algValue;
}
}
-
+
if ("true".equalsIgnoreCase(sr.getSetting("signaturelayout.strict", "false"))) {
logger.debug("Enforcing bku support check.");
throw new ConnectorException(ErrorCode.BKU_NOT_SUPPORTED, "Unsupported BKU: " + bkuIdentifier);
@@ -233,7 +236,7 @@ public final class SigKZIDHelper
logger.debug("bku support check disabled.");
return null;
}
-
+
}
public static boolean isATrustSigned(SignSignatureObject so) {
@@ -241,7 +244,7 @@ public final class SigKZIDHelper
if (sig_id == null && StringUtils.isEmpty(sig_id)) {
return false;
}
- return sig_id.startsWith("etsi-bka-atrust-1.0");
+ return sig_id.startsWith("etsi-bka-atrust-1.0");
}
/**
@@ -251,11 +254,11 @@ public final class SigKZIDHelper
*/
public static boolean isBKUSigned(SignSignatureObject so) throws ConnectorException {
if (isOldBKU(so)) return true;
-
+
if (so.id.startsWith("etsi-bka-1.0")) {
return true;
}
-
+
return false;
}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/signaturelayout/mocca/MoccaXades14SignatureLayoutHandler.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/signaturelayout/mocca/MoccaXades14SignatureLayoutHandler.java
new file mode 100644
index 0000000..ed14315
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/signaturelayout/mocca/MoccaXades14SignatureLayoutHandler.java
@@ -0,0 +1,53 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.sig.signaturelayout.mocca;
+
+import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
+import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorEnvironment;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.connectors.mocca.MOCCAHelper;
+import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedMOCIdFormatter;
+import at.knowcenter.wag.egov.egiz.sig.signaturelayout.SignatureLayoutHandler;
+
+/**
+ * Layout handler for XAdES 1.4 based signature layouts.
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public class MoccaXades14SignatureLayoutHandler implements SignatureLayoutHandler {
+
+ /**
+ * The signature parameter identifier for XAdES 1.4 signatures.
+ */
+ private final static String ALGORITHM_ID = "etsi-moc-1.2";
+
+ /**
+ * Parses the given xmlResponse with respect to the specific signature layout of mocca.
+ */
+ public SignSignatureObject parseCreateXMLSignatureResponse(String xmlResponse, ConnectorEnvironment env)
+ throws ConnectorException {
+ return MOCCAHelper.parseCreateXMLResponse(xmlResponse, new DetachedMOCIdFormatter(ALGORITHM_ID), env);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java
index 5132021..3546cd7 100644
--- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java
@@ -38,7 +38,7 @@ import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper;
/**
* This class provides encoding and decoding methods and other coding methods.
* All methods are static!
- *
+ *
* @author wlackner
*/
public class CodingHelper
@@ -52,7 +52,7 @@ public class CodingHelper
/**
* This method encodes a given Unicode (Java) String to UTF-8 bytes and then
* encodes these UTF-8 bytes to a Base64 US-ASCII (Java) String.
- *
+ *
* @param plain_string
* to be encoded
* @return the UTF-8 and Base64 encoded string
@@ -68,7 +68,6 @@ public class CodingHelper
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -76,7 +75,7 @@ public class CodingHelper
/**
* This method decodes the UTF-8 bytes from a Base64 US-ASCII (Java) String
* and decodes the UTF-8 bytes to a unicode (Java) String.
- *
+ *
* @param encoded_string
* to be decoded
* @return the Base64 and UTF-8 decoded string
@@ -92,7 +91,6 @@ public class CodingHelper
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -108,7 +106,6 @@ public class CodingHelper
// try {
// utf8 = theString.getBytes("UTF-8");
// } catch (UnsupportedEncodingException e) {
- // e.printStackTrace();
// }
// return utf8;
// }
@@ -139,20 +136,19 @@ public class CodingHelper
// try {
// the_string = new String(ba, "UTF-8");
// } catch (UnsupportedEncodingException e) {
- // e.printStackTrace();
// }
// return the_string;
// }
/**
* This method decodes a given Base64 string.
- *
+ *
* <p>
* Note that the given String must only contain Base64 characters. (The string
* will be converted to a byte array of "US-ASCII" (7 bit) bytes and then this
* byte array will be decoded using the Base64 algorithm.
* </p>
- *
+ *
* @param theString
* to be decoded
* @return a Base64 decoded byte array
@@ -166,14 +162,13 @@ public class CodingHelper
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException("Very Strange: US-ASCII encoding not supported???", e);
}
}
/**
* This method decodes a given Base64 byte array
- *
+ *
* @param ba
* the byte array to be decoded
* @return a Base64 decoded byte array
@@ -185,7 +180,7 @@ public class CodingHelper
/**
* This method encodes a given byte array Base64
- *
+ *
* @param plainString
* the byte array to be encoded
* @return the Base64 encoded string
@@ -199,7 +194,6 @@ public class CodingHelper
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException("Very Strange: US-ASCII encoding not supported???", e);
}
}
@@ -207,15 +201,15 @@ public class CodingHelper
// dferbas
/**
* This method builds an hash value of a given byte array.
- *
+ *
* @param data
* the byte array to build the hash value for
- * @param hashAlg hash algorithm for {@link MessageDigest} e.g. "SHA-1"
+ * @param hashAlg hash algorithm for {@link MessageDigest} e.g. "SHA-1"
* @return the calculated hash value as a byte array
* @see MessageDigest
*/
public static byte[] buildDigest(byte[] data, String hashAlg)
- {
+ {
MessageDigest digester = null;
try
{
@@ -243,10 +237,10 @@ public class CodingHelper
byte [] data = DataSourceHelper.convertDataSourceToByteArray(input);
return buildDigest(data, hashAlg);
}
-
+
/**
* This method escapes a given string with HTML entities.
- *
+ *
* @param rawString
* the string to escaped
* @return the HTML escaped string
@@ -263,7 +257,7 @@ public class CodingHelper
/**
* This method checks, if a byte array contains chars that are not base64
* conform.
- *
+ *
* @param byteArray
* the array to test
* @return boolean, if a byte array is base64 conform, false otherwise
@@ -282,7 +276,7 @@ public class CodingHelper
/**
* This method checks, if a string contains chars that are not base64 conform.
- *
+ *
* @param string
* the chars to test
* @return boolean, if the given string is base64 conform, false otherwise