From 8e3ed85168edaeadcd4f3ec92450036a399d6ede Mon Sep 17 00:00:00 2001 From: knowcenter Date: Sat, 12 May 2007 17:37:16 +0000 Subject: Detached Multipart BKU for Auftrag "Support" git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@73 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .settings/org.eclipse.jdt.core.prefs | 12 + .settings/org.eclipse.jdt.ui.prefs | 3 + .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 250 +++-- .../wag/egov/egiz/framework/Signator.java | 17 + .../wag/egov/egiz/framework/SignatorFactory.java | 45 +- .../framework/signators/BinarySignator_1_0_0.java | 67 +- .../framework/signators/BinarySignator_1_1_0.java | 66 ++ .../signators/DetachedSignator_1_0_0.java | 30 +- .../signators/DetachedfTextualSignator_1_0_0.java | 31 +- .../framework/signators/TextualSignator_1_0_0.java | 36 +- .../framework/signators/TextualSignator_1_1_0.java | 45 + .../wag/egov/egiz/pdf/BinarySignature.java | 40 +- .../egiz/pdf/IncrementalUpdateInformation.java | 17 +- .../wag/egov/egiz/sig/SignatureData.java | 62 ++ .../wag/egov/egiz/sig/SignatureDataImpl.java | 101 ++ .../egov/egiz/sig/connectors/TemplateReplaces.java | 105 ++ .../egiz/sig/connectors/bku/BKUPostConnection.java | 119 +++ .../bku/DetachedMultipartBKUConnector.java | 1125 ++++++++++++++++++++ .../sig/connectors/bku/SignSignatureObject.java | 111 ++ .../connectors/bku/SignSignatureObjectHelper.java | 56 + .../AdditionalSignatureInformation.java | 18 + .../AlgorithmSignatureInformation.java | 13 + .../ConnectorSignatureInformation.java | 14 + .../MandatorySignatureInformation.java | 20 + .../egiz/web/AsynchronousRedirectResponder.java | 3 +- .../wag/egov/egiz/web/LocalRequestHelper.java | 3 +- .../java/at/knowcenter/wag/egov/egiz/web/Sign.java | 3 +- .../test/at/knowcenter/wag/egov/egiz/TestNeu.java | 265 +++++ .../wag/egov/egiz/detached/BKUConnector.java | 987 +++++++++++++++++ .../wag/egov/egiz/detached/BKUPostConnection.java | 230 ++++ .../wag/egov/egiz/detached/MOAConnector.java | 869 +++++++++++++++ work/cfg/config.properties | 14 +- work/cfg/log4j.properties | 4 +- work/templates/BKUSignRequestB64.xml | 14 - work/templates/BKUSignRequestDetached.xml | 17 + work/templates/BKUVerifyRequest.xml | 9 - work/templates/BKUVerifyRequestDetached.xml | 14 + work/templates/BKUVerifyTemplateB64.xml | 6 - work/templates/BKUVerifyTemplateB64_neueBKU.xml | 6 - work/templates/BKUVerifyTemplateDetached.xml | 13 + work/templates/BKUVerifyTemplateSP.xml | 1 - work/templates/BKUVerifyTemplateSP_neueBKU.xml | 1 - work/templates/MOASignRequest.xml | 19 - work/templates/MOASignRequestB64.xml | 19 - work/templates/MOAVerifyRequest.xml | 10 - work/templates/MOAVerifyTemplate.xml | 11 - work/templates/MOAVerifyTemplateB64.xml | 11 - work/templates/MOAVerifyTemplateSP.xml | 1 - work/templates/old/BKUSignRequestB64.xml | 14 + .../templates/old/BKUSignRequestBinaryDetached.xml | 17 + .../old/BKUSignRequestTextualDetached.xml | 17 + work/templates/old/BKUVerifyRequest.xml | 9 + work/templates/old/BKUVerifyTemplateB64.xml | 6 + .../templates/old/BKUVerifyTemplateB64_neueBKU.xml | 6 + .../old/BKUVerifyTemplateDetached_mitQPextern.xml | 13 + work/templates/old/BKUVerifyTemplateSP.xml | 1 + work/templates/old/BKUVerifyTemplateSP_neueBKU.xml | 1 + .../old/BKUVerifyTemplateSP_neueBKU_bin.xml | 1 + .../old/BKUVerifyTemplateSP_neueBKU_text.xml | 1 + work/templates/old/MOASignRequest.xml | 19 + work/templates/old/MOASignRequestB64.xml | 19 + work/templates/old/MOASignRequestDetached.xml | 19 + work/templates/old/MOAVerifyRequest.xml | 10 + work/templates/old/MOAVerifyTemplate.xml | 11 + work/templates/old/MOAVerifyTemplateB64.xml | 11 + work/templates/old/MOAVerifyTemplateSP.xml | 1 + 66 files changed, 4838 insertions(+), 271 deletions(-) create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.jdt.ui.prefs create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_1_0.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedMultipartBKUConnector.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObject.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/SignSignatureObjectHelper.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AdditionalSignatureInformation.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/AlgorithmSignatureInformation.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/ConnectorSignatureInformation.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/signatureobject/MandatorySignatureInformation.java create mode 100644 src/test/java/test/at/knowcenter/wag/egov/egiz/TestNeu.java create mode 100644 src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUConnector.java create mode 100644 src/test/java/test/at/knowcenter/wag/egov/egiz/detached/BKUPostConnection.java create mode 100644 src/test/java/test/at/knowcenter/wag/egov/egiz/detached/MOAConnector.java delete mode 100644 work/templates/BKUSignRequestB64.xml create mode 100644 work/templates/BKUSignRequestDetached.xml delete mode 100644 work/templates/BKUVerifyRequest.xml create mode 100644 work/templates/BKUVerifyRequestDetached.xml delete mode 100644 work/templates/BKUVerifyTemplateB64.xml delete mode 100644 work/templates/BKUVerifyTemplateB64_neueBKU.xml create mode 100644 work/templates/BKUVerifyTemplateDetached.xml delete mode 100644 work/templates/BKUVerifyTemplateSP.xml delete mode 100644 work/templates/BKUVerifyTemplateSP_neueBKU.xml delete mode 100644 work/templates/MOASignRequest.xml delete mode 100644 work/templates/MOASignRequestB64.xml delete mode 100644 work/templates/MOAVerifyRequest.xml delete mode 100644 work/templates/MOAVerifyTemplate.xml delete mode 100644 work/templates/MOAVerifyTemplateB64.xml delete mode 100644 work/templates/MOAVerifyTemplateSP.xml create mode 100644 work/templates/old/BKUSignRequestB64.xml create mode 100644 work/templates/old/BKUSignRequestBinaryDetached.xml create mode 100644 work/templates/old/BKUSignRequestTextualDetached.xml create mode 100644 work/templates/old/BKUVerifyRequest.xml create mode 100644 work/templates/old/BKUVerifyTemplateB64.xml create mode 100644 work/templates/old/BKUVerifyTemplateB64_neueBKU.xml create mode 100644 work/templates/old/BKUVerifyTemplateDetached_mitQPextern.xml create mode 100644 work/templates/old/BKUVerifyTemplateSP.xml create mode 100644 work/templates/old/BKUVerifyTemplateSP_neueBKU.xml create mode 100644 work/templates/old/BKUVerifyTemplateSP_neueBKU_bin.xml create mode 100644 work/templates/old/BKUVerifyTemplateSP_neueBKU_text.xml create mode 100644 work/templates/old/MOASignRequest.xml create mode 100644 work/templates/old/MOASignRequestB64.xml create mode 100644 work/templates/old/MOASignRequestDetached.xml create mode 100644 work/templates/old/MOAVerifyRequest.xml create mode 100644 work/templates/old/MOAVerifyTemplate.xml create mode 100644 work/templates/old/MOAVerifyTemplateB64.xml create mode 100644 work/templates/old/MOAVerifyTemplateSP.xml 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. *

