org.bouncycastle.pkix.jcajce.CrlCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpkix-jdk15to18 Show documentation
Show all versions of bcpkix-jdk15to18 Show documentation
The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.5 to JDK 1.8. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
package org.bouncycastle.pkix.jcajce;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URI;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.bouncycastle.jcajce.PKIXCRLStore;
import org.bouncycastle.util.CollectionStore;
import org.bouncycastle.util.Iterable;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
class CrlCache
{
private static final int DEFAULT_TIMEOUT = 15000;
private static Map> cache =
Collections.synchronizedMap(new WeakHashMap>());
static synchronized PKIXCRLStore getCrl(CertificateFactory certFact, Date validDate, URI distributionPoint)
throws IOException, CRLException
{
PKIXCRLStore crlStore = null;
WeakReference markerRef = (WeakReference)cache.get(distributionPoint);
if (markerRef != null)
{
crlStore = (PKIXCRLStore)markerRef.get();
}
if (crlStore != null)
{
boolean isExpired = false;
for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();)
{
X509CRL crl = (X509CRL)it.next();
Date nextUpdate = crl.getNextUpdate();
if (nextUpdate != null && nextUpdate.before(validDate))
{
isExpired = true;
break;
}
}
if (!isExpired)
{
return crlStore;
}
}
Collection crls;
if (distributionPoint.getScheme().equals("ldap"))
{
crls = getCrlsFromLDAP(certFact, distributionPoint);
}
else
{
// http, https, ftp
crls = getCrls(certFact, distributionPoint);
}
LocalCRLStore localCRLStore = new LocalCRLStore(new CollectionStore(crls));
cache.put(distributionPoint, new WeakReference(localCRLStore));
return localCRLStore;
}
private static Collection getCrlsFromLDAP(CertificateFactory certFact, URI distributionPoint)
throws IOException, CRLException
{
Map env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, distributionPoint.toString());
byte[] val = null;
try
{
DirContext ctx = new InitialDirContext((Hashtable)env);
Attributes avals = ctx.getAttributes("");
Attribute aval = avals.get("certificateRevocationList;binary");
val = (byte[])aval.get();
}
catch (NamingException e)
{
throw new CRLException("issue connecting to: " + distributionPoint.toString(), e);
}
if ((val == null) || (val.length == 0))
{
throw new CRLException("no CRL returned from: " + distributionPoint);
}
else
{
return certFact.generateCRLs(new ByteArrayInputStream(val));
}
}
private static Collection getCrls(CertificateFactory certFact, URI distributionPoint)
throws IOException, CRLException
{
HttpURLConnection crlCon = (HttpURLConnection)distributionPoint.toURL().openConnection();
crlCon.setConnectTimeout(DEFAULT_TIMEOUT);
crlCon.setReadTimeout(DEFAULT_TIMEOUT);
InputStream crlIn = crlCon.getInputStream();
Collection crls = certFact.generateCRLs(crlIn);
crlIn.close();
return crls;
}
private static class LocalCRLStore
implements PKIXCRLStore, Iterable
{
private Collection _local;
/**
* Basic constructor.
*
* @param collection - initial contents for the store, this is copied.
*/
public LocalCRLStore(
Store collection)
{
_local = new ArrayList(collection.getMatches(null));
}
/**
* Return the matches in the collection for the passed in selector.
*
* @param selector the selector to match against.
* @return a possibly empty collection of matching objects.
*/
public Collection getMatches(Selector selector)
{
if (selector == null)
{
return new ArrayList(_local);
}
else
{
List col = new ArrayList();
Iterator iter = _local.iterator();
while (iter.hasNext())
{
CRL obj = iter.next();
if (selector.match(obj))
{
col.add(obj);
}
}
return col;
}
}
public Iterator iterator()
{
return getMatches(null).iterator();
}
}
}