org.viafirma.nucleo.validacion.CRLValidationHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.viafirma.nucleo.validacion.CRLValidationHandler.java

Source

/* 
 * File: CRLValidationHandler.java
 *
 * Created on Nov 7, 2007
 *
 *
 * Copyright 2006-2007 Felix Garcia Borrego (borrego at gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.viafirma.nucleo.validacion;

import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXParameters;
import java.security.cert.PolicyNode;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.viafirma.excepciones.CodigoError;
import org.viafirma.excepciones.ExcepcionErrorInterno;

/**
 * Manejador de las validaciones basadas en CRLs y certpath
 * 
 * @author Felix Garcia Borrego (borrego@gmail.com)
 */
public class CRLValidationHandler {

    /**
     * Crea un nuevo validador, recuperando los certificados de confianza.
     * 
     * @param certificadosConfianza
     */
    public CRLValidationHandler(boolean validacionOnline, Set<TrustAnchor> certificadosConfianza) {
        this.certificadosConfianza = certificadosConfianza;
        this.validacionOnline = validacionOnline;
    }

    /**
     * Metodo encargado de la verificacin de los certificados
     * 
     * @param certificadoX509
     * @throws ExcepcionErrorInterno
     */
    public CodigoError validarCRL(X509Certificate certificadoX509) {

        try {
            // 1.- Inicia la factoria de certificados
            CertificateFactory factoriaCertificados = CertificateFactory.getInstance("X.509",
                    BouncyCastleProvider.PROVIDER_NAME);
            log.debug("Validando certificado perteneciente a: " + certificadoX509.getIssuerDN());
            CertPathValidator validador = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME);

            // 2.- Configuracin de los parametros del validador
            // 2.1.- Para comprobar que el camino de confianza no esta roto,
            // tengo en cuenta todos los certificados
            PKIXParameters parametros = new PKIXParameters(certificadosConfianza);
            // Fecha para la comprobacin de validez.
            parametros.setDate(new Date());

            if (validacionOnline) {
                // Para la validacin online de del estado de revocacin de los
                // certificados

                // ************
                // creo un almacen( cache ) de certificados y CRLs para no tener
                // que conectarme a las crls
                // en cada validacin

                // Genero un listado de las CRLS que vamos a utilizar para la
                // validacin del certificado.
                List<CRL> listaCRLsCertificadosAlmacenados = new LinkedList<CRL>();

                // Aade las crls de los certificados de confianza reconocidos
                // por Viafirma.
                // estos certificados son los marcados con el prefijo viafirma_
                for (TrustAnchor trustAnchor : certificadosConfianza) {
                    // TODO establecer un sistema de cache eficiente
                    // TODO recuperar solo las crls del certificado en uso.
                    listaCRLsCertificadosAlmacenados
                            .addAll(CRLUtil.getCurrentInstance().getCRLs(trustAnchor.getTrustedCert()));
                    // para cada certificado.
                }

                // aado al listado todas las crls del certificado actual. EJ
                // para el caso de
                // un certificado de FNMT el certificado personal contiene CN =
                // CRL1827,OU = FNMT Clase 2 CA,O = FNMT,C = ES
                listaCRLsCertificadosAlmacenados.addAll(CRLUtil.getCurrentInstance().getCRLs(certificadoX509));

                // parametros para la creacin del almacen(cache CRLs)
                CollectionCertStoreParameters params = new CollectionCertStoreParameters(
                        listaCRLsCertificadosAlmacenados);
                CertStore almacen = CertStore.getInstance("Collection", params, BouncyCastleProvider.PROVIDER_NAME);

                parametros.addCertStore(almacen);
            } else {
                // No se utilizan las CRLs para la comprobacin de la
                // revocacin.
                parametros.setRevocationEnabled(false);
            }

            // certificados a validar ( solo 1)
            List<X509Certificate> certificadosValidar = new ArrayList<X509Certificate>(1);
            certificadosValidar.add(certificadoX509);

            // genero el listado de certificados a validar
            CertPath certPath = factoriaCertificados.generateCertPath(certificadosValidar);
            // validacin
            CertPathValidatorResult resultado = validador.validate(certPath, parametros);
            if (log.isDebugEnabled()) {
                if (resultado instanceof java.security.cert.PKIXCertPathValidatorResult) {
                    // pintamos el arbol de politicas
                    PolicyNode node = ((java.security.cert.PKIXCertPathValidatorResult) resultado).getPolicyTree();
                    StringBuffer ruta = new StringBuffer(
                            "Certificado vlido: " + certificadoX509.getSubjectDN().getName());
                    while (node != null) {
                        ruta.append("-->");
                        ruta.append(node.getValidPolicy());
                        if (node.getChildren().hasNext()) {
                            node = node.getChildren().next();
                        } else {
                            node = null;
                        }
                    }
                    log.info("ruta de validacin: " + ruta);
                }
            }
            return CodigoError.OK_CERTIFICADO_VALIDADO;
        } catch (CertificateException e) {
            log.fatal(CodigoError.ERROR_INTERNO, e);
            return CodigoError.ERROR_INTERNO;
        } catch (NoSuchProviderException e) {
            log.fatal(CodigoError.ERROR_INTERNO, e);
            return CodigoError.ERROR_INTERNO;

        } catch (NoSuchAlgorithmException e) {
            log.fatal(CodigoError.ERROR_INTERNO, e);
            return CodigoError.ERROR_INTERNO;
        } catch (InvalidAlgorithmParameterException e) {
            log.fatal(CodigoError.ERROR_VALIDACION_CONFIGURACION_PARAMETRO, e);
            return CodigoError.ERROR_VALIDACION_CONFIGURACION_PARAMETRO;
        } catch (CRLException e) {
            log.fatal(CodigoError.ERROR_VALIDACION_CRL, e);
            return CodigoError.ERROR_VALIDACION_CRL;
        } catch (CertPathValidatorException e) {
            // detectamos el tipo de problema
            if (e.getMessage().contains(java.security.cert.CertificateExpiredException.class.getName())
                    || e.getMessage().contains("Certificate revocation after")
                    || e.getMessage().contains("NotAfter") || e.getMessage().contains("certificate expired on")) {
                log.warn("El certificado esta caducado." + e.getMessage() + " " + certificadoX509.getSubjectDN());
                return CodigoError.ERROR_VALIDACION_CERTIFICADO_CADUCADO;
            } else if (e.getMessage().contains(java.security.SignatureException.class.getName())) {
                log.warn(
                        "Algunos de los certificados en el camino de certificacin no tiene crl. Algunos de los certificados no se puede validar."
                                + e.getMessage() + " " + certificadoX509.getSubjectDN());
                return CodigoError.ERROR_VALIDACION_CRL;
            } else if (e.getMessage().contains("no valid CRL found")) {
                log.warn("No se ha podido comprobar la validez del certificado. " + e.getMessage() + " "
                        + certificadoX509.getSubjectDN());
                return CodigoError.ERROR_VALIDACION_CRL;
            } else if (e.getMessage().contains("CertPath not found")) {
                log.warn("Autoridad de certificacin no reconicida." + e.getMessage() + " "
                        + certificadoX509.getIssuerDN());
                return CodigoError.ERROR_VALIDACION_AUTORIDAD_NO_RECONOCIDA;
            } else {
                log.warn("Autoridad de certificacin no reconicida." + e.getMessage() + " "
                        + certificadoX509.getIssuerDN());
                return CodigoError.ERROR_VALIDACION_AUTORIDAD_NO_RECONOCIDA;
            }

            // TODO java.security.cert.CertPathValidatorException: couldn't
            // validate certificate:
            // java.security.cert.CertificateNotYetValidException: NotBefore:
            // Thu Apr 19 19:22:17 CEST 2007
            // at
            // org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:819)

        }
    }

    private Log log = LogFactory.getLog(CRLValidationHandler.class);

    /**
     * Conjunto de certificados de confianza reconocidos por el sistema. Se
     * inicializan al arrancar la aplicacin.
     */
    private Set<TrustAnchor> certificadosConfianza;

    /**
     * Indica si se conectara remotamente para realizar la validacin.
     */
    private boolean validacionOnline;
}