/** * */ package at.knowcenter.wag.egov.egiz.sig.connectors.moa; import java.security.cert.X509Certificate; import java.util.Properties; 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.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.sig.SignatureData; import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; 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.EnvelopedBase64BKUConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.OldEnvelopingBase64BKUConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; import at.knowcenter.wag.egov.egiz.sig.sigid.OldMOAIdFormatter; import at.knowcenter.wag.egov.egiz.sig.sigkz.SigKZIDHelper; import at.knowcenter.wag.egov.egiz.tools.CodingHelper; import at.knowcenter.wag.egov.egiz.tools.FileHelper; /** * @author wprinz * */ public class EnvelopingBase64MOAConnector implements Connector { /** * The log. */ private static Log log = LogFactory.getLog(EnvelopingBase64MOAConnector.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 ConnectorException * f.e. */ public EnvelopingBase64MOAConnector(String profile) throws ConnectorException { this.environment = new Environment(profile); } /** * @see at.knowcenter.wag.egov.egiz.sig.connectors.Connector#doSign(at.knowcenter.wag.egov.egiz.sig.SignatureData) */ public SignSignatureObject doSign(SignatureData data) throws ConnectorException { log.debug("doSign:"); //$NON-NLS-1$ String sign_request_xml = prepareSignRequest(data); log.debug("sign_request_xml = " + sign_request_xml); //$NON-NLS-1$ String url = this.environment.getSignURL(); Properties response_properties = sendRequest(url, MOASoapConnection.SERVICE_SIGN, sign_request_xml); log.debug("response_string = " + response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY));; //$NON-NLS-1$ 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; } /** * @see at.knowcenter.wag.egov.egiz.sig.connectors.Connector#doVerify(at.knowcenter.wag.egov.egiz.sig.SignatureData, * at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject) */ public SignatureResponse doVerify(SignatureData data, SignSignatureObject so) throws ConnectorException { log.debug("doVerify:"); //$NON-NLS-1$ String verify_request_xml = prepareVerifyRequest(data, so); log.debug("verify_request_xml = " + verify_request_xml); //$NON-NLS-1$ String url = this.environment.getVerifyURL(); Properties response_properties = sendRequest(url, MOASoapConnection.SERVICE_VERIFY, verify_request_xml); SignatureResponse signature_response = analyzeVerifyResponse(response_properties); log.debug("doVerify finished."); //$NON-NLS-1$ return signature_response; } protected Properties sendRequest(String url, String mode, String request_string) throws ConnectorException { try { Properties response_properties = MOASoapConnection.connectMOA(request_string, MOASoapConnection.SERVICE_SIGN, url); return response_properties; } catch (Exception e) { throw new ConnectorException(330, e); } } /** * 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 ConnectorException * f.e. */ protected String prepareSignRequest(SignatureData data) throws ConnectorException { log.debug("prepareSignRequest:"); //$NON-NLS-1$ String sign_request_template = this.environment.getSignRequestTemplate(); String sign_key_identifier = this.environment.getSignKeyIdentifier(); String base64 = BKUHelper.prepareBase64Content(data); String sign_request_xml = sign_request_template.replaceFirst(TemplateReplaces.KEY_IDENTIFIER_REPLACE, sign_key_identifier); sign_request_xml = sign_request_xml.replaceFirst(TemplateReplaces.BASE64_CONTENT_REPLACE, base64); log.debug("prepareSignRequest finished."); //$NON-NLS-1$ return sign_request_xml; } /** * 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 ConnectorException * f.e. */ public String prepareVerifyRequest(SignatureData data, SignSignatureObject so) throws ConnectorException { String verify_request_template = this.environment.getVerifyRequestTemplate(); String xml_content = null; if (!SigKZIDHelper.isMOASigned(so)) { if (SigKZIDHelper.isOldBKU(so)) { OldEnvelopingBase64BKUConnector bku_connector = new OldEnvelopingBase64BKUConnector(this.environment.getProfile()); xml_content = bku_connector.prepareXMLContent(data, so); } else { EnvelopedBase64BKUConnector bku_connector = new EnvelopedBase64BKUConnector(this.environment.getProfile()); 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()); return verify_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 ConnectorException * f.e. */ public SignSignatureObject analyzeSignResponse(Properties response_properties) throws ConnectorException { log.debug("analyzeSignResponse:"); //$NON-NLS-1$ String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY); BKUHelper.checkResponseForError(response_string); SignSignatureObject so = MOAHelper.parseCreateXMLResponse(response_string, new OldMOAIdFormatter()); log.debug("analyzeSignResponse finished."); //$NON-NLS-1$ return so; } /** * Analyzes the verify response string. * * @param response_properties * The response properties containing the response XML. * @return Returns the SignatureResponse containing the verification result. * @throws ConnectorException * f.e. */ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws ConnectorException { log.debug("analyzeVerifyResponse:"); //$NON-NLS-1$ String response_string = response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY); BKUHelper.checkResponseForError(response_string); SignatureResponse signature_response = BKUHelper.parseVerifyXMLResponse(response_string); log.debug("analyzeVerifyResponse finished."); //$NON-NLS-1$ return signature_response; } /** * 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 ConnectorException * f.e. */ public String prepareXMLContent(SignatureData data, SignSignatureObject so) throws ConnectorException { log.debug("prepareXMLContent:"); //$NON-NLS-1$ try { String verify_template = this.environment.getVerifyTemplate(); 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.replaceFirst(TemplateReplaces.CERT_ALG_REPLACE, cert_alg); // data digest replace byte[] data_value = BKUHelper.prepareEnvelopingData(data); { byte[] data_value_hash = CodingHelper.buildDigest(data_value); String object_data_hash = CodingHelper.encodeBase64(data_value_hash); 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); // Base64 content replace String base64 = CodingHelper.encodeBase64(data_value); verify_xml = verify_xml.replaceFirst(TemplateReplaces.BASE64_CONTENT_REPLACE, base64); // Qualified Properties replaces verify_xml = verify_xml.replaceFirst(TemplateReplaces.SIGNING_TIME_REPLACE, so.getDate()); verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_CERTIFICATE_REPLACE, certDigest); verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_ISSUER_NAME_REPLACE, so.getIssuer()); verify_xml = verify_xml.replaceFirst(TemplateReplaces.X509_SERIAL_NUMBER_REPLACE, so.getSerialNumber()); // SigDataRefReplace already done above // Signed Properties hash { final String ETSI_SIGNED_PROPERTIES_START_TAG = "