aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknowcenter <knowcenter@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2007-05-12 17:37:16 +0000
committerknowcenter <knowcenter@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2007-05-12 17:37:16 +0000
commit8e3ed85168edaeadcd4f3ec92450036a399d6ede (patch)
tree4fd938ebad8a042dd270ede88f7412909bfc3a4f
parent064682ea2ccb0bbb7497d52790b282b179d98ae0 (diff)
downloadpdf-as-3-8e3ed85168edaeadcd4f3ec92450036a399d6ede.tar.gz
pdf-as-3-8e3ed85168edaeadcd4f3ec92450036a399d6ede.tar.bz2
pdf-as-3-8e3ed85168edaeadcd4f3ec92450036a399d6ede.zip
Detached Multipart BKU for Auftrag "Support"
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@73 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
-rw-r--r--.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--.settings/org.eclipse.jdt.ui.prefs3
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java250
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java17
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java45
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java67
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java66
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java30
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java31
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java36
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_1_0.java45
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java40
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java17
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java62
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java101
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java105
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java119
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedMultipartBKUConnector.java1125
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObject.java111
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObjectHelper.java56
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AdditionalSignatureInformation.java18
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AlgorithmSignatureInformation.java13
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/ConnectorSignatureInformation.java14
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/MandatorySignatureInformation.java20
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java3
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java3
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/Sign.java3
-rw-r--r--src/test/java/test/at/knowcenter/wag/egov/egiz/TestNeu.java265
-rw-r--r--src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUConnector.java987
-rw-r--r--src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUPostConnection.java230
-rw-r--r--src/test/java/test/at/knowcenter/wag/egov/egiz/detached/MOAConnector.java869
-rw-r--r--work/cfg/config.properties14
-rw-r--r--work/cfg/log4j.properties4
-rw-r--r--work/templates/BKUSignRequestDetached.xml17
-rw-r--r--work/templates/BKUVerifyRequestDetached.xml14
-rw-r--r--work/templates/BKUVerifyTemplateDetached.xml13
-rw-r--r--work/templates/old/BKUSignRequestB64.xml (renamed from work/templates/BKUSignRequestB64.xml)0
-rw-r--r--work/templates/old/BKUSignRequestBinaryDetached.xml17
-rw-r--r--work/templates/old/BKUSignRequestTextualDetached.xml17
-rw-r--r--work/templates/old/BKUVerifyRequest.xml (renamed from work/templates/BKUVerifyRequest.xml)0
-rw-r--r--work/templates/old/BKUVerifyTemplateB64.xml (renamed from work/templates/BKUVerifyTemplateB64.xml)0
-rw-r--r--work/templates/old/BKUVerifyTemplateB64_neueBKU.xml (renamed from work/templates/BKUVerifyTemplateB64_neueBKU.xml)0
-rw-r--r--work/templates/old/BKUVerifyTemplateDetached_mitQPextern.xml13
-rw-r--r--work/templates/old/BKUVerifyTemplateSP.xml (renamed from work/templates/BKUVerifyTemplateSP.xml)0
-rw-r--r--work/templates/old/BKUVerifyTemplateSP_neueBKU.xml (renamed from work/templates/BKUVerifyTemplateSP_neueBKU.xml)0
-rw-r--r--work/templates/old/BKUVerifyTemplateSP_neueBKU_bin.xml1
-rw-r--r--work/templates/old/BKUVerifyTemplateSP_neueBKU_text.xml1
-rw-r--r--work/templates/old/MOASignRequest.xml (renamed from work/templates/MOASignRequest.xml)0
-rw-r--r--work/templates/old/MOASignRequestB64.xml (renamed from work/templates/MOASignRequestB64.xml)0
-rw-r--r--work/templates/old/MOASignRequestDetached.xml19
-rw-r--r--work/templates/old/MOAVerifyRequest.xml (renamed from work/templates/MOAVerifyRequest.xml)0
-rw-r--r--work/templates/old/MOAVerifyTemplate.xml (renamed from work/templates/MOAVerifyTemplate.xml)0
-rw-r--r--work/templates/old/MOAVerifyTemplateB64.xml (renamed from work/templates/MOAVerifyTemplateB64.xml)0
-rw-r--r--work/templates/old/MOAVerifyTemplateSP.xml (renamed from work/templates/MOAVerifyTemplateSP.xml)0
54 files changed, 4730 insertions, 163 deletions
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..f97d4fa
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Tue May 08 14:45:03 CEST 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.4
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..4285f5a
--- /dev/null
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Tue May 08 14:45:03 CEST 2007
+eclipse.preferences.version=1
+internal.default.compliance=user
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
index 313a11c..8de93c0 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
@@ -53,10 +53,16 @@ import at.knowcenter.wag.egov.egiz.pdf.TablePos;
import at.knowcenter.wag.egov.egiz.pdf.TextualSignature;
import at.knowcenter.wag.egov.egiz.sig.Connector;
import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.DetachedMultipartBKUConnector;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
+import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
import at.knowcenter.wag.egov.egiz.tools.Normalizer;
import at.knowcenter.wag.exactparser.ParseDocument;
import at.knowcenter.wag.exactparser.parsing.PDFUtils;
@@ -390,7 +396,7 @@ public abstract class PdfAS
for (int key_idx = 0; key_idx < keys.size(); key_idx++)
{
String key = (String) keys.get(key_idx);
- //logger_.debug("Key="+key);
+ // logger_.debug("Key="+key);
if (old_style && key.equals(SignatureTypes.SIG_KZ))
{
// If separating the old style way - skip The "Kennzeichnung"
@@ -402,15 +408,19 @@ public abstract class PdfAS
// int found_index = text.lastIndexOf(caption);
// we're searching for captions that start at the beginning of the line.
- int found_index =text.lastIndexOf("\n" +caption) + 1;//text.lastIndexOf("\n" + caption) + 1; // the +1 text.lastIndexOf(caption) + 1; //
+ int found_index = text.lastIndexOf("\n" + caption) + 1;// text.lastIndexOf("\n"
+ // + caption) + 1;
+ // // the +1
+ // text.lastIndexOf(caption)
+ // + 1; //
// compensates the
// \n
if (found_index == 0)
{
- //try without /n
- found_index = text.lastIndexOf(caption);
+ // try without /n
+ found_index = text.lastIndexOf(caption);
}
- logger_.debug("found key:"+caption+" at index:"+found_index);
+ logger_.debug("found key:" + caption + " at index:" + found_index);
if (key.equals(SignatureTypes.SIG_ID))
{
if (found_index < 0 || found_index >= last_index)
@@ -430,16 +440,16 @@ public abstract class PdfAS
}
FoundKey fk = new FoundKey(key, caption, found_index);
- found_keys.add(fk);
+ found_keys.add(fk);
last_index = found_index;
}
}
sortFoundKeysDescendingly(found_keys);
-
+
boolean matched = checkThatOrderIsCorrectAndCorrectFoundKeys(found_keys, keys, old_style);
// boolean found_required = checkFoundRequiredKeys(found_keys, old_style);
- //logger_.debug("KKKKKKKKKKmatched="+matched);
+ // logger_.debug("KKKKKKKKKKmatched="+matched);
if (matched)
{
return found_keys;
@@ -780,7 +790,7 @@ public abstract class PdfAS
String connector) throws NormalizeException, PDFDocumentException, SignatureException
{
String text_to_be_verified = signature_holder.getSignedText();
- //logger_.debug("verify text_to_be_verified"+text_to_be_verified);
+ // logger_.debug("verify text_to_be_verified"+text_to_be_verified);
SignatureObject so_to_be_verified = signature_holder.getSignatureObject();
if (text_to_be_verified == null)
@@ -799,10 +809,31 @@ public abstract class PdfAS
try
{
- Connector connector_impl = ConnectorFactory.createConnector(connector);
- return connector_impl.doVerify(text_to_be_verified, so_to_be_verified);
+ DetachedMultipartBKUConnector connector_impl = new DetachedMultipartBKUConnector("xxxprofile");
+
+ // FIXME this has to be made better
+ SignatureData sd = null;
+ if (so_to_be_verified.isBinary())
+ {
+ byte[] data = CodingHelper.decodeBase64(text_to_be_verified);
+ sd = new SignatureDataImpl(data, "application/pdf");
+ }
+ else
+ {
+ sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8");
+ }
+
+ SignSignatureObject so = new SignSignatureObject();
+ so.date = so_to_be_verified.getSignationDate();
+ so.signatureValue = so_to_be_verified.getSignationValue();
+ so.issuer = so_to_be_verified.getSignationIssuer();
+ so.x509Certificate = so_to_be_verified.getX509Cert().getX509Certificate();
+ so.id = so_to_be_verified.getSignationIds();
+
+ // Connector connector_impl = ConnectorFactory.createConnector(connector);
+ return connector_impl.doVerify(sd, so);
}
- catch (ConnectorFactoryException e)
+ catch (Exception e)
{
throw new SignatureException(310, e);
}
@@ -812,46 +843,46 @@ public abstract class PdfAS
* Signs the given text with the provided connector using the given signature
* type.
*
- * @param text_to_sign
- * The text String to be signed.
+ * @param data_to_sign
+ * The data to be signed.
* @param signature_type
* The type of the signature.
* @param connector
* The connector.
- * @param user_name
- * The user name.
- * @param user_password
- * The user password.
* @return Returns the corresponding SignatureObject.
* @throws SignatureException
* F.e.
* @throws PDFDocumentException
* F.e.
*/
- public static SignatureObject sign(final String text_to_sign,
- final String signature_type, final String connector,
- final String user_name, final String user_password) throws SignatureException, PDFDocumentException
+ public static SignSignatureObject sign(final SignatureData data_to_sign,
+ final String signature_type, final String connector) throws SignatureException, PDFDocumentException
{
- logger_.info("User signed a document: " + user_name);
- if (text_to_sign == null)
+ if (data_to_sign == null || data_to_sign.getData() == null)
{
- throw new SignatureException(301, "Signature can not be produced. Text is null.");
+ throw new SignatureException(301, "Signature can not be produced. Data is null."); //$NON-NLS-1$
}
- if (text_to_sign.length() <= 0)
+ if (data_to_sign.getData().length <= 0)
{
- throw new SignatureException(301, "Signature can not be produced. Text is empty. (length = " + text_to_sign.length() + ")");
+ throw new SignatureException(301, "Signature can not be produced. Data is empty. (length = " + data_to_sign.getData().length + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}
try
{
- Connector connector_impl = ConnectorFactory.createConnector(connector);
- SignatureObject signed_signature_object = connector_impl.doSign(signature_type, user_name, text_to_sign);
+ // TODO temporary workaround:
+ DetachedMultipartBKUConnector connector_impl = new DetachedMultipartBKUConnector(signature_type);
+ // Connector connector_impl = ConnectorFactory.createConnector(connector);
+ SignSignatureObject signed_signature_object = connector_impl.doSign(data_to_sign);
return signed_signature_object;
}
- catch (ConnectorFactoryException e)
+ catch (SettingsException e)
{
throw new SignatureException(300, e);
}
+ // catch (ConnectorFactoryException e)
+ // {
+ // throw new SignatureException(300, e);
+ // }
}
/**
@@ -903,10 +934,10 @@ public abstract class PdfAS
final String user_name, final String user_password, TablePos pos) throws PresentableException
{
Signator signator = SignatorFactory.createSignator(algorithm);
-
+
IncrementalUpdateInformation iui = signator.prepareSign(pdf, signature_type, pos, ConnectorFactory.needsSIG_ID(connector));
- iui.signed_signature_object = sign(iui.document_text, signature_type, connector, user_name, user_password);
+ iui.signed_signature_object = sign(iui.signature_data, signature_type, connector);
SignResult sign_result = signator.finishSign(iui);
@@ -949,9 +980,11 @@ public abstract class PdfAS
{
ByteArrayInputStream bais = new ByteArrayInputStream(pdf, 0, length);
String raw_document_text = TextualSignature.extractTextTextual(bais);
- //logger_.info("extractNormalizedTextTextual raw_document_text="+raw_document_text);
+ // logger_.info("extractNormalizedTextTextual
+ // raw_document_text="+raw_document_text);
String document_text = normalizeText(raw_document_text);
- //logger_.info("extractNormalizedTextTextual document_text ="+document_text);
+ // logger_.info("extractNormalizedTextTextual document_text
+ // ="+document_text);
return document_text;
}
@@ -1024,12 +1057,14 @@ public abstract class PdfAS
}
if (pos == null)
{
- // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because y:auto
- pos = new TablePos();
+ // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because
+ // y:auto
+ pos = new TablePos();
}
- //System.out.println("Tablepos="+pos);
- return PdfAS.adjustSignatureTableandCalculatePosition(pdf, pdf_table, pos);
+ // System.out.println("Tablepos="+pos);
+ return PdfAS.adjustSignatureTableandCalculatePosition(pdf, pdf_table, pos);
}
+
/**
* Sets the width of the table according to the layout of the document and
* calculates the y position where the PDFPTable should be placed.
@@ -1045,125 +1080,125 @@ public abstract class PdfAS
public static PositioningInstruction adjustSignatureTableandCalculatePosition(
final byte[] pdf, PdfPTable pdf_table, TablePos pos) throws PDFDocumentException
{
- //first check pageinstruction in TablePos-object
- //new,auto,absolut
- PdfReader reader = readInPdfDocument(pdf);
- //get pages of currentdocument
- int doc_pages = reader.getNumberOfPages();
- int page = doc_pages;
- boolean make_new_page = pos.isNewPage();
- if(!(pos.isNewPage() || pos.isPauto()))
- {
- //we should posit signaturtable on this page
-
- page = pos.getPage();
- //System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages);
- if (page > doc_pages)
- {
- make_new_page = true;
- page = doc_pages;
- //throw new PDFDocumentException(227, "Page number is to big(=" + page+ ") cannot be parsed.");
- }
- }
-
- //getPagedimensions
+ // first check pageinstruction in TablePos-object
+ // new,auto,absolut
+ PdfReader reader = readInPdfDocument(pdf);
+ // get pages of currentdocument
+ int doc_pages = reader.getNumberOfPages();
+ int page = doc_pages;
+ boolean make_new_page = pos.isNewPage();
+ if (!(pos.isNewPage() || pos.isPauto()))
+ {
+ // we should posit signaturtable on this page
+
+ page = pos.getPage();
+ // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages);
+ if (page > doc_pages)
+ {
+ make_new_page = true;
+ page = doc_pages;
+ // throw new PDFDocumentException(227, "Page number is to big(=" + page+
+ // ") cannot be parsed.");
+ }
+ }
+
+ // getPagedimensions
Rectangle psize = reader.getPageSizeWithRotation(page);
int page_rotation = reader.getPageRotation(page);
-
+
float page_width = psize.width();
float page_height = psize.height();
- //now we can calculate x-position
+ // now we can calculate x-position
float pre_pos_x = SIGNATURE_BORDER / 2;
if (!pos.isXauto())
{
- //we do have absolute x
+ // we do have absolute x
pre_pos_x = pos.getPosX();
- }
- //calculate width
- //center
+ }
+ // calculate width
+ // center
float pre_width = page_width - pre_pos_x - pre_pos_x;
if (!pos.isWauto())
{
- //we do have absolute width
+ // we do have absolute width
pre_width = pos.getWidth();
if (pos.isXauto())
- { //center x
+ { // center x
pre_pos_x = (page_width - pre_width) / 2;
}
- }
+ }
final float pos_x = pre_pos_x;
final float width = pre_width;
- //Signatur table dimensions are complete
+ // Signatur table dimensions are complete
pdf_table.setTotalWidth(width);
pdf_table.setLockedWidth(true);
final float table_height = pdf_table.getTotalHeight();
- //now check pos_y
+ // now check pos_y
float pos_y = pos.getPosY();
if (!pos.isYauto())
{
- //we do have y-position too --> all parameters but page ok
- if (make_new_page)
- {
- page++;
- }
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ // we do have y-position too --> all parameters but page ok
+ if (make_new_page)
+ {
+ page++;
+ }
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
}
- //pos_y is auto
+ // pos_y is auto
if (make_new_page)
{
- //ignore footer in new page
- page++;
- pos_y = page_height - SIGNATURE_BORDER / 2;
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
- }
- //up to here no checks have to be made if Tablesize and Pagesize are fit
- //Now we have to getfreespace in page and reguard footerline
+ // ignore footer in new page
+ page++;
+ pos_y = page_height - SIGNATURE_BORDER / 2;
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
+ // up to here no checks have to be made if Tablesize and Pagesize are fit
+ // Now we have to getfreespace in page and reguard footerline
float footer_line = pos.getFooterLine();
- float pre_page_length = PDFUtilities.calculatePageLength(pdf, page-1, page_height-footer_line, page_rotation);
+ float pre_page_length = PDFUtilities.calculatePageLength(pdf, page - 1, page_height - footer_line, page_rotation);
if (pre_page_length == Float.NEGATIVE_INFINITY)
{
- //we do have an empty page or nothing in area above footerline
- pre_page_length = page_height;
- //no text --> SIGNATURE_BORDER
+ // we do have an empty page or nothing in area above footerline
+ pre_page_length = page_height;
+ // no text --> SIGNATURE_BORDER
pos_y = page_height - SIGNATURE_BORDER / 2;
if (pos_y - footer_line <= table_height)
{
make_new_page = true;
if (!pos.isPauto())
- {
- //we have to correct pagenumber
- page = reader.getNumberOfPages();
+ {
+ // we have to correct pagenumber
+ page = reader.getNumberOfPages();
}
page++;
- //no text --> SIGNATURE_BORDER
- pos_y = page_height - SIGNATURE_BORDER / 2;
+ // no text --> SIGNATURE_BORDER
+ pos_y = page_height - SIGNATURE_BORDER / 2;
}
- return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
- }
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
final float page_length = pre_page_length;
- //we do have text take SIGNATURE_MARGIN
+ // we do have text take SIGNATURE_MARGIN
pos_y = page_height - page_length - SIGNATURE_MARGIN;
if (pos_y - footer_line <= table_height)
{
make_new_page = true;
if (!pos.isPauto())
- {
- //we have to correct pagenumber in case of absolute page and not enough space
- page = reader.getNumberOfPages();
+ {
+ // we have to correct pagenumber in case of absolute page and not enough
+ // space
+ page = reader.getNumberOfPages();
}
page++;
- //no text --> SIGNATURE_BORDER
- pos_y = page_height - SIGNATURE_BORDER / 2;
+ // no text --> SIGNATURE_BORDER
+ pos_y = page_height - SIGNATURE_BORDER / 2;
}
return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
}
-
-
-
/**
* Sets the width of the table according to the layout of the document and
* calculates the y position where the PDFPTable should be placed.
+ *
* @deprecated
* @param pdf
* The PDF document.
@@ -1214,6 +1249,7 @@ public abstract class PdfAS
* This algorithm tries to position the table between the end of the text and
* the footer line.
* </p>
+ *
* @deprecated
* @param pdf
* The PDF document.
@@ -1286,14 +1322,14 @@ public abstract class PdfAS
* Parses the TablePos object from a given String with the appropriate format.
*
* @param pos_string
- * The pos string. e.g. x:40.0;y:auto;w:auto;p:1;f:300.0
+ * The pos string. e.g. x:40.0;y:auto;w:auto;p:1;f:300.0
* @return Returns the parsed TablePos object.
* @throws PDFDocumentException
* Thrown, if the String doesn't have the proper format.
*/
public static TablePos parsePositionFromPosString(String pos_string) throws PDFDocumentException
{
- TablePos pos = new TablePos(pos_string);
- return pos;
+ TablePos pos = new TablePos(pos_string);
+ return pos;
}
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java
index 7719818..8d1688c 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java
@@ -17,6 +17,7 @@
*/
package at.knowcenter.wag.egov.egiz.framework;
+import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
@@ -30,6 +31,22 @@ import at.knowcenter.wag.egov.egiz.pdf.TablePos;
public interface Signator
{
/**
+ * Returns the PdfASID of this Connector.
+ *
+ * <p>
+ * This should always return the MY_ID static field of the connector. Dont't
+ * forget to override this.
+ * </p>
+ * <p>
+ * Within connector code always use this method so that code reuse through
+ * derivation can take place correctly.
+ * </p>
+ *
+ * @return Returns the PdfASID of this Connector.
+ */
+ public PdfASID getMyId();
+
+ /**
* This is called before the data is sent to the connector.
*
* @param pdf
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java
index a9bc144..c26055f 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java
@@ -20,9 +20,11 @@ package at.knowcenter.wag.egov.egiz.framework;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.exceptions.SignatorFactoryException;
import at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_0_0;
+import at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_1_0;
import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0;
import at.knowcenter.wag.egov.egiz.framework.signators.DetachedfTextualSignator_1_0_0;
import at.knowcenter.wag.egov.egiz.framework.signators.TextualSignator_1_0_0;
+import at.knowcenter.wag.egov.egiz.framework.signators.TextualSignator_1_1_0;
/**
* This factory creates instances of Signator classes corresponding to the given
@@ -35,42 +37,47 @@ public abstract class SignatorFactory
/**
* The Vendor.
*/
- public static final String VENDOR = "bka.gv.at";
+ public static final String VENDOR = "bka.gv.at"; //$NON-NLS-1$
/**
* The binary Signator algorithm.
*/
- public static final String TYPE_BINARY = "binaer";
+ public static final String TYPE_BINARY = "binaer"; //$NON-NLS-1$
/**
* The textual Signator algorithm.
*/
- public static final String TYPE_TEXTUAL = "text";
+ public static final String TYPE_TEXTUAL = "text"; //$NON-NLS-1$
/**
* This signator is only for testing the framework.
*/
- public static final String TYPE_TEST = "testalgo";
+ public static final String TYPE_TEST = "testalgo"; //$NON-NLS-1$
/**
* This signator is only for testing the framework.
*/
- public static final String TYPE_DETACHED_TEXTUAL = "detachedtext";
+ public static final String TYPE_DETACHED_TEXTUAL = "detachedtext"; //$NON-NLS-1$
/**
* This application's current algorithm versions.
*/
- public static final String VERSION_1_0_0 = "v1.0.0";
+ public static final String VERSION_1_0_0 = "v1.0.0"; //$NON-NLS-1$
+
+ /**
+ * This application's current algorithm versions.
+ */
+ public static final String VERSION_1_1_0 = "v1.1.0"; //$NON-NLS-1$
/**
* The most recent binary algorithm this application provides.
*/
- public static final PdfASID MOST_RECENT_BINARY_SIGNATOR_ID = BinarySignator_1_0_0.MY_ID;
+ public static final PdfASID MOST_RECENT_BINARY_SIGNATOR_ID = BinarySignator_1_1_0.MY_ID;
/**
* The most recent textual algorithm this application provides.
*/
- public static final PdfASID MOST_RECENT_TEXTUAL_SIGNATOR_ID = TextualSignator_1_0_0.MY_ID;
+ public static final PdfASID MOST_RECENT_TEXTUAL_SIGNATOR_ID = TextualSignator_1_1_0.MY_ID;
/**
* The most recent test algorithm this application provides.
@@ -96,7 +103,7 @@ public abstract class SignatorFactory
{
if (!id.getVendor().equals(VENDOR))
{
- throw new SignatorFactoryException("The vendor '" + id.getVendor() + "' is unrecognized by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The vendor '" + id.getVendor() + "' is unrecognized by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
if (id.getType().equals(TYPE_BINARY))
@@ -105,8 +112,12 @@ public abstract class SignatorFactory
{
return new BinarySignator_1_0_0();
}
+ if (id.getVersion().equals(VERSION_1_1_0))
+ {
+ return new BinarySignator_1_1_0();
+ }
- throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
if (id.getType().equals(TYPE_TEXTUAL))
@@ -115,8 +126,12 @@ public abstract class SignatorFactory
{
return new TextualSignator_1_0_0();
}
+ if (id.getVersion().equals(VERSION_1_1_0))
+ {
+ return new TextualSignator_1_1_0();
+ }
- throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
if (id.getType().equals(TYPE_TEST))
@@ -126,7 +141,7 @@ public abstract class SignatorFactory
return new DetachedSignator_1_0_0();
}
- throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
if (id.getType().equals(TYPE_DETACHED_TEXTUAL))
@@ -136,10 +151,10 @@ public abstract class SignatorFactory
return new DetachedfTextualSignator_1_0_0();
}
- throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
- throw new SignatorFactoryException("The type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')");
+ throw new SignatorFactoryException("The type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
@@ -171,7 +186,7 @@ public abstract class SignatorFactory
if (id == null)
{
- throw new SignatorFactoryException("The type '" + signator_type + "' is not supported by this SignatorFactory.");
+ throw new SignatorFactoryException("The type '" + signator_type + "' is not supported by this SignatorFactory."); //$NON-NLS-1$ //$NON-NLS-2$
}
return createSignator(id);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
index 6f167c8..2c5ecf5 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
@@ -35,9 +35,12 @@ import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.ReplaceInfo;
import at.knowcenter.wag.egov.egiz.pdf.StringInfo;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
import at.knowcenter.wag.egov.egiz.sig.SignatureFieldDefinition;
import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObjectHelper;
import at.knowcenter.wag.exactparser.ByteArrayUtils;
import com.lowagie.text.pdf.PdfPTable;
@@ -67,6 +70,14 @@ public class BinarySignator_1_0_0 implements Signator
public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_0_0);
/**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+ /**
* Default constructor.
*/
public BinarySignator_1_0_0()
@@ -86,7 +97,7 @@ public class BinarySignator_1_0_0 implements Signator
SignatureObject signature_object = PdfAS.createSignatureObjectFromType(signature_type);
signature_object.fillValues((char) BinarySignature.LAYOUT_PLACEHOLDER, has_SIG_ID);
- signature_object.setKZ(MY_ID);
+ signature_object.setKZ(getMyId());
PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(signature_object);
@@ -108,8 +119,8 @@ public class BinarySignator_1_0_0 implements Signator
}
IncrementalUpdateInformation iui = BinarySignature.writeIncrementalUpdate(pdf, pdf_table, pi, variable_field_definitions, all_field_definitions);
- String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj";
- byte[] temp_bytes = temp_string.getBytes("US-ASCII");
+ String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$
+ byte[] temp_bytes = temp_string.getBytes("US-ASCII"); //$NON-NLS-1$
int temp_start = ByteArrayUtils.lastIndexOf(iui.signed_pdf, temp_bytes);
byte[] stream_bytes = new byte[] { '>', '>', 's', 't', 'r', 'e', 'a',
'm', 0x0A };
@@ -142,7 +153,7 @@ public class BinarySignator_1_0_0 implements Signator
// byte [] old_signed_pdf = iui.signed_pdf;
iui.signed_pdf = BinarySignature.prepareDataToSign(iui.signed_pdf, iui.byte_ranges);
- iui.document_text = BinarySignature.retrieveSignableTextFromData(iui.signed_pdf, iui.signed_pdf.length); // signed_pdf.length);
+ iui.signature_data = formSignatureData(iui);
return iui;
@@ -160,18 +171,54 @@ public class BinarySignator_1_0_0 implements Signator
public SignResult finishSign(IncrementalUpdateInformation iui) throws PresentableException
{
// PdfAS.prefixID(iui.signed_signature_object, PdfAS.BINARY_ID);
+ fillReplacesWithValues(iui);
+ BinarySignature.replaceCertificate(iui);
+ BinarySignature.replacePlaceholders(iui);
+
+ SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, iui.signed_pdf);
+ return sign_result;
+ }
+
+ /**
+ * Reads the signature values from the signed signature object and fills the
+ * corresponding value in the Replaces array.
+ *
+ * @param iui
+ * The IncrementalUpdateInformation.
+ */
+ protected void fillReplacesWithValues(IncrementalUpdateInformation iui)
+ {
Iterator it = iui.replaces.iterator();
while (it.hasNext())
{
ReplaceInfo ri = (ReplaceInfo) it.next();
+
+ ri.value = SignSignatureObjectHelper.retrieveStringValueFromSignatureObject(iui.signed_signature_object, ri.sfd.field_name);
+ }
+ }
+
+ /**
+ * Forms the SignatureData to be used for signing.
+ *
+ * @param iui
+ * The IncrementalUpdateInformation.
+ * @return Returns the SignatureData to be used for signing.
+ */
+ protected SignatureData formSignatureData(IncrementalUpdateInformation iui)
+ {
+ String document_text = BinarySignature.retrieveSignableTextFromData(iui.signed_pdf, iui.signed_pdf.length); // signed_pdf.length);
- ri.value = iui.signed_signature_object.getSigValue(ri.sfd.field_name);
+ byte[] data;
+ try
+ {
+ data = document_text.getBytes("UTF-8"); //$NON-NLS-1$
}
- BinarySignature.replaceCertificate(iui);
- BinarySignature.replacePlaceholders(iui);
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("Very strange: UTF-8 character encoding not supported.", e); //$NON-NLS-1$
+ }
+ SignatureData signature_data = new SignatureDataImpl(data, PdfAS.PDF_MIME_TYPE);
- SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, iui.signed_pdf);
- return sign_result;
+ return signature_data;
}
-
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java
new file mode 100644
index 0000000..174f0b6
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java
@@ -0,0 +1,66 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: BinarySignator_1_0_0.java,v 1.1 2006/08/25 17:07:35 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.framework.signators;
+
+import at.knowcenter.wag.egov.egiz.PdfAS;
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
+import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
+
+/**
+ * Signs the document binary.
+ *
+ * <p>
+ * This just differs from version 1.0.0 in the fact that the signature data is
+ * the actual binary PDF instead of a Base64 encoding.
+ * </p>
+ *
+ * @see BinarySignator_1_0_0
+ *
+ * @author wprinz
+ */
+public class BinarySignator_1_1_0 extends BinarySignator_1_0_0
+{
+ /**
+ * The Pdf-AS ID of this Signator.
+ */
+ public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_1_0);
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+ /**
+ * Overrides the SignatureData generation of the BinarySignator 1.0.0 so that
+ * the SignatureData is the actual binary PDF instead of a Base64 encoding.
+ *
+ * @see at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_0_0#formSignatureData(at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation)
+ */
+ protected SignatureData formSignatureData(IncrementalUpdateInformation iui)
+ {
+ SignatureData signature_data = new SignatureDataImpl(iui.signed_pdf, PdfAS.PDF_MIME_TYPE);
+
+ return signature_data;
+ }
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
index 88d9338..5d0fd65 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java
@@ -19,15 +19,17 @@ package at.knowcenter.wag.egov.egiz.framework.signators;
import java.io.UnsupportedEncodingException;
+import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
import at.knowcenter.wag.egov.egiz.framework.SignResult;
import at.knowcenter.wag.egov.egiz.framework.Signator;
import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
-import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* This signator is just for testing purposes.
@@ -47,9 +49,17 @@ public class DetachedSignator_1_0_0 implements 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()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+ /**
* The Mime Type.
*/
- public static final String MIME_TYPE = "text/xml";
+ public static final String MIME_TYPE = "text/xml"; //$NON-NLS-1$
/**
* Default constructor.
@@ -71,7 +81,17 @@ public class DetachedSignator_1_0_0 implements Signator
iui.signature_type = signature_type;
iui.pos = pos;
- iui.document_text = BinarySignature.retrieveSignableTextFromData(iui.original_document, iui.original_document.length);
+ String document_text = PdfAS.extractNormalizedTextTextual(pdf);
+ // logger_.debug("signed_text = " + document_text);
+
+ try
+ {
+ iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$
+ }
return iui;
}
@@ -83,8 +103,8 @@ public class DetachedSignator_1_0_0 implements Signator
{
try
{
- String response = iui.signed_signature_object.getRawSignatureResponse();
- byte[] response_bytes = response.getBytes("UTF-8");
+ String response = iui.signed_signature_object.response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
+ byte[] response_bytes = response.getBytes("UTF-8"); //$NON-NLS-1$
SignResult sign_result = new SignResult(MIME_TYPE, response_bytes);
return sign_result;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
index 0de4bc4..93f10ff 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java
@@ -26,12 +26,10 @@ import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
import at.knowcenter.wag.egov.egiz.framework.SignResult;
import at.knowcenter.wag.egov.egiz.framework.Signator;
import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
-import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
-import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
-
-import com.lowagie.text.pdf.PdfPTable;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* Signs a document textually.
@@ -51,12 +49,20 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
/**
* The Mime Type.
*/
- public static final String MIME_TYPE = "text/xml";
+ 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()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
/**
* Default constructor.
@@ -83,8 +89,17 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
iui.signature_type = signature_type;
iui.pos = pos;
- iui.document_text = PdfAS.extractNormalizedTextTextual(pdf);
+ String document_text = PdfAS.extractNormalizedTextTextual(pdf);
// logger_.debug("signed_text = " + document_text);
+
+ try
+ {
+ iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$
+ }
return iui;
}
@@ -96,8 +111,8 @@ public class DetachedfTextualSignator_1_0_0 implements Signator
{
try
{
- String response = iui.signed_signature_object.getRawSignatureResponse();
- byte[] response_bytes = response.getBytes("UTF-8");
+ String response = iui.signed_signature_object.response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
+ byte[] response_bytes = response.getBytes("UTF-8"); //$NON-NLS-1$
SignResult sign_result = new SignResult(MIME_TYPE, response_bytes);
return sign_result;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
index 8cdcf63..0af80d9 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
@@ -17,6 +17,8 @@
*/
package at.knowcenter.wag.egov.egiz.framework.signators;
+import java.io.UnsupportedEncodingException;
+
import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
@@ -27,6 +29,8 @@ import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
import com.lowagie.text.pdf.PdfPTable;
@@ -51,6 +55,14 @@ public class TextualSignator_1_0_0 implements Signator
public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_TEXTUAL, SignatorFactory.VERSION_1_0_0);
/**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+ /**
* Default constructor.
*/
public TextualSignator_1_0_0()
@@ -75,8 +87,17 @@ public class TextualSignator_1_0_0 implements Signator
iui.signature_type = signature_type;
iui.pos = pos;
- iui.document_text = PdfAS.extractNormalizedTextTextual(pdf);
+ String document_text = PdfAS.extractNormalizedTextTextual(pdf);
// logger_.debug("signed_text = " + document_text);
+
+ try
+ {
+ iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), "text/plain", "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$
+ }
return iui;
}
@@ -88,9 +109,18 @@ public class TextualSignator_1_0_0 implements Signator
{
// PdfAS.prefixID(iui.signed_signature_object, PdfAS.TEXT_ID);
- iui.signed_signature_object.setKZ(MY_ID);
+ iui.signed_signature_object.kz = getMyId().toString();
- PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(iui.signed_signature_object);
+ SignatureObject so = new SignatureObject();
+ so.setSigType(iui.signature_type);
+ so.initByType();
+ so.setSignationDate(iui.signed_signature_object.getDate());
+ so.setSignationIssuer(iui.signed_signature_object.getIssuer());
+ so.setSignationSerialNumber(iui.signed_signature_object.getSerialNumber());
+ so.setSignationValue(iui.signed_signature_object.getSignatureValue());
+ so.setSignationIDs(iui.signed_signature_object.getSigID());
+ so.setKZ(getMyId());
+ PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(so);
PositioningInstruction pi = PdfAS.determineTablePositioning(iui.pos, iui.signature_type, iui.original_document, pdf_table);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_1_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_1_0.java
new file mode 100644
index 0000000..8ca8ee0
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_1_0.java
@@ -0,0 +1,45 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: TextualSignator_1_0_0.java,v 1.3 2006/10/31 08:07:50 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.framework.signators;
+
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
+
+/**
+ * Signs a document textually.
+ *
+ * @see TextualSignator_1_0_0
+ *
+ * @author wprinz
+ */
+public class TextualSignator_1_1_0 extends TextualSignator_1_0_0
+{
+ /**
+ * The Pdf-AS ID of this Signator.
+ */
+ public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_TEXTUAL, SignatorFactory.VERSION_1_1_0);
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId()
+ */
+ public PdfASID getMyId()
+ {
+ return MY_ID;
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
index e10061c..52d1d9f 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
@@ -27,6 +27,8 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -1131,11 +1133,11 @@ public abstract class BinarySignature
*/
public static void replaceCertificate(IncrementalUpdateInformation iui) throws PDFDocumentException
{
- X509Cert cert = iui.signed_signature_object.getX509Cert();
- // X509Certificate certificate = cert.getX509Certificate();
+ X509Certificate certificate = iui.signed_signature_object.getX509Certificate();
try
{
- byte[] encoded = cert.getCertString().getBytes("US-ASCII"); // certificate.getEncoded();
+ byte[] der = certificate.getEncoded();
+ byte[] encoded = CodingHelper.encodeBase64(der).getBytes("US-ASCII");
byte[] escaped = Placeholder.escapePDFString(encoded);
if (escaped.length > iui.cert_length)
{
@@ -1143,14 +1145,38 @@ public abstract class BinarySignature
}
System.arraycopy(escaped, 0, iui.signed_pdf, iui.cert_start, escaped.length);
}
- // catch (CertificateEncodingException e)
- // {
- // throw new PDFDocumentException(300, e);
- // }
+ catch (CertificateEncodingException e)
+ {
+ throw new PDFDocumentException(300, e);
+ }
catch (UnsupportedEncodingException e)
{
throw new PDFDocumentException(300, e);
}
+
+ // X509Cert cert = iui.signed_signature_object.getX509Cert();
+ // // X509Certificate certificate = cert.getX509Certificate();
+ // try
+ // {
+ // byte[] encoded = cert.getCertString().getBytes("US-ASCII"); //
+ // certificate.getEncoded();
+ // byte[] escaped = Placeholder.escapePDFString(encoded);
+ // if (escaped.length > iui.cert_length)
+ // {
+ // throw new PlaceholderException("certificate", escaped.length -
+ // iui.cert_length);
+ // }
+ // System.arraycopy(escaped, 0, iui.signed_pdf, iui.cert_start,
+ // escaped.length);
+ // }
+ // // catch (CertificateEncodingException e)
+ // // {
+ // // throw new PDFDocumentException(300, e);
+ // // }
+ // catch (UnsupportedEncodingException e)
+ // {
+ // throw new PDFDocumentException(300, e);
+ // }
}
/**
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java
index cb983cb..76c59c3 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java
@@ -20,7 +20,9 @@ package at.knowcenter.wag.egov.egiz.pdf;
import java.io.Serializable;
import java.util.List;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
/**
* This parameter object contains all useful inforamtion the binary incremental
@@ -105,10 +107,19 @@ public class IncrementalUpdateInformation implements Serializable
*/
public int content_stream_length = -1;
+// /**
+// * The document text for signing.
+// */
+// public String document_text;
/**
- * The document text for signing.
+ * The data to be signed or verified.
+ *
+ * <p>
+ * For text signature this is the document text.
+ * For binary signature this is the PDF document.
+ * </p>
*/
- public String document_text;
+ public SignatureData signature_data = null;
/**
* The SignatureObject containing the variable values after the document text
@@ -117,7 +128,7 @@ public class IncrementalUpdateInformation implements Serializable
* These values have to be filled in.
* </p>
*/
- public SignatureObject signed_signature_object;
+ public SignSignatureObject signed_signature_object;
/**
* The start of the /encodings array.
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java
new file mode 100644
index 0000000..015831e
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java
@@ -0,0 +1,62 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig;
+
+/**
+ * This encapsuilates the content data to be signed or verified.
+ *
+ * <p>
+ * For a text signature this would be the text to be signed or verified. For a
+ * binary signature this would be the PDF to be signed or verified.
+ * </p>
+ *
+ * <p>
+ * This is an abstract reprsenation of data: the binary data, its mime type and
+ * (if appropriate according to the mime type) the charset the data is encoded.
+ * </p>
+ *
+ * @author wprinz
+ */
+public interface SignatureData
+{
+
+ // TODO Performance: make this to an InputStream
+ /**
+ * Returns the data to be signed or verified.
+ *
+ * @return Returns the data to be signed or verified.
+ */
+ public byte[] getData();
+
+ /**
+ * Returns the mime type of the data.
+ *
+ * <p>
+ * E.g. "text/plain" for text data or "application/pdf" for a PDF.
+ * </p>
+ *
+ * @return Returns the mime type of the data.
+ */
+ public String getMimeType();
+
+ /**
+ * Returns the character encoding (charset) of the data if appropriate.
+ *
+ * <p>
+ * This is only appropriate if the mime type suggests that the data contained
+ * in here is textually encoded. Usually text/plain or similar data types will
+ * have a character encoding present.
+ * </p>
+ * <p>
+ * If no character encoding is present, null is returned here.
+ * </p>
+ * <p>
+ * E.g. "UTF-8" is the most common encoding for textual data.
+ * </p>
+ *
+ * @return Returns the character encoding (charset) of the data if
+ * appropriate.
+ */
+ public String getCharacterEncoding();
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java
new file mode 100644
index 0000000..5b9304d
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java
@@ -0,0 +1,101 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig;
+
+import java.io.Serializable;
+
+/**
+ * Generic implementation of the SignatureData interface for being used by
+ * signators and verificators.
+ *
+ * @author wprinz
+ */
+public class SignatureDataImpl implements SignatureData, Serializable
+{
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -8652845539968684408L;
+
+ /**
+ * The signature data.
+ */
+ protected byte[] data = null;
+
+ /**
+ * The mime type of the data.
+ */
+ protected String mimeType = null;
+
+ /**
+ * The character encoding of the data if appropriate, or null if not.
+ */
+ protected String characterEncoding = null;
+
+ /**
+ * Constructor that fills the SignatureData.
+ *
+ * <p>
+ * The charactor encoding is set to null, so this constructor is primarily for
+ * signature data that has no character encoding (e.g. binary data).
+ * </p>
+ *
+ * @param data
+ * The signature data.
+ * @param mime_type
+ * The mime type of the data.
+ */
+ public SignatureDataImpl(byte[] data, String mime_type)
+ {
+ this.data = data;
+ this.mimeType = mime_type;
+ this.characterEncoding = null;
+ }
+
+ /**
+ * Constructor that fills the SignatureData.
+ *
+ * <p>
+ * Use this constructor for textual data as it allows to provide the character
+ * encoding.
+ * </p>
+ *
+ * @param data
+ * The signature data.
+ * @param mime_type
+ * The mime type of the data.
+ * @param character_encoding
+ * The character encoding of the data if appropriate, or null if not.
+ */
+ public SignatureDataImpl(byte[] data, String mime_type, String character_encoding)
+ {
+ this.data = data;
+ this.mimeType = mime_type;
+ this.characterEncoding = character_encoding;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getData()
+ */
+ public byte[] getData()
+ {
+ return this.data;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getMimeType()
+ */
+ public String getMimeType()
+ {
+ return this.mimeType;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getCharacterEncoding()
+ */
+ public String getCharacterEncoding()
+ {
+ return this.characterEncoding;
+ }
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java
new file mode 100644
index 0000000..46a721a
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java
@@ -0,0 +1,105 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.connectors;
+
+/**
+ * This class contains String constants that are frequently used in various
+ * connector templates to fill in the data into the templates.
+ *
+ * @author wprinz
+ */
+public final class TemplateReplaces
+{
+ /**
+ * The placeholder text in the template to be replaced by the keybox
+ * identifier.
+ */
+ public static final String KEYBOX_IDENTIFIER_REPLACE = "KeyboxIdentifierReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the mime type.
+ */
+ public static final String MIME_TYPE_REPLACE = "MimeTypeReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the XML content of
+ * another template.
+ */
+ public static final String XML_CONTENT_REPLACE = "XMLContentReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the cert alg.
+ */
+ public static final String CERT_ALG_REPLACE = "CertAlgReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the digest value of
+ * the signed data.
+ */
+ public static final String DIGEST_VALUE_SIGNED_DATA_REPLACE = "DigestValueSignedDataReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the signature value.
+ */
+ public static final String SIGNATURE_VALUE_REPLACE = "SignatureValueReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the X.509
+ * certificate.
+ */
+ public static final String X509_CERTIFICATE_REPLACE = "X509CertificateReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the signing time.
+ */
+ public static final String SIGNING_TIME_REPLACE = "SigningTimeReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the certificate
+ * digest.
+ */
+ public static final String DIGEST_VALUE_CERTIFICATE_REPLACE = "DigestValueX509CertificateReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the issuer name.
+ */
+ public static final String X509_ISSUER_NAME_REPLACE = "X509IssuerNameReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the serial number.
+ */
+ public static final String X509_SERIAL_NUMBER_REPLACE = "X509SerialNumberReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the signed
+ * properties digest.
+ */
+ public static final String DIGEST_VALUE_SIGNED_PROPERTIES_REPLACE = "DigestValueSignedPropertiesReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the SigDataRef.
+ */
+ public static final String SIG_DATA_REF_REPLACE = "SigDataRefReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the EtsiDataRef.
+ */
+ public static final String ETSI_DATA_REF_REPLACE = "EtsiDataRefReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the SigDataObjURI.
+ */
+ public static final String SIG_DATA_OBJ_URI_REPLACE = "SigDataObjURIReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the EtsiDataObjURI.
+ */
+ public static final String ETSI_DATA_OBJ_URI_REPLACE = "EtsiDataObjURIReplace"; //$NON-NLS-1$
+
+ /**
+ * The placeholder text in the template to be replaced by the SigId.
+ */
+ public static final String SIG_ID_REPLACE = "SigIdReplace"; //$NON-NLS-1$
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java
new file mode 100644
index 0000000..321287d
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java
@@ -0,0 +1,119 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+
+/**
+ * Helper class with methods that use the Apache Https Client to send HTTP
+ * requests.
+ *
+ * @author wprinz
+ */
+public final class BKUPostConnection
+{
+ /**
+ * The response Properties key that identifies the response string.
+ */
+ public static final String RESPONSE_STRING_KEY = "response_string"; //$NON-NLS-1$
+
+ /**
+ * The response Properties key that identifies the BKU Server header.
+ */
+ public static final String BKU_SERVER_HEADER_KEY = "BKU-Server-Header"; //$NON-NLS-1$
+
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(BKUPostConnection.class);
+
+ /**
+ * Sends a multipart/form-data HTTP Post request to the given URL.
+ *
+ * @param url The url the request is directed to.
+ * @param request The request XML, which will be the UTF-8 text/xml first part of the message.
+ * @param data The binary second part of the message.
+ * @return Returns the response properties which, among others, contain the response String.
+ * @throws HttpException
+ * @throws IOException
+ */
+ public static Properties doPostRequestMultipart(String url, String request,
+ SignatureData data) throws HttpException, IOException
+ {
+ log.debug("doPostRequestMultipart:"); //$NON-NLS-1$
+
+ StringPart xmlpart = new StringPart("XmlRequest", request, "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$
+
+ // TODO this is a BUG in BKU that doesn't allow the Content-Type header
+ xmlpart.setContentType(null);
+ xmlpart.setTransferEncoding(null);
+ // BKU 2.7.4 can't handle the Content-Type Header for the XML
+ // xmlpart.setContentType("text/xml");
+ // xmlpart.setTransferEncoding(null);
+
+ String filename = data.getMimeType().equals("application/pdf") ? "myfile.pdf" : "myfile.txt"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ ByteArrayPartSource baps = new ByteArrayPartSource(filename, data.getData());
+ FilePart filepart = new FilePart("fileupload", baps); //$NON-NLS-1$
+ filepart.setContentType(data.getMimeType());
+ // this is optional
+ // filepart.setCharSet(data.getCharacterEncoding());
+
+ Part[] parts = { xmlpart, filepart };
+
+ HttpMethodParams method_params = new HttpMethodParams();
+ method_params.setContentCharset("UTF-8"); //$NON-NLS-1$
+
+ PostMethod post_method = new PostMethod(url);
+ post_method.setParams(method_params);
+
+ MultipartRequestEntity mprqe = new MultipartRequestEntity(parts, post_method.getParams());
+ post_method.setRequestEntity(mprqe);
+
+ HttpClient http_client = new HttpClient();
+ int method_response = http_client.executeMethod(post_method);
+ log.debug("method_response = " + method_response); //$NON-NLS-1$
+
+ Properties response_properties = new Properties();
+
+ if (log.isDebugEnabled())
+ {
+ Header[] response_headers = post_method.getResponseHeaders();
+ for (int i = 0; i < response_headers.length; i++)
+ {
+ log.debug(" response_header[" + i + "]: name = " + response_headers[i].getName() + ", value = " + response_headers[i].getValue()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ }
+ Header server_header = post_method.getResponseHeader("Server"); //$NON-NLS-1$
+ response_properties.setProperty(BKU_SERVER_HEADER_KEY, server_header.getValue());
+
+ log.debug(post_method.getResponseCharSet());
+ if (!post_method.getResponseCharSet().equals("UTF-8")) //$NON-NLS-1$
+ {
+ log.warn("BKU response charset is not UTF-8!"); //$NON-NLS-1$
+ }
+ String response_string = post_method.getResponseBodyAsString();
+
+ response_properties.setProperty(RESPONSE_STRING_KEY, response_string);
+
+ log.debug("doPostRequestMultipart finished."); //$NON-NLS-1$
+ return response_properties;
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedMultipartBKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedMultipartBKUConnector.java
new file mode 100644
index 0000000..b30c9e2
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedMultipartBKUConnector.java
@@ -0,0 +1,1125 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
+import at.knowcenter.wag.egov.egiz.sig.X509Cert;
+import at.knowcenter.wag.egov.egiz.sig.connectors.TemplateReplaces;
+import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
+import at.knowcenter.wag.egov.egiz.tools.FileHelper;
+
+/**
+ * Connects to the BKU using the detached multipart/formdata requests.
+ *
+ * <p>
+ * This feature is available since BKU version 2.7.4.
+ * </p>
+ *
+ * @author wprinz
+ */
+public class DetachedMultipartBKUConnector
+{
+ /**
+ * The SIG_ID prefix.
+ */
+ public static final String SIG_ID_PREFIX = "etsi-bku-detached@"; //$NON-NLS-1$
+
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(DetachedMultipartBKUConnector.class);
+
+ /**
+ * The environemnt configuration of this connector containing templates and
+ * other configurable elements.
+ */
+ protected Environment environment = null;
+
+ /**
+ * Constructor that builds the configuration environment for this connector
+ * according to the given profile.
+ *
+ * <p>
+ * If confuguration parameters are not defined on that profile, the default
+ * parameters defined in the configuration are used.
+ * </p>
+ *
+ * @param profile
+ * The profile from which the Environment should be assembled.
+ * @throws SettingsException
+ * f.e.
+ * @throws SignatureException
+ * f.e.
+ */
+ public DetachedMultipartBKUConnector(String profile) throws SignatureException, SettingsException
+ {
+ this.environment = new Environment(profile);
+ }
+
+ /**
+ * 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.
+ * @throws SignatureException
+ * f.e.
+ */
+ protected String prepareSignRequestDetached(SignatureData data) throws SignatureException
+ {
+ log.debug("prepareSignRequestDetached:"); //$NON-NLS-1$
+
+ String sign_request_template = this.environment.getSignRequestTemplate();
+
+ String sign_keybox_identifier = this.environment.getSignKeyboxIdentifier();
+ String mime_type = data.getMimeType();
+ if (log.isDebugEnabled())
+ {
+ log.debug("signn keybox identifier = " + sign_keybox_identifier); //$NON-NLS-1$
+ log.debug("mime type = " + mime_type); //$NON-NLS-1$
+ }
+
+ String sign_request_xml = sign_request_template.replace(TemplateReplaces.KEYBOX_IDENTIFIER_REPLACE, sign_keybox_identifier);
+ sign_request_xml = sign_request_xml.replace(TemplateReplaces.MIME_TYPE_REPLACE, mime_type);
+
+ log.debug("prepareSignRequestDetached finished."); //$NON-NLS-1$
+ return sign_request_xml;
+ }
+
+ /**
+ * Analyzes the sign response xml and extracts the signature data.
+ *
+ * @param response_properties
+ * The response properties containing the response String and
+ * transport related information.
+ * @return Returns the extracted data encapsulated in a SignatureObject.
+ * @throws SignatureException
+ * f.e.
+ */
+ public SignSignatureObject analyzeSignResponse(Properties response_properties) throws SignatureException
+ {
+ log.debug("analyzeSignResponse:"); //$NON-NLS-1$
+
+ String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
+
+ // TODO debug
+ try
+ {
+ FileOutputStream fos = new FileOutputStream("C:\\wprinz\\Filer\\egiz2\\sign_response.utf8.xml"); //$NON-NLS-1$
+ OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); //$NON-NLS-1$
+ osw.write(response_string);
+ osw.close();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ }
+
+ checkResponseForError(response_string);
+
+ SignSignatureObject so = parseCreateXMLResponse(response_string);
+
+ log.debug("analyzeSignResponse finished."); //$NON-NLS-1$
+ return so;
+ }
+
+ /**
+ * Checks the response xml for an error description and if found throws an
+ * appropriate exception.
+ *
+ * @param response_string
+ * The response xml.
+ * @throws SignatureException
+ * f.e.
+ */
+ protected void checkResponseForError(String response_string) throws SignatureException
+ {
+ Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>"); //$NON-NLS-1$
+ Pattern erc_p_e = Pattern.compile("</[\\w]*:?ErrorCode>"); //$NON-NLS-1$
+ Matcher erc_m_s = erc_p_s.matcher(response_string);
+ Matcher erc_m_e = erc_p_e.matcher(response_string);
+
+ if (erc_m_s.find() && erc_m_e.find())
+ {
+ log.error("Found error in response: " + response_string); //$NON-NLS-1$
+
+ Pattern erm_p_s = Pattern.compile("<[\\w]*:?Info>"); //$NON-NLS-1$
+ Pattern erm_p_e = Pattern.compile("</[\\w]*:?Info>"); //$NON-NLS-1$
+ Matcher erm_m_s = erm_p_s.matcher(response_string);
+ Matcher erm_m_e = erm_p_e.matcher(response_string);
+ SignatureException se = new SignatureException(0, "BKUSigExc"); //$NON-NLS-1$
+ String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start());
+ se.setExternalErrorCode(error_code);
+ if (erm_m_s.find() && erm_m_e.find())
+ {
+ String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start());
+ se.setExternalErrorMessage(error_mess);
+ }
+ throw se;
+ }
+ }
+
+ /**
+ * This method parses the BKU-Response string.
+ *
+ * <p>
+ * It separates the SignatureValue, X509IssuerName, SigningTime,
+ * X509SerialNumber, X509Certificate, CertDigest, DigestValue and the
+ * signation id-s. If the X509Certificate is extracted it would be stored in
+ * the certificates directory.
+ * </p>
+ *
+ * @param xmlResponse
+ * The response string.
+ * @return Returns the parsed signature object holding the data.
+ *
+ * @throws SignatureException
+ * ErrorCode (303, 304)
+ * @see SignatureObject
+ * @see CodingHelper
+ * @see X509Cert
+ */
+ private SignSignatureObject parseCreateXMLResponse(
+ String xmlResponse) throws SignatureException
+ {
+ Pattern sig_val_p_s = Pattern.compile("<[\\w]*:?SignatureValue>"); //$NON-NLS-1$
+ Pattern sig_val_p_e = Pattern.compile("</[\\w]*:?SignatureValue>"); //$NON-NLS-1$
+ Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>"); //$NON-NLS-1$
+ Pattern iss_nam_p_e = Pattern.compile("</[\\w]*:?X509IssuerName>"); //$NON-NLS-1$
+ Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>"); //$NON-NLS-1$
+ Pattern sig_tim_p_e = Pattern.compile("</[\\w]*:?SigningTime>"); //$NON-NLS-1$
+ Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>"); //$NON-NLS-1$
+ Pattern ser_num_p_e = Pattern.compile("</[\\w]*:?X509SerialNumber>"); //$NON-NLS-1$
+ Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>"); //$NON-NLS-1$
+ Pattern sig_cer_p_e = Pattern.compile("</[\\w]*:?X509Certificate>"); //$NON-NLS-1$
+
+ // Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>");
+ // //$NON-NLS-1$
+ // Pattern sig_cer_d_p_e = Pattern.compile("</[\\w]*:?CertDigest>");
+ // //$NON-NLS-1$
+ // Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>");
+ // //$NON-NLS-1$
+ // Pattern dig_val_p_e = Pattern.compile("</[\\w]*:?DigestValue>");
+ // //$NON-NLS-1$
+
+ Matcher sig_val_m_s = sig_val_p_s.matcher(xmlResponse);
+ Matcher sig_val_m_e = sig_val_p_e.matcher(xmlResponse);
+ Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+ Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+ Matcher sig_tim_m_s = sig_tim_p_s.matcher(xmlResponse);
+ Matcher sig_tim_m_e = sig_tim_p_e.matcher(xmlResponse);
+ Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+ Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+ Matcher sig_cer_m_s = sig_cer_p_s.matcher(xmlResponse);
+ Matcher sig_cer_m_e = sig_cer_p_e.matcher(xmlResponse);
+
+ // Matcher sig_cer_d_m_s = sig_cer_d_p_s.matcher(xmlResponse);
+ // Matcher sig_cer_d_m_e = sig_cer_d_p_e.matcher(xmlResponse);
+ // Matcher dig_val_m_s = dig_val_p_s.matcher(xmlResponse);
+ // Matcher dig_val_m_e = dig_val_p_e.matcher(xmlResponse);
+
+ // SignatureValue
+ String sig_val = null;
+ if (sig_val_m_s.find() && sig_val_m_e.find())
+ {
+ sig_val = removeAllWhitespace(xmlResponse.substring(sig_val_m_s.end(), sig_val_m_e.start()));
+ }
+ log.debug("sig_val = " + sig_val); //$NON-NLS-1$
+
+ // X509IssuerName
+ String iss_nam = null;
+ if (iss_nam_m_s.find() && iss_nam_m_e.find())
+ {
+ iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+ }
+ log.debug("iss_nam = " + iss_nam); //$NON-NLS-1$
+
+ // X509SerialNumber
+ String ser_num = null;
+ if (ser_num_m_s.find() && ser_num_m_e.find())
+ {
+ ser_num = removeAllWhitespace(xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start()));
+ }
+ log.debug("ser_num = " + ser_num); //$NON-NLS-1$
+
+ // SigningTime
+ String sig_tim = null;
+ if (sig_tim_m_s.find() && sig_tim_m_e.find())
+ {
+ sig_tim = xmlResponse.substring(sig_tim_m_s.end(), sig_tim_m_e.start());
+ }
+ log.debug("sig_tim = " + sig_tim); //$NON-NLS-1$
+
+ // CertDigest
+ // if (sig_cer_d_m_s.find() && sig_cer_d_m_e.find())
+ // {
+ // String cert_digest = xmlResponse.substring(sig_cer_d_m_s.end(),
+ // sig_cer_d_m_e.start());
+ // if (dig_val_m_s.find() && dig_val_m_e.find())
+ // {
+ // sig_dig = cert_digest.substring(dig_val_m_s.end(), dig_val_m_e.start());
+ // //sigObj.setX509CertificateDigest(sig_dig);
+ // }
+ // }
+
+ // X509Certificate
+ X509Certificate cert = null;
+ if (sig_cer_m_s.find() && sig_cer_m_e.find())
+ {
+ String sig_cer = removeAllWhitespace(xmlResponse.substring(sig_cer_m_s.end(), sig_cer_m_e.start()));
+
+ try
+ {
+ byte[] der = CodingHelper.decodeBase64(sig_cer);
+ ByteArrayInputStream bais = new ByteArrayInputStream(der);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
+ cert = (X509Certificate) cf.generateCertificate(bais);
+ bais.close();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ log.error(e);
+ throw new SignatureException(300, e);
+ }
+ catch (CertificateException e)
+ {
+ log.error(e);
+ throw new SignatureException(300, e);
+ }
+ catch (IOException e)
+ {
+ log.error(e);
+ throw new SignatureException(300, e);
+ }
+ }
+ log.debug("X509Certificate = " + cert); //$NON-NLS-1$
+
+ if (log.isDebugEnabled())
+ {
+
+ String cert_iss = cert.getIssuerDN().getName();
+ log.debug("certificate's issuer = " + cert_iss); //$NON-NLS-1$
+ log.debug("response's issuer = " + iss_nam); //$NON-NLS-1$
+ log.debug("issuer matches = " + cert_iss.equals(iss_nam)); //$NON-NLS-1$
+ log.debug("ser number matches = " + cert.getSerialNumber().toString().equals(ser_num)); //$NON-NLS-1$
+ }
+
+ // extract Subject Name from X509Certificate
+ // if (sig_cer_m_s.find() && sig_cer_m_e.find())
+ // {
+ // sig_cer = xmlResponse.substring(sig_cer_m_s.end(), sig_cer_m_e.start());
+ // sig_cer = sig_cer.replaceAll("\\s", "");
+ // //sigObj.setX509Certificate(sig_cer);
+ // X509Cert cert = X509Cert.initByString(sig_cer);
+ // if (cert.isX509Cert())
+ // {
+ // //sigObj.setX509Certificate(cert.getCertString());
+ // String serial_num = cert.getSerialNumber();
+ // String subject_name = cert.getSubjectName();
+ // if (!ser_num.equals(serial_num))
+ // {
+ // SignatureException se = new SignatureException(303, "Serialnumber of
+ // certificate and tag X509SerialNumber differs!");
+ // throw se;
+ // }
+ // //sigObj.setSignationName(subject_name);
+ // }
+ // }
+
+ // extract Signature Id's
+ String[] ids = new String[5];
+ ids[0] = extractId(xmlResponse, "signature-"); //$NON-NLS-1$
+ ids[1] = extractId(xmlResponse, "signed-data-reference-"); //$NON-NLS-1$
+ 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 final_ids = formatSigIds(ids);
+
+ SignSignatureObject so = new SignSignatureObject();
+ so.date = sig_tim;
+ so.issuer = iss_nam;
+ so.signatureValue = sig_val;
+ so.x509Certificate = cert;
+
+ so.id = final_ids;
+
+ return so;
+ }
+
+ /**
+ * Removes all whitespaces ("\\s") from the String.
+ *
+ * @param str
+ * The String.
+ * @return The String with all whitespaces removed.
+ */
+ protected static String removeAllWhitespace(String str)
+ {
+ return str.replaceAll("\\s", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * 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
+ * the id-key
+ * @return the value of the given key in the text
+ */
+ private String extractId(String text, String name)
+ {
+ String id = null;
+ int start_idx = text.indexOf(name) + name.length();
+ int end_idx = text.indexOf("\"", start_idx); //$NON-NLS-1$
+
+ final int quot_end_idx = end_idx;
+ final int squot_end_idx = text.indexOf("'", start_idx); //$NON-NLS-1$
+ end_idx = Math.min(quot_end_idx, squot_end_idx);
+ id = text.substring(start_idx, end_idx);
+ log.info("extract id:" + name + id); //$NON-NLS-1$
+ if (log.isDebugEnabled())
+ {
+ log.debug("extract id:" + name + id); //$NON-NLS-1$
+ }
+ return id;
+ }
+
+ protected String formatSigIds(String[] sigIds) throws SignatureException
+ {
+ // ids algorithm:
+ String join = ""; //$NON-NLS-1$
+ String base = null;
+ for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
+ {
+ String id = sigIds[arr_idx];
+ if (log.isDebugEnabled())
+ {
+ log.debug("Set BKU id:" + id); //$NON-NLS-1$
+ }
+ int id_idx = id.lastIndexOf("-"); //$NON-NLS-1$
+ if (arr_idx == 0)
+ {
+ base = id.substring(0, id_idx);
+ }
+ String cur_id = id.substring(id_idx + 1);
+ if (cur_id.equalsIgnoreCase("")) //$NON-NLS-1$
+ {
+ cur_id = "0"; //$NON-NLS-1$
+ }
+
+ join += "-" + cur_id; //$NON-NLS-1$
+ }
+ String ids = base + "@" + join.substring(1); //$NON-NLS-1$
+ String final_ids = SIG_ID_PREFIX + ids;
+ return final_ids;
+ }
+
+ public static String[] parseSigIds(String sig_ids)
+ {
+ if (sig_ids == null || sig_ids.length() == 0)
+ {
+ return null;
+ }
+
+ // int index = sig_ids.indexOf(PdfAS.IDS);
+ // if (index < 0)
+ // {
+ // return null;
+ // }
+ // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
+ //
+ // if (sig_ids == null || sig_ids.length() == 0)
+ // {
+ // return null;
+ // }
+
+ String[] ids_str = sig_ids.split("@");
+
+ String etsi_string = null;
+ if (ids_str.length == 3)
+ {
+ etsi_string = ids_str[0];
+ String[] rest_ids = new String[] { ids_str[1], ids_str[2] };
+ ids_str = rest_ids;
+ }
+
+ String base = ids_str[0];
+ String[] ids = ids_str[1].split("-");
+ String[] real_ids = new String[6]; // the last one contains the etsi string
+ real_ids[0] = base + "-" + ids[0];
+ real_ids[1] = "0-" + base + "-" + ids[1];
+ real_ids[2] = "0-" + base + "-" + ids[2];
+ real_ids[3] = "0-" + base + "-" + ids[3];
+ real_ids[4] = "0-" + base + "-" + ids[4];
+ real_ids[5] = etsi_string;
+
+ if (log.isDebugEnabled())
+ {
+ for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
+ {
+ log.debug("real_ids[" + id_idx + "] = " + real_ids[id_idx]);
+ }
+ }
+
+ return real_ids;
+ }
+
+ /**
+ * Sends the request and data to the given URL.
+ *
+ * <p>
+ * This method mainly handles communication exceptions. The actual send work
+ * is done by doPostRequestMultipart.
+ * </p>
+ *
+ * @see BKUPostConnection#doPostRequestMultipart(String, String, SignatureData)
+ *
+ * @param url
+ * The URL to send the request to.
+ * @param request_string
+ * The request XML.
+ * @param data
+ * The data.
+ * @return Returns the response properties containing among others the
+ * response XML.
+ * @throws SignatureException
+ * f.e.
+ */
+ protected Properties sendRequest(String url, String request_string,
+ SignatureData data) throws SignatureException
+ {
+ try
+ {
+ Properties response_properties = BKUPostConnection.doPostRequestMultipart(url, request_string, data);
+ return response_properties;
+ }
+ catch (Exception e)
+ {
+ SignatureException se = new SignatureException(320, e);
+ throw se;
+ }
+ }
+
+ /**
+ * Performs a sign.
+ *
+ * @param data
+ * The data to be signed.
+ * @return Returns the signature object containing the signature data.
+ * @throws SignatureException
+ * f.e.
+ */
+ public SignSignatureObject doSign(SignatureData data) throws SignatureException
+ {
+ log.debug("doSign:"); //$NON-NLS-1$
+
+ String sign_request_xml = prepareSignRequestDetached(data);
+ log.debug("sign_request_xml = " + sign_request_xml); //$NON-NLS-1$
+
+ String url = this.environment.getSignURL();
+ Properties response_properties = sendRequest(url, sign_request_xml, data);
+
+ try
+ {
+ FileOutputStream fos = new FileOutputStream("C:\\wprinz\\Filer\\egiz2\\sign_response.utf8.xml"); //$NON-NLS-1$
+ fos.write(response_properties.getProperty("response_string").getBytes("UTF-8")); //$NON-NLS-1$ //$NON-NLS-2$
+ fos.close();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ }
+
+ SignSignatureObject sso = analyzeSignResponse(response_properties);
+
+ // TODO this could be made more generic
+ sso.response_properties = response_properties;
+
+ log.debug("doSign finished."); //$NON-NLS-1$
+ return sso;
+ }
+
+ /**
+ * Performs a verification.
+ *
+ * @param data
+ * The data to be verified.
+ * @param so
+ * The signature object with the signature information.
+ * @return Returns the SignatureResponse with the result of the verification.
+ * @throws SignatureException
+ * f.e.
+ */
+ public SignatureResponse doVerify(SignatureData data, SignSignatureObject so) throws SignatureException
+ {
+ log.debug("doVerify:"); //$NON-NLS-1$
+
+ String verify_request_xml = prepareVerifyRequestDetached(data, so);
+ log.debug("verify_request_xml = " + verify_request_xml); //$NON-NLS-1$
+
+ try
+ {
+ FileOutputStream fos = new FileOutputStream("C:\\wprinz\\Filer\\egiz2\\verify_request.utf8.xml"); //$NON-NLS-1$
+ fos.write(verify_request_xml.getBytes("UTF-8")); //$NON-NLS-1$
+ fos.close();
+ }
+ catch (Exception e)
+ {
+ log.error(e);
+ }
+
+ String url = this.environment.getVerifyURL();
+ Properties response_properties = sendRequest(url, verify_request_xml, data);
+
+ SignatureResponse signature_response = analyzeVerifyResponse(response_properties);
+
+ log.debug("doVerify finished."); //$NON-NLS-1$
+ return signature_response;
+ }
+
+ /**
+ * Prepares the verify request xml to be sent using the verify request
+ * template.
+ *
+ * @param data
+ * The SignatureData.
+ * @param so
+ * The signature information object.
+ * @return Returns the verify request xml to be sent.
+ * @throws SignatureException
+ * f.e.
+ */
+ public String prepareVerifyRequestDetached(SignatureData data,
+ SignSignatureObject so) throws SignatureException
+ {
+ String verify_request_template = this.environment.getVerifyRequestTemplate();
+
+ String xml_content = null;
+ // TODO implement MOA
+ // if (sigObject.isMOASigned())
+ // {
+ // MOAConnector moa_conn = new MOAConnector();
+ // // get the MOA-template
+ // verify_template_str = moa_conn.getVerifyTemplate(normalizedText,
+ // sigObject);
+ // }
+ // else
+ // {
+ // get the BKU-template
+ xml_content = prepareXMLContent(data, so);
+ // }
+
+ String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
+
+ return verify_request_xml;
+ }
+
+ /**
+ * Prepares the XML content the holds the actual signature data.
+ *
+ * <p>
+ * This strongly rebuilds the XML content as retuned from a sign request.
+ * </p>
+ *
+ * @param data
+ * The data.
+ * @param so
+ * The signature object containing the signature information.
+ * @return Returns the XML content.
+ * @throws SignatureException
+ * f.e.
+ */
+ public String prepareXMLContent(SignatureData data, SignSignatureObject so) throws SignatureException
+ {
+ log.debug("prepareXMLContent:"); //$NON-NLS-1$
+ try
+ {
+
+ String verify_template = this.environment.getVerifyTemplate();
+
+ String ids_string = so.getSigID();
+ String[] ids = SignatureObject.parseSigIds(ids_string);
+
+ X509Certificate cert = so.getX509Certificate();
+ String cert_alg = this.environment.getCertAlgEcdsa();
+ if (cert.getPublicKey().getAlgorithm().indexOf("RSA") >= 0) //$NON-NLS-1$
+ {
+ cert_alg = this.environment.getCertAlgRsa();
+ }
+
+ // cert alg replace
+ String verify_xml = verify_template.replace(TemplateReplaces.CERT_ALG_REPLACE, cert_alg);
+
+ // data digest replace
+ {
+ byte[] data_value = data.getData();
+ byte[] data_value_hash = CodingHelper.buildDigest(data_value);
+ String object_data_hash = CodingHelper.encodeBase64(data_value_hash);
+
+ verify_xml = verify_xml.replace(TemplateReplaces.DIGEST_VALUE_SIGNED_DATA_REPLACE, object_data_hash);
+ }
+
+ // SIG id replaces
+ verify_xml = verify_xml.replaceAll(TemplateReplaces.SIG_DATA_REF_REPLACE, ids[1]);
+ verify_xml = verify_xml.replaceAll(TemplateReplaces.ETSI_DATA_REF_REPLACE, ids[3]);
+ verify_xml = verify_xml.replaceAll(TemplateReplaces.SIG_DATA_OBJ_URI_REPLACE, ids[2]);
+
+ verify_xml = verify_xml.replace(TemplateReplaces.SIGNATURE_VALUE_REPLACE, so.getSignatureValue());
+
+ // X.509 Certificate replace
+ byte[] der = cert.getEncoded();
+ byte[] cert_hash = CodingHelper.buildDigest(der);
+ String certDigest = CodingHelper.encodeBase64(cert_hash);
+ String x509_cert_string = CodingHelper.encodeBase64(der);
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_CERTIFICATE_REPLACE, x509_cert_string);
+
+ // Qualified Properties replaces
+ verify_xml = verify_xml.replaceAll(TemplateReplaces.ETSI_DATA_OBJ_URI_REPLACE, ids[4]);
+ 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());
+ 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());
+
+ // Signed Properties hash
+ {
+ final String ETSI_SIGNED_PROPERTIES_START_TAG = "<etsi:SignedProperties"; //$NON-NLS-1$
+ final String ETSI_SIGNED_PROPERTIES_END_TAG = "</etsi:SignedProperties>"; //$NON-NLS-1$
+
+ final int hash_start = verify_xml.indexOf(ETSI_SIGNED_PROPERTIES_START_TAG);
+ assert hash_start >= 0;
+ final int hash_end = verify_xml.indexOf(ETSI_SIGNED_PROPERTIES_END_TAG, hash_start) + ETSI_SIGNED_PROPERTIES_END_TAG.length();
+ assert hash_end - ETSI_SIGNED_PROPERTIES_END_TAG.length() >= 0;
+ assert hash_end > hash_start;
+
+ final String string_to_be_hashed = verify_xml.substring(hash_start, hash_end);
+ log.debug("etsi:SignedProperties string to be hashed: " + string_to_be_hashed); //$NON-NLS-1$
+
+ final byte[] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8"); //$NON-NLS-1$
+ byte[] sig_prop_code = CodingHelper.buildDigest(bytes_to_be_hashed);
+ 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."); //$NON-NLS-1$
+ return verify_xml;
+ }
+ catch (Exception e)
+ {
+ log.debug(e);
+ throw new SignatureException(310, e);
+ }
+ }
+
+ /**
+ * Analyzes the verify response string.
+ *
+ * @param response_properties
+ * The response properties containing the response XML.
+ * @return Returns the SignatureResponse containing the verification result.
+ * @throws SignatureException
+ * f.e.
+ */
+ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException
+ {
+ log.debug("analyzeVerifyResponse:"); //$NON-NLS-1$
+
+ String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
+
+ checkResponseForError(response_string);
+
+ SignatureResponse signature_response = parseVerifyXMLResponse(response_string);
+
+ log.debug("analyzeVerifyResponse finished."); //$NON-NLS-1$
+ return signature_response;
+ }
+
+ /**
+ * 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
+ * @see SignatureResponse
+ */
+ private SignatureResponse parseVerifyXMLResponse(String xmlResponse)
+ {
+ log.debug("parseVerifyXMLResponse:"); //$NON-NLS-1$
+
+ Pattern sub_nam_p_s = Pattern.compile("<dsig:X509SubjectName>"); //$NON-NLS-1$
+ Pattern sub_nam_p_e = Pattern.compile("</dsig:X509SubjectName>"); //$NON-NLS-1$
+ Pattern iss_nam_p_s = Pattern.compile("<dsig:X509IssuerName>"); //$NON-NLS-1$
+ Pattern iss_nam_p_e = Pattern.compile("</dsig:X509IssuerName>"); //$NON-NLS-1$
+ Pattern ser_num_p_s = Pattern.compile("<dsig:X509SerialNumber>"); //$NON-NLS-1$
+ Pattern ser_num_p_e = Pattern.compile("</dsig:X509SerialNumber>"); //$NON-NLS-1$
+
+ Pattern sig_chk_p_s = Pattern.compile("<sl:SignatureCheck>"); //$NON-NLS-1$
+ Pattern sig_chk_p_e = Pattern.compile("</sl:SignatureCheck>"); //$NON-NLS-1$
+ Pattern man_chk_p_s = Pattern.compile("<sl:SignatureManifestCheck>"); //$NON-NLS-1$
+ Pattern man_chk_p_e = Pattern.compile("</sl:SignatureManifestCheck>"); //$NON-NLS-1$
+ Pattern cer_chk_p_s = Pattern.compile("<sl:CertificateCheck>"); //$NON-NLS-1$
+ Pattern cer_chk_p_e = Pattern.compile("</sl:CertificateCheck>"); //$NON-NLS-1$
+
+ // [tknall] start qualified certificate
+ Pattern cert_qualified_p = Pattern.compile("<sl:QualifiedCertificate/>"); //$NON-NLS-1$
+ Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse);
+ // [tknall] stop qualified certificate
+
+ Pattern code_p_s = Pattern.compile("<sl:Code>"); //$NON-NLS-1$
+ Pattern code_p_e = Pattern.compile("</sl:Code>"); //$NON-NLS-1$
+ Pattern info_p_s = Pattern.compile("<sl:Info>"); //$NON-NLS-1$
+ Pattern info_p_e = Pattern.compile("</sl:Info>"); //$NON-NLS-1$
+
+ Pattern cert_p_s = Pattern.compile("<dsig:X509Certificate>"); //$NON-NLS-1$
+ Pattern cert_p_e = Pattern.compile("</dsig:X509Certificate>"); //$NON-NLS-1$
+
+ Matcher sub_nam_m_s = sub_nam_p_s.matcher(xmlResponse);
+ Matcher sub_nam_m_e = sub_nam_p_e.matcher(xmlResponse);
+ Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+ Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+ Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+ Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+
+ Matcher sig_chk_m_s = sig_chk_p_s.matcher(xmlResponse);
+ Matcher sig_chk_m_e = sig_chk_p_e.matcher(xmlResponse);
+ Matcher man_chk_m_s = man_chk_p_s.matcher(xmlResponse);
+ Matcher man_chk_m_e = man_chk_p_e.matcher(xmlResponse);
+ Matcher cer_chk_m_s = cer_chk_p_s.matcher(xmlResponse);
+ Matcher cer_chk_m_e = cer_chk_p_e.matcher(xmlResponse);
+
+ Matcher cert_m_s = cert_p_s.matcher(xmlResponse);
+ Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
+
+ SignatureResponse sig_res = new SignatureResponse();
+
+ // [tknall] start qualified certificate
+ sig_res.setQualifiedCertificate(cert_qualified_m.find());
+ // [tknall] stop qualified certificate
+
+ if (sub_nam_m_s.find() && sub_nam_m_e.find())
+ {
+ String sub_nam = xmlResponse.substring(sub_nam_m_s.end(), sub_nam_m_e.start());
+ sig_res.setX509SubjectName(sub_nam);
+ }
+ if (iss_nam_m_s.find() && iss_nam_m_e.find())
+ {
+ String iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+ sig_res.setX509IssuerName(iss_nam);
+ }
+ if (ser_num_m_s.find() && ser_num_m_e.find())
+ {
+ String ser_num = xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start());
+ sig_res.setX509SerialNumber(ser_num);
+ }
+ if (sig_chk_m_s.find() && sig_chk_m_e.find())
+ {
+ String sig_chk = xmlResponse.substring(sig_chk_m_s.end(), sig_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(sig_chk);
+ Matcher code_m_e = code_p_e.matcher(sig_chk);
+ Matcher info_m_s = info_p_s.matcher(sig_chk);
+ Matcher info_m_e = info_p_e.matcher(sig_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = sig_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setSignatureCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = sig_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setSignatureCheckInfo(info);
+ }
+ }
+ if (man_chk_m_s.find() && man_chk_m_e.find())
+ {
+ String man_chk = xmlResponse.substring(man_chk_m_s.end(), man_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(man_chk);
+ Matcher code_m_e = code_p_e.matcher(man_chk);
+ Matcher info_m_s = info_p_s.matcher(man_chk);
+ Matcher info_m_e = info_p_e.matcher(man_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = man_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setSignatureManifestCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = man_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setSignatureManifestCheckInfo(info);
+ }
+ }
+ if (cer_chk_m_s.find() && cer_chk_m_e.find())
+ {
+ String cer_chk = xmlResponse.substring(cer_chk_m_s.end(), cer_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(cer_chk);
+ Matcher code_m_e = code_p_e.matcher(cer_chk);
+ Matcher info_m_s = info_p_s.matcher(cer_chk);
+ Matcher info_m_e = info_p_e.matcher(cer_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = cer_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setCertificateCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = cer_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setCertificateCheckInfo(info);
+ }
+ }
+ if (cert_m_s.find() && cert_m_e.find())
+ {
+ String cert_string = xmlResponse.substring(cert_m_s.end(), cert_m_e.start());
+
+ X509Cert resp_cert = X509Cert.initByString(cert_string);
+ sig_res.setCertificate(resp_cert);
+ }
+
+ log.debug("parseVerifyXMLResponse finished."); //$NON-NLS-1$
+ return sig_res;
+ }
+
+
+ /**
+ * Holds environment configuration information like templates.
+ *
+ * @author wprinz
+ */
+ public static class Environment
+ {
+ /**
+ * The configuration key of the sign keybox identifier.
+ */
+ protected static final String SIGN_KEYBOX_IDENTIFIER_KEY = "bku.sign.KeyboxIdentifier"; //$NON-NLS-1$
+
+ /**
+ * The configuration key of the sign request template.
+ */
+ protected static final String SIGN_REQUEST_TEMPLATE_KEY = "bku.sign.request.detached"; //$NON-NLS-1$
+
+ /**
+ * The configuration key of the sign URL.
+ */
+ protected static final String SIGN_URL_KEY = "bku.sign.url"; //$NON-NLS-1$
+
+ /**
+ * The configuration key of the verify request template.
+ */
+ protected static final String VERIFY_REQUEST_TEMPLATE_KEY = "bku.verify.request.detached"; //$NON-NLS-1$
+
+ /**
+ * The configuration key of the verify template.
+ */
+ protected static final String VERIFY_TEMPLATE_KEY = "bku.verify.template.detached"; //$NON-NLS-1$
+
+ /**
+ * The configuration key of the verify URL.
+ */
+ protected static final String VERIFY_URL_KEY = "bku.verify.url"; //$NON-NLS-1$
+
+ /**
+ * The configuration key for the ECDSA cert alg property.
+ */
+ protected static final String ECDSA_CERT_ALG_KEY = "cert.alg.ecdsa"; //$NON-NLS-1$
+
+ /**
+ * 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 sign_keybox_identifier = null;
+
+ protected String sign_request_template = null;
+
+ protected String sign_url = null;
+
+ protected String verify_request_template = null;
+
+ protected String verify_template = null;
+
+ protected String verify_url = null;
+
+ protected String cert_alg_ecdsa = null;
+
+ protected String cert_alg_rsa = null;
+
+ /**
+ * Initializes the environment with a given profile.
+ *
+ * @param profile
+ * The configuration profile.
+ * @throws SettingsException
+ * f.e.
+ * @throws SignatureException
+ * f.e.
+ */
+ public Environment(String profile) throws SettingsException, SignatureException
+ {
+ SettingsReader settings = SettingsReader.getInstance();
+
+ this.sign_keybox_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEYBOX_IDENTIFIER_KEY);
+
+ String sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY);
+ this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
+ if (this.sign_request_template == null)
+ {
+ // TODO make this a settings exception
+ throw new SignatureException(300, "Can not read the create xml request template"); //$NON-NLS-1$
+ }
+
+ this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY);
+
+ String verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY);
+ this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
+ if (this.verify_request_template == null)
+ {
+ // TODO make this a settings exception
+ throw new SignatureException(300, "Can not read the verify xml request template"); //$NON-NLS-1$
+ }
+
+ String verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY);
+ this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename));
+ if (this.verify_template == null)
+ {
+ // TODO make this a settings exception
+ throw new SignatureException(300, "Can not read the verify template"); //$NON-NLS-1$
+ }
+
+ this.verify_url = getConnectorValueFromProfile(settings, profile, VERIFY_URL_KEY);
+
+ this.cert_alg_ecdsa = settings.getValueFromKey(ECDSA_CERT_ALG_KEY);
+
+ this.cert_alg_rsa = settings.getValueFromKey(RSA_CERT_ALG_KEY);
+
+ }
+
+ /**
+ * Returns the sign keybox identifier.
+ *
+ * @return Returns the sign keybox identifier.
+ */
+ public String getSignKeyboxIdentifier()
+ {
+ return this.sign_keybox_identifier;
+ }
+
+ /**
+ * Returns the sign request template.
+ *
+ * @return Returns the sign request template.
+ */
+ public String getSignRequestTemplate()
+ {
+ return this.sign_request_template;
+ }
+
+ /**
+ * Returns the sign URL.
+ *
+ * @return Returns the sign URL.
+ */
+ public String getSignURL()
+ {
+ return this.sign_url;
+ }
+
+ /**
+ * Returns the verify request template.
+ *
+ * @return Returns the verify request template.
+ */
+ public String getVerifyRequestTemplate()
+ {
+ return this.verify_request_template;
+ }
+
+ /**
+ * Returns the verify template.
+ *
+ * @return Returns the verify template.
+ */
+ public String getVerifyTemplate()
+ {
+ return this.verify_template;
+ }
+
+ /**
+ * Returns the verify URL.
+ *
+ * @return Returns the verify URL.
+ */
+ public String getVerifyURL()
+ {
+ return this.verify_url;
+ }
+
+ /**
+ * Returns the ecdsa cert alg property.
+ *
+ * @return Returns the ecdsa cert alg property.
+ */
+ public String getCertAlgEcdsa()
+ {
+ return this.cert_alg_ecdsa;
+ }
+
+ /**
+ * Returns the rsa cert alg property.
+ *
+ * @return Returns the rsa cert alg property.
+ */
+ public String getCertAlgRsa()
+ {
+ return this.cert_alg_rsa;
+ }
+
+ /**
+ * 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
+ * The profile.
+ * @param key
+ * The configuration key.
+ * @return Returns the configuration entry.
+ */
+ public static String getConnectorValueFromProfile(SettingsReader settings,
+ String profile, String key)
+ {
+ String value = settings.getValueFromKey("sig_obj." + profile + "." + key); //$NON-NLS-1$//$NON-NLS-2$
+ if (value == null)
+ {
+ value = settings.getValueFromKey(key);
+ }
+ return value;
+ }
+
+ }
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObject.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObject.java
new file mode 100644
index 0000000..67d5497
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObject.java
@@ -0,0 +1,111 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
+
+import java.io.Serializable;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+
+import at.knowcenter.wag.egov.egiz.sig.signatureobject.AdditionalSignatureInformation;
+import at.knowcenter.wag.egov.egiz.sig.signatureobject.AlgorithmSignatureInformation;
+import at.knowcenter.wag.egov.egiz.sig.signatureobject.ConnectorSignatureInformation;
+import at.knowcenter.wag.egov.egiz.sig.signatureobject.MandatorySignatureInformation;
+
+/**
+ * @author wprinz
+ *
+ */
+public class SignSignatureObject implements Serializable, MandatorySignatureInformation, ConnectorSignatureInformation, AlgorithmSignatureInformation, AdditionalSignatureInformation
+{
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -2689261480444802213L;
+
+ public String date = null;
+ public String issuer = null;
+ public String signatureValue = null;
+
+ public String id = null;
+ public String kz = null;
+
+ /**
+ * This is used to transport the response properties to the Detached signator.
+ */
+ public Properties response_properties = null;
+
+ /**
+ * The X509Certificate.
+ *
+ * <p>
+ * This also provides the serial number and name.
+ * </p>
+ */
+ public X509Certificate x509Certificate = null;
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.MandatorySignatureInformation#getDate()
+ */
+ public String getDate()
+ {
+ return this.date;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.MandatorySignatureInformation#getIssuer()
+ */
+ public String getIssuer()
+ {
+ return this.issuer;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.MandatorySignatureInformation#getSerialNumber()
+ */
+ public String getSerialNumber()
+ {
+ return this.x509Certificate.getSerialNumber().toString();
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.MandatorySignatureInformation#getSignatureValue()
+ */
+ public String getSignatureValue()
+ {
+ return this.signatureValue;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.ConnectorSignatureInformation#getSigID()
+ */
+ public String getSigID()
+ {
+ return this.id;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.AlgorithmSignatureInformation#getSigKZ()
+ */
+ public String getSigKZ()
+ {
+ return this.kz;
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.AdditionalSignatureInformation#getName()
+ */
+ public String getName()
+ {
+ return this.x509Certificate.getSubjectDN().getName();
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.signatureobject.AdditionalSignatureInformation#getX509Certificate()
+ */
+ public X509Certificate getX509Certificate()
+ {
+ return this.x509Certificate;
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObjectHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObjectHelper.java
new file mode 100644
index 0000000..fa44811
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObjectHelper.java
@@ -0,0 +1,56 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
+
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+
+/**
+ * @author wprinz
+ *
+ */
+public abstract class SignSignatureObjectHelper
+{
+ public static String retrieveStringValueFromSignatureObject (SignSignatureObject so, String key)
+ {
+ // mandatory
+ if (key.equals(SignatureTypes.SIG_DATE))
+ {
+ return so.getDate();
+ }
+ if (key.equals(SignatureTypes.SIG_VALUE))
+ {
+ return so.getSignatureValue();
+ }
+ if (key.equals(SignatureTypes.SIG_ISSUER))
+ {
+ return so.getIssuer();
+ }
+ if (key.equals(SignatureTypes.SIG_NUMBER))
+ {
+ return so.getSerialNumber();
+ }
+
+ // connector
+ if (key.equals(SignatureTypes.SIG_ID))
+ {
+ return so.getSigID();
+ }
+
+ // algorithm
+ if (key.equals(SignatureTypes.SIG_KZ))
+ {
+ return so.getSigKZ();
+ }
+
+ // additional
+ if (key.equals(SignatureTypes.SIG_NAME))
+ {
+ return so.getName();
+ }
+
+ throw new RuntimeException("The key '" + key + "' is not a recognized SignatorObject member."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AdditionalSignatureInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AdditionalSignatureInformation.java
new file mode 100644
index 0000000..bedf014
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AdditionalSignatureInformation.java
@@ -0,0 +1,18 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.signatureobject;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * @author wprinz
+ *
+ */
+public interface AdditionalSignatureInformation
+{
+
+ public String getName();
+
+ public X509Certificate getX509Certificate();
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AlgorithmSignatureInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AlgorithmSignatureInformation.java
new file mode 100644
index 0000000..56ab279
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AlgorithmSignatureInformation.java
@@ -0,0 +1,13 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.signatureobject;
+
+/**
+ * @author wprinz
+ *
+ */
+public interface AlgorithmSignatureInformation
+{
+public String getSigKZ();
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/ConnectorSignatureInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/ConnectorSignatureInformation.java
new file mode 100644
index 0000000..1586404
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/ConnectorSignatureInformation.java
@@ -0,0 +1,14 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.signatureobject;
+
+/**
+ *
+ * @author wprinz
+ *
+ */
+public interface ConnectorSignatureInformation
+{
+ public String getSigID();
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/MandatorySignatureInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/MandatorySignatureInformation.java
new file mode 100644
index 0000000..bb3a1eb
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/MandatorySignatureInformation.java
@@ -0,0 +1,20 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.signatureobject;
+
+/**
+ * Encapsulates all information required to define a signature.
+ *
+ * @author wprinz
+ */
+public interface MandatorySignatureInformation
+{
+ public String getDate();
+
+ public String getSignatureValue();
+
+ public String getIssuer();
+
+ public String getSerialNumber();
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
index 031b03c..b98c83e 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
@@ -176,7 +176,8 @@ public class AsynchronousRedirectResponder extends HttpServlet
// has already been computed - don't recompute it.
if (si.sign_result == null)
{
- si.iui.signed_signature_object = local_conn.analyzeSignResponse(si.response_properties[0], si.type);
+ //FIXME refactor WEB
+ si.iui.signed_signature_object = null; //local_conn.analyzeSignResponse(si.response_properties[0], si.type);
PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode);
Signator signator = SignatorFactory.createSignator(algorithm);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
index 95f72ef..cac8eb3 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
@@ -66,7 +66,8 @@ public abstract class LocalRequestHelper
{
LocalConnector local_conn = (LocalConnector) ConnectorFactory.createConnector(si.connector);
- String document_text = si.iui.document_text;
+ // FIXME refactor WEB
+ String document_text = "fixme"; //si.iui.document_text;
String request_string = local_conn.prepareSignRequest(si.user_name, document_text, si.type);
String request_url = local_conn.getSignURL(si.type);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/Sign.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/Sign.java
index 0a5a451..2b1c2a4 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/Sign.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/Sign.java
@@ -333,7 +333,8 @@ public class Sign extends HttpServlet
PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode);
Signator signator = SignatorFactory.createSignator(algorithm);
- si.iui.signed_signature_object = PdfAS.sign(si.iui.document_text, si.type, si.connector, si.user_name, si.user_password);
+ // FIXME refactor WEB
+ si.iui.signed_signature_object = null; //PdfAS.sign(si.iui.document_text, si.type, si.connector, si.user_name, si.user_password);
si.sign_result = signator.finishSign(si.iui);
diff --git a/src/test/java/test/at/knowcenter/wag/egov/egiz/TestNeu.java b/src/test/java/test/at/knowcenter/wag/egov/egiz/TestNeu.java
new file mode 100644
index 0000000..84fda4c
--- /dev/null
+++ b/src/test/java/test/at/knowcenter/wag/egov/egiz/TestNeu.java
@@ -0,0 +1,265 @@
+/**
+ *
+ */
+package test.at.knowcenter.wag.egov.egiz;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.PropertyConfigurator;
+
+import test.at.knowcenter.wag.egov.egiz.detached.BKUConnector;
+import test.at.knowcenter.wag.egov.egiz.detached.MOAConnector;
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+import at.knowcenter.wag.egov.egiz.sig.SignatureData;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.DetachedMultipartBKUConnector;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
+import at.knowcenter.wag.egov.egiz.tools.FileHelper;
+
+/**
+ * @author wprinz
+ *
+ */
+public class TestNeu
+{
+ private static Log logger = LogFactory.getLog(TestNeu.class);
+
+ protected static String TEXT = "Test 123 äöüß"; //$NON-NLS-1$
+
+ protected static File PDF = new File("C:\\wprinz\\Filer\\egiz\\docs\\document4.pdf"); //$NON-NLS-1$
+
+
+ /**
+ * @param args
+ * @throws SignatureException
+ */
+ public static void main(String[] args) throws Exception
+ {
+ SettingsReader.initializeForCommandLine();
+ PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties"); //$NON-NLS-1$
+
+ testDetachedMultipartBKUConnector();
+
+ // testTexMOA();
+
+ // testBinBKU();
+
+ // testTexBKU();
+
+ // SignatureResponse sr = bku_c.doVerify(TEXT, so);
+
+ // logger.debug("sr = " + sr);
+
+ logger.info("finished.");
+ }
+
+ public static void testDetachedMultipartBKUConnector() throws Exception
+ {
+ DetachedMultipartBKUConnector c = new DetachedMultipartBKUConnector("CIO-BUND2"); //$NON-NLS-1$
+
+ SignatureData data = new BinarySignatureData();
+
+ SignSignatureObject so = c.doSign(data);
+
+ FileOutputStream fos = new FileOutputStream("C:\\wprinz\\Filer\\egiz2\\SignatureObject.bin");
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
+ oos.writeObject(so);
+ oos.close();
+
+ FileInputStream fis = new FileInputStream("C:\\wprinz\\Filer\\egiz2\\SignatureObject.bin");
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ so = (SignSignatureObject) ois.readObject();
+ ois.close();
+
+ SignatureResponse sr = c.doVerify(data, so);
+ logger.debug("sr = " + sr);
+
+ }
+
+ public static void testBinBKU() throws Exception
+ {
+ FileInputStream fis = new FileInputStream(PDF);
+ byte[] data = new byte[(int) PDF.length()];
+ fis.read(data);
+ fis.close();
+
+ PdfASID algorithm = new PdfASID("urn:pdfsigfilter:bka.gv.at:binaer:v1.0.0");
+
+ SignatureObject so = testSignBKU(data, algorithm);
+
+ so.setKZ(algorithm);
+
+ SignatureResponse sr = testVerifyBKU(data, so);
+
+ logger.debug("sr = " + sr);
+
+ }
+
+ public static void testTexBKU() throws Exception
+ {
+ PdfASID algorithm = new PdfASID("urn:pdfsigfilter:bka.gv.at:text:v1.0.0");
+
+ SignatureObject so = testSignBKU(TEXT.getBytes("UTF-8"), algorithm);
+
+ so.setKZ(algorithm);
+
+ // FileOutputStream fos = new
+ // FileOutputStream("C:\\wprinz\\Filer\\egiz2\\SignatureObject.bin");
+ // ObjectOutputStream oos = new ObjectOutputStream(fos);
+ // oos.writeObject(so);
+ // oos.close();
+
+ SignatureResponse sr = testVerifyBKU(TEXT.getBytes("UTF-8"), so);
+
+ logger.debug("sr = " + sr);
+ }
+
+ public static void testTexMOA() throws Exception
+ {
+ PdfASID algorithm = new PdfASID("urn:pdfsigfilter:bka.gv.at:text:v1.0.0");
+
+ SignatureObject so = testSignMOA(TEXT.getBytes("UTF-8"), algorithm);
+
+ so.setKZ(algorithm);
+
+ // FileOutputStream fos = new
+ // FileOutputStream("C:\\wprinz\\Filer\\egiz2\\SignatureObject.bin");
+ // ObjectOutputStream oos = new ObjectOutputStream(fos);
+ // oos.writeObject(so);
+ // oos.close();
+
+ // SignatureResponse sr = testVerifyBKU(TEXT.getBytes("UTF-8"), so);
+ //
+ // logger.debug("sr = " + sr);
+ }
+
+ public static SignatureObject testSignBKU(byte[] data, PdfASID algorithm) throws Exception
+ {
+ BKUConnector bku_c = new BKUConnector();
+
+ SignatureObject so = bku_c.doSign("CIO-BUND2", data, algorithm);
+
+ logger.debug("so = " + so);
+
+ return so;
+ }
+
+ public static SignatureObject testSignMOA(byte[] data, PdfASID algorithm) throws Exception
+ {
+ MOAConnector moa_c = new MOAConnector();
+
+ SignatureObject so = moa_c.doSign("CIO-BUND2", data, algorithm);
+
+ logger.debug("so = " + so);
+
+ return so;
+ }
+
+ public static SignatureResponse testVerifyBKU(byte[] data, SignatureObject so) throws Exception
+ {
+ BKUConnector bku_c = new BKUConnector();
+
+ SignatureResponse sr = bku_c.doVerify(data, so);
+
+ logger.debug("sr = " + sr);
+
+ return sr;
+ }
+
+ /**
+ * A data source for text data.
+ *
+ * @author wprinz
+ */
+ public static class TextSignatureData implements SignatureData
+ {
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getData()
+ */
+ public byte[] getData()
+ {
+ try
+ {
+ return TEXT.getBytes(getCharacterEncoding());
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getMimeType()
+ */
+ public String getMimeType()
+ {
+ return "text/plain"; //$NON-NLS-1$
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getCharacterEncoding()
+ */
+ public String getCharacterEncoding()
+ {
+ return "UTF-8"; //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * A data source for binary (PDF) data.
+ *
+ * @author wprinz
+ */
+ public static class BinarySignatureData implements SignatureData
+ {
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getData()
+ */
+ public byte[] getData()
+ {
+ try
+ {
+ FileInputStream fis = new FileInputStream(PDF);
+ byte[] data = new byte[(int) PDF.length()];
+ fis.read(data);
+ fis.close();
+
+ return data;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getMimeType()
+ */
+ public String getMimeType()
+ {
+ return "application/pdf"; //$NON-NLS-1$
+ }
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getCharacterEncoding()
+ */
+ public String getCharacterEncoding()
+ {
+ return null;
+ }
+
+ }
+
+}
diff --git a/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUConnector.java b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUConnector.java
new file mode 100644
index 0000000..d395de5
--- /dev/null
+++ b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUConnector.java
@@ -0,0 +1,987 @@
+/*
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: BKUConnector.java,v 1.5 2006/10/31 08:18:41 wprinz Exp $
+ */
+package test.at.knowcenter.wag.egov.egiz.detached;
+
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException;
+import at.knowcenter.wag.egov.egiz.sig.ConnectorInformation;
+import at.knowcenter.wag.egov.egiz.sig.LocalConnector;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
+import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
+import at.knowcenter.wag.egov.egiz.sig.X509Cert;
+import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorConfigurationKeys;
+import at.knowcenter.wag.egov.egiz.sig.connectors.MOAConnector;
+import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
+import at.knowcenter.wag.egov.egiz.tools.FileHelper;
+
+/**
+ * Connector for communicating with BKU.
+ *
+ * @author wlackner
+ * @author wprinz
+ */
+public class BKUConnector
+{
+ /**
+ * ConnectorInformation that identifies this Connector to the system.
+ *
+ * @see at.knowcenter.wag.egov.egiz.sig.ConnectorFactory
+ * @see ConnectorInformation
+ */
+ public static final ConnectorInformation CONNECTOR_INFORMATION = new ConnectorInformation("bku", "BKU");
+
+ /**
+ * The SettingsReader instance
+ */
+ private SettingsReader settings_ = null;
+
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger_ = ConfigLogger.getLogger(BKUConnector.class);
+
+ /**
+ * The empty constructor
+ */
+ public BKUConnector() throws SignatureException
+ {
+ loadSettings();
+ }
+
+ /**
+ * load the inital signature settings
+ *
+ * @see SettingsReader
+ */
+ private void loadSettings() throws SignatureException
+ {
+ if (settings_ == null)
+ {
+ try
+ {
+ settings_ = SettingsReader.getInstance();
+ }
+ catch (SettingsException e)
+ {
+ String log_message = "Can not load signature settings. Cause:\n" + e.getMessage();
+ logger_.error(log_message);
+ throw new SignatureException(101, log_message, e);
+ }
+ }
+ }
+
+ public SignatureObject doSign(String sigType, byte[] data, PdfASID algorithm) throws SignatureException
+ {
+ String sigmode = algorithm.getType();
+
+ String request_string = prepareSignRequestDetached(sigType, sigmode);
+
+ String sign_url = getSignURL(sigType);
+
+ String versionstring = algorithm.getVersion();
+ logger_.info("versionstring=" + versionstring);
+
+ String mimetype = "";
+ if (sigmode.equalsIgnoreCase(SignatorFactory.TYPE_TEXTUAL))
+ {
+ mimetype = "text/plain";
+ }
+ if (sigmode.equalsIgnoreCase(SignatorFactory.TYPE_BINARY))
+ {
+ mimetype = "application/pdf";
+ }
+
+ Properties response_properties = sendRequest(sign_url, request_string, data, mimetype);
+
+ return analyzeSignResponse(response_properties, sigType);
+ }
+
+ public SignatureResponse doVerify(byte[] data, SignatureObject sigObject) throws SignatureException
+ {
+ String sigmode = sigObject.getKZ().getType();
+ String sigversion = sigObject.getKZ().getVersion();
+
+ // decide which template should be used to verify
+ // use versionstring to decide if detached Signature
+ String request_string = prepareVerifyRequestDetached(data, sigObject);
+ // if (sigversion.equals(SignatorFactory.VERSION_1_1_0))
+ // {
+ // TODO support Sign v1.1.0 Remove base64 and write tempfile
+ // String sigversion=SignatorFactory.TYPE_TEXTUAL;
+
+ String mimetype = "";
+ if (sigmode.equalsIgnoreCase(SignatorFactory.TYPE_TEXTUAL))
+ {
+ mimetype = "text/plain";
+ }
+ if (sigmode.equalsIgnoreCase(SignatorFactory.TYPE_BINARY))
+ {
+ mimetype = "application/pdf";
+ }
+
+ String verify_url = getVerifyURL(sigObject.getSignationType());
+ Properties response_properties = sendRequest(verify_url, request_string, data, mimetype);
+
+ return analyzeVerifyResponse(response_properties);
+ }
+
+ /**
+ * 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 from the BKU sign-request
+ * @param sigObj
+ * the SignatureObject that should be filled
+ * @throws SignatureException
+ * ErrorCode (303, 304)
+ * @see SignatureObject
+ * @see CodingHelper
+ * @see X509Cert
+ */
+ private void parseCreateXMLResponse(Properties response_properties,
+ SignatureObject sigObj) throws SignatureException
+ {
+ String xmlResponse = response_properties.getProperty("response_string");
+
+ Pattern sig_val_p_s = Pattern.compile("<[\\w]*:?SignatureValue>");
+ Pattern sig_val_p_e = Pattern.compile("</[\\w]*:?SignatureValue>");
+ Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>");
+ Pattern iss_nam_p_e = Pattern.compile("</[\\w]*:?X509IssuerName>");
+ Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>");
+ Pattern sig_tim_p_e = Pattern.compile("</[\\w]*:?SigningTime>");
+ Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>");
+ Pattern ser_num_p_e = Pattern.compile("</[\\w]*:?X509SerialNumber>");
+ Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>");
+ Pattern sig_cer_p_e = Pattern.compile("</[\\w]*:?X509Certificate>");
+
+ Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>");
+ Pattern sig_cer_d_p_e = Pattern.compile("</[\\w]*:?CertDigest>");
+ Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>");
+ Pattern dig_val_p_e = Pattern.compile("</[\\w]*:?DigestValue>");
+
+ Matcher sig_val_m_s = sig_val_p_s.matcher(xmlResponse);
+ Matcher sig_val_m_e = sig_val_p_e.matcher(xmlResponse);
+ Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+ Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+ Matcher sig_tim_m_s = sig_tim_p_s.matcher(xmlResponse);
+ Matcher sig_tim_m_e = sig_tim_p_e.matcher(xmlResponse);
+ Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+ Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+ Matcher sig_cer_m_s = sig_cer_p_s.matcher(xmlResponse);
+ Matcher sig_cer_m_e = sig_cer_p_e.matcher(xmlResponse);
+
+ Matcher sig_cer_d_m_s = sig_cer_d_p_s.matcher(xmlResponse);
+ Matcher sig_cer_d_m_e = sig_cer_d_p_e.matcher(xmlResponse);
+
+ String sig_val = "";
+ String iss_nam = "";
+ String ser_num = "";
+ String sig_tim = "";
+ String sig_cer = "";
+ String sig_dig = "";
+
+ // SignatureValue
+ if (sig_val_m_s.find() && sig_val_m_e.find())
+ {
+ sig_val = xmlResponse.substring(sig_val_m_s.end(), sig_val_m_e.start());
+ sig_val = sig_val.replaceAll("\\s", "");
+ sigObj.setSignationValue(sig_val);
+ }
+ // X509IssuerName
+ if (iss_nam_m_s.find() && iss_nam_m_e.find())
+ {
+ iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+ sigObj.setSignationIssuer(iss_nam);
+ }
+ // X509SerialNumber
+ if (ser_num_m_s.find() && ser_num_m_e.find())
+ {
+ ser_num = xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start());
+ sigObj.setSignationSerialNumber(ser_num);
+ }
+ // SigningTime
+ if (sig_tim_m_s.find() && sig_tim_m_e.find())
+ {
+ sig_tim = xmlResponse.substring(sig_tim_m_s.end(), sig_tim_m_e.start());
+ sigObj.setSignationDate(sig_tim);
+ }
+ // CertDigest
+ if (sig_cer_d_m_s.find() && sig_cer_d_m_e.find())
+ {
+ String cert_digest = xmlResponse.substring(sig_cer_d_m_s.end(), sig_cer_d_m_e.start());
+ Matcher dig_val_m_s = dig_val_p_s.matcher(cert_digest);
+ Matcher dig_val_m_e = dig_val_p_e.matcher(cert_digest);
+ if (dig_val_m_s.find() && dig_val_m_e.find())
+ {
+ sig_dig = cert_digest.substring(dig_val_m_s.end(), dig_val_m_e.start());
+ sigObj.setX509CertificateDigest(sig_dig);
+ }
+ }
+ // extract Subject Name from X509Certificate
+ if (sig_cer_m_s.find() && sig_cer_m_e.find())
+ {
+ sig_cer = xmlResponse.substring(sig_cer_m_s.end(), sig_cer_m_e.start());
+ sig_cer = sig_cer.replaceAll("\\s", "");
+ sigObj.setX509Certificate(sig_cer);
+ X509Cert cert = X509Cert.initByString(sig_cer);
+ if (cert.isX509Cert())
+ {
+ sigObj.setX509Certificate(cert.getCertString());
+ String serial_num = cert.getSerialNumber();
+ String subject_name = cert.getSubjectName();
+ if (!ser_num.equals(serial_num))
+ {
+ SignatureException se = new SignatureException(303, "Serialnumber of certificate and tag X509SerialNumber differs!");
+ throw se;
+ }
+ sigObj.setSignationName(subject_name);
+ }
+ }
+ // extract Signature Id's
+ String[] ids = new String[5];
+ ids[0] = extractId(xmlResponse, "signature-");
+ ids[1] = extractId(xmlResponse, "signed-data-reference-");
+ ids[2] = extractId(xmlResponse, "signed-data-object-");
+ ids[3] = extractId(xmlResponse, "etsi-data-reference-");
+ ids[4] = extractId(xmlResponse, "etsi-data-object-");
+ String final_ids = formatSigIds(ids);
+ sigObj.setSignationIDs(final_ids);
+ }
+
+ protected String formatSigIds(String[] sigIds) throws SignatureException
+ {
+ // ids algorithm:
+ String join = "";
+ String base = null;
+ for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
+ {
+ String id = sigIds[arr_idx];
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("Set BKU id:" + id);
+ }
+ int id_idx = id.lastIndexOf("-");
+ if (arr_idx == 0)
+ {
+ base = id.substring(0, id_idx);
+ }
+ String cur_id = id.substring(id_idx + 1);
+ if (cur_id.equalsIgnoreCase(""))
+ {
+ cur_id = "0";
+ }
+
+ join += "-" + cur_id;
+ }
+ String ids = base + "@" + join.substring(1);
+ String final_ids = getSigIDprefixValueFromProfile() + ids;
+ return final_ids;
+ }
+
+ protected String getSigIDprefixValueFromProfile()
+ {
+ String key = getType() + ".sign.SIG_IDprefix";
+ String value = settings_.getValueFromKey(key);
+ if (value == null)
+ {
+ value = "";
+ }
+ return value;
+ }
+
+ /**
+ * 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
+ * the id-key
+ * @return the value of the given key in the text
+ */
+ private String extractId(String text, String name)
+ {
+ String id = null;
+ int start_idx = text.indexOf(name) + name.length();
+ int end_idx = text.indexOf("\"", start_idx);
+
+ final int quot_end_idx = end_idx;
+ final int squot_end_idx = text.indexOf("'", start_idx);
+ end_idx = Math.min(quot_end_idx, squot_end_idx);
+ id = text.substring(start_idx, end_idx);
+ logger_.info("extract id:" + name + id);
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("extract id:" + name + id);
+ }
+ return id;
+ }
+
+ public String getVerifyTemplate(byte [] data,
+ SignatureObject sigObject) throws SignatureException
+ {
+ // TODO Template selection depending on Sigid
+ try
+ {
+ if (data == null)
+ {
+ SignatureException se = new SignatureException(311, "Document can not be verified because data is empty.");
+ throw se;
+ }
+ if (sigObject == null)
+ {
+ SignatureException se = new SignatureException(312, "Document can not be verified because no signature object are set.");
+ throw se;
+ }
+
+ String verify_template = "./templates/BKUVerifyTemplateDetached.xml";//getVerifyTemplateFileName(sigObject.getSignationType());
+ String sigmode = sigObject.getKZ().getType();
+
+ String sig_prop_filename = "./templates/BKUVerifyTemplateSP_neueBKU_text.xml"; //getSigPropFileName(sigObject.getSignationType(), sigmode);
+
+ if (sigObject.getKZ().getType().equals("binaer"))
+ {
+ sig_prop_filename = "./templates/BKUVerifyTemplateSP_neueBKU_bin.xml";
+ }
+
+
+ logger_.info(" verify_template= " + verify_template);
+ logger_.info("sig_prop_filename = " + sig_prop_filename);
+ String ids_string = sigObject.getSignationIds();
+ logger_.info("ids_string = " + ids_string);
+ String[] ids = SignatureObject.parseSigIds(ids_string);
+
+ // TODO hotfix
+ boolean neue_bku = true;
+ if (ids[5] != null)
+ {
+ // Hash has to be made over an other part than in previous versions.
+ // i dont know how this is in newer versions than 2.7.1
+ // id[5] of Signature of 2.7.1 signed Pdfs is "etsi-bka-1.0@"
+ if (ids[5].equals("etsi-bka-1.0@"))
+ {
+ neue_bku = true;
+ }
+ }
+ logger_.info("verify ids[5] = " + ids[5]);
+ logger_.info("verify neue_bku = " + neue_bku);
+ if (neue_bku)
+ {
+ // verify_template =
+ // getConnectorValueFromProfile(sigObject.getSignationType(),
+ // "bku.verify.template2");
+ // //"./templates/BKUVerifyTemplateB64_neueBKU.xml";
+ // sig_prop_filename =
+ // getConnectorValueFromProfile(sigObject.getSignationType(),
+ // "bku.verify.template2.SP");
+ // //"./templates/BKUVerifyTemplateSP_neueBKU.xml";
+ }
+
+ String ver_temp_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_template));
+ String sig_prop_str = FileHelper.readFromFile(SettingsReader.relocateFile(sig_prop_filename));
+ if (logger_.isDebugEnabled())
+ {
+ // logger_.debug(verify_template);
+ logger_.debug(sig_prop_filename);
+ }
+
+ String x509_cert_string = sigObject.getX509CertificateString();
+ if (x509_cert_string == null)
+ {
+ SignatureException se = new SignatureException(313, "Document certificate is not defined.");
+ throw se;
+ }
+ String cert_alg = settings_.getValueFromKey("cert.alg.ecdsa");
+ X509Cert x509_cert = sigObject.getX509Cert();
+ if (x509_cert.isRSA())
+ {
+ cert_alg = settings_.getValueFromKey("cert.alg.rsa");
+ }
+
+ sig_prop_str = sig_prop_str.replaceFirst("SigningTimeReplace", sigObject.getSignationDate());
+
+ String issuer_name = sigObject.getSignationIssuer();
+ // The issuer is already unicode, so it mustn't be encoded again.
+ // byte[] issuer_name =
+ // CodingHelper.encodeUTF8(sigObject.getSignationIssuer());
+ // new String(issuer_name); // this would double encode the String, not to
+ // mention the missing encoding
+ sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", issuer_name);
+
+ sig_prop_str = sig_prop_str.replaceFirst("X509SerialNumberReplace", sigObject.getSignationSerialNumber());
+ sig_prop_str = sig_prop_str.replaceFirst("DigestValueX509CertificateReplace", sigObject.getX509CertificateDigest());
+ sig_prop_str = sig_prop_str.replaceFirst("SigIdReplace", ids[0]);
+ sig_prop_str = sig_prop_str.replaceFirst("SigDataRefReplace", ids[1]);
+
+ ver_temp_str = ver_temp_str.replaceFirst("CertAlgReplace", cert_alg);
+ ver_temp_str = ver_temp_str.replaceFirst("TemplateQualifyingPropertiesReplace", sig_prop_str);
+ byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8"));
+
+ String sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
+ logger_.info("XXXXXSignedPropertiesoldbase64bku sig_prop_hash=" + sig_prop_hash);
+ // TODO hotfix
+ // if (neue_bku)
+ // {
+ // BKU Version 2.7.1 builds hash over other than previous
+ final String ETSI_SIGNED_PROPERTIES_START_TAG = "<etsi:SignedProperties"; // xml
+ // name
+ // spaces
+ // follow,
+ // so
+ // this
+ // is
+ // not
+ // a
+ // complete
+ // tag...
+ final String ETSI_SIGNED_PROPERTIES_END_TAG = "</etsi:SignedProperties>";
+
+ final int hash_start = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_START_TAG);
+ assert hash_start >= 0;
+ final int hash_end = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_END_TAG, hash_start) + ETSI_SIGNED_PROPERTIES_END_TAG.length();
+ assert hash_end - ETSI_SIGNED_PROPERTIES_END_TAG.length() >= 0;
+ assert hash_end > hash_start;
+
+ final String string_to_be_hashed = sig_prop_str.substring(hash_start, hash_end);
+ logger_.info("etsi:SignedProperties string to be hashed: " + string_to_be_hashed);
+
+ final byte[] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
+ sig_prop_code = CodingHelper.buildDigest(bytes_to_be_hashed);
+ sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
+ logger_.info("XXXXXSignedPropertiesnewbase64bku sig_prop_hash=" + sig_prop_hash);
+ // }
+
+ ver_temp_str = ver_temp_str.replaceFirst("DigestValueSignedPropertiesReplace", sig_prop_hash);
+ // logger_.info("DIGEST:" + sig_prop_hash);
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("build digest from QualifyingProperties:start");
+ // logger_.debug("DATA :" + sig_prop_str);
+ logger_.debug("DIGEST:" + sig_prop_hash);
+ logger_.debug("build digest from QualifyingProperties:end");
+ }
+
+ ver_temp_str = ver_temp_str.replaceFirst("SignatureValueReplace", sigObject.getSignationValue());
+ ver_temp_str = ver_temp_str.replaceFirst("X509CertificateReplace", x509_cert_string);
+ byte[] data_value = data; // normalizedText.getBytes("UTF-8");
+ byte[] data_value_hash = CodingHelper.buildDigest(data_value);
+ String object_data_hash = CodingHelper.encodeBase64(data_value_hash);
+ // logger_.info("XXXXXXxbase64 object_data_hash="+object_data_hash);
+ // String object_data = new String(data_value);
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("build digest from data object:start");
+ // logger_.debug("DATA :" + normalizedText);
+ logger_.debug("DIGEST:" + object_data_hash);
+ logger_.debug("build digest from data object:end");
+ }
+
+ // String raw_b64 = CodingHelper.encodeUTF8AsBase64(normalizedText);
+ String raw_b64 = CodingHelper.encodeBase64(data_value);
+
+ ver_temp_str = ver_temp_str.replaceFirst("Base64ContentReplace", raw_b64);
+ ver_temp_str = ver_temp_str.replaceFirst("DigestValueSignedDataReplace", object_data_hash);
+
+ ver_temp_str = ver_temp_str.replaceAll("SigIdReplace", ids[0]);
+ ver_temp_str = ver_temp_str.replaceAll("SigDataRefReplace", ids[1]);
+ ver_temp_str = ver_temp_str.replaceAll("SigDataObjURIReplace", ids[2]);
+ ver_temp_str = ver_temp_str.replaceAll("EtsiDataRefReplace", ids[3]);
+ ver_temp_str = ver_temp_str.replaceAll("EtsiDataObjURIReplace", ids[4]);
+ if (logger_.isDebugEnabled())
+ {
+ // logger_.debug("VERIFY REQUEST:" + ver_temp_str);
+ }
+
+ return ver_temp_str;
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new SignatureException(310, e);
+ }
+ }
+
+ /**
+ * 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
+ * @see SignatureResponse
+ */
+ private SignatureResponse parseVerifyXMLResponse(String xmlResponse)
+ {
+ if (logger_.isInfoEnabled())
+ {
+ logger_.info("Try parsing the verify response");
+ }
+
+ Pattern sub_nam_p_s = Pattern.compile("<dsig:X509SubjectName>");
+ Pattern sub_nam_p_e = Pattern.compile("</dsig:X509SubjectName>");
+ Pattern iss_nam_p_s = Pattern.compile("<dsig:X509IssuerName>");
+ Pattern iss_nam_p_e = Pattern.compile("</dsig:X509IssuerName>");
+ Pattern ser_num_p_s = Pattern.compile("<dsig:X509SerialNumber>");
+ Pattern ser_num_p_e = Pattern.compile("</dsig:X509SerialNumber>");
+
+ Pattern sig_chk_p_s = Pattern.compile("<sl:SignatureCheck>");
+ Pattern sig_chk_p_e = Pattern.compile("</sl:SignatureCheck>");
+ Pattern man_chk_p_s = Pattern.compile("<sl:SignatureManifestCheck>");
+ Pattern man_chk_p_e = Pattern.compile("</sl:SignatureManifestCheck>");
+ Pattern cer_chk_p_s = Pattern.compile("<sl:CertificateCheck>");
+ Pattern cer_chk_p_e = Pattern.compile("</sl:CertificateCheck>");
+
+ // [tknall] start qualified certificate
+ Pattern cert_qualified_p = Pattern.compile("<sl:QualifiedCertificate/>");
+ Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse);
+ // [tknall] stop qualified certificate
+
+ Pattern code_p_s = Pattern.compile("<sl:Code>");
+ Pattern code_p_e = Pattern.compile("</sl:Code>");
+ Pattern info_p_s = Pattern.compile("<sl:Info>");
+ Pattern info_p_e = Pattern.compile("</sl:Info>");
+
+ Pattern cert_p_s = Pattern.compile("<dsig:X509Certificate>");
+ Pattern cert_p_e = Pattern.compile("</dsig:X509Certificate>");
+
+ Matcher sub_nam_m_s = sub_nam_p_s.matcher(xmlResponse);
+ Matcher sub_nam_m_e = sub_nam_p_e.matcher(xmlResponse);
+ Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+ Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+ Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+ Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+
+ Matcher sig_chk_m_s = sig_chk_p_s.matcher(xmlResponse);
+ Matcher sig_chk_m_e = sig_chk_p_e.matcher(xmlResponse);
+ Matcher man_chk_m_s = man_chk_p_s.matcher(xmlResponse);
+ Matcher man_chk_m_e = man_chk_p_e.matcher(xmlResponse);
+ Matcher cer_chk_m_s = cer_chk_p_s.matcher(xmlResponse);
+ Matcher cer_chk_m_e = cer_chk_p_e.matcher(xmlResponse);
+
+ Matcher cert_m_s = cert_p_s.matcher(xmlResponse);
+ Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
+
+ SignatureResponse sig_res = new SignatureResponse();
+
+ // [tknall] start qualified certificate
+ sig_res.setQualifiedCertificate(cert_qualified_m.find());
+ // [tknall] stop qualified certificate
+
+ if (sub_nam_m_s.find() && sub_nam_m_e.find())
+ {
+ String sub_nam = xmlResponse.substring(sub_nam_m_s.end(), sub_nam_m_e.start());
+ sig_res.setX509SubjectName(sub_nam);
+ }
+ if (iss_nam_m_s.find() && iss_nam_m_e.find())
+ {
+ String iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+ sig_res.setX509IssuerName(iss_nam);
+ }
+ if (ser_num_m_s.find() && ser_num_m_e.find())
+ {
+ String ser_num = xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start());
+ sig_res.setX509SerialNumber(ser_num);
+ }
+ if (sig_chk_m_s.find() && sig_chk_m_e.find())
+ {
+ String sig_chk = xmlResponse.substring(sig_chk_m_s.end(), sig_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(sig_chk);
+ Matcher code_m_e = code_p_e.matcher(sig_chk);
+ Matcher info_m_s = info_p_s.matcher(sig_chk);
+ Matcher info_m_e = info_p_e.matcher(sig_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = sig_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setSignatureCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = sig_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setSignatureCheckInfo(info);
+ }
+ }
+ if (man_chk_m_s.find() && man_chk_m_e.find())
+ {
+ String man_chk = xmlResponse.substring(man_chk_m_s.end(), man_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(man_chk);
+ Matcher code_m_e = code_p_e.matcher(man_chk);
+ Matcher info_m_s = info_p_s.matcher(man_chk);
+ Matcher info_m_e = info_p_e.matcher(man_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = man_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setSignatureManifestCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = man_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setSignatureManifestCheckInfo(info);
+ }
+ }
+ if (cer_chk_m_s.find() && cer_chk_m_e.find())
+ {
+ String cer_chk = xmlResponse.substring(cer_chk_m_s.end(), cer_chk_m_e.start());
+ Matcher code_m_s = code_p_s.matcher(cer_chk);
+ Matcher code_m_e = code_p_e.matcher(cer_chk);
+ Matcher info_m_s = info_p_s.matcher(cer_chk);
+ Matcher info_m_e = info_p_e.matcher(cer_chk);
+ if (code_m_s.find() && code_m_e.find())
+ {
+ String code = cer_chk.substring(code_m_s.end(), code_m_e.start());
+ sig_res.setCertificateCheckCode(code);
+ }
+ if (info_m_s.find() && info_m_e.find())
+ {
+ String info = cer_chk.substring(info_m_s.end(), info_m_e.start());
+ sig_res.setCertificateCheckInfo(info);
+ }
+ }
+ if (cert_m_s.find() && cert_m_e.find())
+ {
+ String cert_string = xmlResponse.substring(cert_m_s.end(), cert_m_e.start());
+
+ X509Cert resp_cert = X509Cert.initByString(cert_string);
+ sig_res.setCertificate(resp_cert);
+ }
+
+ return sig_res;
+ }
+
+ public String prepareSignRequestDetached(String signType, String sigmode) throws SignatureException
+ {
+ logger_.info("Call " + getType() + " connector sigmode=" + sigmode);
+
+ String keybox_identifier = getSignKeyboxIdentifier(signType);
+ String sign_request_filename = getSignRequestTemplateFileName(signType, sigmode);
+ String sign_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
+
+ if (sign_req_str == null)
+ {
+ throw new SignatureException(300, "Can not read the create xml request template");
+ }
+ sign_req_str = sign_req_str.replaceFirst("KeyboxIdentifierReplace", keybox_identifier);
+ return sign_req_str;
+ }
+
+ // decides if moasigned or BKU
+ public String prepareVerifyRequestDetached(byte[] data,
+ SignatureObject sigObject) throws SignatureException
+ {
+ // get templates
+ String verify_request = "./templates/BKUVerifyRequestDetached.xml"; //getVerifyRequestTemplateFileName(sigObject.getSignationType());
+ String verify_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request));
+ logger_.info("prepareVerifyRequest TemplateFile=" + verify_request);
+
+ String verify_template_str = null;
+ // TODO implement MOA
+// if (sigObject.isMOASigned())
+// {
+// MOAConnector moa_conn = new MOAConnector();
+// // get the MOA-template
+// verify_template_str = moa_conn.getVerifyTemplate(normalizedText, sigObject);
+// }
+// else
+// {
+ // get the BKU-template
+ verify_template_str = getVerifyTemplate(data, sigObject);
+// }
+
+ verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("verify_req_str.xml : " + verify_req_str);
+ }
+
+ return verify_req_str;
+ }
+
+ /**
+ * Sends the request to the given URL.
+ *
+ * @param url
+ * The URL.
+ * @param request_string
+ * The request string.
+ * @return Returns the response string.
+ * @throws SignatureException
+ * F.e.
+ */
+ protected Properties sendRequest(String url, String request_string) throws SignatureException
+ {
+ try
+ {
+ Properties response_properties = BKUPostConnection.doPostRequest(url, request_string);
+ return response_properties;
+ }
+ catch (Exception e)
+ {
+ SignatureException se = new SignatureException(320, e);
+ throw se;
+ }
+ }
+
+ /**
+ *
+ * @param url
+ * The URL.
+ * @param request_string
+ * The request string.
+ * @return Returns the response string.
+ * @throws SignatureException
+ * F.e.
+ */
+ protected Properties sendRequest(String url, String request_string,
+ byte[] signdata, String mimetype) throws SignatureException
+ {
+ try
+ {
+ // Properties response_properties =
+ // BKUPostConnection.doPostRequest272(url, request_string, signdata,
+ // mimetype);
+ Properties response_properties = BKUPostConnection.doPostRequest272(url, request_string, signdata, mimetype);
+ return response_properties;
+ }
+ catch (Exception e)
+ {
+ SignatureException se = new SignatureException(320, e);
+ throw se;
+ }
+ }
+
+ public SignatureObject analyzeSignResponse(Properties response_properties,
+ String sigType) throws SignatureException
+ {
+ // String sign_request_filename = getSignRequestTemplateFileName(sigType);
+
+ // TODO hotfix
+ String response_string = response_properties.getProperty("response_string");
+
+ // TODO debug
+ try
+ {
+ FileOutputStream fos = new FileOutputStream("C:\\wprinz\\Filer\\egiz2\\sign_response.utf8.xml");
+ OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+ osw.write(response_string);
+ osw.close();
+ }
+ catch (Exception e)
+ {
+ logger_.error(e);
+ }
+
+ SignatureObject sig_obj = new SignatureObject();
+ sig_obj.setRawSignatureResponse(response_string);
+ try
+ {
+ sig_obj.setSigType(sigType);
+ sig_obj.initByType();
+ }
+ catch (SignatureTypesException e)
+ {
+ SignatureException se = new SignatureException(300, "Cannot init signature object with type:" + sigType, e);
+ throw se;
+ }
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("Signature Type is:" + sig_obj.getSignationType());
+ }
+
+ if (!response_string.equals(""))
+ {
+ Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>");
+ Pattern erc_p_e = Pattern.compile("</[\\w]*:?ErrorCode>");
+ Matcher erc_m_s = erc_p_s.matcher(response_string);
+ Matcher erc_m_e = erc_p_e.matcher(response_string);
+ // System.err.println(response_string);
+
+ if (erc_m_s.find() && erc_m_e.find())
+ {
+ if (logger_.isEnabledFor(Level.ERROR))
+ {
+ // logger_.debug(sign_request_filename + "_response.xml : " +
+ // response_string);
+ logger_.error("BKU Error response: " + response_string);
+ }
+ Pattern erm_p_s = Pattern.compile("<[\\w]*:?Info>");
+ Pattern erm_p_e = Pattern.compile("</[\\w]*:?Info>");
+ Matcher erm_m_s = erm_p_s.matcher(response_string);
+ Matcher erm_m_e = erm_p_e.matcher(response_string);
+ SignatureException se = new SignatureException(0, "BKUSigExc");
+ String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start());
+ se.setExternalErrorCode(error_code);
+ if (erm_m_s.find() && erm_m_e.find())
+ {
+ String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start());
+ se.setExternalErrorMessage(error_mess);
+ }
+ throw se;
+ }
+ else
+ {
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("signature_response_string: " + response_string);
+ }
+ parseCreateXMLResponse(response_properties, sig_obj);
+ }
+ }
+ sig_obj.setSigResponse(response_string);
+ return sig_obj;
+ }
+
+ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException
+ {
+ String response_string = response_properties.getProperty("response_string");
+
+ if (!response_string.equals(""))
+ {
+ Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>");
+ Pattern erc_p_e = Pattern.compile("</[\\w]*:?ErrorCode>");
+ Matcher erc_m_s = erc_p_s.matcher(response_string);
+ Matcher erc_m_e = erc_p_e.matcher(response_string);
+
+ if (erc_m_s.find() && erc_m_e.find())
+ {
+ if (logger_.isEnabledFor(Level.ERROR))
+ {
+ // logger_.debug(getType() + "_response.xml : " + response_string);
+ logger_.error(getType() + "_response.xml : " + response_string);
+ }
+ Pattern erm_p_s = Pattern.compile("<[\\w]*:?Info>");
+ Pattern erm_p_e = Pattern.compile("</[\\w]*:?Info>");
+ Matcher erm_m_s = erm_p_s.matcher(response_string);
+ Matcher erm_m_e = erm_p_e.matcher(response_string);
+ SignatureException se = new SignatureException(0, "BKUSigExc");
+ if (erc_m_s.find() && erc_m_e.find())
+ {
+ String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start());
+ se.setExternalErrorCode(error_code);
+ }
+ if (erm_m_s.find() && erm_m_e.find())
+ {
+ String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start());
+ se.setExternalErrorMessage(error_mess);
+ }
+ throw se;
+ }
+ else
+ {
+ if (logger_.isDebugEnabled())
+ {
+ // logger_.debug(getType() + "_response.xml : " + response_string);
+ }
+ return parseVerifyXMLResponse(response_string);
+ }
+ }
+ return null;
+ }
+
+ protected String getConnectorValueFromProfile(String profile, String key)
+ {
+ String value = settings_.getValueFromKey("sig_obj." + profile + "." + key);
+ if (value == null)
+ {
+ value = settings_.getValueFromKey(key);
+ }
+ return value;
+ }
+
+ public String getSignURL(String profile)
+ {
+ final String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".url";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSignRequestTemplateFileName(String profile, String sigmode)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".request" + "." + sigmode;
+ logger_.info("getSignRequestTemplateFileName: profile=" + profile + "" + " key=" + key);
+ String filename = getConnectorValueFromProfile(profile, key);
+ logger_.info("getSignRequestTemplateFileName filename=" + filename);
+ return filename;// getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSignKeyboxIdentifier(String profile)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".KeyboxIdentifier";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ public String getVerifyURL(String profile)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".url";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getVerifyRequestTemplateFileName(String profile)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".request";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getVerifyTemplateFileName(String profile)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".template";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSigPropFileName(String profile, String sigmode)
+ {
+ String key = getType() + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".template.SP." + sigmode;
+ logger_.info("getSigPropFileName: profile=" + profile + "" + " key=" + key);
+ String filename = getConnectorValueFromProfile(profile, key);
+ logger_.info("getSigPropFileName filename=" + filename);
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ /**
+ * Returns the type of this BKU-like connector.
+ *
+ * <p>
+ * All settings keys will be prefixed by this type. So to reuse the BKU
+ * connector, a deriving class has to implement this method specifying an own
+ * type.
+ * </p>
+ *
+ * @return Returns the type of this BKU-like connector.
+ */
+ protected String getType()
+ {
+ return CONNECTOR_INFORMATION.getIdentifier();
+ }
+
+} \ No newline at end of file
diff --git a/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUPostConnection.java b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUPostConnection.java
new file mode 100644
index 0000000..0c219b8
--- /dev/null
+++ b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUPostConnection.java
@@ -0,0 +1,230 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: BKUPostConnection.java,v 1.3 2006/10/11 07:56:10 wprinz Exp $
+ */
+package test.at.knowcenter.wag.egov.egiz.detached;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.log4j.Logger;
+
+import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
+
+/**
+ * @author wprinz
+ */
+public abstract class BKUPostConnection
+{
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger_ = ConfigLogger.getLogger(BKUPostConnection.class);
+
+ /**
+ * This method connects the BKU server getting the request and the url. The
+ * request is an XML Message send and recieve by the HttpClient module. The
+ * Response message of the BKU server is is send back to the calling method.
+ *
+ * @param url
+ * the URL which the BKU server is running
+ * @param request
+ * the request string (XML) to send.
+ * @return the response string (XML) of the BKU server
+ * @throws IOException
+ * @throws HttpException
+ * ErrorCode:320
+ */
+
+ public static Properties doPostRequest272(String url, String request,
+ byte[] signdata, String mimetype) throws HttpException, IOException
+ {
+ // // TODO remove write request to File
+ // FileOutputStream fos = new
+ // FileOutputStream("F:\\PDFAS_SVN\\trunk\\work\\pdfastmp\\bku_request.xml");
+ // fos.write(request.getBytes("UTF-8"));
+ // fos.close();
+
+ StringPart xmlpart = new StringPart("XmlRequest", request, "UTF-8");
+ xmlpart.setContentType(null);
+ xmlpart.setTransferEncoding(null);
+ // BKU 2.7.4 can't handle the Content-Type Header for the XML
+ // xmlpart.setContentType("text/xml");
+ // xmlpart.setTransferEncoding(null);
+
+ String filename = mimetype.equals("application/pdf") ? "myfile.pdf" : "myfile.txt";
+ ByteArrayPartSource baps = new ByteArrayPartSource(filename, signdata);
+ // FilePart fpart = new FilePart("fileupload",signdata.getName(), signdata);
+ FilePart filepart = new FilePart("fileupload", baps);
+ filepart.setContentType(mimetype);
+
+ // Part[] parts = {fpart, xmlrequest};
+ Part[] parts = { xmlpart, filepart };
+
+ HttpMethodParams method_params = new HttpMethodParams();
+ method_params.setContentCharset("UTF-8");
+
+ PostMethod post_method = new PostMethod(url);
+ post_method.setParams(method_params);
+
+ MultipartRequestEntity mprqe = new MultipartRequestEntity(parts, post_method.getParams());
+ post_method.setRequestEntity(mprqe);
+
+ HttpClient http_client = new HttpClient();
+ int method_response = http_client.executeMethod(post_method);
+ logger_.debug("method_response = " + method_response);
+
+ Properties response_properties = new Properties();
+
+ if (logger_.isDebugEnabled())
+ {
+ Header[] response_headers = post_method.getResponseHeaders();
+ for (int i = 0; i < response_headers.length; i++)
+ {
+ logger_.debug(" response_header[" + i + "]: name = " + response_headers[i].getName() + ", value = " + response_headers[i].getValue());
+ }
+ }
+ // Header server_header = post_method.getResponseHeader("Server");
+
+ // TODO does BKU really send Content-Type Header
+ logger_.debug(post_method.getResponseCharSet());
+ if (!post_method.getResponseCharSet().equals("UTF-8"))
+ {
+ logger_.error("BKU response charset is not UTF-8!");
+ }
+ String response_string = post_method.getResponseBodyAsString();
+
+// byte[] response_body = post_method.getResponseBody();
+// String response_string = new String(response_body, "UTF-8");
+
+ response_properties.setProperty("response_string", response_string);
+
+ return response_properties;
+ }
+
+ /**
+ * This method connects the BKU server getting the request and the url. The
+ * request is an XML Message send and recieve by the HttpClient module. The
+ * Response message of the BKU server is is send back to the calling method.
+ *
+ * @param url
+ * the URL which the BKU server is running
+ * @param request
+ * the request string (XML) to send.
+ * @return the response string (XML) of the BKU server
+ * @throws IOException
+ * @throws HttpException
+ * ErrorCode:320
+ */
+ public static Properties doPostRequest(String url, String request) throws HttpException, IOException
+ {
+
+ PostMethod post_method = new PostMethod(url);
+
+ // It is very important to specify the charset of the content (the request)
+ // as UTF-8 this way.
+ // The HttpClient will then perform the URL encoding assuming that the
+ // request is UTF-8 as the BKU expects.
+ // If the MethodParams are omitted, the HttpClient will assume that the
+ // request is ISO-8859-1 and thereby the BKU cannot properly decode it.
+ HttpMethodParams method_params = new HttpMethodParams();
+ method_params.setContentCharset("UTF-8");
+ post_method.setParams(method_params);
+
+ // This is just a hint: do not set the content-type this way or the BKU will
+ // assume it as text/XML, but the HttpClient sends it as URL-encoded.
+ // The HttpClient will automatically generate the proper Content-Type:
+ // application/x-www-form-urlencoded
+ // post.addRequestHeader(new Header("Content-Type",
+ // "text/xml;charset=UTF-8"));
+
+ NameValuePair[] data = { new NameValuePair("XMLRequest", request) };
+ post_method.setRequestBody(data);
+
+ HttpClient http_client = new HttpClient();
+ int method_response = http_client.executeMethod(post_method);
+ logger_.debug("method_response = " + method_response);
+
+ Properties response_properties = new Properties();
+
+ if (logger_.isDebugEnabled())
+ {
+ Header[] response_headers = post_method.getResponseHeaders();
+ logger_.debug("#" + response_headers.length + " headers in response:");
+ for (int i = 0; i < response_headers.length; i++)
+ {
+ logger_.debug(" response_header[" + i + "]: name = " + response_headers[i].getName() + ", value = " + response_headers[i].getValue());
+ }
+ }
+
+ Header server_header = post_method.getResponseHeader("Server");
+ logger_.debug("server_header: name = " + server_header.getName() + ", value = " + server_header.getValue());
+ parseBKUVersion(server_header.getValue(), response_properties);
+
+ byte[] response_body = post_method.getResponseBody();
+ String response_string = new String(response_body, "UTF-8");
+
+ // Alternatively this could be used.
+ // The HttpClient is assumed to use the Content-Type provided by the
+ // response.
+ // String response_string = post.getResponseBodyAsString();
+
+ response_properties.setProperty("response_string", response_string);
+
+ return response_properties;
+ }
+
+ // TODO hotfix
+ public static void parseBKUVersion(String header_value, Properties properties)
+ {
+ Pattern pattern = Pattern.compile("^citizen-card-environment/(\\d+\\.\\d+) (.+)/(\\d+\\.\\d+\\.\\d+)$");
+ Matcher m = pattern.matcher(header_value);
+
+ m.matches();
+
+ logger_.debug("group count = " + m.groupCount());
+
+ for (int i = 0; i <= m.groupCount(); i++)
+ {
+ logger_.debug(" group[" + i + "] = " + m.group(i));
+ }
+
+ final String cceVersion = m.group(1);
+ final String productName = m.group(2);
+ final String productVersion = m.group(3);
+
+ logger_.debug("cceVersion = " + cceVersion);
+ logger_.debug("productName = " + productName);
+ logger_.debug("productVersion = " + productVersion);
+
+ properties.setProperty("cceVersion", cceVersion);
+ properties.setProperty("productName", productName);
+ properties.setProperty("productVersion", productVersion);
+ }
+}
diff --git a/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/MOAConnector.java b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/MOAConnector.java
new file mode 100644
index 0000000..e6df790
--- /dev/null
+++ b/src/test/java/test/at/knowcenter/wag/egov/egiz/detached/MOAConnector.java
@@ -0,0 +1,869 @@
+/*
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $Id: MOAConnector.java,v 1.5 2006/10/31 08:18:41 wprinz Exp $
+ */
+package test.at.knowcenter.wag.egov.egiz.detached;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.rpc.Call;
+import javax.xml.rpc.Service;
+import javax.xml.rpc.ServiceFactory;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Document;
+
+import at.knowcenter.wag.egov.egiz.PdfASID;
+import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException;
+import at.knowcenter.wag.egov.egiz.exceptions.WebException;
+import at.knowcenter.wag.egov.egiz.sig.Connector;
+import at.knowcenter.wag.egov.egiz.sig.ConnectorInformation;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
+import at.knowcenter.wag.egov.egiz.sig.X509Cert;
+import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorConfigurationKeys;
+import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
+import at.knowcenter.wag.egov.egiz.tools.FileHelper;
+
+/**
+ * Connector to access the MOA service.
+ *
+ * @author wlackner
+ * @author wprinz
+ */
+public class MOAConnector
+{
+ /**
+ * ConnectorInformation that identifies this Connector to the system.
+ *
+ * @see at.knowcenter.wag.egov.egiz.sig.ConnectorFactory
+ * @see ConnectorInformation
+ */
+ public static final ConnectorInformation CONNECTOR_INFORMATION = new ConnectorInformation("moa", "MOA");
+
+ /**
+ * The class type value.
+ *
+ * <p>
+ * Just for convenience.
+ * </p>
+ */
+ private static final String TYPE = CONNECTOR_INFORMATION.getIdentifier();
+
+ /**
+ * The connector description.
+ */
+ public static final String DESCRIPTION = "MOA";
+
+ /**
+ * The SettingsReader instance
+ */
+ private SettingsReader settings_ = null;
+
+ /**
+ * MOA siganture verification mode
+ */
+ public static final String SERVICE_VERIFY = "SignatureVerification";
+
+ /**
+ * MOA siganture creation mode
+ */
+ public static final String SERVICE_SIGN = "SignatureCreation";
+
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger_ = ConfigLogger.getLogger(MOAConnector.class);
+
+ /**
+ * The empty constructor
+ */
+ public MOAConnector() throws SignatureException
+ {
+ loadSettings();
+ }
+
+ /**
+ * load the inital signature settings
+ *
+ * @see SettingsReader
+ */
+ private void loadSettings() throws SignatureException
+ {
+ if (settings_ == null)
+ {
+ try
+ {
+ settings_ = SettingsReader.getInstance();
+ }
+ catch (SettingsException e)
+ {
+ String log_message = "Can not load signature settings. Cause:\n" + e.getMessage();
+ logger_.error(log_message);
+ throw new SignatureException(101, log_message, e);
+ }
+ }
+ }
+
+ public SignatureObject doSign(String sigType, byte [] data, PdfASID algorithm) throws SignatureException
+ {
+ SignatureObject sig_obj = new SignatureObject();
+ try
+ {
+ sig_obj.setSigType(sigType);
+ sig_obj.initByType();
+ }
+ catch (SignatureTypesException e)
+ {
+ SignatureException se = new SignatureException(300, "Can ot init signature object with type:" + sigType, e);
+ throw se;
+ }
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("Signature Type is:" + sig_obj.getSignationType());
+ }
+
+ String url = getSignURL(sigType);
+
+ String sign_request_filename = "./templates/MOASignRequestDetached.xml";//getSignRequestTemplateFileName(sigType);
+ String key_ident = getSignKeyIdentifier(sigType);
+ String sign_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
+ if (sign_req_str == null)
+ {
+ SignatureException se = new SignatureException(300, "File not found:" + sign_request_filename);
+ throw se;
+ }
+
+ sign_req_str = sign_req_str.replaceFirst("KeyIdentifierReplace", key_ident);
+ if (logger_.isDebugEnabled())
+ {
+ //logger_.debug("error_signature_response = " + sign_req_str);
+ // FileHelper.writeToFile(sign_request_filename + "_signText.xml",
+ // signText);
+ }
+ // sign_req_str = sign_req_str.replaceFirst("XMLContentReplace", signText);
+ // now use the the base64 Template
+// signText = CodingHelper.encodeUTF8AsBase64(signText);
+// sign_req_str = sign_req_str.replaceFirst("Base64ContentReplace", signText);
+// if (logger_.isDebugEnabled())
+// {
+// //logger_.debug(sign_req_str);
+// // FileHelper.writeToFile(sign_request_filename + "_request.xml",
+// // sign_req_str);
+// }
+
+ String response_string = "";
+ try
+ {
+ response_string = MOAConnector.connectMOA(sign_req_str, MOAConnector.SERVICE_SIGN, url);
+ sig_obj.setRawSignatureResponse(response_string);
+ }
+ catch (WebException we)
+ {
+ if (logger_.isDebugEnabled())
+ {
+ we.printStackTrace();
+ }
+ SignatureException se = new SignatureException(we.getErrorCode(), we);
+ throw se;
+ }
+
+ if (!response_string.equals(""))
+ {
+ if (logger_.isInfoEnabled())
+ {
+ logger_.info("get MOA response");
+ }
+ Pattern erc_p_s = Pattern.compile("<ErrorCode>");
+ Pattern erc_p_e = Pattern.compile("</ErrorCode>");
+ Matcher erc_m_s = erc_p_s.matcher(response_string);
+ Matcher erc_m_e = erc_p_e.matcher(response_string);
+ // System.err.println(response_string);
+
+ if (erc_m_s.find() && erc_m_e.find())
+ {
+ if (logger_.isEnabledFor(Level.ERROR))
+ {
+ logger_.error("error_signature_response = " + response_string);
+ // FileHelper.writeToFile(sign_request_filename + "_response.xml",
+ // response_string);
+ //logger_.error("Write error response to file:" + sign_request_filename + "_response.xml");
+ }
+ Pattern erm_p_s = Pattern.compile("<Info>");
+ Pattern erm_p_e = Pattern.compile("</Info>");
+ Matcher erm_m_s = erm_p_s.matcher(response_string);
+ Matcher erm_m_e = erm_p_e.matcher(response_string);
+
+ String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start());
+ logger_.debug("error_code = " + error_code);
+ String error_mess = "";
+ if (erm_m_s.find() && erm_m_e.find())
+ {
+ error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start());
+ logger_.debug(error_mess);
+ }
+ SignatureException se = new SignatureException(0, "MOASigExc ext error code = " + error_code + ", err_mess = " + error_mess);
+ se.setExternalErrorCode(error_code);
+ se.setExternalErrorMessage(error_mess);
+ throw se;
+ }
+ else
+ {
+ if (logger_.isDebugEnabled())
+ {
+ //logger_.debug("response_string = " + response_string);
+ // FileHelper.writeToFile(sign_request_filename + "_response.xml",
+ // response_string);
+ }
+ parseCreateXMLResponse(response_string, sig_obj);
+ }
+ }
+ sig_obj.setSigResponse(response_string);
+ return sig_obj;
+ }
+
+ /**
+ * This method parses the MOA-Response string. It separates the
+ * SignatureValue, X509IssuerName, SigningTime, X509SerialNumber,
+ * X509Certificate, CertDigest and DigestValues. If the X509Certificate is
+ * extracted it would be stored in the certificates directory.
+ *
+ * @param xmlResponse
+ * the response string from the MOA sign-request
+ * @param sigObj
+ * the SignatureObject that should be filled
+ * @throws SignatureException
+ * ErrorCode (303, 304)
+ * @see SignatureObject
+ * @see CodingHelper
+ * @see X509Cert
+ */
+ private void parseCreateXMLResponse(String xmlResponse, SignatureObject sigObj) throws SignatureException
+ {
+ Pattern sig_val_p_s = Pattern.compile("<[\\w]*:?SignatureValue>");
+ Pattern sig_val_p_e = Pattern.compile("</[\\w]*:?SignatureValue>");
+ Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>");
+ Pattern iss_nam_p_e = Pattern.compile("</[\\w]*:?X509IssuerName>");
+ Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>");
+ Pattern sig_tim_p_e = Pattern.compile("</[\\w]*:?SigningTime>");
+ Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>");
+ Pattern ser_num_p_e = Pattern.compile("</[\\w]*:?X509SerialNumber>");
+ Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>");
+ Pattern sig_cer_p_e = Pattern.compile("</[\\w]*:?X509Certificate>");
+
+ Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>");
+ Pattern sig_cer_d_p_e = Pattern.compile("</[\\w]*:?CertDigest>");
+ Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>");
+ Pattern dig_val_p_e = Pattern.compile("</[\\w]*:?DigestValue>");
+
+ Matcher sig_val_m_s = sig_val_p_s.matcher(xmlResponse);
+ Matcher sig_val_m_e = sig_val_p_e.matcher(xmlResponse);
+ Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+ Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+ Matcher sig_tim_m_s = sig_tim_p_s.matcher(xmlResponse);
+ Matcher sig_tim_m_e = sig_tim_p_e.matcher(xmlResponse);
+ Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+ Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+ Matcher sig_cer_m_s = sig_cer_p_s.matcher(xmlResponse);
+ Matcher sig_cer_m_e = sig_cer_p_e.matcher(xmlResponse);
+
+ Matcher sig_cer_d_m_s = sig_cer_d_p_s.matcher(xmlResponse);
+ Matcher sig_cer_d_m_e = sig_cer_d_p_e.matcher(xmlResponse);
+
+ String sig_val = "";
+ String iss_nam = "";
+ String ser_num = "";
+ String sig_tim = "";
+ String sig_cer = "";
+ String sig_dig = "";
+
+ // SignatureValue
+ if (sig_val_m_s.find() && sig_val_m_e.find())
+ {
+ sig_val = xmlResponse.substring(sig_val_m_s.end(), sig_val_m_e.start());
+ sig_val = sig_val.replaceAll("\\s", "");
+ sigObj.setSignationValue(sig_val);
+ }
+ // X509IssuerName
+ if (iss_nam_m_s.find() && iss_nam_m_e.find())
+ {
+ iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+ sigObj.setSignationIssuer(iss_nam);
+ }
+ // X509SerialNumber
+ if (ser_num_m_s.find() && ser_num_m_e.find())
+ {
+ ser_num = xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start());
+ sigObj.setSignationSerialNumber(ser_num);
+ }
+ // SigningTime
+ if (sig_tim_m_s.find() && sig_tim_m_e.find())
+ {
+ sig_tim = xmlResponse.substring(sig_tim_m_s.end(), sig_tim_m_e.start());
+ sigObj.setSignationDate(sig_tim);
+ }
+ // CertDigest
+ if (sig_cer_d_m_s.find() && sig_cer_d_m_e.find())
+ {
+ String cert_digest = xmlResponse.substring(sig_cer_d_m_s.end(), sig_cer_d_m_e.start());
+ Matcher dig_val_m_s = dig_val_p_s.matcher(cert_digest);
+ Matcher dig_val_m_e = dig_val_p_e.matcher(cert_digest);
+ if (dig_val_m_s.find() && dig_val_m_e.find())
+ {
+ sig_dig = cert_digest.substring(dig_val_m_s.end(), dig_val_m_e.start());
+ sigObj.setX509CertificateDigest(sig_dig);
+ }
+ }
+ // extract Subject Name from X509Certificate
+ if (sig_cer_m_s.find() && sig_cer_m_e.find())
+ {
+ sig_cer = xmlResponse.substring(sig_cer_m_s.end(), sig_cer_m_e.start());
+ sig_cer = sig_cer.replaceAll("\\s", "");
+ X509Cert cert = X509Cert.initByString(sig_cer);
+ if (cert.isX509Cert())
+ {
+ sigObj.setX509Certificate(cert.getCertString());
+ String serial_num = cert.getSerialNumber();
+ String subject_name = cert.getSubjectName();
+ if (!ser_num.equals(serial_num))
+ {
+ SignatureException se = new SignatureException(303, "Serialnumber of certificate and tag X509SerialNumber differs!");
+ throw se;
+ }
+ sigObj.setSignationName(subject_name);
+ }
+ }
+ }
+
+ /**
+ * This method reads the verify template from the file system and fills out
+ * the template with the SignatureObject values.
+ *
+ * @param normalizedText
+ * the normalized text to veryfied
+ * @param sigObject
+ * the SignatureObject holding the singature values
+ * @return the filled verify template string
+ * @throws SignatureException
+ * ErrorCode (311, 312, 313)
+ * @see SignatureObject
+ * @see CodingHelper
+ */
+ public String getVerifyTemplate(String normalizedText,
+ SignatureObject sigObject) throws SignatureException
+ {
+ try
+ {
+ if (normalizedText == null || normalizedText.length() == 0)
+ {
+ SignatureException se = new SignatureException(311, "Document can not be verified because normalized text is empty.");
+ throw se;
+ }
+ if (sigObject == null)
+ {
+ SignatureException se = new SignatureException(312, "Document can not be verified because no signature object are set.");
+ throw se;
+ }
+ String verify_template = getVerifyTemplateFileName(sigObject.getSignationType());
+ String sig_prop_template = getSigPropFileName(sigObject.getSignationType());
+ String verify_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_template));
+ String sig_prop_str = FileHelper.readFromFile(SettingsReader.relocateFile(sig_prop_template));
+
+ if (logger_.isDebugEnabled())
+ {
+ //logger_.debug(verify_template);
+ //logger_.debug(sig_prop_template);
+ }
+
+ String x509Certificate = sigObject.getX509CertificateString();
+ if (x509Certificate == null)
+ {
+ SignatureException se = new SignatureException(313, "Document certificate is not defined.");
+ throw se;
+ }
+ String cert_alg = settings_.getValueFromKey("cert.alg.ecdsa");
+ X509Cert x509_cert = sigObject.getX509Cert();
+ if (x509_cert.isRSA())
+ {
+ cert_alg = settings_.getValueFromKey("cert.alg.rsa");
+ }
+
+ sig_prop_str = sig_prop_str.replaceFirst("SigningTimeReplace", sigObject.getSignationDate());
+ // The issuer is already a valid Unicode String.
+ // No need to convert it - not to mention the missing encoding.
+ // byte[] issuer_name =
+ // CodingHelper.encodeUTF8(sigObject.getSignationIssuer());
+ // new String(issuer_name)
+ sig_prop_str = sig_prop_str.replaceFirst("X509IssuerNameReplace", sigObject.getSignationIssuer());
+ sig_prop_str = sig_prop_str.replaceFirst("X509SerialNumberReplace", sigObject.getSignationSerialNumber());
+ sig_prop_str = sig_prop_str.replaceFirst("DigestValueX509CertificateReplace", sigObject.getX509CertificateDigest());
+
+ verify_req_str = verify_req_str.replaceFirst("CertAlgReplace", cert_alg);
+ verify_req_str = verify_req_str.replaceFirst("TemplateSignedPropertiesReplace", sig_prop_str);
+ byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8")); // added
+ // the
+ // ("UTF-8")
+ // encoding
+ String sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
+ verify_req_str = verify_req_str.replaceFirst("DigestValueSignedPropertiesReplace", sig_prop_hash);
+ if (logger_.isDebugEnabled())
+ {
+ logger_.debug("build digest from SignedProperties:start");
+ //logger_.debug("DATA :" + sig_prop_str);
+ logger_.debug("DIGEST:" + sig_prop_hash);
+ logger_.debug("build digest from SignedProperties:end");
+ }
+
+ verify_req_str = verify_req_str.replaceFirst("SignatureValueReplace", sigObject.getSignationValue());
+ verify_req_str = verify_req_str.replaceFirst("X509CertificateReplace", x509Certificate);
+ byte[] data_value = normalizedText.getBytes("UTF-8");
+ byte[] data_value_hash = CodingHelper.buildDigest(data_value);
+ // byte[] data_value_hash =
+ // CodingHelper.buildDigest(normalizedText.getBytes());
+ String object_data_hash = CodingHelper.encodeBase64(data_value_hash);
+ //String object_data = normalizedText; // new String(data_value);
+ // System.err.println(object_data_hash);
+ // very_req_str = very_req_str.replaceFirst("ObjectDataReplace",
+ // object_data);
+ String raw_b64 = CodingHelper.encodeBase64(data_value);
+ verify_req_str = verify_req_str.replaceFirst("Base64ContentReplace", raw_b64);
+
+ verify_req_str = verify_req_str.replaceFirst("DigestValueSignedDataReplace", object_data_hash);
+ if (logger_.isDebugEnabled())
+ {
+ // FileHelper.writeToFile(verify_template + "_verifyText.xml",
+ // normalizedText);
+ logger_.debug("build digest from data object:start");
+ //logger_.debug("DATA :" + object_data);
+ logger_.debug("DIGEST:" + object_data_hash);
+ logger_.debug("build digest from data object:end");
+ }
+ return verify_req_str;
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new SignatureException(310, e);
+ }
+ }
+
+// /**
+// * This method generates the MOA verify prozess. It checks if the given
+// * SignatureObject is signed by MOA or BKU. The verify template string is
+// * filled out by the corresponding method.
+// *
+// * @param normalizedText
+// * the normalized text to verify
+// * @param sigObject
+// * the SignatureObject holding the singature values
+// * @return a SignatureResponse object if the verify prozess does not fails
+// * @throws SignatureException
+// * @see SignatureResponse
+// */
+// public SignatureResponse doVerify(String normalizedText,
+// SignatureObject sigObject) throws SignatureException
+// {
+// String verify_url = getVerifyURL(sigObject.getSignationType()); // settings_.getValueFromKey(TYPE
+// // + "." +
+// // Signature.VALUE_MODE_VERIFY
+// // +
+// // ".url");
+// String verify_request = getVerifyRequestTemplateFileName(sigObject.getSignationType()); // settings_.getValueFromKey(TYPE
+// // +
+// // "."
+// // +
+// // Signature.VALUE_MODE_VERIFY
+// // +
+// // ".request");
+// String trust_profile = getVerifyTrustProfileID(sigObject.getSignationType());
+// String verify_req_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request));
+//
+// String verify_template_str = null;
+// if (sigObject.isMOASigned())
+// {
+// verify_template_str = getVerifyTemplate(normalizedText, sigObject);
+// }
+// else
+// {
+// BKUConnector bku_conn = new BKUConnector();
+// verify_template_str = bku_conn.getVerifyTemplate(normalizedText, sigObject);
+// }
+// verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
+// verify_req_str = verify_req_str.replaceFirst("TrustProfileIDReplace", trust_profile);
+//
+// if (logger_.isDebugEnabled())
+// {
+// //logger_.debug(verify_req_str);
+// // FileHelper.writeToFile(verify_request + "_request.xml",
+// // verify_req_str);
+// }
+// String response_string = "";
+// try
+// {
+// response_string = MOAConnector.connectMOA(verify_req_str, MOAConnector.SERVICE_VERIFY, verify_url);
+// }
+// catch (WebException we)
+// {
+// if (logger_.isDebugEnabled())
+// {
+// we.printStackTrace();
+// }
+// SignatureException se = new SignatureException(we.getErrorCode(), we);
+// throw se;
+// }
+//
+// if (!response_string.equals(""))
+// {
+// Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>");
+// Pattern erc_p_e = Pattern.compile("</[\\w]*:?ErrorCode>");
+// Matcher erc_m_s = erc_p_s.matcher(response_string);
+// Matcher erc_m_e = erc_p_e.matcher(response_string);
+//
+// if (erc_m_s.find() && erc_m_e.find())
+// {
+// if (logger_.isEnabledFor(Level.ERROR))
+// {
+// //logger_.debug(response_string);
+// // FileHelper.writeToFile(verify_request + "_response.xml",
+// // response_string);
+// logger_.error("Write error response to file:" + verify_request + "_response.xml");
+// }
+// Pattern erm_p_s = Pattern.compile("<[\\w]*:?Info>");
+// Pattern erm_p_e = Pattern.compile("</[\\w]*:?Info>");
+// Matcher erm_m_s = erm_p_s.matcher(response_string);
+// Matcher erm_m_e = erm_p_e.matcher(response_string);
+// SignatureException se = new SignatureException(0, "MOASigExc2");
+// String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start());
+// se.setExternalErrorCode(error_code);
+// if (erm_m_s.find() && erm_m_e.find())
+// {
+// String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start());
+// se.setExternalErrorMessage(error_mess);
+// }
+// throw se;
+// }
+// else
+// {
+// if (logger_.isDebugEnabled())
+// {
+// //logger_.debug(verify_request + "_response.xml " + response_string);
+// }
+// return parseVerifyXMLResponse(response_string);
+// }
+// }
+// return null;
+// }
+
+// /**
+// * This method parses the verify response string and return a
+// * SignatureResponse object. The SignatureResponse object is filled out by the
+// * response values from the BKU-response.
+// *
+// * @param xmlResponse
+// * the response values from the MOA-verify request
+// * @return SignatureResponse object
+// * @see SignatureResponse
+// */
+// private SignatureResponse parseVerifyXMLResponse(String xmlResponse)
+// {
+// if (logger_.isInfoEnabled())
+// {
+// logger_.info("Try parsing the verify response");
+// }
+// Pattern sub_nam_p_s = Pattern.compile("<dsig:X509SubjectName>");
+// Pattern sub_nam_p_e = Pattern.compile("</dsig:X509SubjectName>");
+// Pattern iss_nam_p_s = Pattern.compile("<dsig:X509IssuerName>");
+// Pattern iss_nam_p_e = Pattern.compile("</dsig:X509IssuerName>");
+// Pattern ser_num_p_s = Pattern.compile("<dsig:X509SerialNumber>");
+// Pattern ser_num_p_e = Pattern.compile("</dsig:X509SerialNumber>");
+//
+// // [tknall] start qualified certificate
+// Pattern cert_qualified_p = Pattern.compile("<QualifiedCertificate/>");
+// Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse);
+// // [tknall] stop qualified certificate
+//
+// Pattern sig_chk_p_s = Pattern.compile("<SignatureCheck>");
+// Pattern sig_chk_p_e = Pattern.compile("</SignatureCheck>");
+// Pattern man_chk_p_s = Pattern.compile("<SignatureManifestCheck>");
+// Pattern man_chk_p_e = Pattern.compile("</SignatureManifestCheck>");
+// Pattern cer_chk_p_s = Pattern.compile("<CertificateCheck>");
+// Pattern cer_chk_p_e = Pattern.compile("</CertificateCheck>");
+//
+// Pattern code_p_s = Pattern.compile("<Code>");
+// Pattern code_p_e = Pattern.compile("</Code>");
+//
+// Pattern cert_p_s = Pattern.compile("<dsig:X509Certificate>");
+// Pattern cert_p_e = Pattern.compile("</dsig:X509Certificate>");
+//
+// Matcher sub_nam_m_s = sub_nam_p_s.matcher(xmlResponse);
+// Matcher sub_nam_m_e = sub_nam_p_e.matcher(xmlResponse);
+// Matcher iss_nam_m_s = iss_nam_p_s.matcher(xmlResponse);
+// Matcher iss_nam_m_e = iss_nam_p_e.matcher(xmlResponse);
+// Matcher ser_num_m_s = ser_num_p_s.matcher(xmlResponse);
+// Matcher ser_num_m_e = ser_num_p_e.matcher(xmlResponse);
+//
+// Matcher sig_chk_m_s = sig_chk_p_s.matcher(xmlResponse);
+// Matcher sig_chk_m_e = sig_chk_p_e.matcher(xmlResponse);
+// Matcher man_chk_m_s = man_chk_p_s.matcher(xmlResponse);
+// Matcher man_chk_m_e = man_chk_p_e.matcher(xmlResponse);
+// Matcher cer_chk_m_s = cer_chk_p_s.matcher(xmlResponse);
+// Matcher cer_chk_m_e = cer_chk_p_e.matcher(xmlResponse);
+//
+// Matcher cert_m_s = cert_p_s.matcher(xmlResponse);
+// Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
+//
+// SignatureResponse sig_res = new SignatureResponse();
+//
+// // [tknall] start qualified certificate
+// sig_res.setQualifiedCertificate(cert_qualified_m.find());
+// // [tknall] stop qualified certificate
+//
+// if (sub_nam_m_s.find() && sub_nam_m_e.find())
+// {
+// String sub_nam = xmlResponse.substring(sub_nam_m_s.end(), sub_nam_m_e.start());
+// sig_res.setX509SubjectName(sub_nam);
+// }
+// if (iss_nam_m_s.find() && iss_nam_m_e.find())
+// {
+// String iss_nam = xmlResponse.substring(iss_nam_m_s.end(), iss_nam_m_e.start());
+// sig_res.setX509IssuerName(iss_nam);
+// }
+// if (ser_num_m_s.find() && ser_num_m_e.find())
+// {
+// String ser_num = xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start());
+// sig_res.setX509SerialNumber(ser_num);
+// }
+// if (sig_chk_m_s.find() && sig_chk_m_e.find())
+// {
+// String sig_chk = xmlResponse.substring(sig_chk_m_s.end(), sig_chk_m_e.start());
+// Matcher code_m_s = code_p_s.matcher(sig_chk);
+// Matcher code_m_e = code_p_e.matcher(sig_chk);
+// if (code_m_s.find() && code_m_e.find())
+// {
+// String code = sig_chk.substring(code_m_s.end(), code_m_e.start());
+// sig_res.setSignatureCheckCode(code);
+// }
+// }
+// if (man_chk_m_s.find() && man_chk_m_e.find())
+// {
+// String man_chk = xmlResponse.substring(man_chk_m_s.end(), man_chk_m_e.start());
+// Matcher code_m_s = code_p_s.matcher(man_chk);
+// Matcher code_m_e = code_p_e.matcher(man_chk);
+// if (code_m_s.find() && code_m_e.find())
+// {
+// String code = man_chk.substring(code_m_s.end(), code_m_e.start());
+// sig_res.setSignatureManifestCheckCode(code);
+// }
+// }
+// if (cer_chk_m_s.find() && cer_chk_m_e.find())
+// {
+// String cer_chk = xmlResponse.substring(cer_chk_m_s.end(), cer_chk_m_e.start());
+// Matcher code_m_s = code_p_s.matcher(cer_chk);
+// Matcher code_m_e = code_p_e.matcher(cer_chk);
+// if (code_m_s.find() && code_m_e.find())
+// {
+// String code = cer_chk.substring(code_m_s.end(), code_m_e.start());
+// sig_res.setCertificateCheckCode(code);
+// }
+// }
+// if (cert_m_s.find() && cert_m_e.find())
+// {
+// String cert_string = xmlResponse.substring(cert_m_s.end(), cert_m_e.start());
+//
+// X509Cert resp_cert = X509Cert.initByString(cert_string);
+// sig_res.setCertificate(resp_cert);
+// }
+//
+// return sig_res;
+// }
+
+ protected String getConnectorValueFromProfile(String profile, String key)
+ {
+ String value = settings_.getValueFromKey("sig_obj." + profile + "." + key);
+ if (value == null)
+ {
+ value = settings_.getValueFromKey(key);
+ }
+ return value;
+ }
+
+ public String getSignURL(String profile)
+ {
+ final String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".url";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSignRequestTemplateFileName(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".request";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSignKeyIdentifier(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_SIGN + ".KeyIdentifier";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ public String getVerifyURL(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".url";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getVerifyRequestTemplateFileName(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".request";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getVerifyTemplateFileName(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".template";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getSigPropFileName(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".template.SP";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ protected String getVerifyTrustProfileID(String profile)
+ {
+ String key = TYPE + "." + ConnectorConfigurationKeys.VALUE_MODE_VERIFY + ".TrustProfileID";
+ return getConnectorValueFromProfile(profile, key);
+ }
+
+ /**
+ * This method connects the moa server getting the requestString, the given
+ * serviseMode and the endpointUrl. The requestString is the envelope of the
+ * SOAP Message send and recieve by the AXIS module. The Response SOAP message
+ * of the MOA server is parsed by AXIS and the message envelope is send back
+ * to the calling method.
+ *
+ * @param requestString
+ * the request string (XML) to send.
+ * @param serviceMode
+ * the mode which connect to MOA
+ * @param endpointURL
+ * the URL which the MOA server is running
+ * @return the response string (XML) of the MOA server
+ * @throws WebException
+ */
+ public static String connectMOA(String requestString, String serviceMode,
+ String endpointURL) throws WebException
+ {
+ try
+ {
+ if (logger_.isInfoEnabled())
+ {
+ logger_.info(serviceMode);
+ logger_.info(endpointURL);
+ }
+ // Parser/DOMBuilder instanzieren
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+
+ // XML Datei in einen DOM-Baum umwandeln
+ ByteArrayInputStream bais = new ByteArrayInputStream(requestString.getBytes("UTF-8"));
+ Document xmlRequest = builder.parse(bais);
+
+ // Call öffnen
+ Call call = null;
+
+ // Neues BodyElement anlegen und mit dem DOM-Baum füllen
+ SOAPBodyElement body = new SOAPBodyElement(xmlRequest.getDocumentElement());
+ SOAPBodyElement[] params = new SOAPBodyElement[] { body };
+
+ // AXIS-Server instanzieren
+ Service service = ServiceFactory.newInstance().createService(new QName(serviceMode));
+ call = service.createCall();
+ call.setTargetEndpointAddress(endpointURL);
+
+ // Call auslösen und die Antworten speichern
+ if (logger_.isInfoEnabled())
+ {
+ logger_.info("Calling MOA:" + endpointURL);
+ }
+ Vector responses = (Vector) call.invoke(params);
+
+ // Erstes Body Element auslesen
+ SOAPBodyElement response = (SOAPBodyElement) responses.get(0);
+
+ // Aus der Response den DOM-Baum lesen
+ Document root_response = response.getAsDocument();
+ if (logger_.isInfoEnabled())
+ {
+ logger_.info("Return from MOA:" + serviceMode);
+ }
+
+ // XML-Formatierung konfiguieren
+ OutputFormat format = new OutputFormat((Document) root_response);
+ format.setLineSeparator("\n");
+ format.setIndenting(false);
+ format.setPreserveSpace(true);
+ format.setOmitXMLDeclaration(false);
+ format.setEncoding("UTF-8");
+
+ // Ausgabe der Webservice-Antwort auf die Konsole
+ // XMLSerializer conSerializer = new XMLSerializer(System.out, format);
+ // conSerializer.serialize(root_response);
+
+ // Ausgabe der Webservice-Antwort in Datei
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ XMLSerializer response_serializer = new XMLSerializer(baos, format);
+ response_serializer.serialize(root_response);
+ return baos.toString("UTF-8");
+ }
+ catch (Exception e)
+ {
+ throw new WebException(330, e);
+ }
+ // serialize signature only
+
+ // if
+ // (root_response.getDocumentElement().getLocalName().equals("CreateXMLSignatureResponse"))
+ // {
+ // Element signature = (Element)
+ // root_response.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#",
+ // "Signature").item(0);
+ // String signatureFile = getProperty(mode + "Request").substring(0,
+ // getProperty(mode +
+ // "Request").lastIndexOf('.')) + ".Signature.xml";
+ // fileSerializer = new XMLSerializer(new FileOutputStream(signatureFile),
+ // format);
+ // fileSerializer.serialize(signature);
+ // }
+
+ }
+} \ No newline at end of file
diff --git a/work/cfg/config.properties b/work/cfg/config.properties
index 292886e..53e6799 100644
--- a/work/cfg/config.properties
+++ b/work/cfg/config.properties
@@ -27,11 +27,23 @@ bku.sign.url=http://127.0.0.1:3495/http-security-layer-request
bku.sign.request=./templates/BKUSignRequestB64.xml
bku.sign.KeyboxIdentifier=SecureSignatureKeypair
+bku.sign.request.detached=./templates/BKUSignRequestDetached.xml
+
+bku.sign.request.binaer=./templates/BKUSignRequestBinaryDetached.xml
+bku.sign.request.text=./templates/BKUSignRequestTextualDetached.xml
+
bku.verify.url=http://127.0.0.1:3495/http-security-layer-request
bku.verify.request=./templates/BKUVerifyRequest.xml
+bku.verify.request.detached=./templates/BKUVerifyRequestDetached.xml
-bku.verify.template=./templates/BKUVerifyTemplateB64.xml
+# TODO
+#bku.verify.template=./templates/BKUVerifyTemplateB64.xml
+#bku.verify.template.SP=./templates/BKUVerifyTemplateSP.xml
+bku.verify.template=./templates/BKUVerifyTemplateDetached.xml
bku.verify.template.SP=./templates/BKUVerifyTemplateSP.xml
+
+bku.verify.template.detached=./templates/BKUVerifyTemplateDetached.xml
+
bku.verify.template2=./templates/BKUVerifyTemplateB64_neueBKU.xml
bku.verify.template2.SP=./templates/BKUVerifyTemplateSP_neueBKU.xml
diff --git a/work/cfg/log4j.properties b/work/cfg/log4j.properties
index f44c7d0..a3274a8 100644
--- a/work/cfg/log4j.properties
+++ b/work/cfg/log4j.properties
@@ -21,5 +21,7 @@ log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=%d{ISO8601} %-4r %-5p [%t] %c: %m%n
-log4j.logger.at.knowcenter.wag.egov.egiz = INFO
+log4j.logger.at.knowcenter.wag.egov.egiz = DEBUG
log4j.logger.at.knowcenter.wag.egov.egiz.ldap = DEBUG
+
+log4j.logger.test.at.knowcenter = DEBUG
diff --git a/work/templates/BKUSignRequestDetached.xml b/work/templates/BKUSignRequestDetached.xml
new file mode 100644
index 0000000..f809927
--- /dev/null
+++ b/work/templates/BKUSignRequestDetached.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:CreateXMLSignatureRequest xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
+<sl:KeyboxIdentifier>KeyboxIdentifierReplace</sl:KeyboxIdentifier>
+<sl:DataObjectInfo Structure="detached">
+<sl:DataObject Reference="urn:Document"/>
+<sl:TransformsInfo>
+<sl:FinalDataMetaInfo>
+<sl:MimeType>MimeTypeReplace</sl:MimeType>
+</sl:FinalDataMetaInfo>
+</sl:TransformsInfo>
+<sl:Supplement>
+<sl:Content Reference="urn:Document">
+<sl:LocRefContent>formdata:fileupload</sl:LocRefContent>
+</sl:Content>
+</sl:Supplement>
+</sl:DataObjectInfo>
+</sl:CreateXMLSignatureRequest> \ No newline at end of file
diff --git a/work/templates/BKUVerifyRequestDetached.xml b/work/templates/BKUVerifyRequestDetached.xml
new file mode 100644
index 0000000..ef9aa14
--- /dev/null
+++ b/work/templates/BKUVerifyRequestDetached.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:VerifyXMLSignatureRequest xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+<sl:SignatureInfo>
+<sl:SignatureEnvironment>
+<sl:XMLContent>XMLContentReplace</sl:XMLContent>
+</sl:SignatureEnvironment>
+<sl:SignatureLocation>/dsig:Signature</sl:SignatureLocation>
+</sl:SignatureInfo>
+<sl:Supplement>
+<sl:Content Reference="urn:Document">
+<sl:LocRefContent>formdata:fileupload</sl:LocRefContent>
+</sl:Content>
+</sl:Supplement>
+</sl:VerifyXMLSignatureRequest> \ No newline at end of file
diff --git a/work/templates/BKUVerifyTemplateDetached.xml b/work/templates/BKUVerifyTemplateDetached.xml
new file mode 100644
index 0000000..19a2c1c
--- /dev/null
+++ b/work/templates/BKUVerifyTemplateDetached.xml
@@ -0,0 +1,13 @@
+<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="signature-SigIdReplace">
+<dsig:SignedInfo>
+<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
+<dsig:SignatureMethod Algorithm="CertAlgReplace"/>
+<dsig:Reference Id="signed-data-reference-SigDataRefReplace" URI="urn:Document">
+<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+<dsig:DigestValue>DigestValueSignedDataReplace</dsig:DigestValue>
+</dsig:Reference>
+<dsig:Reference Id="etsi-data-reference-EtsiDataRefReplace" Type="http://uri.etsi.org/01903/v1.1.1#SignedProperties" URI="#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-data-object-EtsiDataObjURIReplace')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)"><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>DigestValueSignedPropertiesReplace</dsig:DigestValue></dsig:Reference></dsig:SignedInfo>
+<dsig:SignatureValue>SignatureValueReplace</dsig:SignatureValue>
+<dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>X509CertificateReplace</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo>
+<dsig:Object Id="etsi-data-object-EtsiDataObjURIReplace"><etsi:QualifyingProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#" Target="#signature-SigIdReplace"><etsi:SignedProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#"><etsi:SignedSignatureProperties><etsi:SigningTime>SigningTimeReplace</etsi:SigningTime><etsi:SigningCertificate><etsi:Cert><etsi:CertDigest><etsi:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></etsi:DigestMethod><etsi:DigestValue>DigestValueX509CertificateReplace</etsi:DigestValue></etsi:CertDigest><etsi:IssuerSerial><dsig:X509IssuerName>X509IssuerNameReplace</dsig:X509IssuerName><dsig:X509SerialNumber>X509SerialNumberReplace</dsig:X509SerialNumber></etsi:IssuerSerial></etsi:Cert></etsi:SigningCertificate><etsi:SignaturePolicyIdentifier><etsi:SignaturePolicyImplied></etsi:SignaturePolicyImplied></etsi:SignaturePolicyIdentifier></etsi:SignedSignatureProperties><etsi:SignedDataObjectProperties><etsi:DataObjectFormat ObjectReference="#signed-data-reference-SigDataRefReplace"><etsi:MimeType>MimeTypeReplace</etsi:MimeType></etsi:DataObjectFormat></etsi:SignedDataObjectProperties></etsi:SignedProperties></etsi:QualifyingProperties></dsig:Object>
+</dsig:Signature> \ No newline at end of file
diff --git a/work/templates/BKUSignRequestB64.xml b/work/templates/old/BKUSignRequestB64.xml
index 4cebb0e..4cebb0e 100644
--- a/work/templates/BKUSignRequestB64.xml
+++ b/work/templates/old/BKUSignRequestB64.xml
diff --git a/work/templates/old/BKUSignRequestBinaryDetached.xml b/work/templates/old/BKUSignRequestBinaryDetached.xml
new file mode 100644
index 0000000..ab154ad
--- /dev/null
+++ b/work/templates/old/BKUSignRequestBinaryDetached.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:CreateXMLSignatureRequest xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
+<sl:KeyboxIdentifier>KeyboxIdentifierReplace</sl:KeyboxIdentifier>
+<sl:DataObjectInfo Structure="detached">
+<sl:DataObject Reference="urn:Document"/>
+<sl:TransformsInfo>
+<sl:FinalDataMetaInfo>
+<sl:MimeType>application/pdf</sl:MimeType>
+</sl:FinalDataMetaInfo>
+</sl:TransformsInfo>
+<sl:Supplement>
+<sl:Content Reference="urn:Document">
+<sl:LocRefContent>formdata:fileupload</sl:LocRefContent>
+</sl:Content>
+</sl:Supplement>
+</sl:DataObjectInfo>
+</sl:CreateXMLSignatureRequest> \ No newline at end of file
diff --git a/work/templates/old/BKUSignRequestTextualDetached.xml b/work/templates/old/BKUSignRequestTextualDetached.xml
new file mode 100644
index 0000000..e673422
--- /dev/null
+++ b/work/templates/old/BKUSignRequestTextualDetached.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:CreateXMLSignatureRequest xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
+<sl:KeyboxIdentifier>KeyboxIdentifierReplace</sl:KeyboxIdentifier>
+<sl:DataObjectInfo Structure="detached">
+<sl:DataObject Reference="urn:Document"/>
+<sl:TransformsInfo>
+<sl:FinalDataMetaInfo>
+<sl:MimeType>text/plain</sl:MimeType>
+</sl:FinalDataMetaInfo>
+</sl:TransformsInfo>
+<sl:Supplement>
+<sl:Content Reference="urn:Document">
+<sl:LocRefContent>formdata:fileupload</sl:LocRefContent>
+</sl:Content>
+</sl:Supplement>
+</sl:DataObjectInfo>
+</sl:CreateXMLSignatureRequest> \ No newline at end of file
diff --git a/work/templates/BKUVerifyRequest.xml b/work/templates/old/BKUVerifyRequest.xml
index e232e51..e232e51 100644
--- a/work/templates/BKUVerifyRequest.xml
+++ b/work/templates/old/BKUVerifyRequest.xml
diff --git a/work/templates/BKUVerifyTemplateB64.xml b/work/templates/old/BKUVerifyTemplateB64.xml
index 229cb4f..229cb4f 100644
--- a/work/templates/BKUVerifyTemplateB64.xml
+++ b/work/templates/old/BKUVerifyTemplateB64.xml
diff --git a/work/templates/BKUVerifyTemplateB64_neueBKU.xml b/work/templates/old/BKUVerifyTemplateB64_neueBKU.xml
index 36b543a..36b543a 100644
--- a/work/templates/BKUVerifyTemplateB64_neueBKU.xml
+++ b/work/templates/old/BKUVerifyTemplateB64_neueBKU.xml
diff --git a/work/templates/old/BKUVerifyTemplateDetached_mitQPextern.xml b/work/templates/old/BKUVerifyTemplateDetached_mitQPextern.xml
new file mode 100644
index 0000000..3c178b8
--- /dev/null
+++ b/work/templates/old/BKUVerifyTemplateDetached_mitQPextern.xml
@@ -0,0 +1,13 @@
+<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Id="signature-SigIdReplace">
+<dsig:SignedInfo>
+<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
+<dsig:SignatureMethod Algorithm="CertAlgReplace"/>
+<dsig:Reference Id="signed-data-reference-SigDataRefReplace" URI="urn:Document">
+<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+<dsig:DigestValue>DigestValueSignedDataReplace</dsig:DigestValue>
+</dsig:Reference>
+<dsig:Reference Id="etsi-data-reference-EtsiDataRefReplace" Type="http://uri.etsi.org/01903/v1.1.1#SignedProperties" URI="#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-data-object-EtsiDataObjURIReplace')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)"><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>DigestValueSignedPropertiesReplace</dsig:DigestValue></dsig:Reference></dsig:SignedInfo>
+<dsig:SignatureValue>SignatureValueReplace</dsig:SignatureValue>
+<dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>X509CertificateReplace</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo>
+<dsig:Object Id="etsi-data-object-EtsiDataObjURIReplace">TemplateQualifyingPropertiesReplace</dsig:Object>
+</dsig:Signature> \ No newline at end of file
diff --git a/work/templates/BKUVerifyTemplateSP.xml b/work/templates/old/BKUVerifyTemplateSP.xml
index 0360b58..0360b58 100644
--- a/work/templates/BKUVerifyTemplateSP.xml
+++ b/work/templates/old/BKUVerifyTemplateSP.xml
diff --git a/work/templates/BKUVerifyTemplateSP_neueBKU.xml b/work/templates/old/BKUVerifyTemplateSP_neueBKU.xml
index 2589e62..2589e62 100644
--- a/work/templates/BKUVerifyTemplateSP_neueBKU.xml
+++ b/work/templates/old/BKUVerifyTemplateSP_neueBKU.xml
diff --git a/work/templates/old/BKUVerifyTemplateSP_neueBKU_bin.xml b/work/templates/old/BKUVerifyTemplateSP_neueBKU_bin.xml
new file mode 100644
index 0000000..8570227
--- /dev/null
+++ b/work/templates/old/BKUVerifyTemplateSP_neueBKU_bin.xml
@@ -0,0 +1 @@
+<etsi:QualifyingProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#" Target="#signature-SigIdReplace"><etsi:SignedProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#"><etsi:SignedSignatureProperties><etsi:SigningTime>SigningTimeReplace</etsi:SigningTime><etsi:SigningCertificate><etsi:Cert><etsi:CertDigest><etsi:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></etsi:DigestMethod><etsi:DigestValue>DigestValueX509CertificateReplace</etsi:DigestValue></etsi:CertDigest><etsi:IssuerSerial><dsig:X509IssuerName>X509IssuerNameReplace</dsig:X509IssuerName><dsig:X509SerialNumber>X509SerialNumberReplace</dsig:X509SerialNumber></etsi:IssuerSerial></etsi:Cert></etsi:SigningCertificate><etsi:SignaturePolicyIdentifier><etsi:SignaturePolicyImplied></etsi:SignaturePolicyImplied></etsi:SignaturePolicyIdentifier></etsi:SignedSignatureProperties><etsi:SignedDataObjectProperties><etsi:DataObjectFormat ObjectReference="#signed-data-reference-SigDataRefReplace"><etsi:MimeType>application/pdf</etsi:MimeType></etsi:DataObjectFormat></etsi:SignedDataObjectProperties></etsi:SignedProperties></etsi:QualifyingProperties> \ No newline at end of file
diff --git a/work/templates/old/BKUVerifyTemplateSP_neueBKU_text.xml b/work/templates/old/BKUVerifyTemplateSP_neueBKU_text.xml
new file mode 100644
index 0000000..2589e62
--- /dev/null
+++ b/work/templates/old/BKUVerifyTemplateSP_neueBKU_text.xml
@@ -0,0 +1 @@
+<etsi:QualifyingProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#" Target="#signature-SigIdReplace"><etsi:SignedProperties xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#"><etsi:SignedSignatureProperties><etsi:SigningTime>SigningTimeReplace</etsi:SigningTime><etsi:SigningCertificate><etsi:Cert><etsi:CertDigest><etsi:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></etsi:DigestMethod><etsi:DigestValue>DigestValueX509CertificateReplace</etsi:DigestValue></etsi:CertDigest><etsi:IssuerSerial><dsig:X509IssuerName>X509IssuerNameReplace</dsig:X509IssuerName><dsig:X509SerialNumber>X509SerialNumberReplace</dsig:X509SerialNumber></etsi:IssuerSerial></etsi:Cert></etsi:SigningCertificate><etsi:SignaturePolicyIdentifier><etsi:SignaturePolicyImplied></etsi:SignaturePolicyImplied></etsi:SignaturePolicyIdentifier></etsi:SignedSignatureProperties><etsi:SignedDataObjectProperties><etsi:DataObjectFormat ObjectReference="#signed-data-reference-SigDataRefReplace"><etsi:MimeType>text/plain</etsi:MimeType></etsi:DataObjectFormat></etsi:SignedDataObjectProperties></etsi:SignedProperties></etsi:QualifyingProperties> \ No newline at end of file
diff --git a/work/templates/MOASignRequest.xml b/work/templates/old/MOASignRequest.xml
index 4873f5e..4873f5e 100644
--- a/work/templates/MOASignRequest.xml
+++ b/work/templates/old/MOASignRequest.xml
diff --git a/work/templates/MOASignRequestB64.xml b/work/templates/old/MOASignRequestB64.xml
index 3c08c9e..3c08c9e 100644
--- a/work/templates/MOASignRequestB64.xml
+++ b/work/templates/old/MOASignRequestB64.xml
diff --git a/work/templates/old/MOASignRequestDetached.xml b/work/templates/old/MOASignRequestDetached.xml
new file mode 100644
index 0000000..5011443
--- /dev/null
+++ b/work/templates/old/MOASignRequestDetached.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CreateXMLSignatureRequest xmlns="http://reference.e-government.gv.at/namespace/moa/20020822#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+<KeyIdentifier>KeyIdentifierReplace</KeyIdentifier>
+<SingleSignatureInfo SecurityLayerConformity="true">
+<DataObjectInfo Structure="detached">
+<DataObject Reference="urn:Document">
+ <LocRefContent>formdata:fileupload</LocRefContent>
+</DataObject>
+<CreateTransformsInfoProfile>
+<CreateTransformsInfo>
+<FinalDataMetaInfo>
+<MimeType>text/plain</MimeType>
+</FinalDataMetaInfo>
+</CreateTransformsInfo>
+</CreateTransformsInfoProfile>
+</DataObjectInfo>
+</SingleSignatureInfo>
+</CreateXMLSignatureRequest>
+
diff --git a/work/templates/MOAVerifyRequest.xml b/work/templates/old/MOAVerifyRequest.xml
index 04c6863..04c6863 100644
--- a/work/templates/MOAVerifyRequest.xml
+++ b/work/templates/old/MOAVerifyRequest.xml
diff --git a/work/templates/MOAVerifyTemplate.xml b/work/templates/old/MOAVerifyTemplate.xml
index ce63949..ce63949 100644
--- a/work/templates/MOAVerifyTemplate.xml
+++ b/work/templates/old/MOAVerifyTemplate.xml
diff --git a/work/templates/MOAVerifyTemplateB64.xml b/work/templates/old/MOAVerifyTemplateB64.xml
index 547bc7c..547bc7c 100644
--- a/work/templates/MOAVerifyTemplateB64.xml
+++ b/work/templates/old/MOAVerifyTemplateB64.xml
diff --git a/work/templates/MOAVerifyTemplateSP.xml b/work/templates/old/MOAVerifyTemplateSP.xml
index 9e902a3..9e902a3 100644
--- a/work/templates/MOAVerifyTemplateSP.xml
+++ b/work/templates/old/MOAVerifyTemplateSP.xml