8038084: CertStore needs a way to add new CertStore types
Summary: Removed internal helper classes and reflection usage for LDAP CertStore.
Reviewed-by: mullan
--- a/jdk/src/java.base/share/classes/java/security/cert/LDAPCertStoreParameters.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/security/cert/LDAPCertStoreParameters.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,12 @@
* <p>
* This class is used to provide necessary configuration parameters (server
* name and port number) to implementations of the LDAP {@code CertStore}
- * algorithm.
+ * algorithm. However, if you are retrieving certificates or CRLs from
+ * an ldap URI as specified by RFC 5280, use the
+ * {@link java.security.cert.URICertStoreParameters URICertStoreParameters}
+ * instead as the URI may contain additional information such as the
+ * distinguished name that will help the LDAP CertStore find the specific
+ * certificates and CRLs.
* <p>
* <b>Concurrent Access</b>
* <p>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/security/cert/URICertStoreParameters.java Fri May 15 01:14:25 2015 +0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.security.cert;
+
+import java.net.URI;
+
+/**
+ * Parameters used as input for {@code CertStore} algorithms which use
+ * information contained in a URI to retrieve certificates and CRLs.
+ * <p>
+ * This class is used to provide necessary configuration parameters
+ * through a URI as defined in RFC 5280 to implementations of
+ * {@code CertStore} algorithms.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @since 1.9
+ * @see CertStore
+ * @see java.net.URI
+ */
+public final class URICertStoreParameters implements CertStoreParameters {
+
+ /**
+ * The uri, cannot be null
+ */
+ private final URI uri;
+
+ /*
+ * Hash code for this parameters.
+ */
+ private int myhash = -1;
+
+ /**
+ * Creates an instance of {@code URICertStoreParameters} with the
+ * specified URI.
+ *
+ * @param uri the URI which contains configuration information.
+ * @throws NullPointerException if {@code uri} is null
+ */
+ public URICertStoreParameters(URI uri) {
+ if (uri == null) {
+ throw new NullPointerException();
+ }
+ this.uri = uri;
+ }
+
+ /**
+ * Returns the URI used to construct this
+ * {@code URICertStoreParameters} object.
+ *
+ * @return the URI.
+ */
+ public URI getURI() {
+ return uri;
+ }
+
+ /**
+ * Returns a copy of this object. Changes to the copy will not affect
+ * the original and vice versa.
+ *
+ * @return the copy
+ */
+ @Override
+ public URICertStoreParameters clone() {
+ try {
+ return new URICertStoreParameters(uri);
+ } catch (NullPointerException e) {
+ /* Cannot happen */
+ throw new InternalError(e.toString(), e);
+ }
+ }
+
+ /**
+ * Returns a hash code value for this parameters object.
+ * The hash code is generated using the URI supplied at construction.
+ *
+ * @return a hash code value for this parameters.
+ */
+ @Override
+ public int hashCode() {
+ if (myhash == -1) {
+ myhash = uri.hashCode()*7;
+ }
+ return myhash;
+ }
+
+ /**
+ * Compares the specified object with this parameters object for equality.
+ * Two URICertStoreParameters are considered equal if the URIs used
+ * to construct them are equal.
+ *
+ * @param p the object to test for equality with this parameters.
+ *
+ * @return true if the specified object is equal to this parameters object.
+ */
+ @Override
+ public boolean equals(Object p) {
+ if (p == null || (!(p instanceof URICertStoreParameters))) {
+ return false;
+ }
+
+ if (p == this) {
+ return true;
+ }
+
+ URICertStoreParameters other = (URICertStoreParameters)p;
+ return uri.equals(other.getURI());
+ }
+
+ /**
+ * Returns a formatted string describing the parameters
+ * including the URI used to construct this object.
+ *
+ * @return a formatted string describing the parameters
+ */
+ @Override
+ public String toString() {
+ return "URICertStoreParameters: " + uri.toString();
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Fri May 15 01:14:25 2015 +0000
@@ -67,10 +67,6 @@
* in RFC 5280. The ValidationAlgorithm attribute notes the
* specification that this provider implements.
*
- * - LDAP is the CertStore type for LDAP repositories. The
- * LDAPSchema attribute notes the specification defining the
- * schema that this provider uses to find certificates and CRLs.
- *
* - JavaPolicy is the default file-based Policy type.
*
* - JavaLoginConfig is the default file-based LoginModule Configuration type.
@@ -275,9 +271,6 @@
/*
* CertStores
*/
- map.put("CertStore.LDAP",
- "sun.security.provider.certpath.ldap.LDAPCertStore");
- map.put("CertStore.LDAP LDAPSchema", "RFC2587");
map.put("CertStore.Collection",
"sun.security.provider.certpath.CollectionCertStore");
map.put("CertStore.com.sun.security.IndexedCollection",
@@ -310,7 +303,6 @@
map.put("KeyStore.JKS ImplementedIn", "Software");
map.put("CertPathValidator.PKIX ImplementedIn", "Software");
map.put("CertPathBuilder.PKIX ImplementedIn", "Software");
- map.put("CertStore.LDAP ImplementedIn", "Software");
map.put("CertStore.Collection ImplementedIn", "Software");
map.put("CertStore.com.sun.security.IndexedCollection ImplementedIn",
"Software");
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/CertStoreHelper.java Thu May 14 13:52:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.provider.certpath;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.security.AccessController;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreException;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509CRLSelector;
-import javax.security.auth.x500.X500Principal;
-import java.io.IOException;
-
-import sun.security.util.Cache;
-
-/**
- * Helper used by URICertStore and others when delegating to another CertStore
- * to fetch certs and CRLs.
- */
-
-public abstract class CertStoreHelper {
-
- private static final int NUM_TYPES = 2;
- private final static Map<String,String> classMap = new HashMap<>(NUM_TYPES);
- static {
- classMap.put(
- "LDAP",
- "sun.security.provider.certpath.ldap.LDAPCertStoreHelper");
- classMap.put(
- "SSLServer",
- "sun.security.provider.certpath.ssl.SSLServerCertStoreHelper");
- };
- private static Cache<String, CertStoreHelper> cache
- = Cache.newSoftMemoryCache(NUM_TYPES);
-
- public static CertStoreHelper getInstance(final String type)
- throws NoSuchAlgorithmException
- {
- CertStoreHelper helper = cache.get(type);
- if (helper != null) {
- return helper;
- }
- final String cl = classMap.get(type);
- if (cl == null) {
- throw new NoSuchAlgorithmException(type + " not available");
- }
- try {
- helper = AccessController.doPrivileged(
- new PrivilegedExceptionAction<CertStoreHelper>() {
- public CertStoreHelper run() throws ClassNotFoundException {
- try {
- Class<?> c = Class.forName(cl, true, null);
- CertStoreHelper csh
- = (CertStoreHelper)c.newInstance();
- cache.put(type, csh);
- return csh;
- } catch (InstantiationException |
- IllegalAccessException e) {
- throw new AssertionError(e);
- }
- }
- });
- return helper;
- } catch (PrivilegedActionException e) {
- throw new NoSuchAlgorithmException(type + " not available",
- e.getException());
- }
- }
-
- static boolean isCausedByNetworkIssue(String type, CertStoreException cse) {
- switch (type) {
- case "LDAP":
- case "SSLServer":
- try {
- CertStoreHelper csh = CertStoreHelper.getInstance(type);
- return csh.isCausedByNetworkIssue(cse);
- } catch (NoSuchAlgorithmException nsae) {
- return false;
- }
- case "URI":
- Throwable t = cse.getCause();
- return (t != null && t instanceof IOException);
- default:
- // we don't know about any other remote CertStore types
- return false;
- }
- }
-
- /**
- * Returns a CertStore using the given URI as parameters.
- */
- public abstract CertStore getCertStore(URI uri)
- throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
-
- /**
- * Wraps an existing X509CertSelector when needing to avoid DN matching
- * issues.
- */
- public abstract X509CertSelector wrap(X509CertSelector selector,
- X500Principal certSubject,
- String dn)
- throws IOException;
-
- /**
- * Wraps an existing X509CRLSelector when needing to avoid DN matching
- * issues.
- */
- public abstract X509CRLSelector wrap(X509CRLSelector selector,
- Collection<X500Principal> certIssuers,
- String dn)
- throws IOException;
-
- /**
- * Returns true if the cause of the CertStoreException is a network
- * related issue.
- */
- public abstract boolean isCausedByNetworkIssue(CertStoreException e);
-}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Fri May 15 01:14:25 2015 +0000
@@ -466,6 +466,34 @@
stackedCerts, params.trustAnchors());
}
+ static boolean isCausedByNetworkIssue(String type, CertStoreException cse) {
+ boolean result;
+ Throwable t = cse.getCause();
+
+ switch (type) {
+ case "LDAP":
+ if (t != null) {
+ // These two exception classes are inside java.naming module
+ String cn = t.getClass().getName();
+ result = (cn.equals("javax.naming.ServiceUnavailableException") ||
+ cn.equals("javax.naming.CommunicationException"));
+ } else {
+ result = false;
+ }
+ break;
+ case "SSLServer":
+ result = (t != null && t instanceof IOException);
+ break;
+ case "URI":
+ result = (t != null && t instanceof IOException);
+ break;
+ default:
+ // we don't know about any other remote CertStore types
+ return false;
+ }
+ return result;
+ }
+
private void checkCRLs(X509Certificate cert, PublicKey prevKey,
X509Certificate prevCert, boolean signFlag,
boolean allowSeparateKey,
@@ -510,7 +538,7 @@
"CertStoreException: " + e.getMessage());
}
if (networkFailureException == null &&
- CertStoreHelper.isCausedByNetworkIssue(store.getType(),e)) {
+ isCausedByNetworkIssue(store.getType(),e)) {
// save this exception, we may need to throw it later
networkFailureException = new CertPathValidatorException(
"Unable to determine revocation status due to " +
@@ -557,8 +585,7 @@
} catch (CertStoreException e) {
if (e instanceof CertStoreTypeException) {
CertStoreTypeException cste = (CertStoreTypeException)e;
- if (CertStoreHelper.isCausedByNetworkIssue(cste.getType(),
- e)) {
+ if (isCausedByNetworkIssue(cste.getType(), e)) {
throw new CertPathValidatorException(
"Unable to determine revocation status due to " +
"network error", e, null, -1,
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/URICertStore.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/URICertStore.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
import java.security.cert.CertStoreSpi;
import java.security.cert.CRLException;
import java.security.cert.CRLSelector;
+import java.security.cert.URICertStoreParameters;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.security.cert.X509CRL;
@@ -118,9 +119,7 @@
// true if URI is ldap
private boolean ldap = false;
- private CertStoreHelper ldapHelper;
private CertStore ldapCertStore;
- private String ldapPath;
// Default maximum connect timeout in milliseconds (15 seconds)
// allowed when downloading CRLs
@@ -165,13 +164,8 @@
// if ldap URI, use an LDAPCertStore to fetch certs and CRLs
if (uri.getScheme().toLowerCase(Locale.ENGLISH).equals("ldap")) {
ldap = true;
- ldapHelper = CertStoreHelper.getInstance("LDAP");
- ldapCertStore = ldapHelper.getCertStore(uri);
- ldapPath = uri.getPath();
- // strip off leading '/'
- if (ldapPath.charAt(0) == '/') {
- ldapPath = ldapPath.substring(1);
- }
+ URICertStoreParameters lparams = new URICertStoreParameters(uri);
+ ldapCertStore = CertStore.getInstance("LDAP", lparams);
}
try {
factory = CertificateFactory.getInstance("X.509");
@@ -246,20 +240,10 @@
public synchronized Collection<X509Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException {
- // if ldap URI we wrap the CertSelector in an LDAPCertSelector to
- // avoid LDAP DN matching issues (see LDAPCertSelector for more info)
if (ldap) {
- X509CertSelector xsel = (X509CertSelector) selector;
- try {
- xsel = ldapHelper.wrap(xsel, xsel.getSubject(), ldapPath);
- } catch (IOException ioe) {
- throw new CertStoreException(ioe);
- }
- // Fetch the certificates via LDAP. LDAPCertStore has its own
// caching mechanism, see the class description for more info.
- // Safe cast since xsel is an X509 certificate selector.
return (Collection<X509Certificate>)
- ldapCertStore.getCertificates(xsel);
+ ldapCertStore.getCertificates(selector);
}
// Return the Certificates for this entry. It returns the cached value
@@ -356,20 +340,11 @@
public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException {
- // if ldap URI we wrap the CRLSelector in an LDAPCRLSelector to
- // avoid LDAP DN matching issues (see LDAPCRLSelector for more info)
if (ldap) {
- X509CRLSelector xsel = (X509CRLSelector) selector;
- try {
- xsel = ldapHelper.wrap(xsel, null, ldapPath);
- } catch (IOException ioe) {
- throw new CertStoreException(ioe);
- }
// Fetch the CRLs via LDAP. LDAPCertStore has its own
// caching mechanism, see the class description for more info.
- // Safe cast since xsel is an X509 certificate selector.
try {
- return (Collection<X509CRL>) ldapCertStore.getCRLs(xsel);
+ return (Collection<X509CRL>) ldapCertStore.getCRLs(selector);
} catch (CertStoreException cse) {
throw new PKIX.CertStoreTypeException("LDAP", cse);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,7 +153,7 @@
throw new UnsupportedOperationException();
}
- static CertStore getInstance(URI uri)
+ public static CertStore getInstance(URI uri)
throws InvalidAlgorithmParameterException
{
return new CS(new SSLServerCertStore(uri), null, "SSLServer", null);
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStoreHelper.java Thu May 14 13:52:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.provider.certpath.ssl;
-
-import java.io.IOException;
-import java.net.URI;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreException;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509CRLSelector;
-import java.util.Collection;
-import javax.security.auth.x500.X500Principal;
-
-import sun.security.provider.certpath.CertStoreHelper;
-
-/**
- * SSL implementation of CertStoreHelper.
- */
-public final class SSLServerCertStoreHelper extends CertStoreHelper {
-
- @Override
- public CertStore getCertStore(URI uri)
- throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
- {
- return SSLServerCertStore.getInstance(uri);
- }
-
- @Override
- public X509CertSelector wrap(X509CertSelector selector,
- X500Principal certSubject,
- String ldapDN)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public X509CRLSelector wrap(X509CRLSelector selector,
- Collection<X500Principal> certIssuers,
- String ldapDN)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isCausedByNetworkIssue(CertStoreException e) {
- Throwable t = e.getCause();
- return (t != null && t instanceof IOException);
- }
-}
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,9 @@
import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
+import java.security.cert.URICertStoreParameters;
+
+
import java.text.Collator;
import java.text.MessageFormat;
import java.util.*;
@@ -69,7 +72,7 @@
import sun.security.pkcs10.PKCS10;
import sun.security.pkcs10.PKCS10Attribute;
import sun.security.provider.X509Factory;
-import sun.security.provider.certpath.CertStoreHelper;
+import sun.security.provider.certpath.ssl.SSLServerCertStore;
import sun.security.util.Password;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@@ -2208,14 +2211,10 @@
}
}
} else { // must be LDAP, and uri is not null
- // Lazily load LDAPCertStoreHelper if present
- CertStoreHelper helper = CertStoreHelper.getInstance("LDAP");
- String path = uri.getPath();
- if (path.charAt(0) == '/') path = path.substring(1);
- CertStore s = helper.getCertStore(uri);
- X509CRLSelector sel =
- helper.wrap(new X509CRLSelector(), null, path);
- return s.getCRLs(sel);
+ URICertStoreParameters params =
+ new URICertStoreParameters(uri);
+ CertStore s = CertStore.getInstance("LDAP", params);
+ return s.getCRLs(new X509CRLSelector());
}
}
@@ -2463,9 +2462,7 @@
out.println(rb.getString("Not.a.signed.jar.file"));
}
} else if (sslserver != null) {
- // Lazily load SSLCertStoreHelper if present
- CertStoreHelper helper = CertStoreHelper.getInstance("SSLServer");
- CertStore cs = helper.getCertStore(new URI("https://" + sslserver));
+ CertStore cs = SSLServerCertStore.getInstance(new URI("https://" + sslserver));
Collection<? extends Certificate> chain;
try {
chain = cs.getCertificates(null);
--- a/jdk/src/java.base/share/conf/security/java.security Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.base/share/conf/security/java.security Fri May 15 01:14:25 2015 +0000
@@ -78,6 +78,7 @@
security.provider.tbd=com.sun.security.sasl.Provider
security.provider.tbd=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.tbd=sun.security.smartcardio.SunPCSC
+security.provider.tbd=sun.security.provider.certpath.ldap.JdkLDAP
#ifdef windows
security.provider.tbd=sun.security.mscapi.SunMSCAPI
#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java Fri May 15 01:14:25 2015 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider.certpath.ldap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.security.Provider;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.ProviderException;
+import java.security.cert.CertStoreParameters;
+
+/**
+ * Provider class for the JdkLDAP provider.
+ * Supports LDAP cert store.
+ *
+ * @since 1.9
+ */
+public final class JdkLDAP extends Provider {
+
+ private static final long serialVersionUID = -2279741232933606418L;
+
+ private static final class ProviderService extends Provider.Service {
+ ProviderService(Provider p, String type, String algo, String cn,
+ List<String> aliases, HashMap<String, String> attrs) {
+ super(p, type, algo, cn, aliases, attrs);
+ }
+
+ @Override
+ public Object newInstance(Object ctrParamObj)
+ throws NoSuchAlgorithmException {
+ String type = getType();
+ String algo = getAlgorithm();
+ if (type.equals("CertStore") && algo.equals("LDAP")) {
+ if (ctrParamObj != null &&
+ !(ctrParamObj instanceof CertStoreParameters)) {
+ throw new InvalidParameterException
+ ("constructorParameter must be instanceof CertStoreParameters");
+ }
+ try {
+ return new LDAPCertStore((CertStoreParameters) ctrParamObj);
+ } catch (Exception ex) {
+ throw new NoSuchAlgorithmException("Error constructing " +
+ type + " for " + algo + " using JdkLDAP", ex);
+ }
+ }
+ throw new ProviderException("No impl for " + algo + " " + type);
+ }
+ }
+
+ public JdkLDAP() {
+ super("JdkLDAP", 1.9d, "JdkLDAP Provider (implements LDAP CertStore)");
+
+ HashMap<String, String> attrs = new HashMap<>(2);
+ attrs.put("LDAPSchema", "RFC2587");
+ attrs.put("ImplementedIn", "Software");
+
+ /*
+ * CertStore
+ * attrs: LDAPSchema, ImplementedIn
+ */
+ putService(new ProviderService(this, "CertStore",
+ "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore",
+ null, attrs));
+ }
+}
--- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,29 +25,15 @@
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.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 java.security.*;
import java.security.cert.Certificate;
import java.security.cert.*;
-import javax.naming.CommunicationException;
-import javax.naming.ldap.InitialLdapContext;
-import javax.naming.ldap.LdapContext;
import javax.security.auth.x500.X500Principal;
-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;
@@ -109,480 +95,124 @@
private final static boolean DEBUG = false;
- /**
- * LDAP attribute identifiers.
- */
- 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 String ldapDN;
+
+ private LDAPCertStoreImpl impl;
+
+ public LDAPCertStore(CertStoreParameters params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
- // Constants for various empty values
- private final static String[] STRING0 = new String[0];
-
- private final static byte[][] BB0 = new byte[0][];
-
- private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes();
-
- // cache related constants
- private final static int DEFAULT_CACHE_SIZE = 750;
- private final static int DEFAULT_CACHE_LIFETIME = 30;
+ String serverName;
+ int port;
+ String dn = null;
+ if (params == null) {
+ throw new InvalidAlgorithmParameterException(
+ "parameters required for LDAP Certore");
+ }
+ if (params instanceof LDAPCertStoreParameters) {
+ LDAPCertStoreParameters p = (LDAPCertStoreParameters) params;
+ serverName = p.getServerName();
+ port = p.getPort();
+ } else if (params instanceof URICertStoreParameters) {
+ URICertStoreParameters p = (URICertStoreParameters) params;
+ URI u = p.getURI();
+ if (!u.getScheme().equalsIgnoreCase("ldap")) {
+ throw new InvalidAlgorithmParameterException(
+ "Only LDAP URIs are supported for LDAP Certore");
+ }
+ // Use the same default values as in LDAPCertStoreParameters
+ // if unspecified in URI
+ serverName = u.getHost();
+ if (serverName == null) {
+ serverName = "localhost";
+ }
+ port = u.getPort();
+ if (port == -1) {
+ port = 389;
+ }
+ dn = u.getPath();
+ if (dn != null && dn.charAt(0) == '/') {
+ dn = dn.substring(1);
+ }
+ } else {
+ throw new InvalidAlgorithmParameterException(
+ "parameters must be either LDAPCertStoreParameters or " +
+ "URICertStoreParameters");
+ }
- private final static int LIFETIME;
+ Key k = new Key(serverName, port);
+ LDAPCertStoreImpl lci = certStoreCache.get(k);
+ if (lci == null) {
+ this.impl = new LDAPCertStoreImpl(serverName, port);
+ certStoreCache.put(k, impl);
+ } else {
+ this.impl = lci;
+ if (debug != null) {
+ debug.println("LDAPCertStore.getInstance: cache hit");
+ }
+ }
+ this.ldapDN = dn;
+ }
- private final static String PROP_LIFETIME =
- "sun.security.certpath.ldap.cache.lifetime";
+ private static class Key {
+ volatile int hashCode;
+
+ String serverName;
+ int port;
- /*
- * Internal system property, that when set to "true", disables the
- * JNDI application resource files lookup to prevent recursion issues
- * when validating signed JARs with LDAP URLs in certificates.
- */
- private final static String PROP_DISABLE_APP_RESOURCE_FILES =
- "sun.security.certpath.ldap.disable.app.resource.files";
+ Key(String serverName, int port) {
+ this.serverName = serverName;
+ this.port = port;
+ }
- static {
- String s = AccessController.doPrivileged(
- (PrivilegedAction<String>) () -> System.getProperty(PROP_LIFETIME));
- if (s != null) {
- LIFETIME = Integer.parseInt(s); // throws NumberFormatException
- } else {
- LIFETIME = DEFAULT_CACHE_LIFETIME;
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Key)) {
+ return false;
+ }
+ Key key = (Key) obj;
+ return (port == key.port &&
+ serverName.equalsIgnoreCase(key.serverName));
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == 0) {
+ int result = 17;
+ result = 37*result + port;
+ result = 37*result +
+ serverName.toLowerCase(Locale.ENGLISH).hashCode();
+ hashCode = result;
+ }
+ return hashCode;
}
}
/**
- * The CertificateFactory used to decode certificates from
- * their binary stored form.
- */
- private CertificateFactory cf;
- /**
- * The JNDI directory context.
- */
- private LdapContext ctx;
-
- /**
- * Flag indicating that communication error occurred.
- */
- private boolean communicationError = false;
-
- /**
- * Flag indicating whether we should prefetch CRLs.
- */
- private boolean prefetchCRLs = false;
-
- private final Cache<String, byte[][]> valueCache;
-
- private int cacheHits = 0;
- private int cacheMisses = 0;
- private int requests = 0;
-
- /**
- * Creates a <code>CertStore</code> with the specified parameters.
- * For this class, the parameters object must be an instance of
- * <code>LDAPCertStoreParameters</code>.
- *
- * @param params the algorithm parameters
- * @exception InvalidAlgorithmParameterException if params is not an
- * instance of <code>LDAPCertStoreParameters</code>
+ * Returns an LDAPCertStoreImpl object. This method consults a cache of
+ * LDAPCertStoreImpl objects (shared per JVM) using the corresponding
+ * LDAP server name and port info as a key.
*/
- public LDAPCertStore(CertStoreParameters params)
- throws InvalidAlgorithmParameterException {
- super(params);
- if (!(params instanceof LDAPCertStoreParameters))
- throw new InvalidAlgorithmParameterException(
- "parameters must be LDAPCertStoreParameters");
-
- LDAPCertStoreParameters lparams = (LDAPCertStoreParameters) params;
-
- // Create InitialDirContext needed to communicate with the server
- createInitialDirContext(lparams.getServerName(), lparams.getPort());
+ private static final Cache<Key, LDAPCertStoreImpl>
+ certStoreCache = Cache.newSoftMemoryCache(185);
- // Create CertificateFactory for use later on
- 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);
- }
- }
-
- /**
- * Returns an LDAP CertStore. This method consults a cache of
- * CertStores (shared per JVM) using the LDAP server/port as a key.
- */
- private static final Cache<LDAPCertStoreParameters, CertStore>
- certStoreCache = Cache.newSoftMemoryCache(185);
- static synchronized CertStore getInstance(LDAPCertStoreParameters params)
+ // Exist solely for regression test for ensuring that caching is done
+ static synchronized LDAPCertStoreImpl getInstance(LDAPCertStoreParameters params)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- // if necessary, convert params to SunLDAPCertStoreParameters because
- // LDAPCertStoreParameters does not override equals() and hashCode()
- if (! (params instanceof SunLDAPCertStoreParameters)) {
- params = new SunLDAPCertStoreParameters(params.getServerName(), params.getPort());
- }
- CertStore lcs = certStoreCache.get(params);
- if (lcs == null) {
- lcs = CertStore.getInstance("LDAP", params);
- certStoreCache.put(params, lcs);
+ String serverName = params.getServerName();
+ int port = params.getPort();
+ Key k = new Key(serverName, port);
+ LDAPCertStoreImpl lci = certStoreCache.get(k);
+ if (lci == null) {
+ lci = new LDAPCertStoreImpl(serverName, port);
+ certStoreCache.put(k, lci);
} else {
if (debug != null) {
debug.println("LDAPCertStore.getInstance: cache hit");
}
}
- return lcs;
- }
-
- /**
- * Create InitialDirContext.
- *
- * @param server Server DNS name hosting LDAP service
- * @param port Port at which server listens for requests
- * @throws InvalidAlgorithmParameterException if creation fails
- */
- 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);
-
- // If property is set to true, disable application resource file lookup.
- boolean disableAppResourceFiles = AccessController.doPrivileged(
- (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(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 InitialLdapContext(env, null);
- /*
- * By default, follow referrals unless application has
- * overridden property in an application resource file.
- */
- Hashtable<?,?> currentEnv = ctx.getEnvironment();
- if (currentEnv.get(Context.REFERRAL) == null) {
- ctx.addToEnvironment(Context.REFERRAL, "follow");
- }
- } 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 encapsulating the actual LDAP operations and cache
- * handling. Use:
- *
- * LDAPRequest request = new LDAPRequest(dn);
- * request.addRequestedAttribute(CROSS_CERT);
- * request.addRequestedAttribute(CA_CERT);
- * byte[][] crossValues = request.getValues(CROSS_CERT);
- * byte[][] caValues = request.getValues(CA_CERT);
- *
- * At most one LDAP request is sent for each instance created. If all
- * getValues() calls can be satisfied from the cache, no request
- * is sent at all. If a request is sent, all requested attributes
- * are always added to the cache irrespective of whether the getValues()
- * method is called.
- */
- private class LDAPRequest {
-
- private final String name;
- private Map<String, byte[][]> valueMap;
- private final List<String> requestedAttributes;
-
- LDAPRequest(String name) {
- this.name = name;
- requestedAttributes = new ArrayList<>(5);
- }
-
- String getName() {
- return name;
- }
-
- void addRequestedAttribute(String attrId) {
- if (valueMap != null) {
- throw new IllegalStateException("Request already sent");
- }
- requestedAttributes.add(attrId);
- }
-
- /**
- * Gets one or more binary values from an attribute.
- *
- * @param name the location holding the attribute
- * @param attrId the attribute identifier
- * @return an array of binary values (byte arrays)
- * @throws NamingException if a naming exception occurs
- */
- 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;
- }
-
- /**
- * Get a map containing the values for this request. The first time
- * this method is called on an object, the LDAP request is sent,
- * the results parsed and added to a private map and also to the
- * cache of this LDAPCertStore. Subsequent calls return the private
- * map immediately.
- *
- * The map contains an entry for each requested attribute. The
- * attribute name is the key, values are byte[][]. If there are no
- * values for that attribute, values are byte[0][].
- *
- * @return the value Map
- * @throws NamingException if a naming exception occurs
- */
- 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;
-
- if (communicationError) {
- ctx.reconnect(null);
- communicationError = false;
- }
-
- try {
- attrs = ctx.getAttributes(name, attrIds);
- } catch (CommunicationException ce) {
- communicationError = true;
- throw ce;
- } catch (NameNotFoundException e) {
- // name does not exist on this LDAP server
- // treat same as not attributes found
- 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;
- }
-
- /**
- * Add the values to the cache.
- */
- private void cacheAttribute(String attrId, byte[][] values) {
- String cacheKey = name + "|" + attrId;
- valueCache.put(cacheKey, values);
- }
-
- /**
- * Get the values for the given attribute. If the attribute is null
- * or does not contain any values, a zero length byte array is
- * returned. NOTE that it is assumed that all values are byte arrays.
- */
- 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;
- }
-
- }
-
- /*
- * Gets certificates from an attribute id and location in the LDAP
- * directory. Returns a Collection containing only the Certificates that
- * match the specified CertSelector.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @param sel a CertSelector that the Certificates must match
- * @return a Collection of Certificates found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509Certificate> getCertificates(LDAPRequest request,
- String id, X509CertSelector sel) throws CertStoreException {
-
- /* fetch encoded certs from storage */
- 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);
- /* decode certs and check if they satisfy selector */
- 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;
- }
-
- /*
- * Gets certificate pairs from an attribute id and location in the LDAP
- * directory.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @return a Collection of X509CertificatePairs found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509CertificatePair> getCertPairs(
- LDAPRequest request, String id) throws CertStoreException {
-
- /* fetch the encoded cert pairs from storage */
- 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);
- /* decode each cert pair and add it to the Collection */
- 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;
- }
-
- /*
- * Looks at certificate pairs stored in the crossCertificatePair attribute
- * at the specified location in the LDAP directory. Returns a Collection
- * containing all Certificates stored in the forward component that match
- * the forward CertSelector and all Certificates stored in the reverse
- * component that match the reverse CertSelector.
- * <p>
- * If either forward or reverse is null, all certificates from the
- * corresponding component will be rejected.
- *
- * @param name the location to look in
- * @param forward the forward CertSelector (or null)
- * @param reverse the reverse CertSelector (or null)
- * @return a Collection of Certificates found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509Certificate> getMatchingCrossCerts(
- LDAPRequest request, X509CertSelector forward,
- X509CertSelector reverse)
- throws CertStoreException {
- // Get the cert pairs
- Collection<X509CertificatePair> certPairs =
- getCertPairs(request, CROSS_CERT);
-
- // Find Certificates that match and put them in a list
- 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;
+ return lci;
}
/**
@@ -612,159 +242,12 @@
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
- // >1: certificate's basicConstraints extension pathlen must match
- 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");
- }
+ } else if (!(selector instanceof X509CertSelector)) {
+ throw new CertStoreException("need X509CertSelector 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;
- }
-
- /*
- * Gets CRLs from an attribute id and location in the LDAP directory.
- * Returns a Collection containing only the CRLs that match the
- * specified CRLSelector.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @param sel a CRLSelector that the CRLs must match
- * @return a Collection of CRLs found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509CRL> getCRLs(LDAPRequest request, String id,
- X509CRLSelector sel) throws CertStoreException {
-
- /* fetch the encoded crls from storage */
- 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);
- /* decode each crl and check if it matches selector */
- 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;
+ return impl.getCertificates((X509CertSelector) selector, ldapDN);
}
/**
@@ -797,314 +280,9 @@
// Set up selector and collection to hold CRLs
if (selector == null) {
selector = new X509CRLSelector();
- }
- if (!(selector instanceof X509CRLSelector)) {
+ } else if (!(selector instanceof X509CRLSelector)) {
throw new CertStoreException("need X509CRLSelector to find CRLs");
}
- X509CRLSelector xsel = (X509CRLSelector) selector;
- HashSet<X509CRL> crls = new HashSet<>();
-
- // Look in directory entry for issuer of cert we're checking.
- 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
- // entries of all acceptable CRL issuers
- 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;
- }
- // If all we want is CA certs, try to get the (probably shorter) ARL
- 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
- // no ARLs on this server at all and prefetch the CRLs.
- 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
- // attribute, so check both for matching CRLs.
- if (entryCRLs.isEmpty() || certChecking == null) {
- LDAPRequest request = new LDAPRequest(issuerName);
- request.addRequestedAttribute(CRL);
- entryCRLs = getCRLs(request, CRL, xsel);
- crls.addAll(entryCRLs);
- }
- }
- return crls;
- }
-
- // converts an LDAP URI into LDAPCertStoreParameters
- 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));
- }
- }
-
- /*
- * Subclass of LDAPCertStoreParameters with overridden equals/hashCode
- * methods. This is necessary because the parameters are used as
- * keys in the LDAPCertStore cache.
- */
- 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();
- }
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
-
- if (!(obj instanceof LDAPCertStoreParameters)) {
- return false;
- }
- LDAPCertStoreParameters params = (LDAPCertStoreParameters) obj;
- return (getPort() == params.getPort() &&
- getServerName().equalsIgnoreCase(params.getServerName()));
- }
- @Override
- 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;
- }
- }
-
- /*
- * This inner class wraps an existing X509CertSelector and adds
- * additional criteria to match on when the certificate's subject is
- * different than the LDAP Distinguished Name entry. The LDAPCertStore
- * implementation uses the subject DN as the directory entry for
- * looking up certificates. This can be problematic if the certificates
- * that you want to fetch have a different subject DN than the entry
- * where they are stored. You could set the selector's subject to the
- * LDAP DN entry, but then the resulting match would fail to find the
- * desired certificates because the subject DNs would not match. This
- * class avoids that problem by introducing a certSubject which should
- * be set to the certificate's subject DN when it is different than
- * the LDAP DN.
- */
- static class LDAPCertSelector extends X509CertSelector {
-
- private X500Principal certSubject;
- private X509CertSelector selector;
- private X500Principal subject;
-
- /**
- * Creates an LDAPCertSelector.
- *
- * @param selector the X509CertSelector to wrap
- * @param certSubject the subject DN of the certificate that you want
- * to retrieve via LDAP
- * @param ldapDN the LDAP DN where the certificate is stored
- */
- 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
- // will not be invoked by the code that uses this LDAPCertSelector.
- 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 the ldap DN
- return subject;
- }
- public String getSubjectAsString() {
- // return the ldap DN
- return subject.getName();
- }
- public byte[] getSubjectAsBytes() throws IOException {
- // return the encoded ldap DN
- 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
- // so that match will not reject the desired certificates
- selector.setSubject(certSubject);
- boolean match = selector.match(cert);
- selector.setSubject(subject);
- return match;
- }
- }
-
- /**
- * This class has the same purpose as LDAPCertSelector except it is for
- * X.509 CRLs.
- */
- static class LDAPCRLSelector extends X509CRLSelector {
-
- private X509CRLSelector selector;
- private Collection<X500Principal> certIssuers;
- private Collection<X500Principal> issuers;
- private HashSet<Object> issuerNames;
-
- /**
- * Creates an LDAPCRLSelector.
- *
- * @param selector the X509CRLSelector to wrap
- * @param certIssuers the issuer DNs of the CRLs that you want
- * to retrieve via LDAP
- * @param ldapDN the LDAP DN where the CRL is stored
- */
- 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
- // will not be invoked by the code that uses this LDAPCRLSelector.
- public Collection<X500Principal> getIssuers() {
- // return the ldap DN
- return Collections.unmodifiableCollection(issuers);
- }
- public Collection<Object> getIssuerNames() {
- // return the ldap DN
- 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
- // so that match will not reject the desired CRL
- selector.setIssuers(certIssuers);
- boolean match = selector.match(crl);
- selector.setIssuers(issuers);
- return match;
- }
+ return impl.getCRLs((X509CRLSelector) selector, ldapDN);
}
}
--- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java Thu May 14 13:52:05 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.provider.certpath.ldap;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Collection;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreException;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509CRLSelector;
-import javax.naming.CommunicationException;
-import javax.naming.ServiceUnavailableException;
-import javax.security.auth.x500.X500Principal;
-
-import sun.security.provider.certpath.CertStoreHelper;
-
-/**
- * LDAP implementation of CertStoreHelper.
- */
-
-public final class LDAPCertStoreHelper
- extends CertStoreHelper
-{
- @Override
- public CertStore getCertStore(URI uri)
- throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
- {
- return LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri));
- }
-
- @Override
- public X509CertSelector wrap(X509CertSelector selector,
- X500Principal certSubject,
- String ldapDN)
- throws IOException
- {
- return new LDAPCertStore.LDAPCertSelector(selector, certSubject, ldapDN);
- }
-
- @Override
- public X509CRLSelector wrap(X509CRLSelector selector,
- Collection<X500Principal> certIssuers,
- String ldapDN)
- throws IOException
- {
- return new LDAPCertStore.LDAPCRLSelector(selector, certIssuers, ldapDN);
- }
-
- @Override
- public boolean isCausedByNetworkIssue(CertStoreException e) {
- Throwable t = e.getCause();
- return (t != null && (t instanceof ServiceUnavailableException ||
- t instanceof CommunicationException));
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java Fri May 15 01:14:25 2015 +0000
@@ -0,0 +1,772 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider.certpath.ldap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.*;
+import javax.naming.Context;
+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 java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.*;
+import javax.naming.CommunicationException;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.security.auth.x500.X500Principal;
+
+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;
+
+/**
+ * Core implementation of a LDAP Cert Store.
+ * @see java.security.cert.CertStore
+ *
+ * @since 1.9
+ */
+final class LDAPCertStoreImpl {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+
+ private final static boolean DEBUG = false;
+
+ /**
+ * LDAP attribute identifiers.
+ */
+ 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";
+
+ // Constants for various empty values
+ private final static String[] STRING0 = new String[0];
+
+ private final static byte[][] BB0 = new byte[0][];
+
+ private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes();
+
+ // cache related constants
+ 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";
+
+ /*
+ * Internal system property, that when set to "true", disables the
+ * JNDI application resource files lookup to prevent recursion issues
+ * when validating signed JARs with LDAP URLs in certificates.
+ */
+ private final static String PROP_DISABLE_APP_RESOURCE_FILES =
+ "sun.security.certpath.ldap.disable.app.resource.files";
+
+ static {
+ String s = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () -> System.getProperty(PROP_LIFETIME));
+ if (s != null) {
+ LIFETIME = Integer.parseInt(s); // throws NumberFormatException
+ } else {
+ LIFETIME = DEFAULT_CACHE_LIFETIME;
+ }
+ }
+
+ /**
+ * The CertificateFactory used to decode certificates from
+ * their binary stored form.
+ */
+ private CertificateFactory cf;
+ /**
+ * The JNDI directory context.
+ */
+ private LdapContext ctx;
+
+ /**
+ * Flag indicating that communication error occurred.
+ */
+ private boolean communicationError = false;
+
+ /**
+ * Flag indicating whether we should prefetch CRLs.
+ */
+ private boolean prefetchCRLs = false;
+
+ private final Cache<String, byte[][]> valueCache;
+
+ private int cacheHits = 0;
+ private int cacheMisses = 0;
+ private int requests = 0;
+
+ /**
+ * Creates a <code>CertStore</code> with the specified parameters.
+ */
+ LDAPCertStoreImpl(String serverName, int port)
+ throws InvalidAlgorithmParameterException {
+ createInitialDirContext(serverName, port);
+ // Create CertificateFactory for use later on
+ 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);
+ }
+ }
+
+ /**
+ * Create InitialDirContext.
+ *
+ * @param server Server DNS name hosting LDAP service
+ * @param port Port at which server listens for requests
+ * @throws InvalidAlgorithmParameterException if creation fails
+ */
+ 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);
+
+ // If property is set to true, disable application resource file lookup.
+ boolean disableAppResourceFiles = AccessController.doPrivileged(
+ (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(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 InitialLdapContext(env, null);
+ /*
+ * By default, follow referrals unless application has
+ * overridden property in an application resource file.
+ */
+ Hashtable<?,?> currentEnv = ctx.getEnvironment();
+ if (currentEnv.get(Context.REFERRAL) == null) {
+ ctx.addToEnvironment(Context.REFERRAL, "follow");
+ }
+ } 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 encapsulating the actual LDAP operations and cache
+ * handling. Use:
+ *
+ * LDAPRequest request = new LDAPRequest(dn);
+ * request.addRequestedAttribute(CROSS_CERT);
+ * request.addRequestedAttribute(CA_CERT);
+ * byte[][] crossValues = request.getValues(CROSS_CERT);
+ * byte[][] caValues = request.getValues(CA_CERT);
+ *
+ * At most one LDAP request is sent for each instance created. If all
+ * getValues() calls can be satisfied from the cache, no request
+ * is sent at all. If a request is sent, all requested attributes
+ * are always added to the cache irrespective of whether the getValues()
+ * method is called.
+ */
+ private class LDAPRequest {
+
+ private final String name;
+ private Map<String, byte[][]> valueMap;
+ private final List<String> requestedAttributes;
+
+ LDAPRequest(String name) {
+ this.name = name;
+ requestedAttributes = new ArrayList<>(5);
+ }
+
+ String getName() {
+ return name;
+ }
+
+ void addRequestedAttribute(String attrId) {
+ if (valueMap != null) {
+ throw new IllegalStateException("Request already sent");
+ }
+ requestedAttributes.add(attrId);
+ }
+
+ /**
+ * Gets one or more binary values from an attribute.
+ *
+ * @param name the location holding the attribute
+ * @param attrId the attribute identifier
+ * @return an array of binary values (byte arrays)
+ * @throws NamingException if a naming exception occurs
+ */
+ 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;
+ }
+
+ /**
+ * Get a map containing the values for this request. The first time
+ * this method is called on an object, the LDAP request is sent,
+ * the results parsed and added to a private map and also to the
+ * cache of this LDAPCertStore. Subsequent calls return the private
+ * map immediately.
+ *
+ * The map contains an entry for each requested attribute. The
+ * attribute name is the key, values are byte[][]. If there are no
+ * values for that attribute, values are byte[0][].
+ *
+ * @return the value Map
+ * @throws NamingException if a naming exception occurs
+ */
+ 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;
+
+ if (communicationError) {
+ ctx.reconnect(null);
+ communicationError = false;
+ }
+
+ try {
+ attrs = ctx.getAttributes(name, attrIds);
+ } catch (CommunicationException ce) {
+ communicationError = true;
+ throw ce;
+ } catch (NameNotFoundException e) {
+ // name does not exist on this LDAP server
+ // treat same as not attributes found
+ 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;
+ }
+
+ /**
+ * Add the values to the cache.
+ */
+ private void cacheAttribute(String attrId, byte[][] values) {
+ String cacheKey = name + "|" + attrId;
+ valueCache.put(cacheKey, values);
+ }
+
+ /**
+ * Get the values for the given attribute. If the attribute is null
+ * or does not contain any values, a zero length byte array is
+ * returned. NOTE that it is assumed that all values are byte arrays.
+ */
+ 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;
+ }
+
+ }
+
+ /*
+ * Gets certificates from an attribute id and location in the LDAP
+ * directory. Returns a Collection containing only the Certificates that
+ * match the specified CertSelector.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @param sel a CertSelector that the Certificates must match
+ * @return a Collection of Certificates found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509Certificate> getCertificates(LDAPRequest request,
+ String id, X509CertSelector sel) throws CertStoreException {
+
+ /* fetch encoded certs from storage */
+ 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);
+ /* decode certs and check if they satisfy selector */
+ 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;
+ }
+
+ /*
+ * Gets certificate pairs from an attribute id and location in the LDAP
+ * directory.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @return a Collection of X509CertificatePairs found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509CertificatePair> getCertPairs(
+ LDAPRequest request, String id) throws CertStoreException {
+
+ /* fetch the encoded cert pairs from storage */
+ 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);
+ /* decode each cert pair and add it to the Collection */
+ 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;
+ }
+
+ /*
+ * Looks at certificate pairs stored in the crossCertificatePair attribute
+ * at the specified location in the LDAP directory. Returns a Collection
+ * containing all X509Certificates stored in the forward component that match
+ * the forward X509CertSelector and all Certificates stored in the reverse
+ * component that match the reverse X509CertSelector.
+ * <p>
+ * If either forward or reverse is null, all certificates from the
+ * corresponding component will be rejected.
+ *
+ * @param name the location to look in
+ * @param forward the forward X509CertSelector (or null)
+ * @param reverse the reverse X509CertSelector (or null)
+ * @return a Collection of X509Certificates found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509Certificate> getMatchingCrossCerts(
+ LDAPRequest request, X509CertSelector forward,
+ X509CertSelector reverse)
+ throws CertStoreException {
+ // Get the cert pairs
+ Collection<X509CertificatePair> certPairs =
+ getCertPairs(request, CROSS_CERT);
+
+ // Find Certificates that match and put them in a list
+ 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;
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>X509Certificate</code>s that
+ * match the specified selector. If no <code>X509Certificate</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.
+ * <p>
+ * It is not practical to search every entry in the LDAP database for
+ * matching <code>X509Certificate</code>s. Instead, the
+ * <code>X509CertSelector</code> is examined in order to determine where
+ * matching <code>Certificate</code>s are likely to be found (according
+ * to the PKIX LDAPv2 schema, RFC 2587).
+ * If the subject is specified, its directory entry is searched. If the
+ * issuer is specified, its directory entry is searched. If neither the
+ * subject nor the issuer are specified (or the selector is not an
+ * <code>X509CertSelector</code>), a <code>CertStoreException</code> is
+ * thrown.
+ *
+ * @param selector a <code>X509CertSelector</code> used to select which
+ * <code>Certificate</code>s should be returned.
+ * @return a <code>Collection</code> of <code>X509Certificate</code>s that
+ * match the specified selector
+ * @throws CertStoreException if an exception occurs
+ */
+ synchronized Collection<X509Certificate> getCertificates
+ (X509CertSelector xsel, String ldapDN) throws CertStoreException {
+
+ if (ldapDN == null) {
+ ldapDN = xsel.getSubjectAsString();
+ }
+ int basicConstraints = xsel.getBasicConstraints();
+ 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
+ // >1: certificate's basicConstraints extension pathlen must match
+ if (ldapDN != null) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() "
+ + " subject is not null");
+ }
+ LDAPRequest request = new LDAPRequest(ldapDN);
+ 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;
+ }
+
+ /*
+ * Gets CRLs from an attribute id and location in the LDAP directory.
+ * Returns a Collection containing only the CRLs that match the
+ * specified X509CRLSelector.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @param sel a X509CRLSelector that the CRLs must match
+ * @return a Collection of CRLs found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509CRL> getCRLs(LDAPRequest request, String id,
+ X509CRLSelector sel) throws CertStoreException {
+
+ /* fetch the encoded crls from storage */
+ 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);
+ /* decode each crl and check if it matches selector */
+ 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;
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>X509CRL</code>s that
+ * match the specified selector. If no <code>X509CRL</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.
+ * <p>
+ * It is not practical to search every entry in the LDAP database for
+ * matching <code>X509CRL</code>s. Instead, the <code>X509CRLSelector</code>
+ * is examined in order to determine where matching <code>X509CRL</code>s
+ * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
+ * If issuerNames or certChecking are specified, the issuer's directory
+ * entry is searched. If neither issuerNames or certChecking are specified
+ * (or the selector is not an <code>X509CRLSelector</code>), a
+ * <code>CertStoreException</code> is thrown.
+ *
+ * @param selector A <code>X509CRLSelector</code> used to select which
+ * <code>CRL</code>s should be returned. Specify <code>null</code>
+ * to return all <code>CRL</code>s.
+ * @return A <code>Collection</code> of <code>X509CRL</code>s that
+ * match the specified selector
+ * @throws CertStoreException if an exception occurs
+ */
+ synchronized Collection<X509CRL> getCRLs(X509CRLSelector xsel,
+ String ldapDN) throws CertStoreException {
+
+ HashSet<X509CRL> crls = new HashSet<>();
+
+ // Look in directory entry for issuer of cert we're checking.
+ 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
+ // entries of all acceptable CRL issuers
+ if (ldapDN != null) {
+ issuerNames = new HashSet<>();
+ issuerNames.add(ldapDN);
+ } else {
+ 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;
+ }
+ // If all we want is CA certs, try to get the (probably shorter) ARL
+ 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
+ // no ARLs on this server at all and prefetch the CRLs.
+ 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
+ // attribute, so check both for matching CRLs.
+ if (entryCRLs.isEmpty() || certChecking == null) {
+ LDAPRequest request = new LDAPRequest(issuerName);
+ request.addRequestedAttribute(CRL);
+ entryCRLs = getCRLs(request, CRL, xsel);
+ crls.addAll(entryCRLs);
+ }
+ }
+ return crls;
+ }
+}
--- a/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java Thu May 14 13:52:05 2015 -0700
+++ b/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java Fri May 15 01:14:25 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,6 +67,7 @@
expected.add("com.sun.security.sasl.Provider");
expected.add("org.jcp.xml.dsig.internal.dom.XMLDSigRI");
expected.add("sun.security.smartcardio.SunPCSC");
+ expected.add("sun.security.provider.certpath.ldap.JdkLDAP");
if (os.startsWith("Windows")) {
expected.add("sun.security.mscapi.SunMSCAPI");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/cert/URICertStoreParameters/TestBasic.java Fri May 15 01:14:25 2015 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.cert.CertStore;
+import java.security.cert.URICertStoreParameters;
+import java.net.URI;
+
+/*
+ * @test
+ * @bug 8038084
+ * @summary Basic testing for URICertStoreParameters
+ * @run main TestBasic
+ */
+public class TestBasic {
+
+ public static void main(String[] args) throws Exception {
+ String str1 = "ldap://myownhost:5000/";
+ String str2 = "ldap://myownhost:5000/cn=foo";
+ test(str1, str2);
+ System.out.println("Test passed");
+ }
+
+ private static void test(String str1, String str2) throws Exception {
+ System.out.println("Testing clone");
+ URICertStoreParameters p1 = new URICertStoreParameters(new URI(str1));
+ URICertStoreParameters p1Too = p1.clone();
+ if (!(p1.getURI().equals(p1Too.getURI())) ||
+ !(p1.equals(p1Too))) {
+ throw new Exception("Error: problem with clone");
+ }
+ System.out.println("Testing equal and hashCode");
+ p1Too = new URICertStoreParameters(new URI(str1));
+ URICertStoreParameters p2 = new URICertStoreParameters(new URI(str2));
+
+ if (p1.equals(null)) {
+ throw new Exception("Error: p1 should NOT equal null");
+ }
+ if ((!p1.equals(p1)) || (p1.hashCode() != p1.hashCode())) {
+ throw new Exception("Error: p1 should equal p1");
+ }
+ if ((!p1.equals(p1Too)) || (p1.hashCode() != p1Too.hashCode())) {
+ throw new Exception("Error: p1 should equal p1Too");
+ }
+ if ((!p1Too.equals(p1)) || (p1Too.hashCode() != p1.hashCode())) {
+ throw new Exception("Error: p1Too should equal p1");
+ }
+ if (p1.equals(p2) || p1Too.equals(p2)) {
+ throw new Exception("Error: p1/p1Too should NOT equal p2");
+ }
+ }
+}