aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/knowcenter/wag/egov/egiz/sig
diff options
context:
space:
mode:
authortknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2008-10-10 11:13:40 +0000
committertknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2008-10-10 11:13:40 +0000
commit6ef9bdefc58cb2553f23aaa9711d6341e293c9f7 (patch)
treed627791fc5e394b0fa47c03a93d19b9e1ec65a36 /src/main/java/at/knowcenter/wag/egov/egiz/sig
parent1318c462d46bb248e0587666c04944cfe2c83db6 (diff)
downloadpdf-as-3-6ef9bdefc58cb2553f23aaa9711d6341e293c9f7.tar.gz
pdf-as-3-6ef9bdefc58cb2553f23aaa9711d6341e293c9f7.tar.bz2
pdf-as-3-6ef9bdefc58cb2553f23aaa9711d6341e293c9f7.zip
Deprecated webapp-folder removed from svn repository.
New DefaultConfiguration.zip integrated in order to allow mocca signatures. Minor bug concerning choice of cce within the web application fixed. Signature with new online bku MOCCA integrated (new signature device "moc" created). Configuration keys for mocca added. New error codes (371 = signature verification not supported by this connector, 372 = invalid signing time) introduced. Optional check of the signing time for the web application implemented. At signature creation time the signing time is checked for plausibility. This is a workaround for the ITS:mac-linux signing time bug. New configuration key ("signing_time_tolerance") added (applies to web application only) to overcome invalid signing times. A signature is only accepted if its signing time is within a time frame of [current time - signing_time_tolerance, current time + signing_time_tolerance] where signing_time_tolerance is interpreted as seconds. Bugfix: Correct extraction of signatures with wrong signing times implemented. (The order of the signatures is still invalid in case of false signing times.) Optional override of the dynamic creation of the signature retrieval url (locrefcontent) implemented in order to overcome ssl problems (retrieve_signature_data_url_override). Note: Assure that this URL is accessible from the citizen card environment. Download of signed pdf-file for external application interface adjusted. Verification of mocca signed documents implemented. Retrieval of xml response via multipart implemented (mocca strictly follows security layer spec) git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@296 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
Diffstat (limited to 'src/main/java/at/knowcenter/wag/egov/egiz/sig')
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java24
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java19
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java695
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedMOCIdFormatter.java48
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java20
5 files changed, 792 insertions, 14 deletions
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java
index e991e04..7188273 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java
@@ -6,6 +6,7 @@ package at.knowcenter.wag.egov.egiz.sig.connectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import at.gv.egiz.pdfas.api.commons.Constants;
import at.gv.egiz.pdfas.framework.ConnectorParameters;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
@@ -16,6 +17,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.MultipartDetachedBKUConnec
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.OldEnvelopingBase64BKUConnector;
import at.knowcenter.wag.egov.egiz.sig.connectors.moa.EnvelopingBase64MOAConnector;
import at.knowcenter.wag.egov.egiz.sig.connectors.moa.MOASoapWithAttachmentConnector;
+import at.knowcenter.wag.egov.egiz.sig.connectors.mocca.LocRefDetachedMOCCAConnector;
import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter;
/**
@@ -39,15 +41,21 @@ public final class ConnectorChooser
log.debug("Choosing LocalConnector for signation...");
log.debug("connector type = " + connector);
-
- if (!connector.equals("bku"))
- {
- log.error("Currently only the BKU connector is fully implemented.");
- }
-
- log.debug("choosing locref detached BKU connector.");
+
ConnectorParameters cp = new ConnectorParameters();
cp.setProfileId(profile);
+
+ if (Constants.SIGNATURE_DEVICE_MOC.equals(connector)) {
+
+ return new LocRefDetachedMOCCAConnector(cp, loc_ref_url);
+
+ } else if (Constants.SIGNATURE_DEVICE_BKU.equals(connector)){
+
+ return new LocRefDetachedBKUConnector(cp, loc_ref_url);
+
+ }
+
+ log.error("Currently only the BKU connector is fully implemented.");
return new LocRefDetachedBKUConnector(cp, loc_ref_url);
}
@@ -58,7 +66,7 @@ public final class ConnectorChooser
log.debug("connector type = " + connector);
- if (!connector.equals("moa"))
+ if (!connector.equals(Constants.SIGNATURE_DEVICE_MOA))
{
log.error("Currently only the MOA connector is available for non local WEB signation.");
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
index 4cc09e1..44a7c38 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java
@@ -11,6 +11,8 @@ import java.util.Date;
import java.util.Properties;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -29,6 +31,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUHelper;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.DetachedBKUConnector;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.connectors.mocca.LocRefDetachedMOCCAConnector;
import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedLocRefMOAIdFormatter;
import at.knowcenter.wag.egov.egiz.sig.sigkz.SigKZIDHelper;
import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
@@ -186,15 +189,19 @@ public class MOASoapWithAttachmentConnector implements Connector
String verify_request_template = this.environment.getVerifyRequestTemplate();
String xml_content = null;
- if (!SigKZIDHelper.isMOASigned(so))
- {
+
+ if (SigKZIDHelper.isMOASigned(so)) {
+ log.debug("MOA signature detected.");
+ xml_content = prepareXMLContent(data, so);
+ } else if (SigKZIDHelper.isMOCCASigned(so)) {
+ log.debug("MOCCA signature detected.");
+ LocRefDetachedMOCCAConnector mocca_connector = new LocRefDetachedMOCCAConnector(this.params, "not needed here");
+ xml_content = mocca_connector.prepareXMLContent(data, so);
+ } else {
+ log.debug("Generic signature (not MOA/MOCCA) signature detected.");
DetachedBKUConnector bku_connector = new DetachedBKUConnector(this.params, "not needed here");
xml_content = bku_connector.prepareXMLContent(data, so);
}
- else
- {
- xml_content = prepareXMLContent(data, so);
- }
String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.TRUST_PROFILE_ID_REPLACE, this.environment.getVerifyTrustProfileId());
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java
new file mode 100644
index 0000000..8ae6d5f
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/LocRefDetachedMOCCAConnector.java
@@ -0,0 +1,695 @@
+package at.knowcenter.wag.egov.egiz.sig.connectors.mocca;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+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.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.gv.egiz.pdfas.framework.ConnectorParameters;
+import at.gv.egiz.pdfas.web.helper.SigningTimeHelper;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
+import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
+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.Connector;
+import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector;
+import at.knowcenter.wag.egov.egiz.sig.connectors.TemplateReplaces;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUHelper;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
+import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
+import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedMOCIdFormatter;
+import at.knowcenter.wag.egov.egiz.sig.sigid.IdFormatter;
+import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
+import at.knowcenter.wag.egov.egiz.tools.FileHelper;
+
+/**
+ * Connector for MOCCA.
+ * @author tknall
+ */
+public class LocRefDetachedMOCCAConnector implements Connector, LocalConnector {
+
+ private static Log log = LogFactory.getLog(LocRefDetachedMOCCAConnector.class);
+
+ /**
+ * The connector parameters.
+ */
+ protected ConnectorParameters params = null;
+
+ /**
+ * The environment of this connector containing templates.
+ */
+ protected Environment environment = null;
+
+ /**
+ * Constructor that builds the configuration environment for this connector according to the
+ * given profile.
+ * @param connectorParameters The connectot parameters.
+ * @throws ConnectorException Thrown in case of error.
+ */
+ public LocRefDetachedMOCCAConnector(ConnectorParameters connectorParameters, String loc_ref_content) throws ConnectorException {
+ this.params = connectorParameters;
+ this.environment = new Environment(this.params.getProfileId(), loc_ref_content);
+ }
+
+ /**
+ * Sends the request to the given URL. This method 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 ConnectorException Thrown in case of an error.
+ */
+ protected Properties sendRequest(String url, String request_string, SignatureData data) throws ConnectorException {
+ try {
+ Properties response_properties = BKUPostConnection.doPostRequestMultipart(url, request_string, data);
+ return response_properties;
+ } catch (Exception e) {
+ ConnectorException se = new ConnectorException(320, e);
+ throw se;
+ }
+ }
+
+ /**
+ * Starts a signature process.
+ * @param data The data to be signed.
+ * @return Returns the signature object containing the signed data.
+ * @throws ConnectorException Thrown in case of an error.
+ */
+ public SignSignatureObject doSign(SignatureData data) throws ConnectorException {
+ log.debug("doSign:");
+
+ String sign_request_xml = prepareSignRequest(data);
+ log.debug("sign_request_xml = " + sign_request_xml);
+
+ String url = this.environment.getSignURL();
+ Properties response_properties = sendRequest(url, sign_request_xml, data);
+
+ SignSignatureObject sso = analyzeSignResponse(response_properties);
+
+ sso.response_properties = response_properties;
+
+ log.debug("doSign finished.");
+ return sso;
+ }
+
+ /**
+ * Verification is not supported by MOCCA. Therefore this method always throws a
+ * {@link ConnectorException} with error code {@link ErrorCode#SIGNATURE_VERIFICATION_NOT_SUPPORTED}.
+ */
+ public SignatureResponse doVerify(SignatureData data, SignSignatureObject so) throws ConnectorException {
+ throw new ConnectorException(ErrorCode.SIGNATURE_VERIFICATION_NOT_SUPPORTED, "Signature Verification is not supported by MOCCA.");
+ }
+
+ /**
+ * This method analyzes a signature response of the signature device.
+ * @param response_properties The response elements of the signature device.
+ * @return The parsed signed signature object.
+ * @throws ConnectorException Thrown in case of an error.
+ */
+ public SignSignatureObject analyzeSignResponse(Properties response_properties) throws ConnectorException {
+ log.debug("analyzeSignResponse:");
+ String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY);
+ BKUHelper.checkResponseForError(response_string);
+ SignSignatureObject so = this.parseCreateXMLResponse(response_string, new DetachedMOCIdFormatter());
+ so.response_properties = response_properties;
+ log.debug("analyzeSignResponse finished.");
+ return so;
+ }
+
+ /**
+ * This method parses the signature creation response of the signature device.
+ * @param xmlResponse The response string.
+ * @return Returns the parsed signature object holding the data.
+ * @see SignatureObject
+ * @see CodingHelper
+ * @see X509Cert
+ */
+ public SignSignatureObject parseCreateXMLResponse(String xmlResponse, IdFormatter id_formatter) throws ConnectorException {
+
+ Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>");
+ Pattern iss_nam_p_e = Pattern.compile("</[\\w]*:?X509IssuerName>");
+ Pattern sig_tim_p_s = Pattern.compile("<[\\w]*:?SigningTime>");
+ Pattern sig_tim_p_e = Pattern.compile("</[\\w]*:?SigningTime>");
+ Pattern ser_num_p_s = Pattern.compile("<[\\w]*:?X509SerialNumber>");
+ Pattern ser_num_p_e = Pattern.compile("</[\\w]*:?X509SerialNumber>");
+ Pattern sig_cer_p_s = Pattern.compile("<[\\w]*:?X509Certificate>");
+ Pattern sig_cer_p_e = Pattern.compile("</[\\w]*:?X509Certificate>");
+
+ 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);
+
+ // SignatureValue
+ String sig_val = null;
+ Matcher signatureValueMatcher = Pattern.compile("<(\\w+:)?SignatureValue( Id=\"[\\w-]+\")?>\\s*(.*)\\s*</(\\w+:)?SignatureValue>").matcher(xmlResponse);
+ if (signatureValueMatcher.find()) {
+ sig_val = signatureValueMatcher.group(3);
+ }
+ log.debug("sig_val = " + sig_val);
+
+ // 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);
+
+ // X509SerialNumber
+ String ser_num = null;
+ if (ser_num_m_s.find() && ser_num_m_e.find()) {
+ ser_num = BKUHelper.removeAllWhitespace(xmlResponse.substring(ser_num_m_s.end(), ser_num_m_e.start()));
+ }
+ log.debug("ser_num = " + ser_num);
+
+ // 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);
+
+ // X509Certificate
+ X509Certificate cert = null;
+ if (sig_cer_m_s.find() && sig_cer_m_e.find()) {
+ String sig_cer = BKUHelper.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");
+ cert = (X509Certificate) cf.generateCertificate(bais);
+ bais.close();
+ } catch (UnsupportedEncodingException e) {
+ throw new ConnectorException(300, e);
+ } catch (CertificateException e) {
+ throw new ConnectorException(300, e);
+ } catch (IOException e) {
+ throw new ConnectorException(300, e);
+ }
+ }
+ log.debug("X509Certificate = " + cert);
+
+ if (log.isDebugEnabled()) {
+
+ String cert_iss = cert.getIssuerDN().getName();
+ log.debug("certificate's issuer = " + cert_iss);
+ log.debug("response's issuer = " + iss_nam);
+ log.debug("issuer matches = " + cert_iss.equals(iss_nam));
+ log.debug("ser number matches = " + cert.getSerialNumber().toString().equals(ser_num));
+ }
+
+ // extract Signature Id's
+ String[] ids = extractIds(xmlResponse);
+ String final_ids = id_formatter.formatIds(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;
+ }
+
+ /**
+ * Extraction of the id attributes from the xml response.
+ * @param xmlResponse The xml response.
+ * @return The parsed id attributes.
+ */
+ public final static String[] extractIds(String xmlResponse) {
+ return new String[] { extractId(xmlResponse) };
+ }
+
+ /**
+ * There is only one special common part of all id attributes of this connector that has to be
+ * stored. This method returns that single part.
+ * @param xmlResponse The xml response.
+ * @return The parsed common part of all id attributes.
+ */
+ private final static String extractId(String xmlResponse) {
+ final Pattern ID_PATTERN = Pattern.compile("Id\\s*=\\s*\"\\s*Signature-([\\p{XDigit}]+)-\\d+\\s*\"");
+ Matcher matcher = ID_PATTERN.matcher(xmlResponse);
+ if (matcher.find() && matcher.groupCount() > 0) {
+ return matcher.group(1);
+ }
+ return null;
+ }
+
+ /**
+ * Verification is not supported by MOCCA. Therefore this method always throws a
+ * {@link ConnectorException} with error code {@link ErrorCode#SIGNATURE_VERIFICATION_NOT_SUPPORTED}.
+ */
+ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws ConnectorException {
+ throw new ConnectorException(ErrorCode.SIGNATURE_VERIFICATION_NOT_SUPPORTED, "Signature Verification is not supported by MOCCA.");
+ }
+
+ /**
+ * Prepares the signature request xml to be sent using the sign request template.
+ * @param data The signature data.
+ * @return Returns the sign request xml to be sent.
+ * @throws ConnectorException Thrown in case of an error.
+ */
+ public String prepareSignRequest(SignatureData data) throws ConnectorException {
+ log.debug("prepareSignRequestDetached:");
+
+ String sign_request_template = this.environment.getSignRequestTemplate();
+
+ String sign_keybox_identifier = this.environment.getSignKeyboxIdentifier();
+ String mime_type = data.getMimeType();
+ String loc_ref_content = this.environment.getLocRefContent();
+
+ if (log.isDebugEnabled()) {
+ log.debug("sign keybox identifier = " + sign_keybox_identifier);
+ log.debug("mime type = " + mime_type);
+ log.debug("loc_ref_content = " + loc_ref_content);
+ }
+
+ String sign_request_xml = sign_request_template.replaceFirst(TemplateReplaces.KEYBOX_IDENTIFIER_REPLACE, sign_keybox_identifier);
+ sign_request_xml = sign_request_xml.replaceFirst(TemplateReplaces.MIME_TYPE_REPLACE, mime_type);
+ sign_request_xml = sign_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, loc_ref_content);
+
+ log.debug("sign_request_xml = " + sign_request_xml);
+ log.debug("prepareSignRequestDetached finished.");
+ return sign_request_xml;
+ }
+
+ /**
+ * Verification is not supported by MOCCA. Therefore this method always throws a
+ * {@link ConnectorException} with error code {@link ErrorCode#SIGNATURE_VERIFICATION_NOT_SUPPORTED}.
+ */
+ public String prepareVerifyRequest(SignatureData data, SignSignatureObject so) throws ConnectorException {
+ throw new ConnectorException(ErrorCode.SIGNATURE_VERIFICATION_NOT_SUPPORTED, "Signature Verification is not supported by MOCCA.");
+ }
+
+ /**
+ * Prepares the xml content of a signature creation request including the link to the signature data.
+ * @param data The signature data.
+ * @param so The signature object containing the signature information.
+ * @return Returns the xml content.
+ * @throws ConnectorException Thrown in case of an error.
+ */
+ public String prepareXMLContent(SignatureData data, SignSignatureObject so) throws ConnectorException {
+ log.debug("prepareXMLContent:");
+ try {
+ String verify_template = this.environment.getVerifyTemplate();
+
+ String ids_string = so.getSigID();
+ String sigId = this.parseSigId(ids_string);
+
+ X509Certificate cert = so.getX509Certificate();
+ String cert_alg = this.environment.getCertAlgEcdsa();
+ if (cert.getPublicKey().getAlgorithm().indexOf("RSA") >= 0)
+ {
+ cert_alg = this.environment.getCertAlgRsa();
+ }
+
+ // cert alg replace
+ String verify_xml = verify_template.replaceFirst(TemplateReplaces.CERT_ALG_REPLACE, cert_alg);
+
+ // data digest replace
+ byte[] data_value_hash = CodingHelper.buildDigest(data.getDataSource());
+ String object_data_hash = CodingHelper.encodeBase64(data_value_hash);
+
+ // template replacements
+
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_SIGNED_DATA_REPLACE, object_data_hash);
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNATURE_VALUE_REPLACE, so.getSignatureValue());
+
+ // 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.SIG_ID_REPLACE, sigId);
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate());
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest);
+ verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer());
+ 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
+ Pattern spPattern = Pattern.compile("(<(\\w+:)?SignedProperties.*>.*</(\\w+:)?SignedProperties>)");
+ Matcher matcher = spPattern.matcher(verify_xml);
+ if (matcher.find()) {
+ log.debug("SignedProperties found.");
+ String string_to_be_hashed = matcher.group(1);
+ log.debug("SignedProperties string to be hashed: " + string_to_be_hashed);
+ final byte[] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
+ 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.");
+ return verify_xml;
+ } catch (Exception e) {
+ log.debug(e);
+ throw new ConnectorException(310, e);
+ }
+ }
+
+ /**
+ * 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 = "moc.sign.KeyboxIdentifier";
+
+ /**
+ * The configuration key of the sign request template.
+ */
+ protected static final String SIGN_REQUEST_TEMPLATE_KEY = "moc.sign.request.detached";
+
+ /**
+ * The configuration key of the sign URL.
+ */
+ protected static final String SIGN_URL_KEY = "moc.sign.url";
+
+ /**
+ * BKU template file prefix
+ */
+ protected static final String TEMPLATE_FILE_PREFIX = "./templates/moc.";
+
+ /**
+ * signing file template sufix
+ */
+ protected static final String SIGN_TEMPLATE_FILE_SUFIX = ".sign.request.xml";
+
+ /**
+ * verifing template file sufix
+ */
+ /* signature verification is not supported by mocca
+ protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml";
+ */
+
+ /**
+ * verifing file template key sufix
+ */
+ protected static final String VERIFY_TEMPLATE_SUFIX = ".verify.template.xml";
+
+ /**
+ * The configuration key of the verify request template.
+ */
+ /* signature verification is not supported by mocca
+ protected static final String VERIFY_REQUEST_TEMPLATE_KEY = "moc.verify.request.detached";
+ */
+
+ /**
+ * The configuration key of the verify template.
+ */
+ protected static final String VERIFY_TEMPLATE_KEY = "moc.verify.template.detached";
+
+ /**
+ * The configuration key of the verify URL.
+ */
+ /* signature verification is not supported by mocca
+ protected static final String xxxVERIFY_URL_KEY = "moc.verify.url";
+ */
+
+ /**
+ * The configuration key for the ECDSA cert alg property.
+ */
+ protected static final String ECDSA_CERT_ALG_KEY = "cert.alg.ecdsa";
+
+ /**
+ * The configuration key for the RSA cert alg property.
+ */
+ protected static final String RSA_CERT_ALG_KEY = "cert.alg.rsa";
+
+ protected String profile = null;
+
+ protected String loc_ref_content = null;
+
+ protected String sign_keybox_identifier = null;
+
+ protected String sign_request_template = null;
+
+ protected String sign_url = null;
+
+ /* signature verification is not supported by mocca
+ protected String verify_request_template = null;
+ */
+
+ protected String verify_template = null;
+
+ /* signature verification is not supported by mocca
+ 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 ConnectorException Thrown in case of an error.
+ */
+ public Environment(String profile, String loc_ref_content) throws ConnectorException {
+ this.profile = profile;
+
+ this.loc_ref_content = loc_ref_content;
+
+ SettingsReader settings = null;
+ try {
+ settings = SettingsReader.getInstance();
+ } catch (SettingsException e) {
+ throw new ConnectorException(300, e);
+ }
+
+ this.sign_keybox_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEYBOX_IDENTIFIER_KEY);
+
+
+ // SIGN REQUEST
+
+ // try specific file
+ String sign_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moc.algorithm.id") + SIGN_TEMPLATE_FILE_SUFIX;
+ log.debug("Trying to load specific sign request file " + sign_request_filename);
+ this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
+
+ // try default request file
+ if (this.sign_request_template == null) {
+ sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY);
+ log.debug("Specific file not found. Trying default sign request file " + sign_request_filename);
+ this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename));
+ }
+
+ // request file is needed !!!
+ if (this.sign_request_template == null) {
+ throw new ConnectorException(300, "Can not read the create xml request template");
+ }
+
+ this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY);
+
+
+ // VERIFY REQUEST
+ /* signature verification is not supported by mocca
+
+ // try specific file
+ String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moc.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX;
+ log.debug("Trying to load specific verify request file " + verify_request_filename);
+ this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
+
+ // try default request file
+ if (this.verify_request_template == null) {
+ verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY);
+ log.debug("Specific file not found. Trying default verify request file " + verify_request_filename);
+ this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename));
+ }
+
+ // request file is needed !!!
+ if (this.verify_request_template == null) {
+ throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template");
+ }
+
+ */
+
+ // load template file
+ // try specific file
+ String verify_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moc.algorithm.id") + VERIFY_TEMPLATE_SUFIX;
+ log.debug("Trying to load specific signature template file " + verify_filename);
+ this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename));
+
+ // try default signature template file
+ if (this.verify_template == null) {
+ verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY);
+ log.debug("Specific signature template file not found. Trying default signature template file " + verify_filename);
+ this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename));
+ }
+
+ // signature template is needed !!!
+ if (this.verify_template == null) {
+ throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template");
+ }
+
+ /* signature verification is not supported by mocca
+ 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 profile name.
+ * @return The profile name.
+ */
+ public String getProfile() {
+ return this.profile;
+ }
+
+ /**
+ * Returns the LocRef content.
+ *
+ * @return Returns the LocRef content.
+ */
+ public String getLocRefContent() {
+ return this.loc_ref_content;
+ }
+
+ /**
+ * 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.
+ */
+ /* signature verification is not supported by mocca
+ 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.
+ */
+ /* signature verification is not supported by mocca
+ 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-2$
+ if (value == null) {
+ value = settings.getValueFromKey(key);
+ }
+ return value;
+ }
+ }
+
+ /**
+ * Parses the common part for all id attributes from a given signature parameter string.
+ * @param sigIdString The given signature parameter string.
+ * @return The common part of all id attributes.
+ */
+ protected String parseSigId(String sigIdString) {
+ int pos = sigIdString.indexOf("@");
+ String result = null;
+ if (pos != -1) {
+ result = sigIdString.substring(pos+1).trim();
+ }
+ return result;
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedMOCIdFormatter.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedMOCIdFormatter.java
new file mode 100644
index 0000000..c942b73
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedMOCIdFormatter.java
@@ -0,0 +1,48 @@
+/**
+ *
+ */
+package at.knowcenter.wag.egov.egiz.sig.sigid;
+
+import org.apache.commons.lang.StringUtils;
+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;
+
+/**
+ * @author tknall
+ *
+ */
+public class DetachedMOCIdFormatter implements IdFormatter {
+
+ public static String SIG_ID_PREFIX = "etsi-moc-1.0";
+
+ /**
+ * Key value in property file
+ */
+ public static final String SIG_ID_PROPERTY_KEY = "default.moc.algorithm.id";
+
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(DetachedIdFormatter.class);
+
+ /**
+ * @see at.knowcenter.wag.egov.egiz.sig.sigid.IdFormatter#formatIds(java.lang.String[])
+ */
+ public String formatIds(String[] ids) {
+ // read id from property file and use it
+ String prefix = null;
+ try {
+ prefix = SettingsReader.getInstance().getValueFromKey(SIG_ID_PROPERTY_KEY);
+ } catch (SettingsException e) {
+ log.error(e.getMessage(), e);
+ }
+ prefix = StringUtils.defaultIfEmpty(prefix, SIG_ID_PREFIX);
+
+ StringBuffer formattedIds = new StringBuffer(prefix).append("@").append(ids[0]);
+ return formattedIds.toString();
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
index 5206ed1..67c5e15 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java
@@ -3,6 +3,8 @@
*/
package at.knowcenter.wag.egov.egiz.sig.sigkz;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -12,6 +14,7 @@ import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException;
import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedLocRefMOAIdFormatter;
+import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedMOCIdFormatter;
import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter;
/**
@@ -87,6 +90,23 @@ public final class SigKZIDHelper
return isMOASigned(kz, sig_id);
}
+
+ /**
+ * @author tknall
+ */
+ public static boolean isMOCCASigned(SignSignatureObject so) {
+ String sig_kz = so.kz;
+ String sig_id = so.id;
+ if (StringUtils.isEmpty(sig_kz) || StringUtils.isEmpty(sig_id)) {
+ return false;
+ }
+ String[] ids = sig_id.split("@");
+ if (ArrayUtils.isEmpty(ids)) {
+ return false;
+ }
+ String prefix = ids[0];
+ return DetachedMOCIdFormatter.SIG_ID_PREFIX.equals(prefix);
+ }
public static boolean isOldBKU(PdfASID sig_kz, String sig_id) throws ConnectorException
{