blob: cadcd92e86fb6ac54ec69321ba3158b56e382c6a [file] [log] [blame]
package org.bouncycastle.est.jcajce;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CRL;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.cert.X509CertificateHolder;
/**
* General utility methods for building common objects for supporting the JCA/JCE/JSSE.
*/
public class JcaJceUtils
{
public static X509TrustManager getTrustAllTrustManager()
{
//
// Trust manager signal distrust by throwing exceptions.
// This one trust all by doing nothing.
//
return new X509TrustManager()
{
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException
{
}
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException
{
}
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return new java.security.cert.X509Certificate[0];
}
};
}
public static X509TrustManager[] getCertPathTrustManager(final Set<TrustAnchor> anchors, final CRL[] revocationLists)
{
final X509Certificate[] x509CertificateTrustAnchors = new X509Certificate[anchors.size()];
int c = 0;
for (Iterator it = anchors.iterator(); it.hasNext();)
{
TrustAnchor ta = (TrustAnchor)it.next();
x509CertificateTrustAnchors[c++] = ta.getTrustedCert();
}
return new X509TrustManager[]{new X509TrustManager()
{
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException
{
try
{
CertStore certStore = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(Arrays.asList(x509Certificates)), "BC");
CertPathBuilder pathBuilder = CertPathBuilder.getInstance("PKIX", "BC");
X509CertSelector constraints = new X509CertSelector();
constraints.setCertificate(x509Certificates[0]);
PKIXBuilderParameters param = new PKIXBuilderParameters(anchors, constraints);
param.addCertStore(certStore);
if (revocationLists != null)
{
param.setRevocationEnabled(true);
param.addCertStore(
CertStore.getInstance(
"Collection",
new CollectionCertStoreParameters(Arrays.asList(revocationLists)
)));
}
else
{
param.setRevocationEnabled(false);
}
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)pathBuilder.build(param);
validateServerCertUsage(x509Certificates[0]);
}
catch (CertificateException e)
{
throw e;
}
catch (GeneralSecurityException e)
{
throw new CertificateException("unable to process certificates: " + e.getMessage(), e);
}
}
public X509Certificate[] getAcceptedIssuers()
{
X509Certificate[] rv = new X509Certificate[x509CertificateTrustAnchors.length];
System.arraycopy(x509CertificateTrustAnchors, 0, rv, 0, rv.length);
return rv;
}
}
};
}
public static void validateServerCertUsage(X509Certificate x509Certificate)
throws CertificateException
{
try
{
X509CertificateHolder cert = new X509CertificateHolder(x509Certificate.getEncoded());
KeyUsage keyUsage = KeyUsage.fromExtensions(cert.getExtensions());
if (keyUsage != null)
{
if (keyUsage.hasUsages(KeyUsage.keyCertSign))
{
throw new CertificateException("Key usage must not contain keyCertSign");
}
if (!(keyUsage.hasUsages(KeyUsage.digitalSignature) || keyUsage.hasUsages(KeyUsage.keyEncipherment)))
{
throw new CertificateException("Key usage must be none, digitalSignature or keyEncipherment");
}
}
//
// Check extended key usage.
//
ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.fromExtensions(cert.getExtensions());
if (extendedKeyUsage != null)
{
if (!(extendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_serverAuth) ||
extendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_msSGC) ||
extendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_nsSGC)))
{
throw new CertificateException("Certificate extended key usage must include serverAuth, msSGC or nsSGC");
}
}
}
catch (CertificateException c)
{
throw c;
}
catch (Exception e)
{
throw new CertificateException(e.getMessage(), e);
}
}
public static KeyManagerFactory createKeyManagerFactory(
String type,
String provider,
KeyStore clientKeyStore,
char[] clientKeyStorePass)
throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, NoSuchProviderException
{
KeyManagerFactory keyManagerFactory = null;
if (type == null && provider == null)
{
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
}
else if (provider == null)
{
keyManagerFactory = KeyManagerFactory.getInstance(type);
}
else
{
keyManagerFactory = KeyManagerFactory.getInstance(type, provider);
}
keyManagerFactory.init(clientKeyStore, clientKeyStorePass);
return keyManagerFactory;
}
}