Package org.jvnet.glassfish.comms.security.auth.impl

Source Code of org.jvnet.glassfish.comms.security.auth.impl.CertValidator

/**
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License).  You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://glassfish.dev.java.net/public/CDDLv1.0.html or
* glassfish/bootstrap/legal/CDDLv1.0.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at glassfish/bootstrap/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright (c) Ericsson AB, 2004-2007. All rights reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*/
package org.jvnet.glassfish.comms.security.auth.impl;

import com.sun.enterprise.security.SSLUtils;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import static org.jvnet.glassfish.comms.security.util.Constants.securityLogger;

/**
*
* @author K.Venugopal@sun.com
*/
public class CertValidator implements CertificateValidator {

    private static KeyStore trustStore;
    private static CertificateValidator validator = null;
    private static boolean revocationCheck = false;

    private CertValidator() {
    }

    public static synchronized void init(Properties props) throws Exception {
        if (validator == null) {
            if (props != null && !props.isEmpty()) {
                String value = props.getProperty("enableRevocationCheck");
                if (value != null && value.length() > 0) {
                    revocationCheck = Boolean.parseBoolean(value);
                }
                String certVC = (String) props.getProperty("certificateValidator");
                if (certVC != null && certVC.length() >0) {
                    Class cvClass;
                    try {
                        cvClass = Class.forName(certVC);
                        validator = (CertificateValidator) cvClass.newInstance();

                    } catch (SecurityException ex) {
                        securityLogger.log(Level.SEVERE, null, ex);
                    } catch (InstantiationException ex) {
                        securityLogger.log(Level.SEVERE, null, ex);
                    } catch (IllegalAccessException ex) {
                        securityLogger.log(Level.SEVERE, null, ex);
                    } catch (ClassNotFoundException ex) {
                        securityLogger.log(Level.SEVERE, null, ex);
                    }
                }
            }

            trustStore = SSLUtils.getTrustStore();
            if (validator == null) {
                validator = new CertValidator();
            }
        }

    }

    public static synchronized CertificateValidator getInstance() throws Exception {
        if (validator == null) {
            trustStore = SSLUtils.getTrustStore();
            validator = new CertValidator();
        }
        return validator;
    }

    public boolean validate(X509Certificate certificate) throws CertificateException {
        try {
            certificate.checkValidity();
            // for self-signed certificate
            if (certificate.getIssuerX500Principal().equals(certificate.getSubjectX500Principal())) {
                try {
                    if (isTrustedSelfSigned(certificate)) {
                        throw new CertificateNotYetValidException("Self signed certificates are not permitted");
                    }
                } catch (KeyStoreException ex) {
                    securityLogger.log(Level.SEVERE, null, ex);
                    throw new CertificateException(ex);
                }
            }
            X509CertSelector certSelector = new X509CertSelector();
            certSelector.setCertificate(certificate);
            PKIXBuilderParameters parameters;
            CertPathBuilder builder = null;
            CertPathValidator certValidator = null;
            CertPath certPath = null;
            List<Certificate> certChainList = new ArrayList<Certificate>();
            boolean caFound = false;
            Principal certChainIssuer = null;
            int noOfEntriesInTrustStore = 0;
            boolean isIssuerCertMatched = false;
            parameters = new PKIXBuilderParameters(trustStore, certSelector);
            parameters.setRevocationEnabled(revocationCheck);
            Certificate[] certChain = null;
            String certAlias = trustStore.getCertificateAlias(certificate);
            if (certAlias != null) {
                certChain = trustStore.getCertificateChain(certAlias);
            }
            if (certChain == null) {
                certChainList.add(certificate);
                certChainIssuer = certificate.getIssuerX500Principal();
                noOfEntriesInTrustStore = trustStore.size();
            } else {
                certChainList = Arrays.asList(certChain);
            }
            while (!caFound && noOfEntriesInTrustStore-- != 0 && certChain == null) {
                Enumeration aliases = trustStore.aliases();
                while (aliases.hasMoreElements()) {
                    String alias = (String) aliases.nextElement();
                    Certificate cert = trustStore.getCertificate(alias);
                    if (cert == null || !"X.509".equals(cert.getType()) || certChainList.contains(cert)) {
                        continue;
                    }
                    X509Certificate x509Cert = (X509Certificate) cert;
                    if (certChainIssuer.equals(x509Cert.getSubjectX500Principal())) {
                        certChainList.add(cert);
                        if (x509Cert.getSubjectX500Principal().equals(x509Cert.getIssuerX500Principal())) {
                            caFound = true;
                            break;
                        } else {
                            certChainIssuer = x509Cert.getIssuerDN();
                            if (!isIssuerCertMatched) {
                                isIssuerCertMatched = true;
                            }
                        }
                    } else {
                        continue;
                    }
                }
                if (!caFound) {
                    if (!isIssuerCertMatched) {
                        break;
                    } else {
                        isIssuerCertMatched = false;
                    }
                }
            }
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            certPath = cf.generateCertPath(certChainList);
            certValidator = CertPathValidator.getInstance("PKIX");
            certValidator.validate(certPath, parameters);

        } catch (CertPathValidatorException ex) {
            securityLogger.log(Level.SEVERE, null, ex);
            throw new CertificateException(ex);
        } catch (NoSuchAlgorithmException ex) {
            securityLogger.log(Level.SEVERE, null, ex);
            throw new CertificateException(ex);
        } catch (KeyStoreException ex) {
            securityLogger.log(Level.SEVERE, null, ex);
            throw new CertificateException(ex);
        } catch (InvalidAlgorithmParameterException ex) {
            securityLogger.log(Level.SEVERE, null, ex);
            throw new CertificateException(ex);
        }
        return true;
    }

    private boolean isTrustedSelfSigned(X509Certificate cert) throws KeyStoreException {
        if (trustStore == null) {
            return false;
        }
        Enumeration aliases = trustStore.aliases();
        while (aliases.hasMoreElements()) {
            String alias = (String) aliases.nextElement();
            Certificate certificate = trustStore.getCertificate(alias);
            if (certificate == null || !"X.509".equals(certificate.getType())) {
                continue;
            }
            X509Certificate x509Cert = (X509Certificate) certificate;
            if (x509Cert != null && x509Cert.equals(cert)) {
                return true;
            }
        }
        return false;
    }
}
TOP

Related Classes of org.jvnet.glassfish.comms.security.auth.impl.CertValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.