All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.gob.afirma.standalone.protocol.ProtocolInvocationLauncherBatch Maven / Gradle / Ivy

There is a newer version: 1.8.2
Show newest version
/* Copyright (C) 2011 [Gobierno de Espana]
 * This file is part of "Cliente @Firma".
 * "Cliente @Firma" is free software; you can redistribute it and/or modify it under the terms of:
 *   - the GNU General Public License as published by the Free Software Foundation;
 *     either version 2 of the License, or (at your option) any later version.
 *   - or The European Software License; either version 1.1 or (at your option) any later version.
 * You may contact the copyright holder at: [email protected]
 */

package es.gob.afirma.standalone.protocol;

import java.security.KeyStore.PrivateKeyEntry;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.callback.PasswordCallback;

import es.gob.afirma.core.AOCancelledOperationException;
import es.gob.afirma.core.misc.Base64;
import es.gob.afirma.core.misc.Platform;
import es.gob.afirma.core.misc.http.HttpError;
import es.gob.afirma.core.misc.protocol.UrlParametersForBatch;
import es.gob.afirma.keystores.AOCertificatesNotFoundException;
import es.gob.afirma.keystores.AOKeyStore;
import es.gob.afirma.keystores.AOKeyStoreDialog;
import es.gob.afirma.keystores.AOKeyStoreManager;
import es.gob.afirma.keystores.AOKeyStoreManagerFactory;
import es.gob.afirma.keystores.filters.CertFilterManager;
import es.gob.afirma.keystores.filters.CertificateFilter;
import es.gob.afirma.signers.batch.client.BatchSigner;
import es.gob.afirma.standalone.crypto.CypherDataManager;

final class ProtocolInvocationLauncherBatch {

	private static final Logger LOGGER = Logger.getLogger("es.gob.afirma"); //$NON-NLS-1$

	private static final String RESULT_CANCEL = "CANCEL"; //$NON-NLS-1$

	private ProtocolInvocationLauncherBatch() {
		// No instanciable
	}