+ * * @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; @@ -29,6 +30,22 @@ import at.knowcenter.wag.egov.egiz.pdf.TablePos; */ public interface Signator { + /** + * Returns the PdfASID of this Connector. + * + *

+ * This should always return the MY_ID static field of the connector. Dont't + * forget to override this. + *

+ *

+ * Within connector code always use this method so that code reuse through + * derivation can take place correctly. + *

+ * + * @return Returns the PdfASID of this Connector. + */ + public PdfASID getMyId(); + /** * This is called before the data is sent to the connector. * 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; @@ -66,6 +69,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. */ @@ -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 (c) 2006 by Know-Center, Graz, Austria + * + * 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. + * + *

+ * 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. + *

+ * + * @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. @@ -46,10 +48,18 @@ 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; @@ -50,6 +54,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. */ @@ -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 (c) 2006 by Know-Center, Graz, Austria + * + * 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. + * + *

+ * For text signature this is the document text. + * For binary signature this is the PDF document. + *

*/ - 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. *

*/ - 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. + * + *

+ * 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. + *

+ * + *

+ * 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. + *

+ * + * @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. + * + *

+ * E.g. "text/plain" for text data or "application/pdf" for a PDF. + *

+ * + * @return Returns the mime type of the data. + */ + public String getMimeType(); + + /** + * Returns the character encoding (charset) of the data if appropriate. + * + *

+ * 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. + *

+ *

+ * If no character encoding is present, null is returned here. + *

+ *

+ * E.g. "UTF-8" is the most common encoding for textual data. + *

+ * + * @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. + * + *

+ * The charactor encoding is set to null, so this constructor is primarily for + * signature data that has no character encoding (e.g. binary data). + *

+ * + * @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. + * + *

+ * Use this constructor for textual data as it allows to provide the character + * encoding. + *

+ * + * @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. + * + *

+ * This feature is available since BKU version 2.7.4. + *

+ * + * @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. + * + *

+ * If confuguration parameters are not defined on that profile, the default + * parameters defined in the configuration are used. + *

+ * + * @param profile + * The profile from which the Environment should be assembled. + * @throws SettingsException + * 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(""); //$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(""); //$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. + * + *

+ * It separates the SignatureValue, X509IssuerName, SigningTime, + * X509SerialNumber, X509Certificate, CertDigest, DigestValue and the + * signation id-s. If the X509Certificate is extracted it would be stored in + * the certificates directory. + *

+ * + * @param xmlResponse + * The response string. + * @return Returns the parsed signature object holding the data. + * + * @throws 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(""); //$NON-NLS-1$ + Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>"); //$NON-NLS-1$ + Pattern iss_nam_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>"); //$NON-NLS-1$ + Pattern sig_tim_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>"); //$NON-NLS-1$ + Pattern ser_num_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>"); //$NON-NLS-1$ + Pattern sig_cer_p_e = Pattern.compile(""); //$NON-NLS-1$ + + // Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>"); + // //$NON-NLS-1$ + // Pattern sig_cer_d_p_e = Pattern.compile(""); + // //$NON-NLS-1$ + // Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>"); + // //$NON-NLS-1$ + // Pattern dig_val_p_e = Pattern.compile(""); + // //$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. + * + *

+ * This method mainly handles communication exceptions. The actual send work + * is done by doPostRequestMultipart. + *

+ * + * @see BKUPostConnection#doPostRequestMultipart(String, String, SignatureData) + * + * @param url + * The URL to send the request to. + * @param request_string + * 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. + * + *

+ * This strongly rebuilds the XML content as retuned from a sign request. + *

+ * + * @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 = "= 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(""); //$NON-NLS-1$ + Pattern sub_nam_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern iss_nam_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern iss_nam_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern ser_num_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern ser_num_p_e = Pattern.compile(""); //$NON-NLS-1$ + + Pattern sig_chk_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern sig_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern man_chk_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern man_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern cer_chk_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern cer_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ + + // [tknall] start qualified certificate + Pattern cert_qualified_p = Pattern.compile(""); //$NON-NLS-1$ + Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse); + // [tknall] stop qualified certificate + + Pattern code_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern code_p_e = Pattern.compile(""); //$NON-NLS-1$ + Pattern info_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern info_p_e = Pattern.compile(""); //$NON-NLS-1$ + + Pattern cert_p_s = Pattern.compile(""); //$NON-NLS-1$ + Pattern cert_p_e = Pattern.compile(""); //$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. + * + *

+ * This also provides the serial number and name. + *

+ */ + 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 (c) 2006 by Know-Center, Graz, Austria + * + * 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(""); + Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>"); + Pattern iss_nam_p_e = Pattern.compile(""); + Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>"); + Pattern sig_tim_p_e = Pattern.compile(""); + Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>"); + Pattern ser_num_p_e = Pattern.compile(""); + Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>"); + Pattern sig_cer_p_e = Pattern.compile(""); + + Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>"); + Pattern sig_cer_d_p_e = Pattern.compile(""); + Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>"); + Pattern dig_val_p_e = Pattern.compile(""); + + 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 = "= 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(""); + Pattern sub_nam_p_e = Pattern.compile(""); + Pattern iss_nam_p_s = Pattern.compile(""); + Pattern iss_nam_p_e = Pattern.compile(""); + Pattern ser_num_p_s = Pattern.compile(""); + Pattern ser_num_p_e = Pattern.compile(""); + + Pattern sig_chk_p_s = Pattern.compile(""); + Pattern sig_chk_p_e = Pattern.compile(""); + Pattern man_chk_p_s = Pattern.compile(""); + Pattern man_chk_p_e = Pattern.compile(""); + Pattern cer_chk_p_s = Pattern.compile(""); + Pattern cer_chk_p_e = Pattern.compile(""); + + // [tknall] start qualified certificate + Pattern cert_qualified_p = Pattern.compile(""); + Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse); + // [tknall] stop qualified certificate + + Pattern code_p_s = Pattern.compile(""); + Pattern code_p_e = Pattern.compile(""); + Pattern info_p_s = Pattern.compile(""); + Pattern info_p_e = Pattern.compile(""); + + Pattern cert_p_s = Pattern.compile(""); + Pattern cert_p_e = Pattern.compile(""); + + 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(""); + 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(""); + 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(""); + 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(""); + 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. + * + *

