From db52e4d66d60184d53a27ba4d6772461daacc03d Mon Sep 17 00:00:00 2001
From: tknall
* 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.
- *
+ *
*
* 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.
* 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.
- *
+ *
*
* 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.
- *
+ *
*
* 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.
- *
+ *
*
* Note: In near future it will be possible to provide a full specified
* profile here instead of the profile id.
*
* 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.
*
* Sample usage:
*
* The commandline uses the PDF-AS API.
*
* The extension of a file name is whatever text follows the last '.'.
*
* 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;
*
* In finishSign, the variable fields (values, /Cert) are replaced with the values according to the encoding.
*
* In prepareSign, the document text is extracted and normalized.
*
* If the placeholder with the given id is not found in the document, the first placeholder without an id will be taken.
* 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.
* 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.
* 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.
- *
+ *
*
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);
@@ -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:
*
- *
+ *
* @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.
- *
+ *
*
+ * 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 @@
+/**
+ * true
: automatically registers IAIK JCE and ECC Provider;
* false
: 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 true
: automatically registers IAIK JCE and ECC Provider;
* false
: 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,13 +96,25 @@ 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()
*/
@@ -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.
- *
+ *
*
* IU blocks without an egiz dict are not considered. *
- * + * * @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. - * + * ** According to definition, if a block is a binary block, it must/cannot * contain other signatures than this one. *
- * + * * @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.include = [path/to/]foo.properties
+ *
+ * Note that wildcard imports are allowed, e.g.
+ *
+ * include = [path/to/]profile.*.properties
+ *
+ * In order to use more than one include instruction within a file append an arbitary postfix to include.
+ * in order to make each include key unique within a properties file, e.g.
+ *
+ * include = profile.SIGNATURBLOCK*.properties
include.amtssignaturen = profile.AMTSSIGNATURBLOCK*.properties
include.1 = myProfiles1/*.properties
include.2 = myProfiles2/*.properties
+ *
+ * Note that
+ * setKeyValue("key.1_level.2_level","the value for k_1_2")
null 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 null
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 null.
- *
+ *
* @param key the key that holds the value (can be a nested key like "key.1.2.3"
)
* @return the value of the key (last node of the key) or null
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 null
.
- *
+ *
* @param key the key that holds the value (can be a nested key like "key.1.2.3"
)
* @return the value of the key (last node of the key) or null
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 "key.1.2.3"
)
* @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 "key.1.2.3"
)
* @return the values (type Vector) of the key or null
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.
* Example: if the key is like: key.1.2.3
the sub tree of the last
* node 3
is returned.
- *
+ *
* @param key the reference of the sub tree
* @return a sub tree of the key or null
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 ;-).
+ * 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 settings.txt
file. The
* settings.txt
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:
- *
+ *
* - * + * * #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 - * + * *- * + * * The internal representation of the example above is: - * + * *
- * + * * .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 + * *- * + * * @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. - * + * *
* This usually contains sub directories for the templates, the configuration * files, etc. *
*/ 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 thesettingsFile == null
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.
- *
+ *
* * Subsequent calls to getInstance will return the new settings. * Note: IAIK JCE and IAIK ECC security providers are automatically registered. *
- * + * * @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. - * + * ** Subsequent calls to getInstance will return the new settings. *
* @param registerProvidertrue
: automatically registers IAIK JCE and ECC Provider;
* false
: 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
* settingsFile == null
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 true
: automatically registers IAIK JCE and ECC Provider;
* false
: 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 Object[]
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 null
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.
- *
+ *
* * If the directory doesn't exist, it is created. *
- * + * * @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. - * + * ** 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. - * + * *
* The extension of a file name is whatever text follows the last '.'. *
- * + * * @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. - * + * ** 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. *
- * + * * @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. - * + * ** It doesn't modify the original document, but simply returns the XML signature * response as the signed document. *
- * + * * @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. - * + * ** In prepareSign, the document text is extracted and normalized. *
@@ -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. * - * + * * @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. * - * + * * @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* These functions are used to replace parts of the original Egiz plain text * signature mechanism. *
- * + * * @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. - * + * ** Used to locate and identify the Egiz Dictionary in the document. *
@@ -195,7 +217,7 @@ public abstract class BinarySignature /** * The PDFName of the Original Document Size (ODS) field in an Egiz * Dictionary. - * + * ** The ODS must be a positive integral number. *
@@ -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. - * + * ** 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. - * + * *
* The signature text is the text of the Signature XObject. *
- * + * * @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. - * + * ** 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. *
- * + * * @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. - * + * ** 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. *
- * + * * @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. - * + * ** This replaces the "dummy numbers" in the egiz dictionary with the correct * values. *
- * + * * @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. * - * + * * @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. - * + * ** This method collects all variable String fields in a content stream and * orders them according to their start offset. *
- * + * * @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 ** 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. *
- * + * ** 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. *
- * + * * @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 @@ +/** + *h S
.
+ *
+ * @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 @@
+/**
+ * h B*
.
+ *
+ * @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 @@
+/**
+ * h B
.
+ *
+ * @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 @@
+/**
+ * B
, except that the path is filled as if with f*
instead of
+ * f
.
+ *
+ * @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 @@
+/**
+ * f
and
+ * the second with S
.
+ *
+ * @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 @@
+/**
+ *
* 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!
* If the key equals to SIG_VALUE
all whitespaces are
* removed!
- *
+ *
* @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
* SIG_NORM
and the value is null
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 null
the key itself is
* returned as caption! If the key does not exist the method returns
* null
.
- *
+ *
* @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
*
.txt
extension to get the meta information of
* the certificate@
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
* .txt
extension to get the meta information of
* the certificate@
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
* .txt
extension to get the meta information of
* the certificate@
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.
- *
+ *
* * This should be used by the Connector to pass the response String to the * signer. *
- * + * * @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* 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. *
- * + * * @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. - * + * ** Just for convenience. *
@@ -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.* The data is Base64 encoded. If the mime-type suggests that the data is * binary, it is Base64 encoded for a second time. *
- * + * * @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 ** This is useful for building the hash. *
- * + * * @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. - * + * ** 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. *
- * + * * @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("* This feature is available since BKU version 2.7.4. *
- * + * * @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. - * + * ** If confuguration parameters are not defined on that profile, the default * parameters defined in the configuration are used. *
- * + * * @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. - * + * ** This method mainly handles communication exceptions. The actual send work * is done by doPostRequestMultipart. *
- * + * * @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. - * + * ** This strongly rebuilds the XML content as retuned from a sign request. *
- * + * * @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. - * + * ** If confuguration parameters are not defined on that profile, the default * parameters defined in the configuration are used. *
- * + * ** This is the new "hotfix" base64 connector. *
- * + * * @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. - * + * ** This strongly rebuilds the XML content as retuned from a sign request. *
- * + * * @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. - * + * ** If confuguration parameters are not defined on that profile, the default * parameters defined in the configuration are used. *
- * + * * @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. - * + * ** If confuguration parameters are not defined on that profile, the default * parameters defined in the configuration are used. *
- * + * * @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. - * + * ** This strongly rebuilds the XML content as retuned from a sign request. *
- * + * * @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 = "* If confuguration parameters are not defined on that profile, the default * parameters defined in the configuration are used. *
- * + * * @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 @@ +/** + ** 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. *
- * + * * @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 Binary files a/pdf-as-lib/src/main/resources/DefaultConfiguration.zip and b/pdf-as-lib/src/main/resources/DefaultConfiguration.zip 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$ @@ -148,6 +150,13 @@ oid.1_2_40_0_10_1_1_1=Verwaltungseigenschaft 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 @@ +This file and the 14 PostScript(R) AFM files it accompanies may be used, copied, and distributed for any purpose and without charge, with or without modification, provided that all copyright notices are retained; that the AFM files are not distributed without this file; that all modifications to this file or any of the AFM files are prominently noted in the modified file(s); and that this paragraph is not modified. Adobe Systems has no responsibility or obligation to support the use of the AFM files. Col |
Common Public License - v 1.0 +
+
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. +
+
1. DEFINITIONS +
"Contribution" means: + +
+
"Contributor" means any person or entity that distributes the Program. +
+
"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. +
+
"Program" means the Contributions distributed in accordance with this Agreement. +
+
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. +
+
2. GRANT OF RIGHTS + +
3. REQUIREMENTS +
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +
When the Program is made available in source code form: + +
+
Contributors may not remove or alter any copyright notices contained within the Program.
+
+
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. +
+
4. COMMERCIAL DISTRIBUTION +
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. +
+
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. +
+
5. NO WARRANTY +
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. +
+
6. DISCLAIMER OF LIABILITY +
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +
+
7. GENERAL +
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. +
+
If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. +
+
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. +
+
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. +
+
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. +
+
+
+
+
+
\ No newline at end of file
diff --git a/pdf-as-web/src/main/assembly/tomcat/configuration/default/pdf-as/licenses/log4j/LICENSE.txt b/pdf-as-web/src/main/assembly/tomcat/configuration/default/pdf-as/licenses/log4j/LICENSE.txt
new file mode 100644
index 0000000..030564f
--- /dev/null
+++ b/pdf-as-web/src/main/assembly/tomcat/configuration/default/pdf-as/licenses/log4j/LICENSE.txt
@@ -0,0 +1,48 @@
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "log4j" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation. For more information on the
+ * Apache Software Foundation, please see
* As stated in the BKU tutorial, this response must be plain text "