aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-lib/src/main')
-rw-r--r--pdf-as-lib/src/main/assembly/lib.xml25
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java33
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java11
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java78
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java123
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java13
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java105
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java314
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java63
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java47
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java441
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java6
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java49
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java9
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java16
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java7
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java218
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java19
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java3
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java5
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java37
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java82
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java268
-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
-rw-r--r--pdf-as-lib/src/main/java/demo/SignatureVerificationDemo.java38
-rw-r--r--pdf-as-lib/src/main/resources/DefaultConfiguration.zipbin957949 -> 978161 bytes
-rw-r--r--pdf-as-lib/src/main/resources/config/defaultconfig.properties209
-rw-r--r--pdf-as-lib/src/main/resources/config/help_text.properties90
-rw-r--r--pdf-as-lib/src/main/resources/config/pdf-as.properties25
-rw-r--r--pdf-as-lib/src/main/resources/config/templates/moc.etsi-moc-1.2.verify.template.xml1
78 files changed, 4792 insertions, 1628 deletions
diff --git a/pdf-as-lib/src/main/assembly/lib.xml b/pdf-as-lib/src/main/assembly/lib.xml
index f9efd00..dcf665b 100644
--- a/pdf-as-lib/src/main/assembly/lib.xml
+++ b/pdf-as-lib/src/main/assembly/lib.xml
@@ -20,7 +20,7 @@
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
- <include>at.gv.egiz:pdf-as-lib:jar</include>
+ <include>eu.europa.ec.joinup.egovlabs.pdf-as:pdf-as-lib:jar</include>
</includes>
<binaries>
<unpack>false</unpack>
@@ -39,7 +39,7 @@
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<excludes>
- <exclude>at.gv.egiz:pdf-as-lib:jar</exclude>
+ <exclude>eu.europa.ec.joinup.egovlabs.pdf-as:pdf-as-lib:jar</exclude>
</excludes>
</dependencySet>
@@ -84,7 +84,7 @@
</includes>
</fileSet>
- <!-- Add specification. -->
+ <!-- Add layout specification. -->
<fileSet>
<directory>../dok/Spezifikation/Spezifikation-Layout-Amtssignatur-las-v1.4.0</directory>
<outputDirectory>doc</outputDirectory>
@@ -92,6 +92,25 @@
<include>Spezifikation-Layout-Amtssignatur-las-v1.4.0.pdf</include>
</includes>
</fileSet>
+
+ <!-- Add core specification. -->
+ <fileSet>
+ <directory>../dok/Spezifikation</directory>
+ <outputDirectory>doc</outputDirectory>
+ <includes>
+ <include>PDF-AS-Spezifikation-2.3.pdf</include>
+ </includes>
+ </fileSet>
+
+ <!-- Add release notes. -->
+ <fileSet>
+ <directory>../dok</directory>
+ <outputDirectory>doc</outputDirectory>
+ <includes>
+ <include>RELEASE_NOTES*.txt</include>
+ </includes>
+ </fileSet>
+
</fileSets>
</assembly>
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
index b351d50..4afec65 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
@@ -27,7 +27,7 @@ import at.knowcenter.wag.egov.egiz.pdf.AdobeSignatureHelper;
/**
* Contains commonly used constants.
- *
+ *
* @author wprinz
*/
public final class Constants
@@ -52,7 +52,7 @@ public final class Constants
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_TYPE_TEXTUAL = "textual";
-
+
/**
* The default signature type (one of "textual", "binary", "detachedtextual").
*/
@@ -60,7 +60,7 @@ public final class Constants
/**
* A "detached" textual signature.
- *
+ *
* <p>
* The document text is signed, but instead of returning the pdf with the signature block,
* the sign result XML of the connector is returned.
@@ -98,14 +98,14 @@ public final class Constants
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_DEVICE_MOBILE = "mobile";
-
+
/**
* Added by rpiazzi
* The signature device MOBILETEST for the test version of the MOBILE CCS.
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_DEVICE_MOBILETEST = "mobiletest";
-
+
/**
* Only binary signatures are verified.
*/
@@ -113,7 +113,7 @@ public final class Constants
/**
* Binary and textual signatures are verified with time optimization.
- *
+ *
* <p>
* This mode of operation tries to minimize the numbers of text extractions,
* which are very time intensive, at the cost of some rare cases, in which some
@@ -141,19 +141,19 @@ public final class Constants
* The zip file containing the default configuration.
*/
public static final String DEFAULT_CONFIGURATION_ZIP_RESOURCE = "DefaultConfiguration.zip";
-
+
/**
* The configuration folder for pdf-as within the user's home folder.
*/
public static final String USERHOME_CONFIG_FOLDER = "PDF-AS";
-
+
/**
* The name of the directory, where temporary files are stored.
*/
public static final String TEMP_DIR_NAME = "pdfastmp";
-
+
public static final String BKU_HEADER_SIGNATURE_LAYOUT = "SignatureLayout";
-
+
public static final String ADOBE_SIG_FILTER = AdobeSignatureHelper.ADOBE_SIG_FILTER;
/**
@@ -161,25 +161,30 @@ public final class Constants
* If the placeholder with the given id is not found in the document, an exception will be thrown.
*/
public static final int PLACEHOLDER_MATCH_MODE_STRICT = 0;
-
+
/**
* A moderate matching mode for placeholder extraction.<br/>
* If the placeholder with the given id is not found in the document, the first placeholder without an id will be taken.<br/>
* If there is no such placeholder, the signature will be placed as usual, according to the pos parameter of the signature profile used.
*/
public static final int PLACEHOLDER_MATCH_MODE_MODERATE = 1;
-
+
/**
* A more lenient matching mode for placeholder extraction.<br/>
* If the placeholder with the given id is not found in the document, the first found placeholder will be taken, regardless if it has an id set, or not.<br/>
* If there is no placeholder at all, the signature will be placed as usual, according to the pos parameter of the signature profile used.
*/
public static final int PLACEHOLDER_MATCH_MODE_LENIENT = 2;
-
+
/**
* Identifier for QR based placeholders.
*/
public static final String QR_PLACEHOLDER_IDENTIFIER = "PDF-AS-POS";
-
+
+ /**
+ * The name of a logger used for statistical logging.
+ */
+ public static final String STATISTIC_LOGGER_NAME = "statistic";
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
index 7e1672a..e1f31f7 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
@@ -159,8 +159,10 @@ public class DynamicSignatureProfileImpl implements DynamicSignatureProfile {
cfg = SettingsReader.getInstance();
- Properties props = cfg.getProperties();
- for (Enumeration e = props.keys(); e.hasMoreElements();) {
+ Properties props = cfg.getProperties();
+ // DTI: props.keys() does not support default properties, therefore we should better use props.propertyNames()
+// for (Enumeration e = props.keys(); e.hasMoreElements();) {
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
String oldKey = (String) e.nextElement();
if (oldKey.startsWith("sig_obj." + parentProfile + ".")) {
String newKey = StringUtils.replace(oldKey, parentProfile, name);
@@ -168,7 +170,7 @@ public class DynamicSignatureProfileImpl implements DynamicSignatureProfile {
this.newProps.put(newKey, val);
}
}
- this.newProps.put("sig_obj.types." + name, "on");
+ this.newProps.put("sig_obj.types." + name, "on");
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
index 8cd3108..1325d04 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
@@ -25,6 +25,8 @@ package at.gv.egiz.pdfas.api.commons;
import java.util.Properties;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes.State;
+
/**
* Definition of a signature profile.
*
@@ -73,4 +75,13 @@ public interface SignatureProfile {
* @return
*/
public boolean isDefault();
+
+ /**
+ * Returns the state of the signature profile. Signature profiles may be restricted to signature (
+ * {@link State#SIGN_ONLY}) or to verification ({@link State#VERIFY_ONLY}).
+ *
+ * @return The state of the profile.
+ */
+ public State getState();
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
index 8834481..5533b8b 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
@@ -34,16 +34,16 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
/**
* Parameter object that holds the sign parameters.
- *
+ *
* @author wprinz
*/
public class SignParameters
{
// 23.11.2010 changed by exthex - added parameters for placeholder handling
-
+
/**
* The document to be signed.
- *
+ *
* <p>
* The DataSource implementation encapsulates the actual representaion of the
* data. E.g. the DataSource may be File based or byte array based. See
@@ -54,7 +54,7 @@ public class SignParameters
/**
* The type of the signature.
- *
+ *
* <p>
* May be {@link Constants#SIGNATURE_TYPE_BINARY} or
* {@link Constants#SIGNATURE_TYPE_TEXTUAL}.
@@ -64,7 +64,7 @@ public class SignParameters
/**
* The signature device to perform the actual signature.
- *
+ *
* <p>
* May be {@link Constants#SIGNATURE_DEVICE_MOA} or
* {@link Constants#SIGNATURE_DEVICE_BKU}.
@@ -75,18 +75,18 @@ public class SignParameters
/**
* The signature profile identifier identifying the profile to be used in the
* config file.
- *
+ *
* <p>
* Note: In near future it will be possible to provide a full specified
* profile here instead of the profile id.
* </p>
*/
protected String signatureProfileId = null;
-
+
/**
* The signature key identifier specifying which signature key should be used
* by the signature device to perform the signature.
- *
+ *
* <p>
* Providing a null value (default) means that no explicit signature key
* identifier is provided. The selected signature device will then use its
@@ -122,7 +122,7 @@ public class SignParameters
* The output DataSink that will receive the signed document.
*/
protected DataSink output = null;
-
+
protected TimeStamper timeStamperImpl;
/**
@@ -142,12 +142,12 @@ public class SignParameters
* Defaults to {@link Constants#PLACEHOLDER_MATCH_MODE_MODERATE}.
*/
protected int placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE;
-
+
protected Properties overrideProps = new Properties();
-
-
+
+
/**
* {@link #setTimeStamperImpl(TimeStamper)}
@@ -158,7 +158,7 @@ public class SignParameters
}
/**
- * Set a {@link TimeStamper} to create a timestamp on the signature value. Will be
+ * Set a {@link TimeStamper} to create a timestamp on the signature value. Will be
* called after sign. For binary signatures only. Timestamp will be embedded in egiz dict /TimeStamp.
* @param timeStamperImpl
*/
@@ -285,21 +285,21 @@ public class SignParameters
}
/**
- * Override user defined values from the used signature profile like "value.SIG_META".
- * You cannot override pre defined values like SIG_VALUE, SIG_DATE {@link SignatureTypes#REQUIRED_SIG_KEYS}.
+ * Override user defined values from the used signature profile like "value.SIG_META".
+ * You cannot override pre defined values like SIG_VALUE, SIG_DATE {@link SignatureTypes#REQUIRED_SIG_KEYS}.
* The override values are bound to the {@link SignParameters} instance.
* <p>
* Sample usage:
* <pre>
SignParameters sp = new SignParameters();
. . .
-
- sp.setSignatureProfileId("SIGNATURBLOCK_DE");
-
+
+ sp.setSignatureProfileId("SIGNATURBLOCK_DE");
+
// expressions do not work on binary signature fields without phlength setting!!
sp.setProfileOverrideValue("SIG_META", "It's nice to be important, but it is more important to be nice ${subject.L}");;
- sp.setProfileOverrideValue("SIG_LABEL", "./images/signatur-logo_en.png");
-
+ sp.setProfileOverrideValue("SIG_LABEL", "./images/signatur-logo_en.png");
+
// execute sign using the overrides
pdfAs.sign(sp);
</pre>
@@ -311,51 +311,51 @@ public class SignParameters
if (SignatureTypes.isRequredSigTypeKey(key)) {
throw new RuntimeException("cannot set value for pre defined signature field names");
}
- this.overrideProps.put(key, value);
+ this.overrideProps.put(key, value);
}
-
+
/**
* Get override values created via {@link #setProfileOverrideValue(String, String)}
* @return
*/
public Properties getProfileOverrideProperties() {
return this.overrideProps;
-
+
}
/**
* Get the value of the checkForPlaceholder flag.
- *
+ *
* @return
*/
public Boolean isCheckForPlaceholder() {
return this.checkForPlaceholder;
}
-
+
/**
- * Set this to true, if you want a search for placeholder images to be performed and
+ * Set this to true, if you want a search for placeholder images to be performed and
* appropriate images to be replaced.
* If this is not set, a search will only be performed if the configuration property "enable_placeholder_search" is set to true.
- *
+ *
* @param check
*/
- public void setCheckForPlaceholder(boolean check) {
- this.checkForPlaceholder = Boolean.valueOf(check);
+ public void setCheckForPlaceholder(Boolean searchForPlaceHolder) {
+ this.checkForPlaceholder = searchForPlaceHolder;
}
/**
- * Set an explicit placeholder id.
+ * Set an explicit placeholder id.
* Only placeholder images that have a matching ID property embedded will be considered for replacement.
- *
+ *
* @param placeholderId
*/
public void setPlaceholderId(String placeholderId) {
- this.placeholderId = placeholderId;
+ this.placeholderId = placeholderId;
}
-
+
/**
* The id of the placeholder to replace.
- *
+ *
* @return the placeholderId
*/
public String getPlaceholderId() {
@@ -367,13 +367,13 @@ public class SignParameters
* Exactly matching meaning:<br/>
* <ul><li>If a placeholderId is set: a placeholder which has exactly this id embedded</li>
* <li>If no placeholderId is set: a placeholder without an embedded id is found</li></ul>
- *
+ *
* @see Constants#PLACEHOLDER_MATCH_MODE_LENIENT
* @see Constants#PLACEHOLDER_MATCH_MODE_MODERATE
* @see Constants#PLACEHOLDER_MATCH_MODE_STRICT
- *
+ *
* Defaults to {@link Constants#PLACEHOLDER_MATCH_MODE_MODERATE}.
- *
+ *
* @param placeholderMatchMode
*/
public void setPlaceholderMatchMode(int placeholderMatchMode) {
@@ -382,12 +382,12 @@ public class SignParameters
/**
* Get the placeholder matching mode.
- *
+ *
* @see SignParameters#getPlaceholderMatchMode()
* @return the placeholderMatchMode
*/
public int getPlaceholderMatchMode() {
return this.placeholderMatchMode;
}
-
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
index 52355f8..d5f7e2f 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
@@ -36,6 +36,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -78,11 +79,11 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
/**
* The main program entry point of the commandline tool.
- *
+ *
* <p>
* The commandline uses the PDF-AS API.
* </p>
- *
+ *
* @author wprinz
*/
public abstract class Main
@@ -127,12 +128,12 @@ public abstract class Main
* Command line parameter signaling to search the source document for a placeholder for the signature
*/
protected static final String PARAMETER_PLACEHOLDER_SEARCH = "-searchplaceholder";
-
+
/**
* Command line parameter selecting the id of the placeholder to use
*/
protected static final String PARAMETER_PLACEHOLDER_ID = "-placeholder_id";
-
+
/**
* Command line parameter selecting the match mode for the placeholder
*/
@@ -143,7 +144,7 @@ public abstract class Main
* verified.
*/
protected static final String PARAMETER_VERIFY_WHICH = "-verify_which";
-
+
/**
* Command line parameter that starts the deployment of the default configuration to the current
* user's home folder.
@@ -195,7 +196,7 @@ public abstract class Main
* The placeholder match mode STRICT
*/
public static final String VALUE_PLACEHOLDER_MATCH_MODE_LENIENT = "lenient";
-
+
/**
* The log.
*/
@@ -203,7 +204,7 @@ public abstract class Main
/**
* Main program entry point.
- *
+ *
* @param args
* The commandline arguments.
* @throws IOException
@@ -216,7 +217,7 @@ public abstract class Main
for (int i = 0; i < args.length; i++) {
if (args[i].trim().equals(PARAMETER_DEPLOY_DEFAULT_CONFIGURATION)) {
try {
- String defaultConfigurationDeployedTo = ConfigUtils.deployDefaultConfiguration();
+ String defaultConfigurationDeployedTo = ConfigUtils.deployDefaultConfiguration();
if (defaultConfigurationDeployedTo != null) {
System.out.println("Default configuration successfully deployed to \"" + defaultConfigurationDeployedTo + "\".");
} else {
@@ -229,7 +230,7 @@ public abstract class Main
} catch (ConfigUtilsException e) {
System.err.println("Deployment of default configuration failed: " + e.getMessage());
System.exit(1);
- }
+ }
}
}
@@ -247,7 +248,8 @@ public abstract class Main
String user_password = null;
String pos_string = null;
- boolean search_placeholder = true;
+ // DTI: fixed searchplaceholder parameter handling preventing consideration of respective configuration parameter
+ Boolean searchPlaceHolder = null;
String placeholderId = null;
int placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE;
@@ -274,7 +276,7 @@ public abstract class Main
// already applied
continue;
}
-
+
if (cur_arg.equals(PARAMETER_MODE))
{
i++;
@@ -351,7 +353,8 @@ public abstract class Main
printNoValue(PARAMETER_PLACEHOLDER_SEARCH);
return;
}
- search_placeholder = Boolean.valueOf(args[i]).booleanValue();
+// search_placeholder = Boolean.valueOf(args[i]).booleanValue();
+ searchPlaceHolder = BooleanUtils.toBooleanObject(args[i]);
continue;
}
@@ -522,7 +525,7 @@ public abstract class Main
output = generateOutputFileNameFromInput(input, signature_mode);
}
- carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string, search_placeholder, placeholderId, placeholderMatchMode);
+ carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string, searchPlaceHolder, placeholderId, placeholderMatchMode);
}
catch (PdfAsException e)
@@ -549,7 +552,7 @@ public abstract class Main
}
protected static void carryOutCommand(final String mode, final String signature_mode, final String connector, final String signature_type, final String user_name, final String user_password,
- final int verify_which, final String input, String output, final String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException
+ final int verify_which, final String input, String output, final String pos_string, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode) throws PdfAsException
{
// File file = new File(input);
//
@@ -570,7 +573,7 @@ public abstract class Main
if (mode.equals(VALUE_MODE_SIGN))
{
- carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput, search_placeholder, placeholderId, placeholderMatchMode);
+ carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput, searchPlaceHolder, placeholderId, placeholderMatchMode);
}
else
{
@@ -580,7 +583,7 @@ public abstract class Main
}
public static void carryOutSign(String input, String connector, String signature_mode, String signature_type, String pos_string, String user_name, String user_password, String output,
- PrintWriter messageOutput, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException
+ PrintWriter messageOutput, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode) throws PdfAsException
{
messageOutput.println("Signing " + input + "...");
@@ -621,7 +624,7 @@ public abstract class Main
}
try {
- processSign(dataSource, connector, signature_mode, signature_type, pos_string, search_placeholder, placeholderId, placeholderMatchMode, dataSink);
+ processSign(dataSource, connector, signature_mode, signature_type, pos_string, searchPlaceHolder, placeholderId, placeholderMatchMode, dataSink);
} catch (Exception e) {
// Exception caught in order to delete file based datasink
if (outputFile != null && outputFile.exists())
@@ -641,14 +644,6 @@ 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 (" + output + ").");
}
@@ -656,22 +651,10 @@ public abstract class Main
{
messageOutput.println("Verifying " + input + "...");
- // 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"))
{
@@ -705,23 +688,15 @@ 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
@@ -743,7 +718,7 @@ public abstract class Main
return file_name.substring(dot_index + 1);
}
- public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode, DataSink dataSink) throws PdfAsException
+ public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode, DataSink dataSink) throws PdfAsException
{
TablePos pos = null;
if (pos_string != null)
@@ -795,7 +770,7 @@ public abstract class Main
sp.setSignatureDevice(connector);
sp.setSignatureProfileId(signature_type);
sp.setSignaturePositioning(posi);
- sp.setCheckForPlaceholder(search_placeholder);
+ sp.setCheckForPlaceholder(searchPlaceHolder);
sp.setPlaceholderId(placeholderId);
sp.setPlaceholderMatchMode(placeholderMatchMode);
pdfAs.sign(sp);
@@ -853,7 +828,7 @@ public abstract class Main
/**
* Prints that the provided option was unrecognized.
- *
+ *
* @param option
* The unrecognized option.
* @throws PresentableException
@@ -867,7 +842,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param parameter
* The parameter, which is missing a value.
* @throws PresentableException
@@ -881,7 +856,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param value
* The unrecognized value.
* @throws PresentableException
@@ -895,7 +870,7 @@ public abstract class Main
/**
* Prints that the provided additional commandline argument was unrecognized.
- *
+ *
* @param argument
* The unrecognized argument.
* @throws PresentableException
@@ -909,7 +884,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
@@ -924,7 +899,7 @@ public abstract class Main
/**
* Prints that something is missing.
- *
+ *
* @param missing_term
* A descriptive message of the missing thing.
* @throws PresentableException
@@ -938,7 +913,7 @@ public abstract class Main
/**
* Prints out the ErrorCodeException in a descriptive form.
- *
+ *
* @param ece
* The ErrorCodeException to be printed.
*/
@@ -974,7 +949,7 @@ public abstract class Main
/**
* Prints the usage text.
- *
+ *
* @param writer
* The writer to print the text to.
* @throws PresentableException
@@ -991,7 +966,7 @@ public abstract class Main
writer.print(" " + PARAMETER_CONNECTOR + " ");
ConnectorInformation[] ci = ConnectorFactory.getConnectorInformationArray();
-
+
// prepare list of connectors available for commandline
ArrayList ciList = new ArrayList();
for (int i = 0; i < ci.length; i++) {
@@ -1000,7 +975,7 @@ public abstract class Main
ciList.add(ci[i]);
}
}
-
+
// list available connectors wrapped in <...|...>
Iterator ciIt = ciList.iterator();
writer.print("<");
@@ -1012,7 +987,7 @@ public abstract class Main
}
writer.print(">");
writer.println();
-
+
// for (int i = 0; i < ci.length; i++)
// {
// String id = ci[i].getIdentifier();
@@ -1046,7 +1021,7 @@ public abstract class Main
writer.println(" " + PARAMETER_DEPLOY_DEFAULT_CONFIGURATION + " ... deploys the default configuration to the current user's home");
- writer.println(" OPTIONS for signation:");
+ writer.println(" OPTIONS for signature:");
writer.println(" " + PARAMETER_SIGNATURE_MODE + " <" + VALUE_SIGNATURE_MODE_BINARY + "|" + VALUE_SIGNATURE_MODE_TEXTUAL + "> [optional]");
writer.println(" " + VALUE_SIGNATURE_MODE_BINARY + " ... signs the complete binary document" + (Constants.DEFAULT_SIGNATURE_TYPE.equals(VALUE_SIGNATURE_MODE_BINARY) ? " (default)" : ""));
@@ -1056,7 +1031,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())
{
@@ -1117,7 +1094,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.
@@ -1129,7 +1106,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.
@@ -1143,7 +1120,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.
@@ -1157,7 +1134,7 @@ public abstract class Main
/**
* Checks the value for correctness (meaning if it exists)
- *
+ *
* @param signature_type
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1166,10 +1143,10 @@ public abstract class Main
{
return SignatureTypes.getInstance().getSignatureTypes().contains(signature_type);
}
-
+
/**
* Translates the commandline argument to a PDF-AS-ID.
- *
+ *
* @param signature_mode
* The signator mode commandline argument.
* @return Returns the corresponding PDFASID.
@@ -1197,7 +1174,7 @@ public abstract class Main
/**
* Formats the verification results.
- *
+ *
* @param results
* The List of SignatureResponse verification results.
* @param writer
@@ -1223,9 +1200,9 @@ 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
@@ -1259,7 +1236,7 @@ public abstract class Main
String public_property = (String) it.next();
writer.println(" Eigenschaft: " + public_property);
}
-
+
writer.println(" Zertifikat-Check:");
writer.println(" " + result.getCertificateCheck().getCode() + " - " + result.getCertificateCheck().getMessage());
writer.println(" Signatur-Check:");
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
index e0ddbf2..e7d2b47 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
@@ -23,6 +23,8 @@
*/
package at.gv.egiz.pdfas.exceptions;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+
/**
* Contains constants for the error codes.
*
@@ -44,6 +46,8 @@ public final class ErrorCode
public static final int NO_EMBEDABLE_TTF_CONFIGURED_FOR_PDFA = 103;
public static final int INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED = 104;
public static final int MISSING_HEADER_SERVER_USER_AGENT = 105;
+ public static final int CIRCULAR_INCLUDE_INSTRUCTION_DETECTED = 106;
+ public static final int UNABLE_TO_LOAD_DEFAULT_CONFIG = 107;
public static final int DOCUMENT_CANNOT_BE_READ = 201;
public static final int TEXT_EXTRACTION_EXCEPTION = 202;
@@ -56,6 +60,15 @@ public final class ErrorCode
//23.11.2010 changed by exthex - added error code for failed extraction
public static final int SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED = 233;
+ /**
+ * Error code for {@code SignatureException}s occurring when trying to sign with a certain signature profile that
+ * is not allowed to be used for signature, e.g. because ist has been set to
+ * <p/>
+ * {@code sig_obj.types.<PROFILE_ID> = verify_only}
+ * @author Datentechnik Innovation GmbH
+ */
+ public static final int SIGNATURE_PROFILE_IS_NOT_ALLOWED_FOR_SIGNATURE = 234;
+
public static final int INVALID_SIGNATURE_POSITION = 224;
public static final int NO_TEXTUAL_CONTENT = 251;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java
new file mode 100644
index 0000000..a295a7b
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java
@@ -0,0 +1,105 @@
+/**
+ * <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.gv.egiz.pdfas.framework.logging;
+
+import org.apache.commons.logging.Log;
+
+import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException;
+import at.gv.egiz.pdfas.utils.CsvUtils;
+
+/**
+ * A statistic logger implementation that prodoces csv based logging entries.
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public class CsvStatisticLogger implements StatisticLogger {
+
+ /**
+ * The underlying logging implementation.
+ */
+ private Log log;
+
+ /**
+ * A csv value indication error conditions.
+ */
+ private static final String VALUE_ERROR = "ERROR";
+
+ /**
+ * A csv value indication success conditions.
+ */
+ private static final String VALUE_OK = "OK";
+
+ /**
+ * Creates a new instance.
+ *
+ * @param log
+ * The underlying logger.
+ */
+ CsvStatisticLogger(Log log) {
+ this.log = log;
+ }
+
+ public void log(StatisticData data) {
+ if (isEnabled()) {
+ StringBuffer msg = new StringBuffer();
+
+ // add escapted fields
+ msg.append(CsvUtils.escapeCsvValue(data.operation)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.signatureMode)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.connector)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.signatureProfileId)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.fileSize)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.userAgent)).append(CsvUtils.DEFAULT_DELIMITER);
+
+ // handle error conditions
+ Integer errorCode = null;
+ String externalErrorCode = null;
+ if (data.exception != null) {
+ msg.append(VALUE_ERROR).append(CsvUtils.DEFAULT_DELIMITER);
+ if (data.exception instanceof PdfAsException) {
+ PdfAsException pdfAsException = (PdfAsException) data.exception;
+ errorCode = pdfAsException.getErrorCode();
+ if (pdfAsException instanceof ExternalErrorException) {
+ externalErrorCode = ((ExternalErrorException) pdfAsException).getExternalErrorCode();
+ }
+ }
+ msg.append(CsvUtils.escapeCsvValue(data.exception.getClass().getName())).append(CsvUtils.DEFAULT_DELIMITER);
+ } else {
+ msg.append(VALUE_OK).append(CsvUtils.DEFAULT_DELIMITER).append(CsvUtils.DEFAULT_DELIMITER);
+ }
+ msg.append(CsvUtils.escapeCsvValue(errorCode)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(externalErrorCode)).append(CsvUtils.DEFAULT_DELIMITER);
+
+ msg.append(CsvUtils.escapeCsvValue(data.duration));
+
+ log.info(msg);
+ }
+ }
+
+ public boolean isEnabled() {
+ return log.isInfoEnabled();
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java
new file mode 100644
index 0000000..3cb1c66
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java
@@ -0,0 +1,314 @@
+/**
+ * <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.gv.egiz.pdfas.framework.logging;
+
+import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
+import at.gv.egiz.pdfas.api.commons.Constants;
+import at.gv.egiz.pdfas.api.sign.SignParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyAfterReconstructXMLDsigParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyParameters;
+import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigAfterAnalysisParameters;
+import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigParameters;
+
+public class StatisticData {
+
+ String operation;
+ String connector;
+ String signatureMode;
+ String signatureProfileId;
+ Integer fileSize;
+ Long duration;
+ String userAgent;
+ Exception exception;
+
+ /**
+ * Creates new data for statistical logging purposes.
+ */
+ public StatisticData() {
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_BINARY},
+ * {@link Constants#SIGNATURE_TYPE_BINARY} or {@code null} in case of verification.
+ * @param duration
+ * The duration the certain operation took (in ms).
+ * @param userAgent
+ * The user agent String.
+ * @param errorCode
+ * The error code resulting from the current operation (0 means no error).
+ */
+ public StatisticData(String operation, String connector, Integer fileSize, String signatureMode, Long duration,
+ String userAgent, Integer errorCode) {
+ this();
+ this.operation = operation;
+ this.connector = connector;
+ this.signatureMode = signatureMode;
+ this.fileSize = fileSize;
+ this.duration = duration;
+ this.userAgent = userAgent;
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ */
+ public StatisticData(String operation, String connector, Integer fileSize) {
+ this();
+ this.operation = operation;
+ this.connector = connector;
+ this.fileSize = fileSize;
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_BINARY},
+ * {@link Constants#SIGNATURE_TYPE_BINARY} or {@code null} in case of verification.
+ * @param duration
+ * The duration the certain operation took (in ms).
+ * @param userAgent
+ * The user agent String.
+ */
+ public StatisticData(String operation, String connector, Integer fileSize, String signatureMode, Long duration,
+ String userAgent) {
+ this(operation, connector, fileSize, signatureMode, duration, userAgent, null);
+ }
+
+ /**
+ * Creates statistical data based on given sign parameters.
+ *
+ * @param signParameters
+ * The given sign parameters.
+ */
+ public StatisticData(SignParameters signParameters) {
+ this();
+ operation = "SIGN";
+ connector = signParameters.getSignatureDevice();
+ signatureMode = signParameters.getSignatureType();
+ fileSize = signParameters.getDocument().getLength();
+ signatureProfileId = signParameters.getSignatureProfileId();
+ }
+
+ /**
+ * Creates statistical data based on given verify parameters.
+ *
+ * @param verifyParameters
+ * The given verify parameters.
+ */
+ public StatisticData(VerifyParameters verifyParameters) {
+ this();
+ operation = "VERIFY";
+ connector = verifyParameters.getSignatureDevice();
+ fileSize = verifyParameters.getDocument().getLength();
+ }
+
+ /**
+ * Creates statistical data based on given analyze parameters.
+ *
+ * @param varxdp
+ * The given analyze parameters.
+ */
+ public StatisticData(AnalyzeParameters analyzeParameters) {
+ this();
+ operation = "ANALYZE";
+ fileSize = analyzeParameters.getDocument().getLength();
+ }
+
+ /**
+ * Creates statistical data based on given reconstruction parameters.
+ *
+ * @param rxdaap
+ * The given reconstruction parameters.
+ */
+ public StatisticData(ReconstructXMLDsigAfterAnalysisParameters rxdaap) {
+ this();
+ operation = "RECONSTRUCT";
+ connector = rxdaap.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given reconstruction parameters.
+ *
+ * @param reconstructParameters
+ * The given reconstruction parameters.
+ */
+ public StatisticData(ReconstructXMLDsigParameters reconstructParameters) {
+ this();
+ operation = "RECONSTRUCT";
+ fileSize = reconstructParameters.getDocument().getLength();
+ connector = reconstructParameters.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given parameters.
+ *
+ * @param vaaParameters
+ * The given verify parameters after analysis.
+ */
+ public StatisticData(VerifyAfterAnalysisParameters vaaParameters) {
+ this();
+ operation = "VERIFY";
+ connector = vaaParameters.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given verify parameters after reconstruction.
+ *
+ * @param varxdp
+ * The given verify parameters after reconstruction.
+ */
+ public StatisticData(VerifyAfterReconstructXMLDsigParameters varxdp) {
+ this();
+ operation = "VERIFY";
+ connector = varxdp.getSignatureDevice();
+ }
+
+ /**
+ * Sets the current operation name.
+ *
+ * @param operation
+ * The operation name.
+ */
+ public StatisticData setOperation(String operation) {
+ this.operation = operation;
+ return this;
+ }
+
+ /**
+ * Sets the connector.
+ *
+ * @param connector
+ * The connector.
+ */
+ public StatisticData setConnector(String connector) {
+ this.connector = connector;
+ return this;
+ }
+
+ /**
+ * Sets the file size of the processed document.
+ *
+ * @param fileSize
+ * The file size in bytes.
+ */
+ public StatisticData setFileSize(Integer fileSize) {
+ this.fileSize = fileSize;
+ return this;
+ }
+
+ /**
+ * Sets the duration of the performed operation.
+ *
+ * @param duration
+ * The duration in ms.
+ */
+ public StatisticData setDuration(Long duration) {
+ this.duration = duration;
+ return this;
+ }
+
+ /**
+ * Sets the user agent identifier.
+ *
+ * @param userAgent
+ * The user agent identifier.
+ */
+ public StatisticData setUserAgent(String userAgent) {
+ this.userAgent = userAgent;
+ return this;
+ }
+
+ /**
+ * Sets the signature mode.
+ *
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_TEXTUAL} and
+ * {@link Constants#SIGNATURE_TYPE_BINARY}).
+ */
+ public StatisticData setSignatureMode(String signatureMode) {
+ this.signatureMode = signatureMode;
+ return this;
+ }
+
+ /**
+ * Sets the profile id.
+ *
+ * @param profileId
+ * The profile id.
+ */
+ public StatisticData setSignatureProfileId(String signatureProfileId) {
+ this.signatureProfileId = signatureProfileId;
+ return this;
+ }
+
+ /**
+ * Sets the exception that has been thrown.
+ *
+ * @param exception
+ * The exception.
+ */
+ public StatisticData setException(Exception exception) {
+ this.exception = exception;
+ return this;
+ }
+
+ /**
+ * Returns {@code true} if an error condition has been set, {@code false} otherwise.
+ *
+ * @return {@code true} in case of an error, {@code false} if not.
+ */
+ public boolean isError() {
+ return exception != null;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java
new file mode 100644
index 0000000..2b6671c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java
@@ -0,0 +1,63 @@
+/**
+ * <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.gv.egiz.pdfas.framework.logging;
+
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This factory creates statistic logger implementations.<br/>
+ * Note that it exclusively creates {@link CsvStatisticLogger} implementations at the moment. It should just be regarded
+ * as template for further factory implementations. Strictly speaking this factory does not fulfil the respective GoF
+ * pattern.
+ *
+ * @see StatisticLogger
+ * @author Datentechnik Innovation GmbH
+ */
+public class StatisticLogFactory {
+
+ /**
+ * Returns a statistic logger implementation.
+ *
+ * @param clazz
+ * The class.
+ * @return A statistic logger implementation.
+ */
+ public static StatisticLogger getLog(Class<?> clazz) {
+ return getLog(clazz.getName());
+ }
+
+ /**
+ * Returns a statistic logger implementation.
+ *
+ * @param name
+ * The name of the logger.
+ * @return A statistic logger implementation.
+ */
+ public static StatisticLogger getLog(String name) {
+
+ // to be changed some day, producing various logger implementations
+ return new CsvStatisticLogger(LogFactory.getLog(name));
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java
new file mode 100644
index 0000000..6e2c587
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java
@@ -0,0 +1,47 @@
+/**
+ * <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.gv.egiz.pdfas.framework.logging;
+
+/**
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public interface StatisticLogger {
+
+ /**
+ * Creates a log entry with the given statistical data.
+ *
+ * @param statisticData
+ * The statistical data.
+ */
+ public void log(StatisticData statisticData);
+
+ /**
+ * Returns {@code true} in case the logger is enabled, {@code false} if not.
+ *
+ * @return {@code true} in case the logger is enabled, {@code false} if not.
+ */
+ public boolean isEnabled();
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
index eda94c0..a2bcd15 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
@@ -33,6 +33,7 @@ import java.util.Properties;
import java.util.Vector;
import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -66,6 +67,9 @@ import at.gv.egiz.pdfas.framework.DataSourceHolder;
import at.gv.egiz.pdfas.framework.config.SettingsHelper;
import at.gv.egiz.pdfas.framework.input.ExtractionStage;
import at.gv.egiz.pdfas.framework.input.PdfDataSource;
+import at.gv.egiz.pdfas.framework.logging.StatisticData;
+import at.gv.egiz.pdfas.framework.logging.StatisticLogFactory;
+import at.gv.egiz.pdfas.framework.logging.StatisticLogger;
import at.gv.egiz.pdfas.framework.signator.Signator;
import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters;
@@ -87,6 +91,7 @@ import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderContext;
import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderData;
import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderExtractor;
import at.gv.egiz.pdfas.utils.ConfigUtils;
+import at.gv.egiz.pdfas.utils.PDFASUtils;
import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.cfg.OverridePropertyHolder;
@@ -111,12 +116,13 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes.State;
import at.knowcenter.wag.egov.egiz.sig.connectors.Connector;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
/**
* Implementation of the {@link PdfAs} interface.
- *
+ *
* @author wprinz
*/
public class PdfAsObject implements PdfAs
@@ -127,25 +133,26 @@ public class PdfAsObject implements PdfAs
* The log.
*/
private static Log log = LogFactory.getLog(PdfAsObject.class);
-
+ private static StatisticLogger statLog = StatisticLogFactory.getLog(Constants.STATISTIC_LOGGER_NAME);
+
private static final String ENABLE_PLACEHOLDER_SEARCH_KEY = "enable_placeholder_search";
-
+
/**
* Configuration key for minimal signature block width threshold. Any width below this certain value will lead to a warning log entry."
*/
private static final String SIGNATURE_BLOCK_WIDTH_THRESHOLD_FOR_WARNING_KEY = "signature_block_width_warning_threshold";
-
+
/**
* Minimal signature block width. If a width below that value is defined (by parameter, by placeholder or by configuration) a warning log entry is created.
*/
public static final float DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD = 150;
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* @param workDirectory
* The work directory.
* @throws PdfAsException
@@ -155,16 +162,16 @@ public class PdfAsObject implements PdfAs
{
this(workDirectory, SettingsReader.REGISTER_IAIK_PROVIDERS_ON_DEFAULT);
}
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
- *
+ *
* @param workDirectory
* The work directory.
* @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 PdfAsException
* Thrown, if the configuration cannot be processed.
*/
@@ -174,12 +181,12 @@ public class PdfAsObject implements PdfAs
SettingsReader.initialize(path, path);
reloadConfig(registerProvider);
}
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* @throws PdfAsException
* Thrown, if the configuration cannot be processed.
*/
@@ -187,7 +194,7 @@ public class PdfAsObject implements PdfAs
{
this(null);
}
-
+
/**
* @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig()
*/
@@ -197,11 +204,11 @@ public class PdfAsObject implements PdfAs
SettingsReader.createInstance();
SignatureTypes.createInstance();
}
-
+
/**
* @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
* @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig()
*/
private void reloadConfig(boolean registerProvider) throws PdfAsException
@@ -228,7 +235,7 @@ public class PdfAsObject implements PdfAs
List profileInformation = new ArrayList(profiles.size());
String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE);
-
+
Iterator it = profiles.iterator();
while (it.hasNext())
{
@@ -240,14 +247,17 @@ public class PdfAsObject implements PdfAs
final String profileDescription = settings.getSetting("sig_obj." + profileId + "." + SignatureTypes.SIG_DESCR, null);
boolean isDefault = (default_type != null && default_type.equals(profileId));
+
+ State state = State.fromString(settings.getSetting(SignatureTypes.TYPES + "." + profileId));
+
// modified by tknall
- SignatureProfileImpl signatureProfile = new SignatureProfileImpl(profileId, profileDescription, moaKeyIdentifier, isDefault);
+ SignatureProfileImpl signatureProfile = new SignatureProfileImpl(profileId, state, profileDescription, moaKeyIdentifier, isDefault);
// start - added by tknall
-
+
// signature entries relevant to the search algorithm
Properties signatureEntries = new Properties();
-
+
// search for table entries
String parentPropertyKey = "sig_obj." + profileId + ".table";
log.debug("Looking for subkeys of \"" + parentPropertyKey + "\".");
@@ -275,7 +285,7 @@ public class PdfAsObject implements PdfAs
}
}
}
-
+
// search for table entries
parentPropertyKey = "sig_obj." + profileId + ".key";
log.debug("Looking for subkeys of \"" + parentPropertyKey + "\".");
@@ -295,46 +305,89 @@ public class PdfAsObject implements PdfAs
}
}
}
-
+
// set properties
signatureProfile.setSignatureBlockEntries(signatureEntries);
// stop - added by tknall
-
+
profileInformation.add(signatureProfile);
}
return profileInformation;
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#sign(at.gv.egiz.pdfas.api.sign.SignParameters)
- */
- public SignResult sign(SignParameters signParameters) throws PdfAsException
+ public SignResult sign(SignParameters signParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performSign(signParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private SignResult performSign(SignParameters signParameters) throws PdfAsException
{
CheckHelper.checkSignParameters(signParameters, false);
-
+
+ // make sure that the selected profile is allowed to be used for signature
+ SettingsReader settings = SettingsReader.getInstance();
+ if (!State.fromString(settings.getSetting(SignatureTypes.TYPES + "." + signParameters.getSignatureProfileId()))
+ .canSign()) {
+ throw new SignatureException(ErrorCode.SIGNATURE_PROFILE_IS_NOT_ALLOWED_FOR_SIGNATURE,
+ "The signature profile '" + signParameters.getSignatureProfileId()
+ + "' is not allowed to be used for signature.");
+ }
+
try {
- SignatureDetailInformation signatorInfo = prepareSign(signParameters);
-
- return sign(signParameters, signatorInfo);
-
+
+ SignatureDetailInformation signatorInfo = performPrepareSign(signParameters);
+ return performSign(signParameters, signatorInfo);
+
} catch (java.lang.OutOfMemoryError e) {
throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e);
}
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyParameters)
- */
- public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException
+ public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private VerifyResults performVerify(VerifyParameters verifyParameters) throws PdfAsException
{
CheckHelper.checkVerifyParameters(verifyParameters);
AnalyzeParameters ap = new AnalyzeParameters();
fillAnalyzeParametersWithVerifyParameters(ap, verifyParameters);
- AnalyzeResult analyzeResult = analyze(ap);
+ AnalyzeResult analyzeResult = performAnalyze(ap);
if (verifyParameters.getSignatureToVerify() != Constants.VERIFY_ALL)
{
@@ -352,17 +405,17 @@ public class PdfAsObject implements PdfAs
VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters();
vaap.setAnalyzeResult(analyzeResult);
fillVerifyAfterAnalysisParametersWithVerifyParameters(vaap, verifyParameters);
- VerifyResults res = verify(vaap);
-
+ VerifyResults res = performVerify(vaap);
+
return res;
-
+
}
-
+
/**
* Copies all adequate parameters from the {@link VerifyParameters} to the
* {@link AnalyzeParameters}.
- *
+ *
* @param ap
* The {@link AnalyzeParameters}.
* @param vp
@@ -385,7 +438,7 @@ public class PdfAsObject implements PdfAs
/**
* Copies all adequate parameters from the {@link VerifyParameters} to the
* {@link VerifyAfterAnalysisParameters}.
- *
+ *
* @param vaap
* The {@link VerifyAfterAnalysisParameters}.
* @param vp
@@ -406,10 +459,30 @@ public class PdfAsObject implements PdfAs
reconstructParams.setSignatureDevice(verifyAfterAnalysisParameters.getSignatureDevice());
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#analyze(at.gv.egiz.pdfas.api.analyze.AnalyzeParameters)
- */
- public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException
+ public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(analyzeParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performAnalyze(analyzeParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private AnalyzeResult performAnalyze(AnalyzeParameters analyzeParameters) throws PdfAsException
{
CheckHelper.checkAnalyzeParameters(analyzeParameters);
@@ -429,10 +502,12 @@ public class PdfAsObject implements PdfAs
assumeOnlySB = false;
}
VerificationFilterParameters parameters = new VerificationFilterParametersImpl(binaryOnly, assumeOnlySB, parametersConfig.scanForOldSignatures());
-
+
at.gv.egiz.pdfas.framework.input.DataSource inputDataSource = null;
if (analyzeParameters.getDocument().getMimeType().equals("application/pdf"))
{
+ // check document permissions
+ PDFASUtils.createPdfReaderCheckingPermissions(analyzeParameters.getDocument());
inputDataSource = new PdfDataSourceAdapter(analyzeParameters.getDocument());
}
else
@@ -447,13 +522,13 @@ public class PdfAsObject implements PdfAs
}
}
assert inputDataSource != null;
-
+
try {
ExtractionStage es = new ExtractionStage();
DataSourceHolder dsh = new DataSourceHolder(inputDataSource);
List signature_holders = es.extractSignatureHolders(dsh, parameters);
-
-
+
+
// List sigInfs = new ArrayList(signature_holders.size());
List sigInfs = new ArrayList();
List noSigs = new ArrayList();
@@ -461,24 +536,24 @@ public class PdfAsObject implements PdfAs
while (it.hasNext())
{
SignatureHolder sh = (SignatureHolder)it.next();
-
+
if(sh instanceof NoSignatureHolder) {
noSigs.add(sh);
} else {
-
+
SignatureInformation si = new SignatureInformationAdapter(sh);
sigInfs.add(si);
- if (analyzeParameters.isReturnNonTextualObjects()) {
- si.setNonTextualObjects(doExtractNonTexualObjects(sh, (PdfDataSource) dsh.getDataSource()));
- }
-
+ if (analyzeParameters.isReturnNonTextualObjects()) {
+ si.setNonTextualObjects(doExtractNonTexualObjects(sh, (PdfDataSource) dsh.getDataSource()));
+ }
+
}
}
return new AnalyzeResultImpl(sigInfs, noSigs, parameters.hasBeenCorrected());
} catch (java.lang.OutOfMemoryError e) {
throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e);
}
-
+
}
private List doExtractNonTexualObjects(SignatureHolder sh, PdfDataSource pdfDataSource) {
@@ -499,30 +574,47 @@ public class PdfAsObject implements PdfAs
}
}
-/**
- * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters)
- */
- public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException
+ public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyAfterAnalysisParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyAfterAnalysisParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private VerifyResults performVerify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException
{
CheckHelper.checkVerifyAfterAnalysisParameters(verifyAfterAnalysisParameters);
List signatures = verifyAfterAnalysisParameters.getAnalyzeResult().getSignatures();
-
+
// added by tknall
if (signatures == null || signatures.isEmpty()) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_NOT_SIGNED, "PDF document not signed."); //$NON-NLS-1$
}
-
+
ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters();
fillReconstructXMLDsigAfterAnalysisParametersWithVerifyAfterAnalysisParameters(rxaap, verifyAfterAnalysisParameters);
- ReconstructXMLDsigResult reconstructResult = reconstructXMLDSIG(rxaap);
-
+ ReconstructXMLDsigResult reconstructResult = performReconstructXMLDSIG(rxaap);
+
VerifyAfterReconstructXMLDsigParameters varxp = new VerifyAfterReconstructXMLDsigParameters();
fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters(varxp, verifyAfterAnalysisParameters);
varxp.setReconstructXMLDsigResult(reconstructResult);
-
- return verify(varxp);
-
+
+ return performVerify(varxp);
+
}
protected void fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters(
@@ -534,31 +626,75 @@ public class PdfAsObject implements PdfAs
varxp.setVerifySignatureIndex(verifyAfterAnalysisParameters.getVerifySignatureIndex());
}
- /**
- * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigParameters)
- */
public ReconstructXMLDsigResult reconstructXMLDSIG(
+ ReconstructXMLDsigParameters reconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(reconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performReconstructXMLDSIG(reconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private ReconstructXMLDsigResult performReconstructXMLDSIG(
ReconstructXMLDsigParameters reconstructXMLDsigParameters)
throws PdfAsException {
-
+
AnalyzeParameters analyzeParameters = new AnalyzeParameters();
fillAnalyzeParametersWithReconstructXMLDsigParameters(analyzeParameters, reconstructXMLDsigParameters);
- AnalyzeResult ar = analyze(analyzeParameters);
-
+ AnalyzeResult ar = performAnalyze(analyzeParameters);
+
ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters();
rxaap.setSignatureDevice(reconstructXMLDsigParameters.getSignatureDevice());
rxaap.setAnalyzeResult(ar);
-
- return reconstructXMLDSIG(rxaap);
+
+ return performReconstructXMLDSIG(rxaap);
}
- /**
- * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigAfterAnalysisParameters)
- */
public ReconstructXMLDsigResult reconstructXMLDSIG(
+ ReconstructXMLDsigAfterAnalysisParameters reconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(reconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performReconstructXMLDSIG(reconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private ReconstructXMLDsigResult performReconstructXMLDSIG(
ReconstructXMLDsigAfterAnalysisParameters reconstructXMLDsigParameters)
throws PdfAsException {
-
+
AnalyzeResult ar = reconstructXMLDsigParameters.getAnalyzeResult();
List extendedSignatureInfos = new Vector();
for (int i = 0; i < ar.getSignatures().size(); i++)
@@ -572,31 +708,52 @@ public class PdfAsObject implements PdfAs
// don't care for connector exceptions because of mutli signs. they are handled during verify
extendedSignatureInfos.add(new ExtendedSignatureInformation(si, null));
}
-
+
}
return new ReconstructXMLDsigResult(extendedSignatureInfos, reconstructXMLDsigParameters.getSignatureDevice());
}
+ public VerifyResults verify(VerifyAfterReconstructXMLDsigParameters verifyAfterReconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyAfterReconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyAfterReconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
/**
* @see PdfAs#verify(VerifyAfterReconstructXMLDsigParameters)
*/
- public VerifyResults verify(
+ private VerifyResults performVerify(
VerifyAfterReconstructXMLDsigParameters verifyAfterReconstructXMLDsigParameters)
throws PdfAsException {
-
+
try {
List extSignatures = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getExtendedSignatures();
String signatureDevice = verifyAfterReconstructXMLDsigParameters.getSignatureDevice();
if (signatureDevice == null){
signatureDevice = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getDevice();
}
- List results = PdfAS.verifyExtendedSignatureHolders(extSignatures,
- signatureDevice,
- verifyAfterReconstructXMLDsigParameters.isReturnHashInputData(),
+ List results = PdfAS.verifyExtendedSignatureHolders(extSignatures,
+ signatureDevice,
+ verifyAfterReconstructXMLDsigParameters.isReturnHashInputData(),
verifyAfterReconstructXMLDsigParameters.getVerificationTime(), verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex());
-
+
List vrs = new ArrayList(results.size());
-
+
int verifySignatureIndex = verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex();
if (verifySignatureIndex < 0)
{
@@ -605,23 +762,23 @@ public class PdfAsObject implements PdfAs
SignatureResponse response = (SignatureResponse) results.get(i);
ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(i);
SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation();
-
+
VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData());
vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects());
-
+
vrs.add(vr);
}
}else{
SignatureResponse response = (SignatureResponse) results.get(0);
ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(verifySignatureIndex);
SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation();
-
+
VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData());
vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects());
-
+
vrs.add(vr);
}
-
+
VerifyResultsImpl verifyResults = new VerifyResultsImpl(vrs);
return verifyResults;
} catch (java.lang.OutOfMemoryError e) {
@@ -632,7 +789,7 @@ public class PdfAsObject implements PdfAs
public DynamicSignatureProfile createDynamicSignatureProfile(String parentProfile, DynamicSignatureLifetimeEnum mode) {
return DynamicSignatureProfileImpl.createFromParent(null, parentProfile, mode);
}
-
+
public DynamicSignatureProfile createEmptyDynamicSignatureProfile(DynamicSignatureLifetimeEnum mode) {
return DynamicSignatureProfileImpl.createEmptyProfile(null, mode);
}
@@ -648,19 +805,44 @@ public class PdfAsObject implements PdfAs
public DynamicSignatureProfile createEmptyDynamicSignatureProfile(String myUniqueName,
DynamicSignatureLifetimeEnum mode) {
- return DynamicSignatureProfileImpl.createEmptyProfile(myUniqueName, mode);
+ return DynamicSignatureProfileImpl.createEmptyProfile(myUniqueName, mode);
+ }
+
+ public SignatureDetailInformation prepareSign(SignParameters signParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performPrepareSign(signParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
}
/**
* @see PdfAs#prepareSign(SignParameters)
*/
- public SignatureDetailInformation prepareSign(SignParameters signParameters) throws PdfAsException {
+ private SignatureDetailInformation performPrepareSign(SignParameters signParameters) throws PdfAsException {
CheckHelper.checkSignParameters(signParameters, true);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
+ PDFASUtils.createPdfReaderCheckingPermissions(signParameters.getDocument());
+
signParameters.setDocument(PdfAS.applyStrictMode(signParameters.getDocument()));
SettingsReader settings = SettingsReader.getInstance();
@@ -730,29 +912,29 @@ public class PdfAsObject implements PdfAs
} else if (fromConfig) {
arguments[0] = "width defined by the profile " + signParameters.getSignatureProfileId();
}
- log.warn(MessageFormat.format(msg, arguments));
+ log.warn(MessageFormat.format(msg, (Object[]) arguments));
}
}
-
+
Signator signator = createSignator(signParameters.getSignatureType());
SignatorInformation signatorInfo = signator.prepareSign(
- new PdfDataSourceAdapter(signParameters.getDocument()),
- signParameters.getSignatureProfileId(),
- pos,
+ new PdfDataSourceAdapter(signParameters.getDocument()),
+ signParameters.getSignatureProfileId(),
+ pos,
signParameters.getTimeStamperImpl());
-
+
SignatureDetailInformationImpl ret = new SignatureDetailInformationImpl();
ret.setSignatorInformation(signatorInfo);
return ret;
}
-
+
private SignaturePlaceholderData getSignaturePlaceholder(SignParameters signParameters,
String defaultProfile) throws SettingsException, PDFDocumentException, PlaceholderExtractionException {
SignaturePlaceholderData spd = null;
SignaturePlaceholderContext.setSignaturePlaceholderData(null);
-
+
SettingsReader settings = SettingsReader.getInstance();
// check sig_obj.PROFILEID.enable_placeholder_search
@@ -766,15 +948,15 @@ public class PdfAsObject implements PdfAs
// check global enable_placeholder_search
configFileActivedString = settings.getValueFromKey(ENABLE_PLACEHOLDER_SEARCH_KEY);
}
-
+
Boolean configFileActived = null;
if (configFileActivedString != null)
configFileActived = Boolean.valueOf(configFileActivedString);
Boolean signParamsActivated = signParameters.isCheckForPlaceholder();
-
+
boolean enableSearch;
-
+
if (signParamsActivated != null)
{
enableSearch = signParamsActivated.booleanValue();
@@ -788,8 +970,8 @@ public class PdfAsObject implements PdfAs
if (enableSearch)
{
spd = SignaturePlaceholderExtractor.extract(
- signParameters.getDocument().createInputStream(),
- signParameters.getPlaceholderId(),
+ signParameters.getDocument().createInputStream(),
+ signParameters.getPlaceholderId(),
signParameters.getPlaceholderMatchMode());
}
return spd;
@@ -809,15 +991,36 @@ public class PdfAsObject implements PdfAs
{
signatorId = SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID;
}
-
+
return at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId);
}
- public SignResult sign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
+ public SignResult sign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performSign(signParameters, signatorInfo);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private SignResult performSign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
throws PdfAsException {
CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, false);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
@@ -832,34 +1035,34 @@ public class PdfAsObject implements PdfAs
SignatureData sd = new SignatureDataImpl(new PdfDataSourceAdapter(signatorInfo.getSignatureData()), signatorInfo.getSignatureData().getMimeType());
SignSignatureObject sso = PdfAS.sign(sd, c, signParameters.getTimeStamperImpl());
((SignatureDetailInformationImpl)signatorInfo).setSignSignatureObject(sso);
-
+
return finishSign(signParameters, signatorInfo);
}
- public SignResult finishSign(SignParameters signParameters, SignatureDetailInformation signatureDetailInformation)
+ public SignResult finishSign(SignParameters signParameters, SignatureDetailInformation signatureDetailInformation)
throws PdfAsException {
try {
CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, true);
CheckHelper.checkSignatureDetailInformation(signatureDetailInformation);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
-
+
Signator signator = createSignator(signParameters.getSignatureType());
SignatorInformation signatorInfo = ((SignatureDetailInformationImpl)signatureDetailInformation).getSignatorInfo();
signator.finishSign(signatorInfo, new DataSinkAdapter(signParameters.getOutput()));
return new SignResultImpl(
- signParameters.getOutput(),
+ signParameters.getOutput(),
signatorInfo.getSignSignatureObject().getX509Certificate(),
- new ActualSignaturePositionAdapter(signatorInfo.getActualTablePos()),
+ new ActualSignaturePositionAdapter(signatorInfo.getActualTablePos()),
signatorInfo.getNonTextualObjects());
} finally {
OverridePropertyHolder.removeProperties();
DynamicSignatureProfileImpl.disposeLocalProfile();
}
}
-
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
index 2aee44f..b91d5a9 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
@@ -30,7 +30,7 @@ import at.gv.egiz.pdfas.api.io.DataSink;
/**
* Adapter that converts an API DataSink to a framework DataSink.
- *
+ *
* @author wprinz
*/
public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSink
@@ -42,7 +42,7 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
/**
* Constructor.
- *
+ *
* @param apiDataSink
* The API DataSink to be adapted to a framework DataSink.
*/
@@ -62,7 +62,6 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
}
catch (IOException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -79,7 +78,6 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
}
catch (IOException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
index 35d8c17..1df1a65 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
@@ -28,6 +28,7 @@ import java.util.Properties;
import org.apache.commons.lang.builder.ToStringBuilder;
import at.gv.egiz.pdfas.api.commons.SignatureProfile;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes.State;
/**
* Holds the data of a signature profile.
@@ -61,6 +62,13 @@ public class SignatureProfileImpl implements SignatureProfile {
* true if this is the default profile, false otherwise.
*/
protected boolean defaultProfile = false;
+
+ /**
+ * The state of the signature profile. Signature profiles may be disabled (OFF), allowed for signature only
+ * (SIGN_ONLY), allowed for verification only (VERIFY_ONLY) or just enabled (ON).
+ * Default value here of ON in order to assure backward compatibility.
+ */
+ private State state = State.ON;
/**
* Constructor.
@@ -88,14 +96,26 @@ public class SignatureProfileImpl implements SignatureProfile {
* @param isDefault
*/
public SignatureProfileImpl(String profileId, String profileDescription, String moaKeyIdentifier, boolean isDefault) {
- this.profileId = profileId;
- this.moaKeyIdentifier = moaKeyIdentifier;
- this.profileDescription = profileDescription;
- this.signatureBlockEntries = new Properties();
- this.defaultProfile = isDefault;
+ this(profileId, moaKeyIdentifier);
+ this.profileDescription = profileDescription;
+ this.defaultProfile = isDefault;
}
/**
+ * Creates a new signature profile instance.
+ * @param profileId The profile identifier.
+ * @param state The profile's state.
+ * @param profileDescription The profile description.
+ * @param moaKeyIdentifier The MOA-SS key identifier.
+ * @param isDefault {@code true} if this is a default profile, {@code false} if not.
+ */
+ public SignatureProfileImpl(String profileId, State state, String profileDescription, String moaKeyIdentifier, boolean isDefault) {
+ this(profileId, profileDescription, moaKeyIdentifier, isDefault);
+ this.state = state;
+ }
+
+
+ /**
* @see at.gv.egiz.pdfas.api.commons.SignatureProfile#getProfileId()
*/
public String getProfileId() {
@@ -140,19 +160,22 @@ public class SignatureProfileImpl implements SignatureProfile {
return this.profileDescription;
}
- public String toString() {
- return new ToStringBuilder(this)
- .append("profileId", this.profileId)
- .append("profileDescription", this.profileDescription)
- .append("moaKeyIdentifier", this.moaKeyIdentifier)
- .toString();
- }
+ @Override
+ public String toString() {
+ return "SignatureProfileImpl [profileId=" + profileId + ", state=" + state + ", profileDescription="
+ + profileDescription + ", moaKeyIdentifier=" + moaKeyIdentifier + ", defaultProfile=" + defaultProfile
+ + "]";
+ }
- /**
+/**
*
*/
public boolean isDefault() {
return this.defaultProfile;
}
+ public State getState() {
+ return state;
+ }
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
index eaa6b7f..b193936 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
@@ -26,6 +26,7 @@ package at.gv.egiz.pdfas.impl.input.correction;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import at.gv.egiz.pdfas.api.io.DataSource;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
import at.gv.egiz.pdfas.exceptions.framework.CorrectorException;
import at.gv.egiz.pdfas.framework.input.PdfDataSource;
@@ -40,7 +41,7 @@ import com.lowagie.text.pdf.PdfStamper;
/**
* Corrects a document using iText.
- *
+ *
* @author wprinz
*/
public class InternalCorrector implements Corrector
@@ -53,11 +54,9 @@ public class InternalCorrector implements Corrector
{
try
{
- byte[] pdf = document.getAsByteArray();
- PdfReader reader = new PdfReader(pdf);
- PDFASUtils.checkReaderPermissions(reader);
+ PdfReader reader = PDFASUtils.createPdfReaderCheckingPermissions(document);
- ByteArrayOutputStream baos = new ByteArrayOutputStream(pdf.length);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(document.getLength());
PdfStamper stamper = new PdfStamper(reader, baos, '\0', false);
stamper.close();
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
index 0af6538..a3ff856 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
@@ -83,7 +83,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 filled with placeholders. After the layout has been fixed, all variable
@@ -92,7 +92,7 @@ import com.lowagie.text.pdf.PdfPTable;
* <p>
* In finishSign, the variable fields (values, /Cert) are replaced with the values according to the encoding.
* </p>
- *
+ *
* @author wprinz
*/
public class BinarySignator_1_0_0 implements Signator {
@@ -204,13 +204,19 @@ public class BinarySignator_1_0_0 implements Signator {
// 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
+
+ // disabled by dti: code fixes certain cases with invisible signatures but prevents usage of minimal
+ // signature profiles; the actual invisible signature issue has fixed in method
+ // adjustSignatureTableandCalculatePosition(...) in class at.knowcenter.wag.egov.egiz.PdfAS
+ /*
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
+ */
+ // end added (rpiazzi)
IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdfDataSource, pdf_table,
profile, pi, variable_field_definitions, all_field_definitions, invisible_field_definitions,
@@ -318,7 +324,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.
*/
@@ -394,7 +400,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/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
index 7fcdb2a..16e2718 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
@@ -41,7 +41,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>
@@ -49,7 +49,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 DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
@@ -93,7 +93,7 @@ public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
// String document_text =
// PdfAS.extractNormalizedTextTextual(pdf.createInputStream());
// // 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$
@@ -119,7 +119,6 @@ public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
// }
// catch (UnsupportedEncodingException e)
// {
- // e.printStackTrace();
// throw new PDFDocumentException(300, e);
// }
// }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
index 3f0f482..0e0da78 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
@@ -80,7 +80,7 @@ public class VerificationFilterImpl implements VerificationFilter
public static final String SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE = "supress_exception_when_last_iublock_is_no_signature";
public static final String BINARY_ONLY = "binary_only";
public static final String ASSUME_ONLY_SIGNATURE_BLOCKS = "assume_only_signature_blocks";
-
+
/**
* @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource,
* java.util.List,
@@ -97,7 +97,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Original IU blocks: " + blocks.size());
debugIUBlocks(blocks);
}
-
+
unrollLinearization(blocks);
if (log.isDebugEnabled())
@@ -106,7 +106,7 @@ public class VerificationFilterImpl implements VerificationFilter
debugIUBlocks(blocks);
}
-
+
SettingsReader settings;
try {
settings = SettingsReader.getInstance();
@@ -115,7 +115,7 @@ public class VerificationFilterImpl implements VerificationFilter
}
String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
- // check document for textual sigs here here if binary_only is set
+ // check document for textual sigs here here if binary_only is set
if ("true".equalsIgnoreCase(check_doc) &&
parameters.extractBinarySignaturesOnly()) {
@@ -125,7 +125,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Skipping checkDocument for textual sigs.");
}
// end add
-
+
List signatureHolderChain = null;
if (parameters.extractBinarySignaturesOnly())
@@ -156,11 +156,11 @@ public class VerificationFilterImpl implements VerificationFilter
}
}
-
+
log.trace("extractSignaturHolders finished (" + (signatureHolderChain != null ? signatureHolderChain.size() : 0) + " elements).");
sw.stop();
log.debug("extractSignatureHolders: " + sw.getTime() + "ms.");
-
+
return signatureHolderChain;
}
@@ -194,12 +194,12 @@ public class VerificationFilterImpl implements VerificationFilter
foundSignatures = extractNewSignaturesFromText(normalizedText);
}
-
+
List textOnlySignatures = filterOutBinarySignatures(foundSignatures);
-
+
return textOnlySignatures;
}
-
+
protected String normalizeText(String freetext) throws VerificationFilterException
{
try
@@ -214,7 +214,7 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Removes the linearization footer from the list of update blocks.
- *
+ *
* @param blocks
* The list of FooterParseResult objects in \prev order.
*/
@@ -263,15 +263,15 @@ public class VerificationFilterImpl implements VerificationFilter
if (sao.oldSignature != null)
{
extractedSignatures.add(0, sao.oldSignature);
- }
+ }
}
else
{
log.debug("extracting signatures from last partition...");
extractedSignatures = extractSignaturesFromPartition(pdf, lastTextPartition);
}
-
-
+
+
List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures);
return signatureHolderChain;
@@ -287,15 +287,15 @@ public class VerificationFilterImpl implements VerificationFilter
Set binarySigValues = new HashSet();
Iterator iterator = binarySignatures.iterator();
while(iterator.hasNext()) {
-
+
SignatureHolder sh = (SignatureHolder)iterator.next();
-
+
String sigVal = sh.getSignatureObject().getSignationValue();
binarySigValues.add(sigVal);
}
-
+
SignatureHolder oldSignature = null;
-
+
//List originalPartitions = partitions;
// This gives every IU block an own text partition
// This allows text signatures to be found correctly if there are
@@ -313,36 +313,36 @@ public class VerificationFilterImpl implements VerificationFilter
}
String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
boolean supressException = "true".equalsIgnoreCase(settings.getSetting(SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE, "false"));
-
+
// flag indicating that the last IU-block of the document is a non-signature IU-block
boolean lastBlockWasModified = false;
-
+
// counter of all signatures (textual and binary) of this document
int signatureCounter = 0;
-
+
// counter of all textual signatures in this document
int txtSigsSoFar = 0;
-
+
// counter of all textual signatures in the current partition
int txtSigsThisPartition = 0;
-
+
List partitionResults = new ArrayList(partitions.size());
- List nshList = new ArrayList();
-
+ List nshList = new ArrayList();
+
boolean sigFound = false;
-
+
for (int i = 0; i < partitions.size(); i++)
{
Partition p = (Partition) partitions.get(i);
-
+
// updating flag and counter
boolean partitionContainsNewTextSignatures = true;
txtSigsSoFar = txtSigsThisPartition;
-
+
if (p instanceof TextPartition)
{
TextPartition tp = (TextPartition) p;
-
+
List partitionResult = null;
boolean scanThisPartitionForOldSignature = (i == 0) && scanForOldSignatures;
@@ -356,34 +356,34 @@ public class VerificationFilterImpl implements VerificationFilter
{
partitionResult = extractSignaturesFromPartition(pdf, tp);
}
-
- // binary signature blocks that have been detected as well are identified by comparing their signature values
+
+ // binary signature blocks that have been detected as well are identified by comparing their signature values
// with those stored in our Set above and are not considered for our IU-check
List onlyTextSignatures = new ArrayList();
Iterator iter = partitionResult.iterator();
while(iter.hasNext()) {
-
+
SignatureHolder sh = (SignatureHolder)iter.next();
if(!binarySigValues.contains(sh.getSignatureObject().getSignationValue())) {
-
+
onlyTextSignatures.add(sh);
}
}
-
+
// update signature counters
txtSigsThisPartition = onlyTextSignatures.size();
int newTextSignatures = txtSigsThisPartition - txtSigsSoFar;
signatureCounter = signatureCounter + newTextSignatures;
-
+
// update sigFound flag
if(txtSigsThisPartition > 0) {
-
+
sigFound = true;
}
-
+
// TextPartition is only valid, if at least one more text signature has been found than in the previous text partition
if(!(newTextSignatures > 0)) {
-
+
partitionContainsNewTextSignatures = false;
}
@@ -391,39 +391,39 @@ public class VerificationFilterImpl implements VerificationFilter
} else {
// should be binary partition
if(p instanceof BinaryPartition) {
-
+
BinaryPartition binpart = (BinaryPartition)p;
// updating counter and flag
signatureCounter = signatureCounter + binpart.blocks.size();
sigFound = true;
-
+
}
}
-
+
// if document checking is enabled, at least one signature has been found so far, we are dealing with a
// non-signature IU-block
if ((check_doc.equalsIgnoreCase("true"))&& (sigFound && !partitionContainsNewTextSignatures)) {
-
- nshList.add(new NoSignatureHolder(signatureCounter));
+
+ nshList.add(new NoSignatureHolder(signatureCounter));
lastBlockWasModified = true;
-
+
} else {
-
+
lastBlockWasModified = false;
}
-
+
}
// throw an exception if the last update block does not contain a signature and signatures have been found in this document
if (lastBlockWasModified) {
if (!supressException) {
- throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+ throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
} else {
log.debug("The document has been modified after being signed. According to the configuration, no exception is thrown.");
}
}
-
+
List extractedSignatures = new ArrayList();
Iterator it = partitionResults.iterator();
List prevPartitionResult = null;
@@ -451,54 +451,54 @@ public class VerificationFilterImpl implements VerificationFilter
}
List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures);
-
+
if (oldSignature != null)
{
signatureHolderChain.add(0, oldSignature);
}
-
+
// add the created NoSignatureHolders
signatureHolderChain.addAll(nshList);
-
+
return signatureHolderChain;
}
-
+
private void mergeSignatures(List oldList, List newList, List result) {
-
+
for(int i=0; i < newList.size(); i++) {
-
+
SignatureHolder currentNewSh = (SignatureHolder)newList.get(i);
-
+
boolean shAlreadyPresentInOldList = false;
int pos = -1;
-
+
for(int j=0; j<oldList.size(); j++) {
-
+
SignatureHolder currentOldSh = (SignatureHolder)oldList.get(j);
-
+
if(currentNewSh.getSignatureObject().getSignationValue().equals(currentOldSh.getSignatureObject().getSignationValue())) {
-
+
shAlreadyPresentInOldList = true;
pos = j;
}
}
-
+
if(!shAlreadyPresentInOldList) {
-
+
// signature holder has not been found earlier -> add
result.add(currentNewSh);
}
-
+
}
-
-
+
+
return;
}
-
-
+
+
protected List flattenOutTextPartitions (List partitions, List blocks)
{
-
+
List blockPartitions = new ArrayList(blocks.size());
Iterator it = partitions.iterator();
while (it.hasNext())
@@ -523,10 +523,10 @@ public class VerificationFilterImpl implements VerificationFilter
blockPartitions.add(p);
}
}
-
+
// note: successive binary blocks are still combined to one binary partition
assert blockPartitions.size() <= blocks.size();
-
+
return blockPartitions;
}
@@ -536,15 +536,15 @@ public class VerificationFilterImpl implements VerificationFilter
protected String extractText(PdfDataSource pdf, int endOfDocument, String encoding) throws PresentableException
{
-
+
log.debug("EXTRACTING TEXT (" + encoding + ")... end index = " + endOfDocument);
-
+
DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, endOfDocument);
//DelimitedInputStream dis = new DelimitedInputStream(pdf.createInputStream(), endOfDocument);
return PdfAS.extractNormalizedTextTextual(dds, encoding);
}
-
-
+
+
protected List extractNewSignaturesFromText(String text) throws VerificationFilterException
{
try
@@ -556,7 +556,7 @@ public class VerificationFilterImpl implements VerificationFilter
throw new VerificationFilterException(e);
}
}
-
+
protected List extractNewAndOldSignaturesFromText(String text) throws VerificationFilterException
{
SignaturesAndOld sao = extractSignaturesAndOld(text);
@@ -651,11 +651,11 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Extracts the binary singatures from the given PDF.
- *
+ *
* <p>
* IU blocks without an egiz dict are not considered.
* </p>
- *
+ *
* @param pdf
* @param blocks
* @return Returns the List of signature holders.
@@ -673,7 +673,7 @@ public class VerificationFilterImpl implements VerificationFilter
String binary_only = settings.getSetting(BINARY_ONLY, "false");
String assume_sigs_only = settings.getSetting(ASSUME_ONLY_SIGNATURE_BLOCKS, "false");
boolean supressException = "true".equalsIgnoreCase(settings.getSetting(SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE, "false"));
-
+
try
{
// PERF: extract binary signatures needs byte array
@@ -689,15 +689,15 @@ public class VerificationFilterImpl implements VerificationFilter
FooterParseResult fpr = (FooterParseResult) it.next();
assert fpr.next_index > prev_end;
- if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr))
+ PdfASID kz = null;
+ if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr) &&
+ (kz = VerificationFilterBinaryHelper.extractKZFromEGIZBlock(data, fpr)) != null)
{
- PdfASID kz = VerificationFilterBinaryHelper.extractKZFromEGIZBlock(data, fpr);
-
// TODO dferbas hack baik test
//kz = new PdfASID("urn:pdfsigfilter:bka.gv.at:binaer:v1.1.0");
-
+
Verificator verificator = VerificatorFactory.createBinaryVerificator(kz);
- List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end);
+ List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end);
binarySignatures.addAll(binary_holders);
if(binary_holders.size() > 0) {
@@ -707,21 +707,21 @@ public class VerificationFilterImpl implements VerificationFilter
// an Exception is thrown here if:
// 1) check_document is activated
// 2) assume_only_signature_blocks is false - otherwise we permit updates
- // 3) binary_only is true - otherwise updates are handled in method performFullConservative().
- // when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual
+ // 3) binary_only is true - otherwise updates are handled in method performFullConservative().
+ // when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual
// signature either but an illegal update, otherwise an Exception (doc contains textual sig) would have been thrown before
// 4) a binary signature has been detected in a previous block
- if(check_doc.equalsIgnoreCase("true") &&
+ if(check_doc.equalsIgnoreCase("true") &&
binary_only.equalsIgnoreCase("true") &&
assume_sigs_only.equalsIgnoreCase("false") &&
- sig_detected) {
-
+ sig_detected) {
+
if (!supressException) {
- throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+ throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
} else {
log.debug("The document has been modified after being signed. According to the configuration, no exception is thrown.");
}
-
+
}
}
@@ -749,7 +749,7 @@ public class VerificationFilterImpl implements VerificationFilter
List extractedSignatures = extractNewSignaturesFromText(extractedText);
log.debug("Extracting signatures finished.");
log.debug("Number of found signatures: " + extractedSignatures.size());
-
+
if (extractedSignatures.size() > 0) {
List cp1252SignaturesPositions = new ArrayList();
//boolean iscp1252Sig = false;
@@ -760,19 +760,19 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("found cp1252 signature");
cp1252SignaturesPositions.add(new Integer(i));
//iscp1252Sig = true;
- //break;
+ //break;
}
- }
+ }
if (cp1252SignaturesPositions.size() > 0) {
log.debug("redo text and signature extraction with cp1252 encoding");
extractedText = extractText(pdf, endOfDocument, "cp1252");
log.debug("Extracting text finished.");
-
+
log.debug("Extracting signatures:");
List cp1252ExtractedSignatures = extractNewSignaturesFromText(extractedText);
log.debug("Extracting signatures finished.");
log.debug("Number of found signatures: " + extractedSignatures.size());
-
+
if (cp1252ExtractedSignatures.size() != extractedSignatures.size()) {
log.error("Invalid cp1252 signatures found. Skipping cp1252 compatibility.");
}
@@ -780,12 +780,12 @@ public class VerificationFilterImpl implements VerificationFilter
for (int i = 0; i < cp1252SignaturesPositions.size(); i++) {
int replaceIndex = ((Integer)cp1252SignaturesPositions.get(i)).intValue();
extractedSignatures.remove(replaceIndex);
- extractedSignatures.add(replaceIndex, cp1252ExtractedSignatures.get(replaceIndex));
+ extractedSignatures.add(replaceIndex, cp1252ExtractedSignatures.get(replaceIndex));
}
}
-
+
}
-
+
if (log.isDebugEnabled())
{
log.debug("extracted signatures:");
@@ -856,7 +856,7 @@ public class VerificationFilterImpl implements VerificationFilter
}
protected void checkBinaryOnly(PdfDataSource pdf, boolean considerOldSigs) throws VerificationFilterException {
-
+
DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength());
String text = null;
try {
@@ -864,10 +864,10 @@ public class VerificationFilterImpl implements VerificationFilter
} catch (PresentableException e) {
throw new VerificationFilterException(e);
}
-
+
List sigs = new ArrayList();
-
- if(considerOldSigs) {
+
+ if(considerOldSigs) {
SignaturesAndOld sao = extractSignaturesAndOld(text);
if(sao != null) {
if(sao.newSignatures != null) {
@@ -877,30 +877,30 @@ public class VerificationFilterImpl implements VerificationFilter
sigs.add(sao.oldSignature);
}
}
- } else {
+ } else {
List signatures = extractSignatures(pdf, pdf.getLength());
if(signatures != null) {
sigs.addAll(signatures);
}
}
-
+
Iterator it = sigs.iterator();
while(it.hasNext()) {
SignatureHolder current = (SignatureHolder)it.next();
if((current != null)&&(!current.getSignatureObject().isBinary())) {
throw new VerificationFilterException(ErrorCode.NON_BINARY_SIGNATURES_PRESENT, "The document contains non-binary signatures.");
}
- }
+ }
}
-
-
+
+
protected static class SignaturesAndOld
{
public List newSignatures = null;
public SignatureHolder oldSignature = null;
}
-
+
protected SignaturesAndOld extractSignaturesAndOld(String text) throws VerificationFilterException
{
try
@@ -908,7 +908,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Extracting signatures:");
List extractedSignatures = extractNewSignaturesFromText(text);
log.debug("Extracting signatures finished.");
-
+
log.debug("Extracting old signatures:");
SignatureHolder oldSignature = extractOldSignature(text, extractedSignatures);
log.debug("Extracting old signatures finished.");
@@ -929,7 +929,7 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Extracts the old signature from the text, but only if it is older than the
* oldest signature of the new signatueres.
- *
+ *
* @param extractedText
* @param newSignatures
* @return
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
index 735b874..3093c36 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
@@ -48,7 +48,7 @@ import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult;
/**
* Contains helpful methods used by the VerificationFilter to analyze the PDF for binary signatures.
- *
+ *
* @author wprinz
*/
public final class VerificationFilterBinaryHelper
@@ -70,12 +70,12 @@ public final class VerificationFilterBinaryHelper
/**
* Tells, if the given incremental update block contains a binary signature.
- *
+ *
* <p>
* According to definition, if a block is a binary block, it must/cannot
* contain other signatures than this one.
* </p>
- *
+ *
* @param block
* The incremental update block.
* @return Returns true, if this block is a binary signature block, false
@@ -94,7 +94,7 @@ public final class VerificationFilterBinaryHelper
/**
* Extracts the PDF AS ID of the egiz block.
- *
+ *
* @param pdf
* The pdf.
* @param block
@@ -120,6 +120,13 @@ public final class VerificationFilterBinaryHelper
IndirectObjectReference ior = egiz_dict_iorpr.ior;
final int egiz_dict_offset = PDFUtils.getObjectOffsetFromXRefByIndirectObjectReference(block.xpr, ior);
+
+ // fix dti:
+ if (egiz_dict_offset < 0) {
+ log.debug("Current ui block contains a /EGIZSigDict trailer entry but no respective xref table entry. This indicates that this ui block does not contain binary signatures.");
+ return null;
+ }
+
// logger_.debug("egiz_dict_offset = " + egiz_dict_offset);
ObjectParseResult obj = PDFUtils.parseObject(pdf, egiz_dict_offset);
@@ -140,7 +147,7 @@ public final class VerificationFilterBinaryHelper
/**
* Restores the Kennzeichnung String from an Array.
- *
+ *
* @param pdf
* The PDF.
* @param kz_apr
@@ -174,7 +181,7 @@ public final class VerificationFilterBinaryHelper
si.pdf = pdf;
log.trace("Adding KZ: " + si.toString());
-
+
partition.add(si);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
index aaf99ea..918b13d 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
@@ -33,7 +33,7 @@ import at.gv.egiz.pdfas.api.io.TextBased;
/**
* FileBased DataSource that is TextBased.
- *
+ *
* @author wprinz
*/
public class FileBasedTextBasedDataSource extends FileBasedDataSource implements TextBased
@@ -113,7 +113,6 @@ public class FileBasedTextBasedDataSource extends FileBasedDataSource implements
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
index 8fe0dd6..8234b2a 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
@@ -32,9 +32,9 @@ import at.gv.egiz.pdfas.api.io.TextBased;
/**
* A String TextBased DataSource.
- *
+ *
* @author wprinz
- *
+ *
*/
public class StringTextBasedDataSource implements DataSource, TextBased
{
@@ -74,7 +74,6 @@ public class StringTextBasedDataSource implements DataSource, TextBased
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
index 8b8c22e..453b620 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
@@ -71,7 +71,7 @@ import com.google.zxing.common.HybridBinarizer;
/**
* Extract all relevant information from a placeholder image.
- *
+ *
* @author exthex
*
*/
@@ -80,10 +80,10 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
* The log.
*/
private static Log log = LogFactory.getLog(SignaturePlaceholderExtractor.class);
-
+
private List placeholders = new Vector();
private int currentPage = 0;
-
+
private SignaturePlaceholderExtractor(String placeholderId, int placeholderMatchMode) throws IOException {
super(ResourceLoader.loadProperties("at/gv/egiz/pdfas/placeholder/pdfbox-reader.properties",
true));
@@ -93,7 +93,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
* Search the document for placeholder images and possibly included
* additional info.<br/>
* Searches only for the first placeholder page after page from top.
- *
+ *
* @param inputStream
* @return all available info from the first found placeholder.
* @throws PDFDocumentException if the document could not be read.
@@ -103,14 +103,13 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
throws PDFDocumentException, PlaceholderExtractionException {
SignaturePlaceholderContext.setSignaturePlaceholderData(null);
PDDocument doc = null;
- try
+ try
{
try {
doc = PDDocument.load(inputStream);
} catch (IOException e) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e);
}
- PDFASUtils.checkDocumentPermissions(doc);
SignaturePlaceholderExtractor extractor;
try
{
@@ -135,7 +134,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
} catch (IOException e1) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e1);
}
-
+
}
if (extractor.placeholders.size() > 0){
SignaturePlaceholderData ret = matchPlaceholderDocument(extractor.placeholders, placeholderId, matchMode);
@@ -146,7 +145,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_STRICT) {
throw new PlaceholderExtractionException(ErrorCode.SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED, "no suitable placeholder found and STRICT matching mode requested.");
}
-
+
return null;
} finally {
if (doc != null)
@@ -158,23 +157,23 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
}
}
-
+
private static SignaturePlaceholderData matchPlaceholderDocument(
List placeholders, String placeholderId, int matchMode) throws PlaceholderExtractionException {
-
+
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_STRICT)
throw new PlaceholderExtractionException(ErrorCode.SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED, "no suitable placeholder found and STRICT matching mode requested.");
-
+
if (placeholders.size() == 0)
return null;
-
+
for (int i = 0; i < placeholders.size(); i++)
{
SignaturePlaceholderData spd = (SignaturePlaceholderData)placeholders.get(i);
if (spd.getId() == null)
return spd;
}
-
+
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_LENIENT)
return (SignaturePlaceholderData)placeholders.get(0);
@@ -219,7 +218,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
PDPage page = getCurrentPage();
Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
double rotationInRadians = (page.findRotation() * Math.PI)/180;
-
+
AffineTransform rotation = new AffineTransform();
rotation.setToRotation( rotationInRadians );
AffineTransform rotationInverse = rotation.createInverse();
@@ -227,13 +226,13 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
rotationInverseMatrix.setFromAffineTransform( rotationInverse );
Matrix rotationMatrix = new Matrix();
rotationMatrix.setFromAffineTransform( rotation );
-
+
Matrix unrotatedCTM = ctm.multiply( rotationInverseMatrix );
-
+
float x = unrotatedCTM.getXPosition();
float y = unrotatedCTM.getYPosition() + unrotatedCTM.getYScale();
float w = unrotatedCTM.getXScale();
-
+
String posString = "p:" + currentPage + ";x:" + x + ";y:" + y + ";w:" + w;
try
{
@@ -259,7 +258,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
/**
* Checks an image if it is a placeholder for a signature.
- *
+ *
* @param image
* @return
* @throws IOException
@@ -291,7 +290,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
formats.add(BarcodeFormat.QR_CODE);
hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
result = new MultiFormatReader().decode(bitmap, hints);
-
+
String text = result.getText();
String profile = null;
String type = null;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java
new file mode 100644
index 0000000..a78da93
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.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.gv.egiz.pdfas.utils;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Methods in order to create valid delimiter separated data, where the semicolon as used as delimiter, also known as
+ * the German version of CSV.
+ *
+ * @author Datentechnik Innovation GmbH
+ * @see <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>
+ */
+public class CsvUtils {
+
+ /**
+ * The delimiter char used instead of COMMA.
+ */
+ public static final char DEFAULT_DELIMITER = ';';
+
+ private static final char QUOTE_CHAR = '"';
+ private static final char LF_CHAR = '\n';
+ private static final char CR_CHAR = '\r';
+
+ private static final char[] SHOULD_BE_QUOTED = { LF_CHAR, CR_CHAR, DEFAULT_DELIMITER, QUOTE_CHAR };
+ private static final String CSV_QUOTE = String.valueOf(QUOTE_CHAR);
+
+ /**
+ * Returns an DSV escapted representation of the given object using the default delimiter character (
+ * {@link #DEFAULT_DELIMITER}).
+ *
+ * @param obj
+ * The object.
+ * @return An escapted representation of the given object.
+ */
+ public static String escapeCsvValue(Object obj) {
+ // null value should be printed as empty column
+ if (obj == null) {
+ return "";
+ }
+ // get String representation of object
+ String asString = String.valueOf(obj);
+ // do we need to escape anything?
+ if (StringUtils.containsNone(asString, SHOULD_BE_QUOTED)) {
+ return asString;
+ }
+
+ // RFC 4180 (7): If double-quotes are used to enclose fields, then a double-quote
+ // appearing inside a field must be escaped by preceding it with
+ // another double quote.
+ asString = StringUtils.replace(asString, CSV_QUOTE, CSV_QUOTE + CSV_QUOTE);
+
+ // RFC 4180 (6): Fields containing line breaks (CRLF), double quotes, and commas
+ // should be enclosed in double-quotes.
+ if (StringUtils.containsAny(asString, SHOULD_BE_QUOTED)) {
+ return QUOTE_CHAR + asString + QUOTE_CHAR;
+ }
+ return asString;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
index 7f09dfc..a2332dd 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
@@ -30,63 +30,233 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
+import at.gv.egiz.pdfas.api.io.DataSource;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
+import com.lowagie.text.Document;
+import com.lowagie.text.pdf.BadPasswordException;
import com.lowagie.text.pdf.PdfReader;
/**
- * @author tknall
+ * Collection of useful utilities.
*/
public class PDFASUtils {
-//23.11.2010 changed by exthex - added checkDocumentPermissions(PDDocument doc)
-
- private PDFASUtils() {
- }
-
- /**
- * Verifies that a document could be opened with full permissions.
- * @param pdfReader The PdfReader
- * @throws PDFDocumentException Thrown if document has not been opened with full permissions.
- */
- public static void checkReaderPermissions(PdfReader pdfReader) throws PDFDocumentException {
- if (pdfReader.isEncrypted()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
- }
- if (!pdfReader.isOpenedWithFullPermissions()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
- }
- }
-
- public static boolean toFile(byte[] data, File file) throws IOException {
- return PDFASUtils.toFile(new ByteArrayInputStream(data), file);
- }
-
- public static boolean toFile(InputStream inputStream, File file) throws IOException {
- boolean result = false;
- BufferedOutputStream bufferedOutputStream = null;
- try {
- bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
- ConfigUtils.writeInputStreamToOutputStream(inputStream, bufferedOutputStream);
- } finally {
- if (bufferedOutputStream != null) {
- try {
- bufferedOutputStream.close();
- result = true;
- } catch (IOException e) {
- result = false;
- }
- }
- }
- return result;
- }
-
- public static void checkDocumentPermissions(PDDocument doc) throws PDFDocumentException {
- if (doc.isEncrypted()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
- }
- }
-
+
+ private static Log log = LogFactory.getLog(PDFASUtils.class);
+
+ /**
+ * The configuration key for PDF/A support.
+ */
+ public static final String CFG_KEY_PDFA = "SIG_PDFA1B_VALID";
+
+ private PDFASUtils() {
+ }
+
+ /**
+ * Verifies that a document could be opened with full permissions.
+ *
+ * @param pdfReader
+ * The PdfReader.
+ * @throws PDFDocumentException
+ * Thrown if document has not been opened with full permissions.
+ */
+ private static void checkReaderPermissions(PdfReader pdfReader) throws PDFDocumentException {
+ if (pdfReader.isEncrypted()) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
+ }
+ if (!pdfReader.isOpenedWithFullPermissions()) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ }
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param dataSource
+ * The document data source.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(DataSource dataSource) throws PDFDocumentException {
+ return createPdfReaderCheckingPermissions(dataSource.createInputStream());
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param dataSource
+ * The document data source.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(at.gv.egiz.pdfas.framework.input.DataSource dataSource)
+ throws PDFDocumentException {
+ return createPdfReaderCheckingPermissions(dataSource.createInputStream());
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param inputStream
+ * The document data input stream.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(InputStream inputStream) throws PDFDocumentException {
+ PdfReader reader = null;
+ try {
+ // try to parse document
+ // If fully encrypted, PdfReader will fail;
+ // It should throw a BadPasswordException, but unfortunately does not (throws an IOException instead,
+ // internally catching BadPAsswordException; see comments below).
+ reader = new PdfReader(inputStream);
+ checkReaderPermissions(reader);
+ return reader;
+ } catch (BadPasswordException e) {
+ // will never be reached with itext-2.1.5-rev3628-pdfas:v1.1
+ // just added for later versions... (see comments below)
+ // itext-2.1.5-rev3628-pdfas:v1.2 correctly throws BadPasswordException
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ } catch (PDFDocumentException e) {
+ throw e;
+ } catch (Exception e) {
+ final String EX_MSG_FOR_ENCRYPTED_DOCUMENT = "Bad user Password";
+ // Inspecting the exception message seems to be the only way when using itext-2.1.5-rev3628-pdfas:v1.1:
+ // itext neither externally throws a BadPasswordException nor passed the cause...,
+ // later versions do!
+ // String "Bad user Password" is set in com.lowagie.text.pdf.BadPasswordException so this approach will
+ // work as long as the underlying itext library is not beeing updated.
+ if (StringUtils.containsIgnoreCase(e.getMessage(), EX_MSG_FOR_ENCRYPTED_DOCUMENT)) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ }
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, "Unable to parse document.");
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ closeQuietly(reader);
+ }
+ }
+
+ /**
+ * Quietly closes a pdf reader.
+ *
+ * @param reader
+ * The reader.
+ */
+ public static void closeQuietly(PdfReader reader) {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(PDDocument pdDocument) {
+ if (pdDocument != null) {
+ try {
+ pdDocument.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(org.pdfbox.pdmodel.PDDocument pdDocument) {
+ if (pdDocument != null) {
+ try {
+ pdDocument.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(Document doc) {
+ if (doc != null) {
+ try {
+ doc.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ public static boolean toFile(byte[] data, File file) throws IOException {
+ return PDFASUtils.toFile(new ByteArrayInputStream(data), file);
+ }
+
+ public static boolean toFile(InputStream inputStream, File file) throws IOException {
+ boolean result = false;
+ BufferedOutputStream bufferedOutputStream = null;
+ try {
+ bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+ ConfigUtils.writeInputStreamToOutputStream(inputStream, bufferedOutputStream);
+ } finally {
+ if (bufferedOutputStream != null) {
+ try {
+ bufferedOutputStream.close();
+ result = true;
+ } catch (IOException e) {
+ result = false;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns {@code true} if the given {@code profileId} is PDF/A-1b enabled, {@code false} if not.
+ *
+ * @param profileId
+ * The signature profile.
+ * @return {@code true} if the given {@code profileId} is PDF/A-1b enabled, {@code false} if not.
+ */
+ public static boolean isPdfAEnabled(String profileId) {
+ if (profileId == null) {
+ throw new NullPointerException("Profile identifier must not be null.");
+ }
+ if (StringUtils.isEmpty(profileId)) {
+ throw new IllegalArgumentException("Profile identifier must not be empty.");
+ }
+ try {
+ String pdfa = SettingsReader.getInstance().getSetting("sig_obj." + profileId + ".key." + CFG_KEY_PDFA,
+ "default." + CFG_KEY_PDFA, "false");
+ return BooleanUtils.toBoolean(pdfa);
+ } catch (Exception e) {
+ log.error("Unable to read settings for PDF/A functionality.", e);
+ return false;
+ }
+ }
+
}
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
diff --git a/pdf-as-lib/src/main/java/demo/SignatureVerificationDemo.java b/pdf-as-lib/src/main/java/demo/SignatureVerificationDemo.java
index 0ba95ff..204339a 100644
--- a/pdf-as-lib/src/main/java/demo/SignatureVerificationDemo.java
+++ b/pdf-as-lib/src/main/java/demo/SignatureVerificationDemo.java
@@ -57,7 +57,7 @@ public class SignatureVerificationDemo {
/**
* Starts a demo that verifies a document.
- *
+ *
* @param args
* The parameter(s).
*/
@@ -67,7 +67,7 @@ public class SignatureVerificationDemo {
System.err.println("Please provide path of file to be verified.");
System.exit(1);
}
-
+
File configdir = new File("./work");
// look for work folder in current directory
if (!configdir.exists()) {
@@ -75,7 +75,7 @@ public class SignatureVerificationDemo {
configdir = new File("../work");
}
File signedFile = new File(args[0]);
-
+
AnalyzeResult analyzeResult = null;
try {
@@ -108,7 +108,7 @@ public class SignatureVerificationDemo {
System.out.println("Analyzing...");
analyzeResult = pdfasAPI.analyze(analyzeParameters);
System.out.println("Successfully analyzed.");
-
+
// information on non-textual objects can be used after analysis step and/or after verification
List signatures = analyzeResult.getSignatures();
if (signatures != null && !signatures.isEmpty()) {
@@ -126,7 +126,7 @@ public class SignatureVerificationDemo {
System.out.println(" -> " + info.toString());
}
System.out.println();
-
+
} else {
System.out.println("\nNo non-textual objects detected for this signature.");
}
@@ -139,7 +139,7 @@ public class SignatureVerificationDemo {
}
System.exit(1);
}
-
+
// retrieve reconstructed signature
ReconstructXMLDsigAfterAnalysisParameters recstrParams = new ReconstructXMLDsigAfterAnalysisParameters();
recstrParams.setAnalyzeResult(analyzeResult);
@@ -166,9 +166,9 @@ public class SignatureVerificationDemo {
*/
// setup verification
-
+
// verification without intermediate step of reconstruction
- /*
+ /*
VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters();
vaap.setAnalyzeResult(analyzeResult);
vaap.setReturnHashInputData(true);
@@ -178,7 +178,7 @@ public class SignatureVerificationDemo {
// use result.isVerificationDone() in order to find out if a signatures was successfully verified
vaap.setSuppressVerifyExceptions(true);
*/
-
+
// verification with intermediate step of reconstruction
VerifyAfterReconstructXMLDsigParameters varp = new VerifyAfterReconstructXMLDsigParameters();
varp.setReconstructXMLDsigResult(recstrResult);
@@ -192,15 +192,15 @@ public class SignatureVerificationDemo {
// invoke verification
System.out.println("Verifying...");
-
+
// without intermediate step of reconstruction
/*
VerifyResults verifyResults = pdfasAPI.verify(vaap);
*/
-
+
// with intermediate step of reconstruction
VerifyResults verifyResults = pdfasAPI.verify(varp);
-
+
// retrieve results
List verifyResultList = verifyResults.getResults();
System.out.println("Verification complete.\n");
@@ -213,14 +213,14 @@ public class SignatureVerificationDemo {
counter++;
VerifyResult result = (VerifyResult) it.next();
out.println("\n------------------------ SIGNATURE #" + counter + " ------------------------\n");
-
+
// check if signature verification of the current signature was successfully completed (independent from result)
if (!result.isVerificationDone()) {
PdfAsException ex = result.getVerificationException();
out.println(ErrorCodeHelper.formErrorMessage(ex));
continue;
}
-
+
Main.formatVerifyResult(result, out);
XMLDsigData xmlDSigData = result.getReconstructedXMLDsig();
if (xmlDSigData != null) {
@@ -233,12 +233,12 @@ public class SignatureVerificationDemo {
byte[] data = result.getSignedData().getAsByteArray();
out.println("\n Signed Data: " + data.length + " bytes (" + result.getSignatureType() + ")");
}
-
+
// check if there are timestamps
if (result.getTimeStampValue() != null) {
out.println("\n TimeStamp value available for this signature");
}
-
+
// check if non textual elements have been detected for this signature
if (result.hasNonTextualObjects()) {
out.println("\n WARNING: " + result.getNonTextualObjects().size() + " non textual object(s) detected for this signature");
@@ -248,13 +248,13 @@ public class SignatureVerificationDemo {
out.println(" -> " + info.toString());
}
out.println();
-
+
} else {
out.println("\n No non-textual objects detected for this signature.");
}
}
- out.flush();
-
+ out.flush();
+
} catch (PdfAsException e) {
if (ErrorCode.DOCUMENT_NOT_SIGNED == e.getErrorCode() && analyzeResult != null && analyzeResult.hasBeenCorrected()) {
System.err.println("\nThe document could not been processed, maybe due to modification by third party tools. An attempt to correct the document was successful but no verifiable signatures could be found. This/these signature(s) - if any - might got lost.");
diff --git a/pdf-as-lib/src/main/resources/DefaultConfiguration.zip b/pdf-as-lib/src/main/resources/DefaultConfiguration.zip
index 688babd..b1ca984 100644
--- a/pdf-as-lib/src/main/resources/DefaultConfiguration.zip
+++ b/pdf-as-lib/src/main/resources/DefaultConfiguration.zip
Binary files differ
diff --git a/pdf-as-lib/src/main/resources/config/defaultconfig.properties b/pdf-as-lib/src/main/resources/config/defaultconfig.properties
new file mode 100644
index 0000000..2f01080
--- /dev/null
+++ b/pdf-as-lib/src/main/resources/config/defaultconfig.properties
@@ -0,0 +1,209 @@
+###############################################################################
+# PDF-AS Standard-Einstellungen
+#
+# Hier werden sinnvolle Standard-Einstellungen fuer die gewohnte
+# PDF-AS Konfiguration (config.properties) gesetzt. Alle Einstellungen koennen
+# lokal (in config.properties) ueberschrieben werden.
+###############################################################################
+
+
+# Betrifft Signieren:
+# Stellt sicher, dass das verarbeitete Dokument mindestens PDF 1.4 entspricht.
+strict_mode=false
+
+# Betrifft Signieren:
+# Wenn das Dokument nicht verarbeitet werden kann wird versucht es
+# zuerst zu korrigieren und dann das korrigierte Dokument zu signieren.
+correct_document_if_necessary=true
+
+# Betrifft Verifizieren:
+# Wenn das Dokument nicht verarbeitet werden kann wird versucht es
+# zuerst zu korrigieren und dann das korrigierte Dokument zu verifizieren.
+# Dies kann nur fuer textuelle Signaturen erfolgreich sein.
+correct_document_on_verify_if_necessary=true
+
+# Wenn ein Dokument korrigiert werden soll:
+# Gibt an mit welchem Corrector ein zu korrigierendes Dokument korrigiert wird:
+# internal - das Dokument wird mit dem "internen" iText Corrector korrigiert
+# external - das Dokument wird durch einen externen Kommandozeilenaufruf korrigiert.
+# Hinweis: ein externes Programm aufzurufen birgt gewisse Risiken in sich
+# und sollte daher moeglichst nicht verwendet werden.
+corrector=internal
+
+# Kommandozeile fuer den externen Connector.
+# Die Variablen ##input_document## bzw. ##output_document## werden von PDF-AS
+# durch die absoluten Pfad- und Dateinamen des zu korrigierenden bzw. des
+# korrigierten Dokuments ersetzt.
+# Als Pfad-Separator sollte '/' verwendet werden.
+external_corrector_commandline=C:/correct.exe "##input_document##" "##output_document##"
+
+# Timeout (ms) fuer die Ausfuehrung des externen Correctors.
+# Das Kommando wird abgebrochen, wenn das Timeout erreicht wird bevor
+# das Kommando abgearbeitet wurde.
+# Achtung: Es besteht allerdings keine Garantie, dass der Korrekturvorgang auch tatsaechlich
+# durch ein Timeout abgebrochen wird. Dies ist im Wesentlichen abhaengig von der Beschaffenheit
+# des Korrekturprogramms sowie vom verwendeten Betriebssystem.
+external_corrector_timeout=15000
+
+# Aktiviert, oder deaktiviert grundsaetzlich das - potenziell zeit- und ressourcen-aufwaendige
+# Suchen nach Platzhalter-Bildern in PDF-Dokumenten
+# Festlegung fuer einzelnes Profil
+# sig_obj.PROFILE.enable_placeholder_search=[true|false]
+# Die Suche ist standardmaessig aus Sicherheitsgruenden deaktiviert (Defaultwert hier = false)
+# Es muss bewusst sein, dass ueber einen Platzhalter benutzerseitig bestimmte Profile zur Signatur
+# ausgewaehlt werden koennen!
+enable_placeholder_search=false
+
+# Ueberpruefe Korrektheit des Dokuments
+# bei binary_only=true: Fehler falls textuelle Signatur
+# bei assume_only_signature_blocks=false: Fehler falls inkrementelle Updates nach Signatur
+# In beiden Faellen wird check_old_textual_sigs beruecksichtigt.
+check_document=true
+
+# Falls der letzte inkrementelle Updateblock keine Signatur enthaelt wuerde sofern
+# check_document=true gesetzt ist eine Exception geworfen werden und die Pruefung
+# abgebrochen werden. Mit diesem Schalter ist es moeglich, diese Exception zu
+# unterdruecken, um die Auswertung extern vornehmen zu koennen (standard: false)
+supress_exception_when_last_iublock_is_no_signature=false
+
+# VerificationFilterParameters
+binary_only=false
+assume_only_signature_blocks=false
+check_old_textual_sigs=true
+
+
+##################
+# Signaturdienste
+
+## lokale BKU
+bku.available_for_web=true
+bku.available_for_commandline=true
+
+# BKU Signatur
+bku.sign.url=http://127.0.0.1:3495/http-security-layer-request
+bku.sign.KeyboxIdentifier=SecureSignatureKeypair
+
+# BKU Verifikation
+bku.verify.url=http://127.0.0.1:3495/http-security-layer-request
+
+## Online BKU (MOCCA)
+moc.available_for_web=true
+moc.available_for_commandline=false
+
+# MOCCA Signatur
+moc.sign.url=http://127.0.0.1:8080/bkuonline/http-security-layer-request
+moc.sign.KeyboxIdentifier=SecureSignatureKeypair
+
+## Handy
+
+# Handy Signatur
+mobile.sign.url=https://www.handy-signatur.at/mobile/https-security-layer-request/default.aspx
+mobile.sign.KeyboxIdentifier=SecureSignatureKeypair
+
+# Handy Signatur (Test)
+mobiletest.sign.url=https://test1.a-trust.at/https-security-layer-request/default.aspx
+mobiletest.sign.KeyboxIdentifier=SecureSignatureKeypair
+
+## MOA
+moa.available_for_web=true
+moa.available_for_commandline=true
+
+# MOA Signatur
+moa.sign.url=http://localhost:8080/moa-spss/services/SignatureCreation
+moa.sign.KeyIdentifier=KG_allgemein
+
+# MOA Detached Signieren aus Konsole moeglich - zurzeit moeglich nur mit BKU
+moa.sign.console.detached.enabled=false
+
+# MOA Verifikation
+moa.verify.url=http://localhost:8080/moa-spss/services/SignatureVerification
+moa.verify.TrustProfileID=SecureSignature
+
+
+#########################################################
+# Standardfeldlaengen der Felder fuer die Binaersignatur
+defaults.phlength.SIG_DATE=70
+defaults.phlength.SIG_NUMBER=70
+defaults.phlength.SIG_ISSUER=150
+defaults.phlength.SIG_VALUE=350
+
+# Reservierte Anzahl Bytes fuer den Signaturparameter
+# z.B. etsi-moc-1.1:ecdsa-sha256@669ee461
+# etsi-bka-atrust-1.0:ecdsa-sha256:sha256:sha256:sha1
+defaults.phlength.SIG_ID=70
+
+# Reservierte Anzahl an Bytes fuer den Signatornamen, falls SIG_NAME anstelle von SIG_SUBJECT verwendet wird.
+defaults.phlength.SIG_NAME=210
+
+# Reservierte Anzahl an Bytes fuer den Signaturalgorithmus
+# (relevant fuer BAIK-Signaturen)
+# z.B. http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
+defaults.phlength.SIG_ALG=100
+
+# Es moeglich in die Werte (value) von eigens definierten Tabellenspalten dynamisch auf Teile des
+# verwendeten Zertifikats zuzugreifen. Konkret kann auf die einzelnen RDNs Teile des Issuer DN
+# und des Subject DN des Signaturzertifikats wie im folgenden Beispiel illustriert zugegriffen
+# werden:
+# (1) sig_obj.PROFIL.value.SIG_SUBJECT= ${subject.CN}${subject.O != null ? ("\n" + subject.O) : ""}
+# (2) sig_obj.PROFIL.value.SIG_SUBJECT= ${subject.T \!\= null ? (subject.T + " ") \: ""}${subject.CN}
+# Beispiel (1) gibt die Organisation des Unterzeichners an, Beispiel (2) Titel und Name
+# Die Notation ${..} ermoeglicht die dynamische Auswertung eines Ausdrucks. Verfuegbar sind "subject"
+# und "issuer" und die im Zertifikat DN vorhandenen RDNs.
+# Achtung: Fuer die binaere Signatur funktioniert diese Ersetzung nur fuer Werte, die als Replacement
+# definiert wurden. Konkret bedeutet dies, dass ein phlength Platzhalter definiert sein muss.
+defaults.phlength.SIG_SUBJECT=128
+
+# Binaersignatur: reservierter Platz fuer Zertifikat
+# profilweise: sig_obj.PROFILE.phlength.certificate=xyz
+defaults.phlength.certificate=10000
+
+# Binaersignatur: reservierte Platz fuer Zeitstempel
+# profilweise: sig_obj.PROFILE.phlength.timestamp=xyz
+defaults.phlength.timestamp=5000
+
+# Standardgroesse des Fensters innerhalb dessen Zeilenumbrueche gesetzt werden duerfe.
+# profilweise: sig_obj.PROFILE.phlength.line_break_tolerance=xyz
+defaults.phlength.line_break_tolerance=10
+
+# Falls die Breite eines Signaturblocks definiert wird (ueber API, Commandline oder ueber das Profil),
+# die unterhalb eines sinnvollen Wertes liegt, dann wird im Log eine Warnung ausgegeben, da
+# Signaturbloecke unter Umstaenden nicht mehr sinnvoll dargestellt werden koennen.
+# Der Standard-Schwellwert fuer diese Warnungen (= 150) kann global oder profilweise festgelegt
+# werden (z.B. um die Warnung zu deaktivieren, kann der Wert auf 0 gesetzt werden).
+# sig_obj.PROFILE.signature_block_width_warning_threshold=xyz
+default.signature_block_width_warning_threshold=150
+
+# PDF/A-1b Unterstuetzung fuer alle Profile einschalten
+default.SIG_PDFA1B_VALID=false
+
+# BAIK-Signatur Unterstuetzung fuer alle Profile einschalten
+default.SIG_BAIK_ENABLED=false
+
+
+#############################################
+# Signaturkennzeichnung (fuer Adobe Acrobat)
+#
+# Jede dieser globalen Einstellungen kann im jeweiligen Profil individuell gesetzt werden.
+# z.B. sig_obj.PROFILE.adobeSignText.binary=Mein Signator
+
+# Adobe Signaturkennzeichnung ein-/ausschalten
+default.adobeSignEnabled=true
+
+# Standard Name fuer die Signaturkennzeichnung (binaer)
+default.adobeSignText.binary=PDF-AS
+
+# Standard Name fuer die Signaturkennzeichnung (textuell)
+default.adobeSignText.textual=PDF-AS
+
+# Standard-Name fuer die PDF-Signatur
+default.adobeSignFieldValue=PDF-AS Signatur
+
+# Standardwert fuer "Reason"-Feld der jeweiligen Signatur
+default.adobeSignReasonValue=Informationen zur Pr\u00FCfung finden Sie unter http://www.signaturpruefung.gv.at
+
+# Standard Prueflink fuer die Adobe Signaturkennzeichnung (nur relevant falls Adobe Plugin fuer Pruefung verwendet wird)
+default.verifyURL=http://www.signaturpruefung.gv.at
+
+# Standard Alternativer Text fuer den Signaturblock (WAI) (globale Einstellung)
+# profilweise: sig_obj.PROFILE.sigLogoAltText=VALUE
+default.sigLogoAltText=Abgebildet ist eine Standard-Signaturbildmarke.
diff --git a/pdf-as-lib/src/main/resources/config/help_text.properties b/pdf-as-lib/src/main/resources/config/help_text.properties
index e3cc17e..500dfde 100644
--- a/pdf-as-lib/src/main/resources/config/help_text.properties
+++ b/pdf-as-lib/src/main/resources/config/help_text.properties
@@ -1,22 +1,24 @@
#ErrorCodeException
error.code.0=Externer Fehler
error.code.1=Das Dokument kann nicht signiert werden.
-error.code.2=Die Signatur für das Dokument kann nicht überprüft werden.
+error.code.2=Die Signatur f\u00fcr das Dokument kann nicht \u00fcberpr\u00fcft werden.
error.code.3=Es wurde kein Dokument zur Signierung angegeben oder das Dokument konnte nicht gespeichert werden.
-error.code.4=Es wurde kein Dokument zur Überprüfung angegeben oder das Dokument konnte nicht gespeichert werden.
-error.code.5=Zum Signieren eines Dokmentes müssen Sie authentifiziert sein.
+error.code.4=Es wurde kein Dokument zur \u00dcberpr\u00fcfung angegeben oder das Dokument konnte nicht gespeichert werden.
+error.code.5=Zum Signieren eines Dokmentes m\u00fcssen Sie authentifiziert sein.
error.code.6=Unbekannter/interner Fehler
-error.code.7=Das Dokument konnte nicht verarbeitet werden, da unzureichend Speicher zu Verfügung steht.
+error.code.7=Das Dokument konnte nicht verarbeitet werden, da unzureichend Speicher zu Verf\u00fcgung steht.
error.code.10=Das System kann nicht initialisiert werden. Bitte wenden Sie sich an einen Systemadministrator.
#SettingNotFoundException
-error.code.100=Der Konfigurationsschlüssel konnte nicht gefunden werden.
+error.code.100=Der Konfigurationsschl\u00fcssel konnte nicht gefunden werden.
error.code.101=Die Konfigurationsdatei konnte nicht geladen werden.
-error.code.102=Das Signaturprofil enthält keinen Bericht für die Kennzeichnung.
-error.code.103=Für den PDA/A Modus muss eine einbettbare TrueType-Schrift konfiguriert sein.
-error.code.104=Die Konfiguration der SignaturLayout-Implementierung fehlt oder ist ungültig.
-error.code.105=Es ist nicht möglich, den Typ der Bürgerkartenumgebung zu ermitteln. Die Antwort der Bürgerkartenumgebung war unvollständig.
+error.code.102=Das Signaturprofil enth\u00e4lt keinen Bericht f\u00fcr die Kennzeichnung.
+error.code.103=F\u00fcr den PDA/A Modus muss eine einbettbare TrueType-Schrift konfiguriert sein.
+error.code.104=Die Konfiguration der SignaturLayout-Implementierung fehlt oder ist ung\u00fcltig.
+error.code.105=Es ist nicht m\u00f6glich, den Typ der B\u00fcrgerkartenumgebung zu ermitteln. Die Antwort der B\u00fcrgerkartenumgebung war unvollst\u00e4ndig.
+error.code.106=Es wurden include-Instruktionen verwendet, die sich gegenseitig referenzieren und dadurch zu einer Endlosschleife f\u00fchren w\u00fcrden.
+error.code.107=Die interne Standard-Konfiguration konnte nicht geladen werden.
#PDFDocumentException
error.code.201=Das PDF Dokument kann nicht gelesen werden, oder die Datei hat ein falsches Format.
@@ -26,61 +28,63 @@ error.code.204=Das Dokument ist bereits signiert.
error.code.205=Das PDF Dokument kann nicht erstellt werden. Der Zugriff auf das Dokument ist blockiert.
error.code.206=Das Dokument ist nicht signiert.
error.code.210=Das Dokument kann nicht geschlossen werden.
-error.code.220=Die Bildmarke für die Signatur kann nicht geladen werden.
-error.code.221=Die Referenz für die Bildmarke der Signatur ist ungültig.
-error.code.222=Der Zugriff auf die Bildmarke der Signatur ist nicht möglich.
+error.code.220=Die Bildmarke f\u00fcr die Signatur kann nicht geladen werden.
+error.code.221=Die Referenz f\u00fcr die Bildmarke der Signatur ist ung\u00fcltig.
+error.code.222=Der Zugriff auf die Bildmarke der Signatur ist nicht m\u00f6glich.
error.code.223=Es ist keine Signaturtabelle definiert.
-error.code.224=Die angegebene Signatur Position ist ungültig.
+error.code.224=Die angegebene Signatur Position ist ung\u00fcltig.
error.code.225=Die angegebene Seite in der absoluten Position darf nicht kleiner als 1 sein.
-error.code.226=Der angegebene Wert für die Breite in der absoluten Position darf nicht kleiner gleich 0 sein.
-error.code.227=Der angegebene Wert für die Seitennummer im Positionsparameter ist zu groß.
-error.code.228=Der angegebene Wert für die x-Position in der absoluten Position darf nicht kleiner gleich 0 sein.
-error.code.229=Der angegebene Wert für die y-Position in der absoluten Position darf nicht kleiner gleich 0 sein.
+error.code.226=Der angegebene Wert f\u00fcr die Breite in der absoluten Position darf nicht kleiner gleich 0 sein.
+error.code.227=Der angegebene Wert f\u00fcr die Seitennummer im Positionsparameter ist zu gro\u00df.
+error.code.228=Der angegebene Wert f\u00fcr die x-Position in der absoluten Position darf nicht kleiner gleich 0 sein.
+error.code.229=Der angegebene Wert f\u00fcr die y-Position in der absoluten Position darf nicht kleiner gleich 0 sein.
error.code.230=Die Schriftart konnte nicht geladen werden.
-error.code.231=Das Dokument kann nicht verarbeitet werden, da es geschützt ist.
-error.code.232=Die Signatur konnte nicht überprüft werden, da das Dokument unvollständige Signaturinformationen enthält.
+error.code.231=Das Dokument kann nicht verarbeitet werden, da es gesch\u00fctzt ist.
+error.code.232=Die Signatur konnte nicht \u00fcberpr\u00fcft werden, da das Dokument unvollst\u00e4ndige Signaturinformationen enth\u00e4lt.
error.code.233=Es konnte kein passender Platzhalter gefunden werden (STRICT mode).
+error.code.234=Das gew\u00e4hlte Signaturprofil kann nicht zur Signatur verwendet werden.
error.code.250=Das angegebene Dokument ist leer.
-error.code.251=Das angegebene Dokument enthält keinen extrahierbaren Text. Falls sich der Inhalt ausschließlich aus Bildern zusammensetzt, wird die Verwendung einer binären Signatur empfohlen.
+error.code.251=Das angegebene Dokument enth\u00e4lt keinen extrahierbaren Text. Falls sich der Inhalt ausschlie\u00dflich aus Bildern zusammensetzt, wird die Verwendung einer bin\u00e4ren Signatur empfohlen.
#SignatureException
error.code.300=Die Signatur kann nicht erstellt werden.
-error.code.301=Die Signatur kann nicht erstellt werden. Das zu signierende Dokument enthält keinen Text.
+error.code.301=Die Signatur kann nicht erstellt werden. Das zu signierende Dokument enth\u00e4lt keinen Text.
error.code.302=Die Signatur kann nicht erstellt werden. Der Signaturtyp ist nicht definiert.
-error.code.303=Die Signatur kann nicht erstellt werden. Die Seriennummer ist ungültig.
+error.code.303=Die Signatur kann nicht erstellt werden. Die Seriennummer ist ung\u00fcltig.
error.code.304=Die Signatur kann nicht erstellt werden. Das Signatur Zertifikat kann nicht gelesen werden.
-error.code.305=Die Signatur kann nicht erstellt werden. Das gewählte Signaturprofil ist nicht für die Textsignatur geeignet, da es nicht alle notwendigen Signaturfelder sichtbar definiert. Bitte wählen Sie ein anderes Signaturprofil oder führen Sie eine Binärsignatur durch.
+error.code.305=Die Signatur kann nicht erstellt werden. Das gew\u00e4hlte Signaturprofil ist nicht f\u00fcr die Textsignatur geeignet, da es nicht alle notwendigen Signaturfelder sichtbar definiert. Bitte w\u00e4hlen Sie ein anderes Signaturprofil oder f\u00fchren Sie eine Bin\u00e4rsignatur durch.
error.code.310=Die Signatur konnte nicht verifiziert werden.
-error.code.311=Der zu prüfende Text ist nicht definiert.
-error.code.312=Die zu prüfende Signatur ist nicht definiert.
+error.code.311=Der zu pr\u00fcfende Text ist nicht definiert.
+error.code.312=Die zu pr\u00fcfende Signatur ist nicht definiert.
error.code.313=Das Zertifikat (Seriennummer oder Aussteller) ist unbekannt oder kann nicht zugeordnet werden.
-error.code.314=Beim Auffinden der Signaturen ist ein Fehler aufgetreten. Es wurden mehrere passende Signaturprofile gefunden, die aber nicht semantisch äquivalent sind. Daher kann die Applikation nicht entscheiden welches Signaturprofil zur Prüfung herangezogen werden muss.
-error.code.315=Beim Auffinden der Signaturen ist ein Fehler aufgetreten. Obwohl mehrere passende Signaturprofile gefunden wurden kann die Applikation auf Grund deren Beschaffenheit nicht eindeutig entscheiden welches Signaturprofil zur Prüfung herangezogen werden muss.
+error.code.314=Beim Auffinden der Signaturen ist ein Fehler aufgetreten. Es wurden mehrere passende Signaturprofile gefunden, die aber nicht semantisch \u00e4quivalent sind. Daher kann die Applikation nicht entscheiden welches Signaturprofil zur Pr\u00fcfung herangezogen werden muss.
+error.code.315=Beim Auffinden der Signaturen ist ein Fehler aufgetreten. Obwohl mehrere passende Signaturprofile gefunden wurden kann die Applikation auf Grund deren Beschaffenheit nicht eindeutig entscheiden welches Signaturprofil zur Pr\u00fcfung herangezogen werden muss.
# added by tzefferer
-error.code.316=Das Dokument wurde nach erfolgter Signierung verändert.
-error.code.317=Das Dokument enthält nicht-binäre Signaturen.
+error.code.316=Das Dokument wurde nach erfolgter Signierung ver\u00e4ndert.
+error.code.317=Das Dokument enth\u00e4lt nicht-bin\u00e4re Signaturen.
-error.code.318=Die binäre Signatur kann nicht geprüft werden. Die Signatur enthält nicht unterstützte /replaces-Namen.
-error.code.319=Die Signatur konnte nicht verifiziert werden, da diese auf einer nicht unterstützten Signaturmethode bzw. einem unbekannten Signaturparameter basiert. Bitte aktualisieren Sie Ihre PDF-AS Software.
+error.code.318=Die bin\u00e4re Signatur kann nicht gepr\u00fcft werden. Die Signatur enth\u00e4lt nicht unterst\u00fctzte /replaces-Namen.
+error.code.319=Die Signatur konnte nicht verifiziert werden, da diese auf einer nicht unterst\u00fctzten Signaturmethode bzw. einem unbekannten Signaturparameter basiert. Bitte aktualisieren Sie Ihre PDF-AS Software.
-error.code.320=Es kann keine Verbindung zur Bürgerkartenumgebung hergestellt werden.
-error.code.330=Es kann keine Verbindung zu MOA hergestellt werden oder MOA hat den Request zurückgewiesen.
-error.code.340=Die Antwort des Signaturgeräts enthielt weder eine Signatur noch ein Verifikationsergebnis.
+error.code.320=Es kann keine Verbindung zur B\u00fcrgerkartenumgebung hergestellt werden.
+error.code.330=Es kann keine Verbindung zu MOA hergestellt werden oder MOA hat den Request zur\u00fcckgewiesen.
+error.code.334=Das Signaturprofil kann nicht f\u00fcr die Signatur verwendet werden.
+error.code.340=Die Antwort des Signaturger\u00e4ts enthielt weder eine Signatur noch ein Verifikationsergebnis.
# TODO remove this when MOA detached is ready
-error.code.370=Eine detached Signature kann zur Zeit mit MOA nicht überprüft werden.
+error.code.370=Eine detached Signature kann zur Zeit mit MOA nicht \u00fcberpr\u00fcft werden.
-# Für die Online-BKU: Signatur-Prüfung wird nicht unterstützt werden.
-error.code.371=Dieses Signaturgerät unterstützt keine Signatur-Prüfung.
+# Fuer die Online-BKU: Signatur-Pruefung wird nicht unterstuetzt werden.
+error.code.371=Dieses Signaturger\u00e4t unterst\u00fctzt keine Signatur-Pr\u00fcfung.
# Workaround for ITS(Mac/Linux) bug concerning the signing time.
-error.code.372=Der Signaturzeitpunkt ist ungültig. Stellen Sie bitte sicher, dass die Systemzeit sowie die Zeitzoneneinstellung Ihres Rechners korrekt sind sowie dass Sie die aktuellste Version Ihrer Bürgerkartenumgebung verwenden.
+error.code.372=Der Signaturzeitpunkt ist ung\u00fcltig. Stellen Sie bitte sicher, dass die Systemzeit sowie die Zeitzoneneinstellung Ihres Rechners korrekt sind sowie dass Sie die aktuellste Version Ihrer B\u00fcrgerkartenumgebung verwenden.
# Unsupported BKU
-error.code.373=Dieses Signaturgerät wird nicht unterstützt.
+error.code.373=Dieses Signaturger\u00e4t wird nicht unterst\u00fctzt.
#NormalizeException
error.code.400=Das Normalisierungsmodul kann nicht initialisiert werden.
@@ -89,14 +93,14 @@ error.code.400=Das Normalisierungsmodul kann nicht initialisiert werden.
error.code.500=Das Zertifikat konnte nicht auf dem LDAP Server gefunden werden.
#Session exception
-error.code.600=Die Sitzung ist entweder ungültig oder wurde bereits beendet.
+error.code.600=Die Sitzung ist entweder ung\u00fcltig oder wurde bereits beendet.
#PlaceholderException
-error.code.700=Der Platzhalter für einen Wert wurde zu kurz gewählt. Es konnte nicht der gesamte Wert in die Signatur eingefügt werden. Bitte vergrößern Sie die Länge des entsprechenden Platzhalters im Signaturprofil.
+error.code.700=Der Platzhalter f\u00fcr einen Wert wurde zu kurz gew\u00e4hlt. Es konnte nicht der gesamte Wert in die Signatur eingef\u00fcgt werden. Bitte vergr\u00f6\u00dfern Sie die L\u00e4nge des entsprechenden Platzhalters im Signaturprofil.
#CaptionNotFoundException
-error.code.701=Die Überschrift (Caption/Label) konnte nicht eindeutig wiedergefunden werden. Dies geschieht gewöhnlich wenn bei der (häufig absoluten) Positionierung zu wenig Platz für die Überschrift (Caption/Label) vorhanden ist und diese ungünstig umgebrochen werden muss. Bitte stellen Sie dieser Überschrift mehr Platz im Signaturblock zur Verfügung oder entfernen Sie aus dieser alle Leerzeichen.
+error.code.701=Die \u00dcberschrift (Caption/Label) konnte nicht eindeutig wiedergefunden werden. Dies geschieht gew\u00f6hnlich wenn bei der (h\u00e4ufig absoluten) Positionierung zu wenig Platz f\u00fcr die \u00dcberschrift (Caption/Label) vorhanden ist und diese ung\u00fcnstig umgebrochen werden muss. Bitte stellen Sie dieser \u00dcberschrift mehr Platz im Signaturblock zur Verf\u00fcgung oder entfernen Sie aus dieser alle Leerzeichen.
#CorrectorException
-error.code.800=Fehler beim Parsen der binären Signatur.
+error.code.800=Fehler beim Parsen der bin\u00e4ren Signatur.
error.code.801=Das Dokument konnte nicht korrigiert werden.
error.code.802=Die externe Korrektur konnte nicht innerhalb des festgesetzten Timeouts fertiggestellt werden.
diff --git a/pdf-as-lib/src/main/resources/config/pdf-as.properties b/pdf-as-lib/src/main/resources/config/pdf-as.properties
index cad47f4..85c5375 100644
--- a/pdf-as-lib/src/main/resources/config/pdf-as.properties
+++ b/pdf-as-lib/src/main/resources/config/pdf-as.properties
@@ -1,5 +1,7 @@
###############################################################################
# PDF-AS system properties
+# Note: This is a collection of fixed properties that CANNOT be overridden by
+# local configurations.
###############################################################################
normalizer.version=V01
@@ -23,9 +25,13 @@ signaturelayout.pattern.moc.none=^((citizen-card-environment/1\\.2 MOCCA(?!.*Sig
signaturelayout.implementation.moc.none=at.knowcenter.wag.egov.egiz.sig.signaturelayout.mocca.OldMOCCASignatureLayoutHandler
# signature layout 1.0 for mocca
-signaturelayout.pattern.moc.10=^citizen-card-environment/1\\.2 MOCCA/.*SignatureLayout/1\\.0.*$
+signaturelayout.pattern.moc.10=^citizen-card-environment/1\\.2 MOCCA/(?!.*-X14).*SignatureLayout/1\\.0.*$
signaturelayout.implementation.moc.10=at.knowcenter.wag.egov.egiz.sig.signaturelayout.mocca.MOCCASignatureLayout10Handler
+# signature layout for mocca with XAdES 1.4 support (works in conjunction with SignatureLayout 1.0 and 1.1
+signaturelayout.pattern.moc.xades14=^citizen-card-environment/1\\.2 MOCCA/.*-X14\\s*SignatureLayout/1\\.[01].*$
+signaturelayout.implementation.moc.xades14=at.knowcenter.wag.egov.egiz.sig.signaturelayout.mocca.MoccaXades14SignatureLayoutHandler
+
# signature layout for supported trustDesk basic versions
signaturelayout.pattern.tdb=^citizen-card-environment/1\\.2 trustDeskbasic((-OSX)|(-Linux))?/((2\\.7\\.\\d)|(2\\.8\\.\\d)|(3\\.0\\.\\d))$
signaturelayout.implementation.tdb=at.knowcenter.wag.egov.egiz.sig.signaturelayout.td.TrustDeskSignatureLayoutHandler
@@ -33,16 +39,12 @@ signaturelayout.implementation.tdb=at.knowcenter.wag.egov.egiz.sig.signaturelayo
# signature layout for supported hotSign
# currently disabled since there are still problems
#signaturelayout.pattern.hotsign=^citizen-card-environment/1\\.2 hotSign/2\\.0\\.0$
-#signaturelayout.implementation.hotsign=at.knowcenter.wag.egov.egiz.sig.signaturelayout.mocca.MOCCASignatureLayout10Handler
+#signaturelayout.implementation.hotsign=[needs to be implemented]
# signature layouts for supported A-Trust CCS
-#for web also a-trust CCS 1.3.0 is ok
-#signaturelayout.pattern.atrust130=^citizen-card-environment/1\\.2 asignSecurityLayer/1\\.3\\.0$
-#signaturelayout.implementation.atrust130=at.knowcenter.wag.egov.egiz.sig.signaturelayout.atrust.ATrustSignatureLayoutHandler
-
-signaturelayout.pattern.atrust133<=^citizen-card-environment/1\\.2 asignSecurityLayer?/((1\\.3\\.3)|(1\\.([4-9]|[1-9][0-9]{1,3})\\.{0,1}(?=[0-9])(?<=\\.)[0-9]{0,3}\\.{0,1}(?=[0-9])(?<=\\.)[0-9]{0,3})|(([2-9]|[1-9][0-9]{1,4})\\.{0,1}(?=[0-9])(?<=\\.)[0-9]{0,3}\\.{0,1}(?=[0-9])(?<=\\.)[0-9]{0,3}\\.{0,1}(?=[0-9])(?<=\\.)[0-9]{0,3}))
-signaturelayout.implementation.atrust133<=at.knowcenter.wag.egov.egiz.sig.signaturelayout.atrust.ATrustSignatureLayoutHandler
+signaturelayout.pattern.atrustlocal=^citizen-card-environment/1\\.2 asignSecurityLayer/((1\\.3\\.3)|(1\\.4\\.[1-2]))$
+signaturelayout.implementation.atrustlocal=at.knowcenter.wag.egov.egiz.sig.signaturelayout.atrust.ATrustSignatureLayoutHandler
# A-Trust Mobile BKU 1.1.0
signaturelayout.pattern.atrustmobile=^citizen-card-environment/1\\.2 asignMobileBku/1\\.1\\.0$
@@ -149,6 +151,13 @@ oid.1_2_40_0_10_1_1_2=Dienstleistereigenschaft
#############################################
+# Signaturkennzeichnung (fuer Adobe Acrobat)
+
+# Adobe Signaturkennzeichnung ein-/ausschalten
+default.adobeSignEnabled=true
+
+
+#############################################
# start LDAP-Mappings
# note: ldap_mapping.xxx.serial_attr may be omitted if value is "eidCertificateSerialNumber"
diff --git a/pdf-as-lib/src/main/resources/config/templates/moc.etsi-moc-1.2.verify.template.xml b/pdf-as-lib/src/main/resources/config/templates/moc.etsi-moc-1.2.verify.template.xml
new file mode 100644
index 0000000..58337ce
--- /dev/null
+++ b/pdf-as-lib/src/main/resources/config/templates/moc.etsi-moc-1.2.verify.template.xml
@@ -0,0 +1 @@
+<dsig:Signature Id="Signature-SigIdReplace-1" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:SignedInfo Id="SignedInfo-SigIdReplace-1"><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><dsig:SignatureMethod Algorithm="CertAlgReplace"/><dsig:Reference Id="Reference-SigIdReplace-1" URI="urn:Document"><dsig:DigestMethod Algorithm="DataDigestReplace"/><dsig:DigestValue>DigestValueSignedDataReplace</dsig:DigestValue></dsig:Reference><dsig:Reference Id="Reference-SigIdReplace-2" Type="http://uri.etsi.org/01903#SignedProperties" URI="#SignedProperties-SigIdReplace-1"><dsig:DigestMethod Algorithm="PropertiesDigestReplace"/><dsig:DigestValue>DigestValueSignedPropertiesReplace</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue Id="SignatureValue-SigIdReplace-1">SignatureValueReplace</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>X509CertificateReplace</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo><dsig:Object Id="Object-SigIdReplace-1"><xades:QualifyingProperties Target="#Signature-SigIdReplace-1" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#"><xades:SignedProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://uri.etsi.org/01903/v1.4.1#" xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Id="SignedProperties-SigIdReplace-1"><xades:SignedSignatureProperties><xades:SigningTime>SigningTimeReplace</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><dsig:DigestMethod Algorithm="CertDigestReplace"></dsig:DigestMethod><dsig:DigestValue>DigestValueX509CertificateReplace</dsig:DigestValue></xades:CertDigest><xades:IssuerSerial><dsig:X509IssuerName>X509IssuerNameReplace</dsig:X509IssuerName><dsig:X509SerialNumber>X509SerialNumberReplace</dsig:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate><xades:SignaturePolicyIdentifier><xades:SignaturePolicyImplied></xades:SignaturePolicyImplied></xades:SignaturePolicyIdentifier></xades:SignedSignatureProperties><xades:SignedDataObjectProperties><xades:DataObjectFormat ObjectReference="#Reference-SigIdReplace-1"><xades:MimeType>MimeTypeReplace</xades:MimeType></xades:DataObjectFormat></xades:SignedDataObjectProperties></xades:SignedProperties></xades:QualifyingProperties></dsig:Object></dsig:Signature> \ No newline at end of file