|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.provider.certpath.ldap; |
|
|
|
import java.io.ByteArrayInputStream; |
|
import java.io.IOException; |
|
import java.math.BigInteger; |
|
import java.net.URI; |
|
import java.util.*; |
|
import javax.naming.Context; |
|
import javax.naming.CompositeName; |
|
import javax.naming.InvalidNameException; |
|
import javax.naming.NamingEnumeration; |
|
import javax.naming.NamingException; |
|
import javax.naming.NameNotFoundException; |
|
import javax.naming.directory.Attribute; |
|
import javax.naming.directory.Attributes; |
|
import javax.naming.directory.BasicAttributes; |
|
import javax.naming.directory.DirContext; |
|
import javax.naming.directory.InitialDirContext; |
|
|
|
import java.security.*; |
|
import java.security.cert.Certificate; |
|
import java.security.cert.*; |
|
import javax.naming.ldap.LdapContext; |
|
import javax.security.auth.x500.X500Principal; |
|
|
|
import com.sun.jndi.ldap.LdapReferralException; |
|
import sun.misc.HexDumpEncoder; |
|
import sun.security.provider.certpath.X509CertificatePair; |
|
import sun.security.util.Cache; |
|
import sun.security.util.Debug; |
|
import sun.security.x509.X500Name; |
|
import sun.security.action.GetBooleanAction; |
|
import sun.security.action.GetPropertyAction; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final class LDAPCertStore extends CertStoreSpi { |
|
|
|
private static final Debug debug = Debug.getInstance("certpath"); |
|
|
|
private final static boolean DEBUG = false; |
|
|
|
|
|
|
|
*/ |
|
private static final String USER_CERT = "userCertificate;binary"; |
|
private static final String CA_CERT = "cACertificate;binary"; |
|
private static final String CROSS_CERT = "crossCertificatePair;binary"; |
|
private static final String CRL = "certificateRevocationList;binary"; |
|
private static final String ARL = "authorityRevocationList;binary"; |
|
private static final String DELTA_CRL = "deltaRevocationList;binary"; |
|
|
|
|
|
private final static String[] STRING0 = new String[0]; |
|
|
|
private final static byte[][] BB0 = new byte[0][]; |
|
|
|
private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes(); |
|
|
|
|
|
private final static int DEFAULT_CACHE_SIZE = 750; |
|
private final static int DEFAULT_CACHE_LIFETIME = 30; |
|
|
|
private final static int LIFETIME; |
|
|
|
private final static String PROP_LIFETIME = |
|
"sun.security.certpath.ldap.cache.lifetime"; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private final static String PROP_DISABLE_APP_RESOURCE_FILES = |
|
"sun.security.certpath.ldap.disable.app.resource.files"; |
|
|
|
static { |
|
String s = AccessController.doPrivileged( |
|
new GetPropertyAction(PROP_LIFETIME)); |
|
if (s != null) { |
|
LIFETIME = Integer.parseInt(s); |
|
} else { |
|
LIFETIME = DEFAULT_CACHE_LIFETIME; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private CertificateFactory cf; |
|
|
|
|
|
*/ |
|
private DirContext ctx; |
|
|
|
|
|
|
|
*/ |
|
private boolean prefetchCRLs = false; |
|
|
|
private final Cache<String, byte[][]> valueCache; |
|
|
|
private int cacheHits = 0; |
|
private int cacheMisses = 0; |
|
private int requests = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public LDAPCertStore(CertStoreParameters params) |
|
throws InvalidAlgorithmParameterException { |
|
super(params); |
|
if (!(params instanceof LDAPCertStoreParameters)) |
|
throw new InvalidAlgorithmParameterException( |
|
"parameters must be LDAPCertStoreParameters"); |
|
|
|
LDAPCertStoreParameters lparams = (LDAPCertStoreParameters) params; |
|
|
|
|
|
createInitialDirContext(lparams.getServerName(), lparams.getPort()); |
|
|
|
|
|
try { |
|
cf = CertificateFactory.getInstance("X.509"); |
|
} catch (CertificateException e) { |
|
throw new InvalidAlgorithmParameterException( |
|
"unable to create CertificateFactory for X.509"); |
|
} |
|
if (LIFETIME == 0) { |
|
valueCache = Cache.newNullCache(); |
|
} else if (LIFETIME < 0) { |
|
valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE); |
|
} else { |
|
valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE, LIFETIME); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final Cache<LDAPCertStoreParameters, CertStore> |
|
certStoreCache = Cache.newSoftMemoryCache(185); |
|
static synchronized CertStore getInstance(LDAPCertStoreParameters params) |
|
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { |
|
|
|
SecurityManager security = System.getSecurityManager(); |
|
if (security != null) { |
|
security.checkConnect(params.getServerName(), params.getPort()); |
|
} |
|
|
|
CertStore lcs = certStoreCache.get(params); |
|
if (lcs == null) { |
|
lcs = CertStore.getInstance("LDAP", params); |
|
certStoreCache.put(params, lcs); |
|
} else { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.getInstance: cache hit"); |
|
} |
|
} |
|
return lcs; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private void createInitialDirContext(String server, int port) |
|
throws InvalidAlgorithmParameterException { |
|
String url = "ldap://" + server + ":" + port; |
|
Hashtable<String,Object> env = new Hashtable<>(); |
|
env.put(Context.INITIAL_CONTEXT_FACTORY, |
|
"com.sun.jndi.ldap.LdapCtxFactory"); |
|
env.put(Context.PROVIDER_URL, url); |
|
|
|
|
|
boolean disableAppResourceFiles = AccessController.doPrivileged( |
|
new GetBooleanAction(PROP_DISABLE_APP_RESOURCE_FILES)); |
|
if (disableAppResourceFiles) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore disabling app resource files"); |
|
} |
|
env.put("com.sun.naming.disable.app.resource.files", "true"); |
|
} |
|
|
|
try { |
|
ctx = new InitialDirContext(env); |
|
|
|
|
|
|
|
*/ |
|
Hashtable<?,?> currentEnv = ctx.getEnvironment(); |
|
if (currentEnv.get(Context.REFERRAL) == null) { |
|
ctx.addToEnvironment(Context.REFERRAL, "throw"); |
|
} |
|
} catch (NamingException e) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineInit about to throw " |
|
+ "InvalidAlgorithmParameterException"); |
|
e.printStackTrace(); |
|
} |
|
Exception ee = new InvalidAlgorithmParameterException |
|
("unable to create InitialDirContext using supplied parameters"); |
|
ee.initCause(e); |
|
throw (InvalidAlgorithmParameterException)ee; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private class LDAPRequest { |
|
|
|
private final String name; |
|
private Map<String, byte[][]> valueMap; |
|
private final List<String> requestedAttributes; |
|
|
|
LDAPRequest(String name) throws CertStoreException { |
|
this.name = checkName(name); |
|
requestedAttributes = new ArrayList<>(5); |
|
} |
|
|
|
private String checkName(String name) throws CertStoreException { |
|
if (name == null) { |
|
throw new CertStoreException("Name absent"); |
|
} |
|
try { |
|
if (new CompositeName(name).size() > 1) { |
|
throw new CertStoreException("Invalid name: " + name); |
|
} |
|
} catch (InvalidNameException ine) { |
|
throw new CertStoreException("Invalid name: " + name, ine); |
|
} |
|
return name; |
|
} |
|
|
|
String getName() { |
|
return name; |
|
} |
|
|
|
void addRequestedAttribute(String attrId) { |
|
if (valueMap != null) { |
|
throw new IllegalStateException("Request already sent"); |
|
} |
|
requestedAttributes.add(attrId); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
byte[][] getValues(String attrId) throws NamingException { |
|
if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) { |
|
System.out.println("Cache hits: " + cacheHits + "; misses: " |
|
+ cacheMisses); |
|
} |
|
String cacheKey = name + "|" + attrId; |
|
byte[][] values = valueCache.get(cacheKey); |
|
if (values != null) { |
|
cacheHits++; |
|
return values; |
|
} |
|
cacheMisses++; |
|
Map<String, byte[][]> attrs = getValueMap(); |
|
values = attrs.get(attrId); |
|
return values; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Map<String, byte[][]> getValueMap() throws NamingException { |
|
if (valueMap != null) { |
|
return valueMap; |
|
} |
|
if (DEBUG) { |
|
System.out.println("Request: " + name + ":" + requestedAttributes); |
|
requests++; |
|
if (requests % 5 == 0) { |
|
System.out.println("LDAP requests: " + requests); |
|
} |
|
} |
|
valueMap = new HashMap<>(8); |
|
String[] attrIds = requestedAttributes.toArray(STRING0); |
|
Attributes attrs; |
|
try { |
|
attrs = ctx.getAttributes(name, attrIds); |
|
} catch (LdapReferralException lre) { |
|
|
|
while (true) { |
|
try { |
|
String newName = (String) lre.getReferralInfo(); |
|
URI newUri = new URI(newName); |
|
if (!newUri.getScheme().equalsIgnoreCase("ldap")) { |
|
throw new IllegalArgumentException("Not LDAP"); |
|
} |
|
String newDn = newUri.getPath(); |
|
if (newDn != null && newDn.charAt(0) == '/') { |
|
newDn = newDn.substring(1); |
|
} |
|
checkName(newDn); |
|
} catch (Exception e) { |
|
throw new NamingException("Cannot follow referral to " |
|
+ lre.getReferralInfo()); |
|
} |
|
LdapContext refCtx = |
|
(LdapContext)lre.getReferralContext(); |
|
|
|
|
|
try { |
|
attrs = refCtx.getAttributes(name, attrIds); |
|
break; |
|
} catch (LdapReferralException re) { |
|
lre = re; |
|
continue; |
|
} finally { |
|
|
|
refCtx.close(); |
|
} |
|
} |
|
} catch (NameNotFoundException e) { |
|
// name does not exist on this LDAP server |
|
|
|
attrs = EMPTY_ATTRIBUTES; |
|
} |
|
for (String attrId : requestedAttributes) { |
|
Attribute attr = attrs.get(attrId); |
|
byte[][] values = getAttributeValues(attr); |
|
cacheAttribute(attrId, values); |
|
valueMap.put(attrId, values); |
|
} |
|
return valueMap; |
|
} |
|
|
|
|
|
|
|
*/ |
|
private void cacheAttribute(String attrId, byte[][] values) { |
|
String cacheKey = name + "|" + attrId; |
|
valueCache.put(cacheKey, values); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private byte[][] getAttributeValues(Attribute attr) |
|
throws NamingException { |
|
byte[][] values; |
|
if (attr == null) { |
|
values = BB0; |
|
} else { |
|
values = new byte[attr.size()][]; |
|
int i = 0; |
|
NamingEnumeration<?> enum_ = attr.getAll(); |
|
while (enum_.hasMore()) { |
|
Object obj = enum_.next(); |
|
if (debug != null) { |
|
if (obj instanceof String) { |
|
debug.println("LDAPCertStore.getAttrValues() " |
|
+ "enum.next is a string!: " + obj); |
|
} |
|
} |
|
byte[] value = (byte[])obj; |
|
values[i++] = value; |
|
} |
|
} |
|
return values; |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Collection<X509Certificate> getCertificates(LDAPRequest request, |
|
String id, X509CertSelector sel) throws CertStoreException { |
|
|
|
|
|
byte[][] encodedCert; |
|
try { |
|
encodedCert = request.getValues(id); |
|
} catch (NamingException namingEx) { |
|
throw new CertStoreException(namingEx); |
|
} |
|
|
|
int n = encodedCert.length; |
|
if (n == 0) { |
|
return Collections.emptySet(); |
|
} |
|
|
|
List<X509Certificate> certs = new ArrayList<>(n); |
|
|
|
for (int i = 0; i < n; i++) { |
|
ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]); |
|
try { |
|
Certificate cert = cf.generateCertificate(bais); |
|
if (sel.match(cert)) { |
|
certs.add((X509Certificate)cert); |
|
} |
|
} catch (CertificateException e) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.getCertificates() encountered " |
|
+ "exception while parsing cert, skipping the bad data: "); |
|
HexDumpEncoder encoder = new HexDumpEncoder(); |
|
debug.println( |
|
"[ " + encoder.encodeBuffer(encodedCert[i]) + " ]"); |
|
} |
|
} |
|
} |
|
|
|
return certs; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Collection<X509CertificatePair> getCertPairs( |
|
LDAPRequest request, String id) throws CertStoreException { |
|
|
|
|
|
byte[][] encodedCertPair; |
|
try { |
|
encodedCertPair = request.getValues(id); |
|
} catch (NamingException namingEx) { |
|
throw new CertStoreException(namingEx); |
|
} |
|
|
|
int n = encodedCertPair.length; |
|
if (n == 0) { |
|
return Collections.emptySet(); |
|
} |
|
|
|
List<X509CertificatePair> certPairs = new ArrayList<>(n); |
|
|
|
for (int i = 0; i < n; i++) { |
|
try { |
|
X509CertificatePair certPair = |
|
X509CertificatePair.generateCertificatePair(encodedCertPair[i]); |
|
certPairs.add(certPair); |
|
} catch (CertificateException e) { |
|
if (debug != null) { |
|
debug.println( |
|
"LDAPCertStore.getCertPairs() encountered exception " |
|
+ "while parsing cert, skipping the bad data: "); |
|
HexDumpEncoder encoder = new HexDumpEncoder(); |
|
debug.println( |
|
"[ " + encoder.encodeBuffer(encodedCertPair[i]) + " ]"); |
|
} |
|
} |
|
} |
|
|
|
return certPairs; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Collection<X509Certificate> getMatchingCrossCerts( |
|
LDAPRequest request, X509CertSelector forward, |
|
X509CertSelector reverse) |
|
throws CertStoreException { |
|
|
|
Collection<X509CertificatePair> certPairs = |
|
getCertPairs(request, CROSS_CERT); |
|
|
|
|
|
ArrayList<X509Certificate> matchingCerts = new ArrayList<>(); |
|
for (X509CertificatePair certPair : certPairs) { |
|
X509Certificate cert; |
|
if (forward != null) { |
|
cert = certPair.getForward(); |
|
if ((cert != null) && forward.match(cert)) { |
|
matchingCerts.add(cert); |
|
} |
|
} |
|
if (reverse != null) { |
|
cert = certPair.getReverse(); |
|
if ((cert != null) && reverse.match(cert)) { |
|
matchingCerts.add(cert); |
|
} |
|
} |
|
} |
|
return matchingCerts; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public synchronized Collection<X509Certificate> engineGetCertificates |
|
(CertSelector selector) throws CertStoreException { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() selector: " |
|
+ String.valueOf(selector)); |
|
} |
|
|
|
if (selector == null) { |
|
selector = new X509CertSelector(); |
|
} |
|
if (!(selector instanceof X509CertSelector)) { |
|
throw new CertStoreException("LDAPCertStore needs an X509CertSelector " + |
|
"to find certs"); |
|
} |
|
X509CertSelector xsel = (X509CertSelector) selector; |
|
int basicConstraints = xsel.getBasicConstraints(); |
|
String subject = xsel.getSubjectAsString(); |
|
String issuer = xsel.getIssuerAsString(); |
|
HashSet<X509Certificate> certs = new HashSet<>(); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: " |
|
+ basicConstraints); |
|
} |
|
|
|
// basicConstraints: |
|
// -2: only EE certs accepted |
|
// -1: no check is done |
|
// 0: any CA certificate accepted |
|
|
|
if (subject != null) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() " |
|
+ "subject is not null"); |
|
} |
|
LDAPRequest request = new LDAPRequest(subject); |
|
if (basicConstraints > -2) { |
|
request.addRequestedAttribute(CROSS_CERT); |
|
request.addRequestedAttribute(CA_CERT); |
|
request.addRequestedAttribute(ARL); |
|
if (prefetchCRLs) { |
|
request.addRequestedAttribute(CRL); |
|
} |
|
} |
|
if (basicConstraints < 0) { |
|
request.addRequestedAttribute(USER_CERT); |
|
} |
|
|
|
if (basicConstraints > -2) { |
|
certs.addAll(getMatchingCrossCerts(request, xsel, null)); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() after " |
|
+ "getMatchingCrossCerts(subject,xsel,null),certs.size(): " |
|
+ certs.size()); |
|
} |
|
certs.addAll(getCertificates(request, CA_CERT, xsel)); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() after " |
|
+ "getCertificates(subject,CA_CERT,xsel),certs.size(): " |
|
+ certs.size()); |
|
} |
|
} |
|
if (basicConstraints < 0) { |
|
certs.addAll(getCertificates(request, USER_CERT, xsel)); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() after " |
|
+ "getCertificates(subject,USER_CERT, xsel),certs.size(): " |
|
+ certs.size()); |
|
} |
|
} |
|
} else { |
|
if (debug != null) { |
|
debug.println |
|
("LDAPCertStore.engineGetCertificates() subject is null"); |
|
} |
|
if (basicConstraints == -2) { |
|
throw new CertStoreException("need subject to find EE certs"); |
|
} |
|
if (issuer == null) { |
|
throw new CertStoreException("need subject or issuer to find certs"); |
|
} |
|
} |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() about to " |
|
+ "getMatchingCrossCerts..."); |
|
} |
|
if ((issuer != null) && (basicConstraints > -2)) { |
|
LDAPRequest request = new LDAPRequest(issuer); |
|
request.addRequestedAttribute(CROSS_CERT); |
|
request.addRequestedAttribute(CA_CERT); |
|
request.addRequestedAttribute(ARL); |
|
if (prefetchCRLs) { |
|
request.addRequestedAttribute(CRL); |
|
} |
|
|
|
certs.addAll(getMatchingCrossCerts(request, null, xsel)); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() after " |
|
+ "getMatchingCrossCerts(issuer,null,xsel),certs.size(): " |
|
+ certs.size()); |
|
} |
|
certs.addAll(getCertificates(request, CA_CERT, xsel)); |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() after " |
|
+ "getCertificates(issuer,CA_CERT,xsel),certs.size(): " |
|
+ certs.size()); |
|
} |
|
} |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCertificates() returning certs"); |
|
} |
|
return certs; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Collection<X509CRL> getCRLs(LDAPRequest request, String id, |
|
X509CRLSelector sel) throws CertStoreException { |
|
|
|
|
|
byte[][] encodedCRL; |
|
try { |
|
encodedCRL = request.getValues(id); |
|
} catch (NamingException namingEx) { |
|
throw new CertStoreException(namingEx); |
|
} |
|
|
|
int n = encodedCRL.length; |
|
if (n == 0) { |
|
return Collections.emptySet(); |
|
} |
|
|
|
List<X509CRL> crls = new ArrayList<>(n); |
|
|
|
for (int i = 0; i < n; i++) { |
|
try { |
|
CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i])); |
|
if (sel.match(crl)) { |
|
crls.add((X509CRL)crl); |
|
} |
|
} catch (CRLException e) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.getCRLs() encountered exception" |
|
+ " while parsing CRL, skipping the bad data: "); |
|
HexDumpEncoder encoder = new HexDumpEncoder(); |
|
debug.println("[ " + encoder.encodeBuffer(encodedCRL[i]) + " ]"); |
|
} |
|
} |
|
} |
|
|
|
return crls; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector) |
|
throws CertStoreException { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCRLs() selector: " |
|
+ selector); |
|
} |
|
|
|
if (selector == null) { |
|
selector = new X509CRLSelector(); |
|
} |
|
if (!(selector instanceof X509CRLSelector)) { |
|
throw new CertStoreException("need X509CRLSelector to find CRLs"); |
|
} |
|
X509CRLSelector xsel = (X509CRLSelector) selector; |
|
HashSet<X509CRL> crls = new HashSet<>(); |
|
|
|
|
|
Collection<Object> issuerNames; |
|
X509Certificate certChecking = xsel.getCertificateChecking(); |
|
if (certChecking != null) { |
|
issuerNames = new HashSet<>(); |
|
X500Principal issuer = certChecking.getIssuerX500Principal(); |
|
issuerNames.add(issuer.getName(X500Principal.RFC2253)); |
|
} else { |
|
// But if we don't know which cert we're checking, try the directory |
|
|
|
issuerNames = xsel.getIssuerNames(); |
|
if (issuerNames == null) { |
|
throw new CertStoreException("need issuerNames or certChecking to " |
|
+ "find CRLs"); |
|
} |
|
} |
|
for (Object nameObject : issuerNames) { |
|
String issuerName; |
|
if (nameObject instanceof byte[]) { |
|
try { |
|
X500Principal issuer = new X500Principal((byte[])nameObject); |
|
issuerName = issuer.getName(X500Principal.RFC2253); |
|
} catch (IllegalArgumentException e) { |
|
continue; |
|
} |
|
} else { |
|
issuerName = (String)nameObject; |
|
} |
|
|
|
Collection<X509CRL> entryCRLs = Collections.emptySet(); |
|
if (certChecking == null || certChecking.getBasicConstraints() != -1) { |
|
LDAPRequest request = new LDAPRequest(issuerName); |
|
request.addRequestedAttribute(CROSS_CERT); |
|
request.addRequestedAttribute(CA_CERT); |
|
request.addRequestedAttribute(ARL); |
|
if (prefetchCRLs) { |
|
request.addRequestedAttribute(CRL); |
|
} |
|
try { |
|
entryCRLs = getCRLs(request, ARL, xsel); |
|
if (entryCRLs.isEmpty()) { |
|
// no ARLs found. We assume that means that there are |
|
|
|
prefetchCRLs = true; |
|
} else { |
|
crls.addAll(entryCRLs); |
|
} |
|
} catch (CertStoreException e) { |
|
if (debug != null) { |
|
debug.println("LDAPCertStore.engineGetCRLs non-fatal error " |
|
+ "retrieving ARLs:" + e); |
|
e.printStackTrace(); |
|
} |
|
} |
|
} |
|
// Otherwise, get the CRL |
|
// if certChecking is null, we don't know if we should look in ARL or CRL |
|
|
|
if (entryCRLs.isEmpty() || certChecking == null) { |
|
LDAPRequest request = new LDAPRequest(issuerName); |
|
request.addRequestedAttribute(CRL); |
|
entryCRLs = getCRLs(request, CRL, xsel); |
|
crls.addAll(entryCRLs); |
|
} |
|
} |
|
return crls; |
|
} |
|
|
|
|
|
static LDAPCertStoreParameters getParameters(URI uri) { |
|
String host = uri.getHost(); |
|
if (host == null) { |
|
return new SunLDAPCertStoreParameters(); |
|
} else { |
|
int port = uri.getPort(); |
|
return (port == -1 |
|
? new SunLDAPCertStoreParameters(host) |
|
: new SunLDAPCertStoreParameters(host, port)); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static class SunLDAPCertStoreParameters |
|
extends LDAPCertStoreParameters { |
|
|
|
private volatile int hashCode = 0; |
|
|
|
SunLDAPCertStoreParameters(String serverName, int port) { |
|
super(serverName, port); |
|
} |
|
SunLDAPCertStoreParameters(String serverName) { |
|
super(serverName); |
|
} |
|
SunLDAPCertStoreParameters() { |
|
super(); |
|
} |
|
public boolean equals(Object obj) { |
|
if (!(obj instanceof LDAPCertStoreParameters)) { |
|
return false; |
|
} |
|
LDAPCertStoreParameters params = (LDAPCertStoreParameters) obj; |
|
return (getPort() == params.getPort() && |
|
getServerName().equalsIgnoreCase(params.getServerName())); |
|
} |
|
public int hashCode() { |
|
if (hashCode == 0) { |
|
int result = 17; |
|
result = 37*result + getPort(); |
|
result = 37*result + |
|
getServerName().toLowerCase(Locale.ENGLISH).hashCode(); |
|
hashCode = result; |
|
} |
|
return hashCode; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
static class LDAPCertSelector extends X509CertSelector { |
|
|
|
private X500Principal certSubject; |
|
private X509CertSelector selector; |
|
private X500Principal subject; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
LDAPCertSelector(X509CertSelector selector, X500Principal certSubject, |
|
String ldapDN) throws IOException { |
|
this.selector = selector == null ? new X509CertSelector() : selector; |
|
this.certSubject = certSubject; |
|
this.subject = new X500Name(ldapDN).asX500Principal(); |
|
} |
|
|
|
// we only override the get (accessor methods) since the set methods |
|
|
|
public X509Certificate getCertificate() { |
|
return selector.getCertificate(); |
|
} |
|
public BigInteger getSerialNumber() { |
|
return selector.getSerialNumber(); |
|
} |
|
public X500Principal getIssuer() { |
|
return selector.getIssuer(); |
|
} |
|
public String getIssuerAsString() { |
|
return selector.getIssuerAsString(); |
|
} |
|
public byte[] getIssuerAsBytes() throws IOException { |
|
return selector.getIssuerAsBytes(); |
|
} |
|
public X500Principal getSubject() { |
|
|
|
return subject; |
|
} |
|
public String getSubjectAsString() { |
|
|
|
return subject.getName(); |
|
} |
|
public byte[] getSubjectAsBytes() throws IOException { |
|
|
|
return subject.getEncoded(); |
|
} |
|
public byte[] getSubjectKeyIdentifier() { |
|
return selector.getSubjectKeyIdentifier(); |
|
} |
|
public byte[] getAuthorityKeyIdentifier() { |
|
return selector.getAuthorityKeyIdentifier(); |
|
} |
|
public Date getCertificateValid() { |
|
return selector.getCertificateValid(); |
|
} |
|
public Date getPrivateKeyValid() { |
|
return selector.getPrivateKeyValid(); |
|
} |
|
public String getSubjectPublicKeyAlgID() { |
|
return selector.getSubjectPublicKeyAlgID(); |
|
} |
|
public PublicKey getSubjectPublicKey() { |
|
return selector.getSubjectPublicKey(); |
|
} |
|
public boolean[] getKeyUsage() { |
|
return selector.getKeyUsage(); |
|
} |
|
public Set<String> getExtendedKeyUsage() { |
|
return selector.getExtendedKeyUsage(); |
|
} |
|
public boolean getMatchAllSubjectAltNames() { |
|
return selector.getMatchAllSubjectAltNames(); |
|
} |
|
public Collection<List<?>> getSubjectAlternativeNames() { |
|
return selector.getSubjectAlternativeNames(); |
|
} |
|
public byte[] getNameConstraints() { |
|
return selector.getNameConstraints(); |
|
} |
|
public int getBasicConstraints() { |
|
return selector.getBasicConstraints(); |
|
} |
|
public Set<String> getPolicy() { |
|
return selector.getPolicy(); |
|
} |
|
public Collection<List<?>> getPathToNames() { |
|
return selector.getPathToNames(); |
|
} |
|
|
|
public boolean match(Certificate cert) { |
|
// temporarily set the subject criterion to the certSubject |
|
|
|
selector.setSubject(certSubject); |
|
boolean match = selector.match(cert); |
|
selector.setSubject(subject); |
|
return match; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
static class LDAPCRLSelector extends X509CRLSelector { |
|
|
|
private X509CRLSelector selector; |
|
private Collection<X500Principal> certIssuers; |
|
private Collection<X500Principal> issuers; |
|
private HashSet<Object> issuerNames; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
LDAPCRLSelector(X509CRLSelector selector, |
|
Collection<X500Principal> certIssuers, String ldapDN) |
|
throws IOException { |
|
this.selector = selector == null ? new X509CRLSelector() : selector; |
|
this.certIssuers = certIssuers; |
|
issuerNames = new HashSet<>(); |
|
issuerNames.add(ldapDN); |
|
issuers = new HashSet<>(); |
|
issuers.add(new X500Name(ldapDN).asX500Principal()); |
|
} |
|
// we only override the get (accessor methods) since the set methods |
|
|
|
public Collection<X500Principal> getIssuers() { |
|
|
|
return Collections.unmodifiableCollection(issuers); |
|
} |
|
public Collection<Object> getIssuerNames() { |
|
|
|
return Collections.unmodifiableCollection(issuerNames); |
|
} |
|
public BigInteger getMinCRL() { |
|
return selector.getMinCRL(); |
|
} |
|
public BigInteger getMaxCRL() { |
|
return selector.getMaxCRL(); |
|
} |
|
public Date getDateAndTime() { |
|
return selector.getDateAndTime(); |
|
} |
|
public X509Certificate getCertificateChecking() { |
|
return selector.getCertificateChecking(); |
|
} |
|
public boolean match(CRL crl) { |
|
// temporarily set the issuer criterion to the certIssuers |
|
|
|
selector.setIssuers(certIssuers); |
|
boolean match = selector.match(crl); |
|
selector.setIssuers(issuers); |
|
return match; |
|
} |
|
} |
|
} |