+ * All settings keys will be prefixed by this type. So to reuse the BKU + * connector, a deriving class has to implement this method specifying an own + * type. + *

+ * + * @return Returns the type of this BKU-like connector. + */ + protected String getType() + { + 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 (c) 2006 by Know-Center, Graz, Austria + * + * 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 (c) 2006 by Know-Center, Graz, Austria + * + * 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. + * + *

+ * Just for convenience. + *

+ */ + 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(""); + Pattern erc_p_e = Pattern.compile(""); + 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(""); + Pattern erm_p_e = Pattern.compile(""); + 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(""); + Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>"); + Pattern iss_nam_p_e = Pattern.compile(""); + Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>"); + Pattern sig_tim_p_e = Pattern.compile(""); + Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>"); + Pattern ser_num_p_e = Pattern.compile(""); + Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>"); + Pattern sig_cer_p_e = Pattern.compile(""); + + Pattern sig_cer_d_p_s = Pattern.compile("<[\\w]*:?CertDigest>"); + Pattern sig_cer_d_p_e = Pattern.compile(""); + Pattern dig_val_p_s = Pattern.compile("<[\\w]*:?DigestValue>"); + Pattern dig_val_p_e = Pattern.compile(""); + + 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(""); +// 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(""); +// 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(""); +// Pattern sub_nam_p_e = Pattern.compile(""); +// Pattern iss_nam_p_s = Pattern.compile(""); +// Pattern iss_nam_p_e = Pattern.compile(""); +// Pattern ser_num_p_s = Pattern.compile(""); +// Pattern ser_num_p_e = Pattern.compile(""); +// +// // [tknall] start qualified certificate +// Pattern cert_qualified_p = Pattern.compile(""); +// Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse); +// // [tknall] stop qualified certificate +// +// Pattern sig_chk_p_s = Pattern.compile(""); +// Pattern sig_chk_p_e = Pattern.compile(""); +// Pattern man_chk_p_s = Pattern.compile(""); +// Pattern man_chk_p_e = Pattern.compile(""); +// Pattern cer_chk_p_s = Pattern.compile(""); +// Pattern cer_chk_p_e = Pattern.compile(""); +// +// Pattern code_p_s = Pattern.compile(""); +// Pattern code_p_e = Pattern.compile(""); +// +// Pattern cert_p_s = Pattern.compile(""); +// Pattern cert_p_e = Pattern.compile(""); +// +// 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/BKUSignRequestB64.xml b/work/templates/BKUSignRequestB64.xml deleted file mode 100644 index 4cebb0e..0000000 --- a/work/templates/BKUSignRequestB64.xml +++ /dev/null @@ -1,14 +0,0 @@ - - -KeyboxIdentifierReplace - - -Base64ContentReplace - - - -text/plain - - - - \ No newline at end of file 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 @@ + + +KeyboxIdentifierReplace + + + + +MimeTypeReplace + + + + +formdata:fileupload + + + + \ No newline at end of file diff --git a/work/templates/BKUVerifyRequest.xml b/work/templates/BKUVerifyRequest.xml deleted file mode 100644 index e232e51..0000000 --- a/work/templates/BKUVerifyRequest.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - -XMLContentReplace - -/dsig:Signature - - \ 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 @@ + + + + +XMLContentReplace + +/dsig:Signature + + + +formdata:fileupload + + + \ No newline at end of file diff --git a/work/templates/BKUVerifyTemplateB64.xml b/work/templates/BKUVerifyTemplateB64.xml deleted file mode 100644 index 229cb4f..0000000 --- a/work/templates/BKUVerifyTemplateB64.xml +++ /dev/null @@ -1,6 +0,0 @@ -id('signed-data-object-SigDataObjURIReplace')/node()DigestValueSignedDataReplaceid('etsi-data-object-EtsiDataObjURIReplace')/node()DigestValueSignedPropertiesReplace -SignatureValueReplace -X509CertificateReplace -Base64ContentReplace -TemplateQualifyingPropertiesReplace - \ No newline at end of file diff --git a/work/templates/BKUVerifyTemplateB64_neueBKU.xml b/work/templates/BKUVerifyTemplateB64_neueBKU.xml deleted file mode 100644 index 36b543a..0000000 --- a/work/templates/BKUVerifyTemplateB64_neueBKU.xml +++ /dev/null @@ -1,6 +0,0 @@ -id('signed-data-object-SigDataObjURIReplace')/node()DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace -SignatureValueReplace -X509CertificateReplace -Base64ContentReplace -TemplateQualifyingPropertiesReplace - \ 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 @@ + + + + + + +DigestValueSignedDataReplace + +DigestValueSignedPropertiesReplace +SignatureValueReplace +X509CertificateReplace +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplaceMimeTypeReplace + \ No newline at end of file diff --git a/work/templates/BKUVerifyTemplateSP.xml b/work/templates/BKUVerifyTemplateSP.xml deleted file mode 100644 index 0360b58..0000000 --- a/work/templates/BKUVerifyTemplateSP.xml +++ /dev/null @@ -1 +0,0 @@ -SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file diff --git a/work/templates/BKUVerifyTemplateSP_neueBKU.xml b/work/templates/BKUVerifyTemplateSP_neueBKU.xml deleted file mode 100644 index 2589e62..0000000 --- a/work/templates/BKUVerifyTemplateSP_neueBKU.xml +++ /dev/null @@ -1 +0,0 @@ -SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file diff --git a/work/templates/MOASignRequest.xml b/work/templates/MOASignRequest.xml deleted file mode 100644 index 4873f5e..0000000 --- a/work/templates/MOASignRequest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - KeyIdentifierReplace - - - - XMLContentReplace - - - - - text/plain - - - - - - - diff --git a/work/templates/MOASignRequestB64.xml b/work/templates/MOASignRequestB64.xml deleted file mode 100644 index 3c08c9e..0000000 --- a/work/templates/MOASignRequestB64.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -KeyIdentifierReplace - - - -Base64ContentReplace - - - - -text/plain - - - - - - - diff --git a/work/templates/MOAVerifyRequest.xml b/work/templates/MOAVerifyRequest.xml deleted file mode 100644 index 04c6863..0000000 --- a/work/templates/MOAVerifyRequest.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -XMLContentReplace - -/dsig:Signature - -TrustProfileIDReplace - \ No newline at end of file diff --git a/work/templates/MOAVerifyTemplate.xml b/work/templates/MOAVerifyTemplate.xml deleted file mode 100644 index ce63949..0000000 --- a/work/templates/MOAVerifyTemplate.xml +++ /dev/null @@ -1,11 +0,0 @@ - -DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace -SignatureValueReplace - - -X509CertificateReplace - - -ObjectDataReplace -TemplateSignedPropertiesReplace - \ No newline at end of file diff --git a/work/templates/MOAVerifyTemplateB64.xml b/work/templates/MOAVerifyTemplateB64.xml deleted file mode 100644 index 547bc7c..0000000 --- a/work/templates/MOAVerifyTemplateB64.xml +++ /dev/null @@ -1,11 +0,0 @@ - -DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace -SignatureValueReplace - - -X509CertificateReplace - - -Base64ContentReplace -TemplateSignedPropertiesReplace - \ No newline at end of file diff --git a/work/templates/MOAVerifyTemplateSP.xml b/work/templates/MOAVerifyTemplateSP.xml deleted file mode 100644 index 9e902a3..0000000 --- a/work/templates/MOAVerifyTemplateSP.xml +++ /dev/null @@ -1 +0,0 @@ -SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file diff --git a/work/templates/old/BKUSignRequestB64.xml b/work/templates/old/BKUSignRequestB64.xml new file mode 100644 index 0000000..4cebb0e --- /dev/null +++ b/work/templates/old/BKUSignRequestB64.xml @@ -0,0 +1,14 @@ + + +KeyboxIdentifierReplace + + +Base64ContentReplace + + + +text/plain + + + + \ No newline at end of file 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 @@ + + +KeyboxIdentifierReplace + + + + +application/pdf + + + + +formdata:fileupload + + + + \ 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 @@ + + +KeyboxIdentifierReplace + + + + +text/plain + + + + +formdata:fileupload + + + + \ No newline at end of file diff --git a/work/templates/old/BKUVerifyRequest.xml b/work/templates/old/BKUVerifyRequest.xml new file mode 100644 index 0000000..e232e51 --- /dev/null +++ b/work/templates/old/BKUVerifyRequest.xml @@ -0,0 +1,9 @@ + + + + +XMLContentReplace + +/dsig:Signature + + \ No newline at end of file diff --git a/work/templates/old/BKUVerifyTemplateB64.xml b/work/templates/old/BKUVerifyTemplateB64.xml new file mode 100644 index 0000000..229cb4f --- /dev/null +++ b/work/templates/old/BKUVerifyTemplateB64.xml @@ -0,0 +1,6 @@ +id('signed-data-object-SigDataObjURIReplace')/node()DigestValueSignedDataReplaceid('etsi-data-object-EtsiDataObjURIReplace')/node()DigestValueSignedPropertiesReplace +SignatureValueReplace +X509CertificateReplace +Base64ContentReplace +TemplateQualifyingPropertiesReplace + \ No newline at end of file diff --git a/work/templates/old/BKUVerifyTemplateB64_neueBKU.xml b/work/templates/old/BKUVerifyTemplateB64_neueBKU.xml new file mode 100644 index 0000000..36b543a --- /dev/null +++ b/work/templates/old/BKUVerifyTemplateB64_neueBKU.xml @@ -0,0 +1,6 @@ +id('signed-data-object-SigDataObjURIReplace')/node()DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace +SignatureValueReplace +X509CertificateReplace +Base64ContentReplace +TemplateQualifyingPropertiesReplace + \ No newline at end of file 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 @@ + + + + + + +DigestValueSignedDataReplace + +DigestValueSignedPropertiesReplace +SignatureValueReplace +X509CertificateReplace +TemplateQualifyingPropertiesReplace + \ No newline at end of file diff --git a/work/templates/old/BKUVerifyTemplateSP.xml b/work/templates/old/BKUVerifyTemplateSP.xml new file mode 100644 index 0000000..0360b58 --- /dev/null +++ b/work/templates/old/BKUVerifyTemplateSP.xml @@ -0,0 +1 @@ +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file diff --git a/work/templates/old/BKUVerifyTemplateSP_neueBKU.xml b/work/templates/old/BKUVerifyTemplateSP_neueBKU.xml new file mode 100644 index 0000000..2589e62 --- /dev/null +++ b/work/templates/old/BKUVerifyTemplateSP_neueBKU.xml @@ -0,0 +1 @@ +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file 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 @@ +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplaceapplication/pdf \ 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 @@ +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file diff --git a/work/templates/old/MOASignRequest.xml b/work/templates/old/MOASignRequest.xml new file mode 100644 index 0000000..4873f5e --- /dev/null +++ b/work/templates/old/MOASignRequest.xml @@ -0,0 +1,19 @@ + + + KeyIdentifierReplace + + + + XMLContentReplace + + + + + text/plain + + + + + + + diff --git a/work/templates/old/MOASignRequestB64.xml b/work/templates/old/MOASignRequestB64.xml new file mode 100644 index 0000000..3c08c9e --- /dev/null +++ b/work/templates/old/MOASignRequestB64.xml @@ -0,0 +1,19 @@ + + +KeyIdentifierReplace + + + +Base64ContentReplace + + + + +text/plain + + + + + + + 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 @@ + + +KeyIdentifierReplace + + + + formdata:fileupload + + + + +text/plain + + + + + + + diff --git a/work/templates/old/MOAVerifyRequest.xml b/work/templates/old/MOAVerifyRequest.xml new file mode 100644 index 0000000..04c6863 --- /dev/null +++ b/work/templates/old/MOAVerifyRequest.xml @@ -0,0 +1,10 @@ + + + + +XMLContentReplace + +/dsig:Signature + +TrustProfileIDReplace + \ No newline at end of file diff --git a/work/templates/old/MOAVerifyTemplate.xml b/work/templates/old/MOAVerifyTemplate.xml new file mode 100644 index 0000000..ce63949 --- /dev/null +++ b/work/templates/old/MOAVerifyTemplate.xml @@ -0,0 +1,11 @@ + +DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace +SignatureValueReplace + + +X509CertificateReplace + + +ObjectDataReplace +TemplateSignedPropertiesReplace + \ No newline at end of file diff --git a/work/templates/old/MOAVerifyTemplateB64.xml b/work/templates/old/MOAVerifyTemplateB64.xml new file mode 100644 index 0000000..547bc7c --- /dev/null +++ b/work/templates/old/MOAVerifyTemplateB64.xml @@ -0,0 +1,11 @@ + +DigestValueSignedDataReplaceDigestValueSignedPropertiesReplace +SignatureValueReplace + + +X509CertificateReplace + + +Base64ContentReplace +TemplateSignedPropertiesReplace + \ No newline at end of file diff --git a/work/templates/old/MOAVerifyTemplateSP.xml b/work/templates/old/MOAVerifyTemplateSP.xml new file mode 100644 index 0000000..9e902a3 --- /dev/null +++ b/work/templates/old/MOAVerifyTemplateSP.xml @@ -0,0 +1 @@ +SigningTimeReplaceDigestValueX509CertificateReplaceX509IssuerNameReplaceX509SerialNumberReplacetext/plain \ No newline at end of file -- cgit v1.2.3