| 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; |
| } |
| } |