blob: a467dfc4dddc3b72460d243b770017f2b6d4e866 [file] [log] [blame]
package org.eclipse.jetty.exssl;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CRL;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertPathValidator;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.jetty.util.log.Log;
public class CertificateValidator
{
private KeyStore _keyStore;
private KeyStore _trustStore;
private Collection<? extends CRL> _crls;
private int _maxCertPathLength = -1;
public CertificateValidator(KeyStore keyStore, KeyStore trustStore, Collection<? extends CRL> crls)
{
_keyStore = keyStore;
_trustStore = trustStore;
_crls = crls;
}
public String validate(String keyAlias) throws CertificateException
{
String result = null;
if (keyAlias != null)
{
try
{
validate(_keyStore.getCertificate(keyAlias));
}
catch (KeyStoreException ex)
{
Log.debug(ex);
throw new CertificateException("Unable to validate certificate for alias [" +
keyAlias + "]: " + ex.getMessage());
}
result = keyAlias;
}
return result;
}
public void validate(Certificate cert) throws CertificateException
{
if (cert != null && cert instanceof X509Certificate)
{
((X509Certificate)cert).checkValidity();
String certAlias = "[none]";
try
{
certAlias = _keyStore.getCertificateAlias((X509Certificate)cert);
Certificate[] certChain = _keyStore.getCertificateChain(certAlias);
ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
for (Certificate item : certChain)
{
if (!(item instanceof X509Certificate))
{
throw new CertificateException("Invalid certificate type in chain");
}
certList.add((X509Certificate)item);
}
if (certList.isEmpty())
{
throw new CertificateException("Invalid certificate chain");
}
X509CertSelector certSelect = new X509CertSelector();
certSelect.setCertificate(certList.get(0));
// Configure certification path builder parameters
PKIXBuilderParameters pbParams = new PKIXBuilderParameters(_trustStore, certSelect);
pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)));
// Set static Certificate Revocation List
if (_crls != null && !_crls.isEmpty())
{
pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls)));
}
// Enable revocation checking
pbParams.setRevocationEnabled(true);
// Set maximum certification path length
pbParams.setMaxPathLength(_maxCertPathLength);
// Build certification path
CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams);
// Validate certification path
CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams);
}
catch (Exception ex)
{
Log.debug(ex);
throw new CertificateException("Unable to validate certificate for alias [" +
certAlias + "]: " + ex.getMessage());
}
}
}
public int getMaxCertPathLength()
{
return _maxCertPathLength;
}
public void setMaxCertPathLength(int maxCertPathLength)
{
_maxCertPathLength = maxCertPathLength;
}
public KeyStore getKeyStore()
{
return _keyStore;
}
public KeyStore getTrustStore()
{
return _trustStore;
}
public Collection<? extends CRL> getCrls()
{
return _crls;
}
}