From 95f6c6fe321d33dc8fa9e18c7d96bd9b21ef10cc Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 14 Jan 2009 11:39:31 +0000 Subject: Switching to itext-2.1.5-rev3628. itext library: minor adjustments for pdf-as Adding new error code (103) for invalid pdfa/1b font configuration. Minor updates for PDF/A support. Support for local MOCCA CCS added. Multi language for web application. Encoding issue for web application fixed by implementing an EncodingFilter. Dynamic sign upload form implemented. Order of input fields for dynamic upload form changed. MOCCA logo added to sign upload form. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@319 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../egiz/sig/connectors/mocca/MOCCAHelper.java | 194 +++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/MOCCAHelper.java (limited to 'src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/MOCCAHelper.java') diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/MOCCAHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/MOCCAHelper.java new file mode 100644 index 0000000..1bb89be --- /dev/null +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/mocca/MOCCAHelper.java @@ -0,0 +1,194 @@ +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.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.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.sig.SignatureObject; +import at.knowcenter.wag.egov.egiz.sig.X509Cert; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUHelper; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; +import at.knowcenter.wag.egov.egiz.sig.sigid.IdFormatter; +import at.knowcenter.wag.egov.egiz.tools.CodingHelper; + +/** + * Provides useful methods for the usage of the open source cce mocca. + * + * @author tknall + */ +public final class MOCCAHelper { + + /** + * Prevents this plain util class from being instantiated. + */ + private MOCCAHelper() { + } + + /** + * The logging implementation. + */ + private final static Log log = LogFactory.getLog(MOCCAHelper.class); + + /** + * The pattern that identifies a mocca response (that matches the header value "Server" or "User-Agent"). + */ + private final static Pattern MOCCA_PATTERN = Pattern.compile("(citizen-card-environment/\\d+(\\.\\d+) MOCCA[ /].*)|(Jetty(.*))"); + + /** + * Checks if the given header value for "Server" or "User-Agent" respectively indicates that + * the response was from a mocca cce. + * @param cceId The value of the http header "Server" or "User-Agent". + * @see http://www.buergerkarte.at/konzept/securitylayer/spezifikation/aktuell/bindings/bindings.html#http.kodierung + * @return true if the id points to a mocca response, false if not. + */ + public final static boolean isMOCCACCEId(String cceId) { + if (cceId == null) { + return false; + } + return MOCCA_PATTERN.matcher(cceId).matches(); + } + + /** + * This method parses the signature creation response of the signature + * device mocca. + * + * @param xmlResponse The response string. + * @return Returns the parsed signature object holding the data. + * @see SignatureObject + * @see CodingHelper + * @see X509Cert + */ + public final static SignSignatureObject parseCreateXMLResponse(String xmlResponse, IdFormatter id_formatter) throws ConnectorException { + + if (log.isDebugEnabled()) { + log.debug("xmlResponse = " + xmlResponse); + } + + 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(""); + + 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*").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; + } + +} -- cgit v1.2.3