/** * 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.gv.egiz.pdfas.impl.api.internal; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.api.PdfAs; import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; import at.gv.egiz.pdfas.api.commons.Constants; import at.gv.egiz.pdfas.api.commons.SignatureInformation; import at.gv.egiz.pdfas.api.exceptions.PdfAsException; import at.gv.egiz.pdfas.api.internal.LocalBKUParams; import at.gv.egiz.pdfas.api.internal.PdfAsInternal; import at.gv.egiz.pdfas.api.internal.SignatureEntry; import at.gv.egiz.pdfas.api.sign.SignParameters; import at.gv.egiz.pdfas.api.sign.SignResult; import at.gv.egiz.pdfas.api.sign.SignatureDetailInformation; import at.gv.egiz.pdfas.api.verify.VerifyResult; import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.gv.egiz.pdfas.framework.ConnectorParameters; import at.gv.egiz.pdfas.framework.input.TextDataSource; import at.gv.egiz.pdfas.impl.api.CheckHelper; import at.gv.egiz.pdfas.impl.api.analyze.AnalyzeResultImpl; import at.gv.egiz.pdfas.impl.api.commons.PdfDataSourceAdapter; import at.gv.egiz.pdfas.impl.api.commons.SignatureInformationAdapter; import at.gv.egiz.pdfas.impl.api.sign.SignatureDetailInformationImpl; import at.gv.egiz.pdfas.impl.api.verify.VerifyResultAdapter; import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; 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.framework.SignatorFactory; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; import at.knowcenter.wag.egov.egiz.sig.ConnectorInformation; 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.SignatureTypes; import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector; 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.LocRefDetachedBKUConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.MultipartDetachedBKUConnector; 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.connectors.mocca.LocRefDetachedMOCCAConnector; import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter; import at.knowcenter.wag.egov.egiz.sig.signaturelayout.SignatureLayoutHandlerFactory; import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; /** * @see PdfAsInternal * * @author exthex * */ public class PdfAsInternalObject implements PdfAsInternal { /** * The log. */ private static Log log = LogFactory.getLog(CheckHelper.class); /** * @see PdfAsInternal#verifyBKUSupport(LocalBKUParams) */ public void verifyBKUSupport(LocalBKUParams bkuParams) throws ConnectorException, SettingsException { String bkuIdentifier = BKUHelper.getBKUIdentifier(bkuParams); SignatureLayoutHandlerFactory.verifyBKUSupport(bkuIdentifier); } /** * @see PdfAsInternal#finishLocalSign(PdfAs, SignParameters, SignatureDetailInformation, LocalBKUParams, String) */ public SignResult finishLocalSign(PdfAs pdfAs, SignParameters signParameters, SignatureDetailInformation sdi, LocalBKUParams bkuParams, boolean multipart, String xmlResponse) throws PdfAsException { LocalConnector c = chooseLocalConnectorForSign(signParameters.getSignatureDevice(), signParameters.getSignatureProfileId(), "not needed", multipart); SignSignatureObject sso = c.analyzeSignResponse(buildResponseProperties(bkuParams, xmlResponse)); ((SignatureDetailInformationImpl)sdi).setSignSignatureObject(sso); return pdfAs.finishSign(signParameters, sdi); } private Properties buildResponseProperties(LocalBKUParams bkuParams, String xmlResponse) { Properties ret = new Properties(); if (bkuParams.getServer() != null) ret.setProperty(BKUPostConnection.BKU_SERVER_HEADER_KEY, bkuParams.getServer()); if (bkuParams.getUserAgent() != null) ret.setProperty(BKUPostConnection.BKU_USER_AGENT_HEADER_KEY, bkuParams.getUserAgent()); if (bkuParams.getSignatureLayout() != null) ret.setProperty(BKUPostConnection.BKU_SIGNATURE_LAYOUT_HEADER_KEY, bkuParams.getSignatureLayout()); ret.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xmlResponse); return ret; } private LocalConnector chooseLocalConnectorForSign(String device, String profile, String loc_ref_url, boolean multipart) throws ConnectorException{ ConnectorParameters cp = new ConnectorParameters(); cp.setProfileId(profile); if (Constants.SIGNATURE_DEVICE_MOC.equals(device)) { if (!multipart) { return new LocRefDetachedMOCCAConnector(cp, loc_ref_url); } } else if (Constants.SIGNATURE_DEVICE_BKU.equals(device)){ if (multipart) { return new MultipartDetachedBKUConnector(cp); } else { return new LocRefDetachedBKUConnector(cp, loc_ref_url); } } else if (Constants.SIGNATURE_DEVICE_MOBILE.equals(device)){ if (multipart) { return new MultipartDetachedBKUConnector(cp); } else { return new LocRefDetachedBKUConnector(cp, loc_ref_url); } } else if (Constants.SIGNATURE_DEVICE_MOBILETEST.equals(device)){ if (multipart) { return new MultipartDetachedBKUConnector(cp); } else { return new LocRefDetachedBKUConnector(cp, loc_ref_url); } } log.error("Currently only the BKU connector is fully implemented."); return new LocRefDetachedBKUConnector(cp, loc_ref_url); } private LocalConnector chooseLocalConnectorForVerify(String connector, PdfASID sig_kz, String sig_id, String profile, String loc_ref_url) throws ConnectorException { log.debug("Choosing LocalConnector for verification..."); log.debug("connector type = " + connector); log.debug("sig_kz = " + sig_kz); log.debug("sig_id = " + sig_id); if (!connector.equals("bku")) { log.error("Currently only the BKU connector is fully implemented."); } if (sig_kz == null) { log.debug("sig_kz is null -> must be old signature -> choosing old Base64 connector."); return new OldEnvelopingBase64BKUConnector(profile); } log.debug("sig_kz is not null -> must be one of the newer ... base64, base64 hotfix, or detached"); if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_0_0)) { log.debug("sig_kz version is 1.0.0 -> choosing base64 (old or hotfix)"); if (sig_id == null) { log.debug("sig_id is null, which means that it is a MOA signature -> choose a hotfix base64 connector (thus it is moa - it doesn't matter)."); return new EnvelopedBase64BKUConnector(profile); } String[] sig_id_parts = sig_id.split("@"); if (sig_id_parts.length == 2) { log.debug("sig_id has 2 @-separated parts -> choosing old base64 connector"); return new OldEnvelopingBase64BKUConnector(profile); } if (sig_id_parts[0].equals(HotfixIdFormatter.SIG_ID_PREFIX)) { log.debug("sig_id prefix is hotfix -> choosing hotfix base64 connector"); return new EnvelopedBase64BKUConnector(profile); } throw new ConnectorException(300, "The SIG_KZ version is 1.0.0, but SIG_ID is neither MOA nor Old base64 nor Hotfix base64 ???'"); } if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_1_0) || sig_kz.getVersion().equals(SignatorFactory.VERSION_1_2_0)) { log.debug("sig_kz version is 1.1.0/1.2.0 -> choosing detached (loc ref) connector."); ConnectorParameters cp = new ConnectorParameters(); cp.setProfileId(profile); return new LocRefDetachedBKUConnector(cp, loc_ref_url); } throw new ConnectorException(ErrorCode.UNSUPPORTED_SIGNATURE, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown."); } /** * @see PdfAsInternal#getLocalServiceAddress(String, String) */ public String getLocalServiceAddress(String profile, String device) throws SettingsException { SettingsReader settings = SettingsReader.getInstance(); String key = device + ".sign.url"; String value = settings.getValueFromKey("sig_obj." + profile + "." + key); //$NON-NLS-1$//$NON-NLS-2$ if (value == null) { value = settings.getValueFromKey(key); } return value; } /** * @see PdfAsInternal#prepareLocalSignRequest(SignParameters, String, SignatureDetailInformation) */ public String prepareLocalSignRequest(SignParameters signParameters, boolean multipart, String loc_ref_url, SignatureDetailInformation sdi) throws ConnectorException { LocalConnector c = chooseLocalConnectorForSign(signParameters.getSignatureDevice(), signParameters.getSignatureProfileId(), loc_ref_url, multipart); SignatureData sd = new SignatureDataImpl(new PdfDataSourceAdapter(sdi.getSignatureData()), sdi.getSignatureData().getMimeType(), sdi.getSignatureData().getCharacterEncoding()); String sign_request = c.prepareSignRequest(sd); return sign_request; } /** * @see PdfAsInternal#analyzeFromRawText(String, Map) */ public AnalyzeResult analyzeFromRawText(String rawText, Map sigValues) throws SignatureException, SettingsException, SignatureTypesException, NormalizeException { String normalizedText = PdfAS.normalizeText(rawText); SignatureObject signature_object = new SignatureObject(); String default_type = SettingsReader.getInstance().getValueFromKey(SignatureTypes.DEFAULT_TYPE); signature_object.setSigType(default_type); signature_object.initByType(); Iterator sigKeys = sigValues.keySet().iterator(); while (sigKeys.hasNext()){ String key = (String)sigKeys.next(); signature_object.setSigValue(key, (String)sigValues.get(key)); } TextDataSource tds = new TextDataSourceImpl(normalizedText); SignatureHolder new_holder = new TextualSignatureHolder(tds, signature_object); SignatureInformation si = new SignatureInformationAdapter(new_holder); List signatures = new Vector(); signatures.add(si); AnalyzeResult ret = new AnalyzeResultImpl(signatures); return ret; } /** * @see PdfAsInternal#prepareLocalVerifyRequest(SignatureInformation, String, String, String) */ public String prepareLocalVerifyRequest(SignatureInformation sigInfo, String connector, String profile, String loc_ref_url) throws SignatureException, ConnectorException { SignatureHolder holder = (SignatureHolder)sigInfo.getInternalSignatureInformation(); SignatureObject s = holder.getSignatureObject(); SignatureData sd = PdfAS.convertSignatureHolderToSignatureData(holder); SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(s); LocalConnector local_conn = chooseLocalConnectorForVerify(connector, s.getKZ(), so.id, profile, loc_ref_url); String request_string = local_conn.prepareVerifyRequest(sd, so, null); return request_string; } /** * @see PdfAsInternal#finishLocalVerify(SignatureInformation, String, String, String, String) */ public VerifyResult finishLocalVerify(SignatureInformation sigInfo, String connector, String profile, String loc_ref_url, String xmlResponse) throws SignatureException, ConnectorException { SignatureHolder holder = (SignatureHolder)sigInfo.getInternalSignatureInformation(); SignatureObject s = holder.getSignatureObject(); SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(s); LocalConnector local_conn = chooseLocalConnectorForVerify(connector, s.getKZ(), so.id, profile, loc_ref_url); Properties props = new Properties(); props.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xmlResponse); SignatureResponse sigResponse = local_conn.analyzeVerifyResponse(props); return new VerifyResultAdapter(sigResponse, holder, null, null); // timestamp and xmldsig not needed here } /** * @see PdfAsInternal#getSignatureEntryFromSignatureInformation(String, SignatureInformation) */ public SignatureEntry getSignatureEntryFromSignatureInformation(String key, SignatureInformation sigInfo) { SignatureHolder holder = (SignatureHolder)sigInfo.getInternalSignatureInformation(); SignatureObject s = holder.getSignatureObject(); at.knowcenter.wag.egov.egiz.sig.SignatureEntry internalEntry = s.getSigEntry(key); if (internalEntry == null) return null; SignatureEntry ret = new SignatureEntry(key); ret.setCaption(internalEntry.getCaption()); ret.setValue(internalEntry.getValue()); return ret; } /** * @see PdfAsInternal#getSignedText(SignatureInformation) */ public String getSignedText(SignatureInformation sigInfo) { SignatureHolder holder = (SignatureHolder)sigInfo.getInternalSignatureInformation(); if (holder instanceof TextualSignatureHolder) return ((TextualSignatureHolder)holder).getSignedText(); return null; } /** * @see PdfAsInternal#getConnectorsAvailableForWeb() */ public Map getConnectorsAvailableForWeb() throws ConnectorFactoryException { ConnectorInformation ci[] = ConnectorFactory.getConnectorInformationArray(); Map ret = new HashMap(); for (int i = 0; i < ci.length; i++) { String id = ci[i].getIdentifier(); if (ConnectorFactory.isAvailableForWeb(id)) { ret.put(id, ci[i].getDescription()); } } return ret; } }