/** * */ package net.conselldemallorca.helium.integracio.plugins.signatura.afirma; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Node; /** * Mètodes d'accés a les funcionalitats proporcionades pel * servei de AFirma * * @author Limit Tecnologies <limit@limit.es> */ public class AfirmaUtils { public static final String MODE_VALIDACIO_SIMPLE = "0"; public static final String MODE_VALIDACIO_AMB_REVOCACIO = "1"; public static final String MODE_VALIDACIO_CADENA = "2"; public static final String FORMAT_SIGNATURA_PKCS7 = "PKCS7"; public static final String FORMAT_SIGNATURA_CMS = "CMS"; public static final String FORMAT_SIGNATURA_CADES_BES = "CAdES-BES"; public static final String FORMAT_SIGNATURA_CADES_T = "CAdES-T"; public static final String FORMAT_SIGNATURA_XMLDSIG = "XMLDSIG"; public static final String FORMAT_SIGNATURA_XADES = "XAdES"; public static final String FORMAT_SIGNATURA_XADES_BES = "XAdES-BES"; public static final String FORMAT_SIGNATURA_XADES_T = "XAdES-T"; public static final String FORMAT_SIGNATURA_PDF = "PDF"; public static final String FORMAT_SIGNATURA_ODF = "ODF"; private String baseUrl; private String aplicacioId; private String usuari; private String password; private String formatSignatura; private String modeValidacio; private boolean logMissatges; public AfirmaUtils( String baseUrl, String aplicacioId) { this.baseUrl = baseUrl; this.aplicacioId = aplicacioId; } public AfirmaUtils( String baseUrl, String aplicacioId, String usuari, String password) { this.baseUrl = baseUrl; this.aplicacioId = aplicacioId; this.usuari = usuari; this.password = password; } public ValidarCertificatResponse validarCertificat( String certificatBase64, boolean obtenirDadesCertificat) throws AfirmaException { try { String respostaXml = cridarValidarCertificado( certificatBase64, obtenirDadesCertificat); ValidarCertificatResponse resposta = new ValidarCertificatResponse(); Document document = obtenirDocumentXmlResposta(respostaXml); Node resultado = document.selectSingleNode("/mensajeSalida/respuesta/ResultadoProcesamiento/ResultadoValidacion/resultado"); if (resultado != null && "0".equals(resultado.getText())) { resposta.setEstat(ValidarSignaturaResponse.ESTAT_OK); //Node descripcion = document.selectSingleNode("/mensajeSalida/respuesta/ResultadoProcesamiento/ResultadoValidacion/descripcion"); if (obtenirDadesCertificat) { Node infoCertificado = document.selectSingleNode("/mensajeSalida/respuesta/ResultadoProcesamiento/InfoCertificado"); resposta.setDadesCertificat(getDadesCertificat(infoCertificado)); } } else { resposta.setEstat(ValidarSignaturaResponse.ESTAT_ERROR); Node codigoError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/codigoError"); Node descripcionError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/descripcion"); Node excepcionAsociada = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/excepcionAsociada"); if (codigoError != null) resposta.setErrorCodi(codigoError.getText()); if (descripcionError != null) resposta.setErrorDescripcio(descripcionError.getText()); if (excepcionAsociada != null) resposta.setErrorExcepcio(excepcionAsociada.getText()); } return resposta; } catch (Exception ex) { throw new AfirmaException("Error en la validació de certificat", ex); } } public ObtenirDadesCertificatResponse obtenirDadesCertificat( String certificatBase64) throws AfirmaException { try { String respostaXml = cridarInfoCertificado( certificatBase64); ObtenirDadesCertificatResponse resposta = new ObtenirDadesCertificatResponse(); Document document = obtenirDocumentXmlResposta(respostaXml); Node infoCertificado = document.selectSingleNode("/mensajeSalida/respuesta/ResultadoProcesamiento/InfoCertificado"); if (infoCertificado != null) { resposta.setEstat(ValidarSignaturaResponse.ESTAT_OK); resposta.setDadesCertificat(getDadesCertificat(infoCertificado)); } else { resposta.setEstat(ValidarSignaturaResponse.ESTAT_ERROR); Node codigoError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/codigoError"); Node descripcionError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/descripcion"); Node excepcionAsociada = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/excepcionAsociada"); if (codigoError != null) resposta.setErrorCodi(codigoError.getText()); if (descripcionError != null) resposta.setErrorDescripcio(descripcionError.getText()); if (excepcionAsociada != null) resposta.setErrorExcepcio(excepcionAsociada.getText()); } return resposta; } catch (Exception ex) { throw new AfirmaException("Error en la obtenció de dades del certificat", ex); } } @SuppressWarnings("unchecked") public ValidarSignaturaResponse validarSignatura( String documentBase64, String signaturaBase64, boolean obtenirDadesCertificat) throws AfirmaException { try { String respostaXml = cridarValidarFirma( signaturaBase64, documentBase64); ValidarSignaturaResponse resposta = new ValidarSignaturaResponse(); Document document = obtenirDocumentXmlResposta(respostaXml); Node estado = document.selectSingleNode("/mensajeSalida/respuesta/Respuesta/estado"); if (estado != null && "true".equalsIgnoreCase(estado.getText())) { resposta.setEstat(ValidarSignaturaResponse.ESTAT_OK); //Node proceso = document.selectSingleNode("/mensajeSalida/respuesta/Respuesta/descripcion/validacionFirmaElectronica/proceso"); //Node detalle = document.selectSingleNode("/mensajeSalida/respuesta/Respuesta/descripcion/validacionFirmaElectronica/detalle"); //Node conclusion = document.selectSingleNode("/mensajeSalida/respuesta/Respuesta/descripcion/validacionFirmaElectronica/conclusion"); List<Node> certificats = document.selectNodes("/mensajeSalida/respuesta/Respuesta/descripcion/validacionFirmaElectronica/informacionAdicional/firmante/certificado"); if (obtenirDadesCertificat && certificats != null) { List<DadesCertificat> dadesCertificat = new ArrayList<DadesCertificat>(); for (Node certificat: certificats) { ObtenirDadesCertificatResponse resp = obtenirDadesCertificat( certificat.getText()); if (resp.isEstatOk()) dadesCertificat.add(resp.getDadesCertificat()); } resposta.setDadesCertificat(dadesCertificat); } } else { resposta.setEstat(ValidarSignaturaResponse.ESTAT_ERROR); Node codigoError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/codigoError"); Node descripcionError = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/descripcion"); Node excepcionAsociada = document.selectSingleNode("/mensajeSalida/respuesta/Excepcion/excepcionAsociada"); if (codigoError != null) resposta.setErrorCodi(codigoError.getText()); if (descripcionError != null) resposta.setErrorDescripcio(descripcionError.getText()); if (excepcionAsociada != null) resposta.setErrorExcepcio(excepcionAsociada.getText()); } return resposta; } catch (Exception ex) { throw new AfirmaException("Error en la validació de signatura", ex); } } public String getBaseUrl() { return baseUrl; } public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } public String getAplicacioId() { return aplicacioId; } public void setAplicacioId(String aplicacioId) { this.aplicacioId = aplicacioId; } public String getUsuari() { return usuari; } public void setUsuari(String usuari) { this.usuari = usuari; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFormatSignatura() { return formatSignatura; } public void setFormatSignatura(String formatSignatura) { this.formatSignatura = formatSignatura; } public String getModeValidacio() { return modeValidacio; } public void setModeValidacio(String modeValidacio) { this.modeValidacio = modeValidacio; } public boolean isLogMissatges() { return logMissatges; } public void setLogMissatges(boolean logMissatges) { this.logMissatges = logMissatges; } @SuppressWarnings("unchecked") private DadesCertificat getDadesCertificat( Node infoCertificado) throws Exception { if (infoCertificado == null) return null; DadesCertificat dades = new DadesCertificat(); List<Node> llistaIds = infoCertificado.selectNodes("Campo/idCampo"); List<Node> llistaValors = infoCertificado.selectNodes("Campo/valorCampo"); for (int i = 0; i < llistaIds.size(); i++) { if ("tipoCertificado".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setTipoCertificado(llistaValors.get(i).getText()); if ("subject".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setSubject(llistaValors.get(i).getText()); if ("nombreResponsable".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setNombreResponsable(llistaValors.get(i).getText()); if ("primerApellidoResponsable".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setPrimerApellidoResponsable(llistaValors.get(i).getText()); if ("segundoApellidoResponsable".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setSegundoApellidoResponsable(llistaValors.get(i).getText()); if ("NIFResponsable".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setNifResponsable(llistaValors.get(i).getText()); if ("idEmisor".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setIdEmisor(llistaValors.get(i).getText()); if ("NIF-CIF".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setNifCif(llistaValors.get(i).getText()); if ("email".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setEmail(llistaValors.get(i).getText()); if ("fechaNacimiento".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setFechaNacimiento(llistaValors.get(i).getText()); if ("razonSocial".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setRazonSocial(llistaValors.get(i).getText()); if ("clasificacion".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setRazonSocial(llistaValors.get(i).getText()); if ("numeroSerie".equalsIgnoreCase(llistaIds.get(i).getText())) dades.setNumeroSerie(llistaValors.get(i).getText()); } return dades; } private Document obtenirDocumentXmlResposta(String xmlResposta) throws DocumentException { // Llevam tots els atributs de mensajeSalida int tall1 = xmlResposta.indexOf("mensajeSalida") + "mensajeSalida".length(); int tall2 = xmlResposta.indexOf(">", tall1); String xmlCorrecte = xmlResposta.substring(0, tall1) + xmlResposta.substring(tall2); return DocumentHelper.parseText(xmlCorrecte); } private String cridarValidarCertificado( String certificatBase64, boolean obtenirDadesCertificat) throws Exception { String xmlPeticio = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<mensajeEntrada xmlns=\"http://afirmaws/ws/validacion\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:SchemaLocation=\"https://localhost/afirmaws/xsd/mvalidacion/ws.xsd\">" + "<peticion>ValidarCertificado</peticion>" + "<versionMsg>1.0</versionMsg>" + "<parametros>" + "<certificado><![CDATA[" + certificatBase64 + "]]></certificado>" + "<idAplicacion>" + aplicacioId + "</idAplicacion>" + ((modeValidacio != null) ? "<modoValidacion>" + modeValidacio + "</modoValidacion>" : "") + "<obtenerInfo>" + obtenirDadesCertificat + "</obtenerInfo>" + "</parametros>" + "</mensajeEntrada>"; logSiActivat(xmlPeticio); Service service = new Service(); Call call = (Call)service.createCall(); call.setTargetEndpointAddress(baseUrl + "/ValidarCertificado"); call.setOperationName(new QName("http://soapinterop.org/", "ValidarCertificado")); if ((usuari != null) && (!usuari.equals(""))) { try { call.setClientHandlers(new AfirmaSecurityHandler(usuari, password), null); } catch (Exception ex) { throw new ServiceException("(Call) Error en la cridada a aFirma", ex); } } call.setReturnType(org.apache.axis.Constants.XSD_STRING); call.addParameter("ValidarCertificadoRequest", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN); String xmlResposta = (String)call.invoke(new Object[]{xmlPeticio}); logSiActivat(xmlResposta); return xmlResposta; } private String cridarInfoCertificado( String certificatBase64) throws Exception { String xmlPeticio = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<mensajeEntrada xmlns=\"http://afirmaws/ws/validacion\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchemainstance\" xsi:SchemaLocation=\"https://localhost/afirmaws/xsd/mvalidacion/ws.xsd\">" + "<peticion>ObtenerInfoCertificado</peticion>" + "<versionMsg>1.0</versionMsg>" + "<parametros>" + "<certificado><![CDATA[" + certificatBase64 + "]]></certificado>" + "<idAplicacion>" + aplicacioId + "</idAplicacion>" + "</parametros>" + "</mensajeEntrada>"; logSiActivat(xmlPeticio); Service service = new Service(); Call call = (Call)service.createCall(); call.setTargetEndpointAddress(baseUrl + "/ObtenerInfoCertificado"); call.setOperationName(new QName("http://soapinterop.org/", "ObtenerInfoCertificado")); if ((usuari != null) && (!usuari.equals(""))) { try { call.setClientHandlers(new AfirmaSecurityHandler(usuari, password), null); } catch (Exception ex) { throw new ServiceException("(Call) Error en la cridada a aFirma", ex); } } call.setReturnType(org.apache.axis.Constants.XSD_STRING); call.addParameter("ObtenerInfoCertificadoRequest", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN); String xmlResposta = (String)call.invoke(new Object[]{xmlPeticio}); logSiActivat(xmlResposta); return xmlResposta; } private String cridarValidarFirma( String signaturaBase64, String documentBase64) throws Exception { String xmlPeticio = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<mensajeEntrada xmlns=\"http://afirmaws/ws/firma\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:SchemaLocation=\"https://localhost/afirmaws/xsd/mfirma/ws.xsd\">" + "<peticion>ValidarFirma</peticion>" + "<versionMsg>1.0</versionMsg>" + "<parametros>" + "<idAplicacion>" + aplicacioId + "</idAplicacion>" + "<firmaElectronica><![CDATA[" + signaturaBase64 + "]]></firmaElectronica>" + ((formatSignatura != null) ? "<formatoFirma>" + formatSignatura + "</formatoFirma>" : "") + "<datos><![CDATA[" + documentBase64 + "]]></datos>" + "</parametros>" + "</mensajeEntrada>"; logSiActivat(xmlPeticio); Service service = new Service(); Call call = (Call)service.createCall(); call.setTargetEndpointAddress(baseUrl + "/ValidarFirma"); call.setOperationName(new QName("http://soapinterop.org/", "ValidarFirma")); if ((usuari != null) && (!usuari.equals(""))) { try { call.setClientHandlers(new AfirmaSecurityHandler(usuari, password), null); } catch (Exception ex) { throw new ServiceException("(Call) Error en la cridada a aFirma", ex); } } call.setReturnType(org.apache.axis.Constants.XSD_STRING); call.addParameter("ValidarFirmaRequest", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN); String xmlResposta = (String)call.invoke(new Object[]{xmlPeticio}); logSiActivat(xmlResposta); return xmlResposta; } private void logSiActivat(String missatge) { if (logMissatges) { logger.info("-------------------------------------"); logger.info(missatge); logger.info("-------------------------------------"); } } private static final Log logger = LogFactory.getLog(AfirmaUtils.class); }