/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ package at.knowcenter.wag.egov.egiz.sig.connectors.bku; 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.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.algorithmSuite.AlgorithmMapper; import at.gv.egiz.pdfas.algorithmSuite.AlgorithmSuiteObject; import at.gv.egiz.pdfas.algorithmSuite.AlgorithmSuiteUtil; import at.gv.egiz.pdfas.api.commons.Constants; import at.gv.egiz.pdfas.api.internal.LocalBKUParams; import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; 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.ConnectorEnvironment; import at.knowcenter.wag.egov.egiz.sig.sigid.IdFormatter; import at.knowcenter.wag.egov.egiz.tools.CodingHelper; /** * Contains static helper methods used by the BKU Connectors. * * @author wprinz */ public final class BKUHelper { private static final Pattern ALLOWED_SL_RESPONSE_PATTERN = Pattern.compile("^.*<[\\w]*:?(CreateXMLSignatureResponse|VerifyXMLSignatureResponse)[^>]*>(.*).*$", Pattern.DOTALL); /** * The log. */ private static Log log = LogFactory.getLog(BKUHelper.class); /** * Encodes the given SignatureData to a valid Base64Content. * *

* The data is Base64 encoded. If the mime-type suggests that the data is * binary, it is Base64 encoded for a second time. *

* * @param data * The data to be converted to a valid Base64 content. * @return Returns the Base64 content. */ public static String prepareBase64Content(SignatureData data) { // PERF: base64 encoding needs byte array byte [] d = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource()); String base64 = CodingHelper.encodeBase64(d); if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$ { log.debug("The data is application/pdf - so the binary data is Base64 encoded."); //$NON-NLS-1$ base64 = CodingHelper.encodeUTF8AsBase64(base64); } return base64; } /** * Prepares the enveloping data. *

* This is useful for building the hash. *

* * @param data * The data to be prepared. * @return Returns the prepared data. */ public static byte[] prepareEnvelopingData(SignatureData data) { // PERF: prepareEnvelopingData needs byte array byte[] enc = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource()); if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$ { log.debug("The data is application/pdf - so the binary data is Base64 encoded."); //$NON-NLS-1$ String base64 = CodingHelper.encodeBase64(enc); try { enc = base64.getBytes("US-ASCII"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { throw new RuntimeException("Very Strange: US-ASCII encoding not supported???", e); //$NON-NLS-1$ } } return enc; } /** * Checks the response xml for an error description and if found throws an * appropriate exception. * * @param response_string * The response xml. * @throws ConnectorException * f.e. */ public static void checkResponseForError(String response_string) throws ConnectorException { if (StringUtils.isEmpty(response_string)) { throw new ConnectorException(ErrorCode.UNABLE_TO_RECEIVE_SUITABLE_RESPONSE, "No suitable response received."); } log.debug("Checking response for error: " + response_string); 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.info("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); String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); String error_mess = null; if (erm_m_s.find() && erm_m_e.find()) { error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); } throw new ExternalErrorException(error_code, error_mess); } log.debug("No error found. Assuring that CreateXMLSignatureResponse or VerifyXMLSignatureResponse elements are available."); // assure that a CreateXMLSignatureResponse or a VerifyXMLSignatureResponse is available Matcher slMatcher = ALLOWED_SL_RESPONSE_PATTERN.matcher(response_string); if (!slMatcher.matches()) { throw new ConnectorException(ErrorCode.UNABLE_TO_RECEIVE_SUITABLE_RESPONSE, "No suitable response received: " + response_string); } } /** * This method parses the BKU-Response string. * *

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

* * @param xmlResponse * The response string. * @return Returns the parsed signature object holding the data. * * @throws ConnectorException * ErrorCode (303, 304) * @see SignatureObject * @see CodingHelper * @see X509Cert */ public static SignSignatureObject parseCreateXMLResponse(String xmlResponse, IdFormatter id_formatter, ConnectorEnvironment environment) throws ConnectorException { if (log.isDebugEnabled()) { log.debug("xmlResponse = " + xmlResponse); } 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 ConnectorException(300, e); } catch (CertificateException e) { log.error(e); throw new ConnectorException(300, e); } catch (IOException e) { log.error(e); throw new ConnectorException(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)) // { // ConnectorException se = new ConnectorException(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 algs = AlgorithmSuiteUtil.extractAlgorithmSuiteString(xmlResponse); SignSignatureObject so = new SignSignatureObject(); so.date = sig_tim; so.issuer = iss_nam; so.signatureValue = sig_val; so.x509Certificate = cert; AlgorithmSuiteObject suite = new AlgorithmSuiteObject(algs, false); so.sigAlgorithm = AlgorithmMapper.getUri(suite.getSignatureMethod()); String defaultCertAlg = environment.getDefaultAlgForCert(cert); if (AlgorithmSuiteUtil.isDefaultCertAlg(algs, defaultCertAlg)) { // do not embed default alg algs = null; } String final_ids = id_formatter.formatIds(ids, algs); so.id = final_ids; return so; } /** * Removes all whitespaces ("\\s") from the String. * * @param str * The String. * @return The String with all whitespaces removed. */ public 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 static String extractId(String text, String name) { String id = null; // fatal bug; fixed by tknall (start) int startOfName = text.indexOf(name); if (startOfName == -1) { log.debug("No id for name \"" + name + "\" extracted. Probably detached signature. Returning empty id: \"\""); //$NON-NLS-1$ return ""; } // stop int start_idx = startOfName + 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); if (log.isDebugEnabled()) { log.debug("extract id:" + name + id); //$NON-NLS-1$ } return id; } /** * 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 */ public static 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("<[\\w]*:?SignatureCheck>"); //$NON-NLS-1$ Pattern sig_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ Pattern man_chk_p_s = Pattern.compile("<[\\w]*:?SignatureManifestCheck>"); //$NON-NLS-1$ Pattern man_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ Pattern cer_chk_p_s = Pattern.compile("<[\\w]*:?CertificateCheck>"); //$NON-NLS-1$ Pattern cer_chk_p_e = Pattern.compile(""); //$NON-NLS-1$ // [tknall] start qualified certificate Pattern cert_qualified_p = Pattern.compile("<[\\w]*:?QualifiedCertificate/>"); //$NON-NLS-1$ Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse); // [tknall] stop qualified certificate Pattern code_p_s = Pattern.compile("<[\\w]*:?Code>"); //$NON-NLS-1$ Pattern code_p_e = Pattern.compile(""); //$NON-NLS-1$ Pattern info_p_s = Pattern.compile("<[\\w]*:?Info>"); //$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); Pattern hash_data_p_s = Pattern.compile(""); //$NON-NLS-1$ Pattern hash_data_p_e = Pattern.compile(""); //$NON-NLS-1$ Matcher hash_data_m_s = hash_data_p_s.matcher(xmlResponse); Matcher hash_data_m_e = hash_data_p_e.matcher(xmlResponse); SignatureResponse sig_res = new SignatureResponse(); // public authority (tknall) Pattern publicAuthority_p = Pattern.compile(""); Matcher publicAuthority_m = publicAuthority_p.matcher(xmlResponse); sig_res.setPublicAuthority(false); sig_res.setPublicAuthorityCode(null); if (publicAuthority_m.find()) { sig_res.setPublicAuthority(true); } else { Matcher publicAuthority_m_s = Pattern.compile("").matcher(xmlResponse); Matcher publicAuthority_m_e = Pattern.compile("").matcher(xmlResponse); if (publicAuthority_m_s.find() && publicAuthority_m_e.find()) { sig_res.setPublicAuthority(true); String codePart = xmlResponse.substring(publicAuthority_m_s.end(), publicAuthority_m_e.start()); Matcher code_m_s = code_p_s.matcher(codePart); Matcher code_m_e = code_p_e.matcher(codePart); if (code_m_s.find() && code_m_e.find()) { String code = codePart.substring(code_m_s.end(), code_m_e.start()); sig_res.setPublicAuthorityCode(code); } } } // [tknall] start qualified certificate sig_res.setQualifiedCertificate(cert_qualified_m.find()); // [tknall] stop qualified certificate if (hash_data_m_s.find() && hash_data_m_e.find()) { String hashInputData = xmlResponse.substring(hash_data_m_s.end(), hash_data_m_e.start()); Pattern b64_p_s = Pattern.compile(""); //$NON-NLS-1$ Pattern b64_p_e = Pattern.compile(""); //$NON-NLS-1$ Matcher b64_m_s = b64_p_s.matcher(hashInputData); Matcher b64_m_e = b64_p_e.matcher(hashInputData); boolean hashInputDataFound = b64_m_s.find() && b64_m_e.find(); String b64 = hashInputDataFound ? hashInputData.substring(b64_m_s.end(), b64_m_e.start()) : ""; sig_res.setHashInputData(b64); } 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; } public static String formDateTimeElement(Date verificationTime) { return formDateTimeElement(verificationTime, null); } public static String formDateTimeElement(Date verificationTime, String namespace) { String nsPrefix = StringUtils.isBlank(namespace) ? "" : (namespace + ":"); String dateTimeElement = ""; if (verificationTime != null) { log.debug("VerificationTime = " + verificationTime); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); df.setTimeZone(TimeZone.getTimeZone("UTC")); String dateTime = df.format(verificationTime) + "Z"; log.debug("DateTime (VerificationTime in UTC) = " + dateTime); dateTimeElement = "<" + nsPrefix + "DateTime>" + dateTime + ""; }; return dateTimeElement; } public static String getBKUIdentifier(Properties parsedResponseProperties) { // http://www.buergerkarte.at/konzept/securitylayer/spezifikation/aktuell/bindings/bindings.html#http.kodierung.response.browser String bkuServerHeader = parsedResponseProperties.getProperty(BKUPostConnection.BKU_SERVER_HEADER_KEY); // http://www.buergerkarte.at/konzept/securitylayer/spezifikation/aktuell/bindings/bindings.html#http.kodierung.response.dataurl String bkuUserAgentHeader = parsedResponseProperties.getProperty(BKUPostConnection.BKU_USER_AGENT_HEADER_KEY); String bkuSignatureLayout = parsedResponseProperties.getProperty(BKUPostConnection.BKU_SIGNATURE_LAYOUT_HEADER_KEY); return getBKUIdentifier(bkuServerHeader, bkuUserAgentHeader, bkuSignatureLayout); } public static String getBKUIdentifier(String bkuServerHeader, String bkuUserAgentHeader, String bkuSignatureLayout) { log.debug("BKU response header \"user-agent\": " + bkuUserAgentHeader); log.debug("BKU response header \"server\": " + bkuServerHeader); log.trace("BKU response header \"" + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "\": " + bkuSignatureLayout); String result = null; if (bkuServerHeader != null) { result = bkuServerHeader; } else if (bkuUserAgentHeader != null) { result = bkuUserAgentHeader; } else { log.warn("Unable to find any BKU identifier (neither header value \"user-agent\" nor \"server\".)"); } if (bkuSignatureLayout != null && result != null) { log.debug("BKU response header \"" + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "\" found."); String signatureLayoutData = " " + Constants.BKU_HEADER_SIGNATURE_LAYOUT + "/" + bkuSignatureLayout; if (!result.endsWith(signatureLayoutData)) { log.debug("Appending signature layout value \"" + bkuSignatureLayout + "\" to bku identifier."); result += signatureLayoutData; } else { log.debug("Signature layout already encoded in server/user-agent header."); } } if (result != null) { log.debug("Returning BKU identifier \"" + result + "\""); } else { log.debug("Returning null BKU identifier."); } return result; } public static String getBKUIdentifier(LocalBKUParams bkuParams) { return getBKUIdentifier(bkuParams.getServer(), bkuParams.getUserAgent(), bkuParams.getSignatureLayout()); } }