	/** Procesa un lote de firma en invocación por protocolo.
	 * @param options Parámetros de la operación.
	 * @param bySocket true para usar comunicación por socket local,
	 *                 false para usar servidor intermedio.
	 * @return XML de respuesta del procesado.
	 * @throws SocketOperationException Si hay errores en la
	 *                                  comunicación por socket local. */
	static String processBatch(final UrlParametersForBatch options,
			                   final boolean bySocket) throws SocketOperationException {


		if (!ProtocolInvocationLauncher.MAX_PROTOCOL_VERSION_SUPPORTED.support(options.getMinimumVersion())) {
			LOGGER.severe(String.format("Version de protocolo no soportada (%1s). Version actual: %s2. Hay que actualizar la aplicacion.", options.getMinimumVersion(), ProtocolInvocationLauncher.MAX_PROTOCOL_VERSION_SUPPORTED)); //$NON-NLS-1$
			ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_21);
			return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_21);
		}

		final AOKeyStore aoks = AOKeyStore.getKeyStore(options.getDefaultKeyStore());
		if (aoks == null) {
			LOGGER.severe("No hay un KeyStore asociado al valor: " + options.getDefaultKeyStore()); //$NON-NLS-1$
			ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_07);
			return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_07);
		}

		final CertFilterManager filterManager = new CertFilterManager(options.getExtraParams());
		final List filters = filterManager.getFilters();
		final boolean mandatoryCertificate = filterManager.isMandatoryCertificate();
		final PrivateKeyEntry pke;

		if (options.getSticky() && ProtocolInvocationLauncher.getStickyKeyEntry() != null) {

			LOGGER.info("Se usa Sticky Signature y tenemos valor de clave privada"); //$NON-NLS-1$
			pke = ProtocolInvocationLauncher.getStickyKeyEntry();

		} else {

			final String aoksLib = options.getDefaultKeyStoreLib();

			final PasswordCallback pwc = aoks.getStorePasswordCallback(null);
			final AOKeyStoreManager ksm;
			try {
				ksm = AOKeyStoreManagerFactory.getAOKeyStoreManager(
					aoks, // Store
					aoksLib, // Lib
					null, // Description
					pwc,  // PasswordCallback
					null  // Parent
				);
			}
			catch (final Exception e3) {
				LOGGER.severe("Error obteniendo el AOKeyStoreManager: " + e3); //$NON-NLS-1$
				ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_08);
				if (!bySocket){
					throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_08);
				}
				return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_08);
			}

			try {
				if (Platform.OS.MACOSX.equals(Platform.getOS())) {
					ServiceInvocationManager.focusApplication();
				}
				final AOKeyStoreDialog dialog = new AOKeyStoreDialog(
					ksm,
					null,
					true,
					true, // showExpiredCertificates
					true, // checkValidity
					filters,
					mandatoryCertificate
				);
				dialog.allowOpenExternalStores(filterManager.isExternalStoresOpeningAllowed());
				dialog.show();
				pke = ksm.getKeyEntry(dialog.getSelectedAlias());

				if (options.getSticky()) {
					ProtocolInvocationLauncher.setStickyKeyEntry(pke);
				} else {
					ProtocolInvocationLauncher.setStickyKeyEntry(null);
				}
			}
			catch (final AOCancelledOperationException e) {
				LOGGER.severe("Operacion cancelada por el usuario: " + e); //$NON-NLS-1$
				if (!bySocket){
					throw new SocketOperationException(RESULT_CANCEL);
				}
				return RESULT_CANCEL;
			}
			catch(final AOCertificatesNotFoundException e) {
				LOGGER.severe("No hay certificados validos en el almacen: " + e); //$NON-NLS-1$
				ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_19);
				if (!bySocket){
					throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_19);
				}
				return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_19);
			}
			catch (final Exception e) {
				LOGGER.severe("Error al mostrar el dialogo de seleccion de certificados: " + e); //$NON-NLS-1$
				ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_08);
				if (!bySocket){
					throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_08);
				}
				return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_08);
			}
		}

		String batchResult;
		try {
			batchResult = BatchSigner.sign(
				Base64.encode(options.getData(), true),
				options.getBatchPresignerUrl(),
				options.getBatchPostSignerUrl(),
				pke.getCertificateChain(),
				pke.getPrivateKey()
			);
			// Devuelve los datos sin codificar en el caso de peticion por socket, por lo que hay que codificarlo
			if (bySocket){
				batchResult = Base64.encode(batchResult.getBytes());
			}
		}
		catch(final HttpError e) {
			if (e.getResponseCode() / 100 == 4) {
				LOGGER.severe("Error en la comunicacion con el servicio de firma de lotes. StatusCode: " + //$NON-NLS-1$
					e.getResponseCode() + ". Descripcion: " + e.getResponseDescription());  //$NON-NLS-1$
			}
			else {
				LOGGER.severe("Error en el servicio de firma de lotes. StatusCode: " + //$NON-NLS-1$
						e.getResponseCode() + ". Descripcion: " + e.getResponseDescription());  //$NON-NLS-1$
			}
			ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_26);
			if (!bySocket){
				throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_26 + ": " + e.getResponseDescription()); //$NON-NLS-1$
			}
			return ProtocolInvocationLauncherErrorManager.SAF_26 + ": " + e.getResponseDescription(); //$NON-NLS-1$
		}
		catch(final Exception e) {
			LOGGER.log(
				Level.SEVERE,
				"Error en el proceso del lote de firmas: " + e, //$NON-NLS-1$
				e
			);
			ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_20);
			if (!bySocket){
				throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_20);
			}
			return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_20);
		}

		// Tenemos el XML de resultado del lote, lo subimos al servidor intermedio


		// Si hay clave de cifrado, ciframos
		if (options.getDesKey() != null) {
			try {
				batchResult = CypherDataManager.cipherData(batchResult.getBytes(), options.getDesKey());
			}
			catch (final Exception e) {
				LOGGER.severe("Error en el cifrado de los datos a enviar: " + e); //$NON-NLS-1$
				ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_12);
				if (!bySocket){
					throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_12);
				}
				return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_12);
			}
		}
		else {
			LOGGER.warning(
				"Se omite el cifrado de los datos resultantes por no haberse proporcionado una clave de cifrado" //$NON-NLS-1$
			);
		}

		if (options.getStorageServletUrl() != null) {
			// Enviamos la firma cifrada al servicio remoto de intercambio
			try {
				IntermediateServerUtil.sendData(batchResult, options.getStorageServletUrl().toString(), options.getId());
			}
			catch (final Exception e) {
				LOGGER.log(Level.SEVERE, "Error al enviar los datos al servidor", e); //$NON-NLS-1$
				ProtocolInvocationLauncherErrorManager.showError(ProtocolInvocationLauncherErrorManager.SAF_11);
				if (!bySocket){
					throw new SocketOperationException(ProtocolInvocationLauncherErrorManager.SAF_11);
				}
				return ProtocolInvocationLauncherErrorManager.getErrorMessage(ProtocolInvocationLauncherErrorManager.SAF_11);
			}
		}
		else {
			LOGGER.info(
				"Se omite el envio por red de los datos resultantes por no haberse proporcionado una URL de destino" //$NON-NLS-1$
			);
		}

		return batchResult;
	}

	public static String getResultCancel() {
		return RESULT_CANCEL;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy