173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/* 273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. 373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is free software; you can redistribute it and/or modify it 673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * under the terms of the GNU General Public License version 2 only, as 773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * published by the Free Software Foundation. Oracle designates this 873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * particular file as subject to the "Classpath" exception as provided 973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by Oracle in the LICENSE file that accompanied this code. 1073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is distributed in the hope that it will be useful, but WITHOUT 1273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * version 2 for more details (a copy is included in the LICENSE file that 1573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * accompanied this code). 1673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * You should have received a copy of the GNU General Public License version 1873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2 along with this work; if not, write to the Free Software Foundation, 1973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * or visit www.oracle.com if you need additional information or have any 2373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * questions. 2473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 2573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 2673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpackage sun.security.provider.certpath; 2773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 2873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.InputStream; 2973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.IOException; 3073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.HttpURLConnection; 3173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.URI; 3273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.URLConnection; 3373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.InvalidAlgorithmParameterException; 3473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.NoSuchAlgorithmException; 3573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.Provider; 3673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertificateException; 3773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertificateFactory; 3873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertSelector; 3973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertStore; 4073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertStoreException; 4173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertStoreParameters; 4273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertStoreSpi; 4373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CRLException; 4473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CRLSelector; 4573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509Certificate; 4673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509CertSelector; 4773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509CRL; 4873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509CRLSelector; 4973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.ArrayList; 5073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Collection; 5173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Collections; 5273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.List; 5373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Locale; 5473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.action.GetIntegerAction; 5573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.AccessDescription; 5673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNameInterface; 5773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.URIName; 5873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Cache; 5973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Debug; 6073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/** 6273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * A <code>CertStore</code> that retrieves <code>Certificates</code> or 6373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <code>CRL</code>s from a URI, for example, as specified in an X.509 6473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * AuthorityInformationAccess or CRLDistributionPoint extension. 6573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <p> 6673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * For CRLs, this implementation retrieves a single DER encoded CRL per URI. 6773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * For Certificates, this implementation retrieves a single DER encoded CRL or 6873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * a collection of Certificates encoded as a PKCS#7 "certs-only" CMS message. 6973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <p> 7073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This <code>CertStore</code> also implements Certificate/CRL caching. 7173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Currently, the cache is shared between all applications in the VM and uses a 7273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * hardcoded policy. The cache has a maximum size of 185 entries, which are held 7373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by SoftReferences. A request will be satisfied from the cache if we last 7473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * checked for an update within CHECK_INTERVAL (last 30 seconds). Otherwise, 7573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * we open an URLConnection to download the Certificate(s)/CRL using an 7673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * If-Modified-Since request (HTTP) if possible. Note that both positive and 7773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * negative responses are cached, i.e. if we are unable to open the connection 7873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * or the Certificate(s)/CRL cannot be parsed, we remember this result and 7973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * additional calls during the CHECK_INTERVAL period do not try to open another 8073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * connection. 8173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <p> 8273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * The URICertStore is not currently a standard CertStore type. We should 8373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * consider adding a standard "URI" CertStore type. 8473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 8573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Andreas Sterbenz 8673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Sean Mullan 8773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @since 7.0 8873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 8973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootclass URICertStore extends CertStoreSpi { 9073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 9173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final Debug debug = Debug.getInstance("certpath"); 9273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 9373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // interval between checks for update of cached Certificates/CRLs 9473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // (30 seconds) 9573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private final static int CHECK_INTERVAL = 30 * 1000; 9673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 9773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // size of the cache (see Cache class for sizing recommendations) 9873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private final static int CACHE_SIZE = 185; 9973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // X.509 certificate factory instance 10173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private final CertificateFactory factory; 10273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // cached Collection of X509Certificates (may be empty, never null) 10473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private Collection<X509Certificate> certs = Collections.emptySet(); 10573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // cached X509CRL (may be null) 10773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private X509CRL crl; 10873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // time we last checked for an update 11073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private long lastChecked; 11173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 11273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // time server returned as last modified time stamp 11373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // or 0 if not available 11473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private long lastModified; 11573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 11673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // the URI of this CertStore 11773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private URI uri; 11873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 11973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // true if URI is ldap 12073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private boolean ldap = false; 12173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private CertStoreHelper ldapHelper; 12273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private CertStore ldapCertStore; 12373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private String ldapPath; 12473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 12573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Default maximum connect timeout in milliseconds (15 seconds) 12673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // allowed when downloading CRLs 12773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final int DEFAULT_CRL_CONNECT_TIMEOUT = 15000; 12873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 12973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 13073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Integer value indicating the connect timeout, in seconds, to be 13173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * used for the CRL download. A timeout of zero is interpreted as 13273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * an infinite timeout. 13373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 13473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final int CRL_CONNECT_TIMEOUT = initializeTimeout(); 13573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 13673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 13773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Initialize the timeout length by getting the CRL timeout 13873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * system property. If the property has not been set, or if its 13973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * value is negative, set the timeout length to the default. 14073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 14173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static int initializeTimeout() { 14273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Integer tmp = java.security.AccessController.doPrivileged( 14373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root new GetIntegerAction("com.sun.security.crl.timeout")); 14473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (tmp == null || tmp < 0) { 14573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return DEFAULT_CRL_CONNECT_TIMEOUT; 14673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 14773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Convert to milliseconds, as the system property will be 14873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // specified in seconds 14973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return tmp * 1000; 15073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 15273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 15373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Creates a URICertStore. 15473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 15573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param parameters specifying the URI 15673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 15773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URICertStore(CertStoreParameters params) 15873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { 15973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root super(params); 16073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!(params instanceof URICertStoreParameters)) { 16173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new InvalidAlgorithmParameterException 16273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("params must be instanceof URICertStoreParameters"); 16373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 16473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this.uri = ((URICertStoreParameters) params).uri; 16573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if ldap URI, use an LDAPCertStore to fetch certs and CRLs 16673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (uri.getScheme().toLowerCase(Locale.ENGLISH).equals("ldap")) { 16773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldap = true; 16873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldapHelper = CertStoreHelper.getInstance("LDAP"); 16973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldapCertStore = ldapHelper.getCertStore(uri); 17073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldapPath = uri.getPath(); 17173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // strip off leading '/' 17273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (ldapPath.charAt(0) == '/') { 17373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldapPath = ldapPath.substring(1); 17473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 17573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 17673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 17773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root factory = CertificateFactory.getInstance("X.509"); 17873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertificateException e) { 17973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new RuntimeException(); 18073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 18173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 18273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 18373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 18473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns a URI CertStore. This method consults a cache of 18573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * CertStores (shared per JVM) using the URI as a key. 18673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 18773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final Cache<URICertStoreParameters, CertStore> 18873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certStoreCache = Cache.newSoftMemoryCache(CACHE_SIZE); 18973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static synchronized CertStore getInstance(URICertStoreParameters params) 19073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { 19173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 19273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("CertStore URI:" + params.uri); 19373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 19473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CertStore ucs = certStoreCache.get(params); 19573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (ucs == null) { 19673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ucs = new UCS(new URICertStore(params), null, "URI", params); 19773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certStoreCache.put(params, ucs); 19873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else { 19973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 20073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("URICertStore.getInstance: cache hit"); 20173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 20273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 20373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return ucs; 20473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 20573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 20673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 20773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Creates a CertStore from information included in the AccessDescription 20873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * object of a certificate's Authority Information Access Extension. 20973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 21073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static CertStore getInstance(AccessDescription ad) { 21173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!ad.getAccessMethod().equals((Object) 21273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root AccessDescription.Ad_CAISSUERS_Id)) { 21373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 21473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNameInterface gn = ad.getAccessLocation().getName(); 21673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!(gn instanceof URIName)) { 21773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 21873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URI uri = ((URIName) gn).getURI(); 22073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 22173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return URICertStore.getInstance 22273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (new URICertStore.URICertStoreParameters(uri)); 22373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (Exception ex) { 22473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 22573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("exception creating CertStore: " + ex); 22673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ex.printStackTrace(); 22773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 22873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 22973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 23073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 23173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 23273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 23373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns a <code>Collection</code> of <code>X509Certificate</code>s that 23473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the specified selector. If no <code>X509Certificate</code>s 23573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the selector, an empty <code>Collection</code> will be returned. 23673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 23773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param selector a <code>CertSelector</code> used to select which 23873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <code>X509Certificate</code>s should be returned. Specify 23973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <code>null</code> to return all <code>X509Certificate</code>s. 24073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return a <code>Collection</code> of <code>X509Certificate</code>s that 24173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the specified selector 24273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws CertStoreException if an exception occurs 24373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 24473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 24573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @SuppressWarnings("unchecked") 24673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public synchronized Collection<X509Certificate> engineGetCertificates 24773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (CertSelector selector) throws CertStoreException { 24873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 24973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if ldap URI we wrap the CertSelector in an LDAPCertSelector to 25073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // avoid LDAP DN matching issues (see LDAPCertSelector for more info) 25173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (ldap) { 25273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertSelector xsel = (X509CertSelector) selector; 25373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 25473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root xsel = ldapHelper.wrap(xsel, xsel.getSubject(), ldapPath); 25573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 25673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertStoreException(ioe); 25773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 25873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Fetch the certificates via LDAP. LDAPCertStore has its own 25973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // caching mechanism, see the class description for more info. 26073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Safe cast since xsel is an X509 certificate selector. 26173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (Collection<X509Certificate>) 26273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ldapCertStore.getCertificates(xsel); 26373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 26473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 26573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Return the Certificates for this entry. It returns the cached value 26673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if it is still current and fetches the Certificates otherwise. 26773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // For the caching details, see the top of this class. 26873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root long time = System.currentTimeMillis(); 26973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (time - lastChecked < CHECK_INTERVAL) { 27073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 27173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Returning certificates from cache"); 27273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCerts(certs, selector); 27473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastChecked = time; 27673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 27773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URLConnection connection = uri.toURL().openConnection(); 27873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (lastModified != 0) { 27973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root connection.setIfModifiedSince(lastModified); 28073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 28173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root long oldLastModified = lastModified; 28273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try (InputStream in = connection.getInputStream()) { 28373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastModified = connection.getLastModified(); 28473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (oldLastModified != 0) { 28573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (oldLastModified == lastModified) { 28673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 28773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Not modified, using cached copy"); 28873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 28973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCerts(certs, selector); 29073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else if (connection instanceof HttpURLConnection) { 29173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // some proxy servers omit last modified 29273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root HttpURLConnection hconn = (HttpURLConnection)connection; 29373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (hconn.getResponseCode() 29473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root == HttpURLConnection.HTTP_NOT_MODIFIED) { 29573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 29673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Not modified, using cached copy"); 29773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 29873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCerts(certs, selector); 29973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 30373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Downloading new certificates..."); 30473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Safe cast since factory is an X.509 certificate factory 30673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certs = (Collection<X509Certificate>) 30773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root factory.generateCertificates(in); 30873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCerts(certs, selector); 31073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException | CertificateException e) { 31173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 31273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Exception fetching certificates:"); 31373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root e.printStackTrace(); 31473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // exception, forget previous values 31773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastModified = 0; 31873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certs = Collections.emptySet(); 31973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return certs; 32073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 32173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 32373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Iterates over the specified Collection of X509Certificates and 32473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * returns only those that match the criteria specified in the 32573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * CertSelector. 32673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 32773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static Collection<X509Certificate> getMatchingCerts 32873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (Collection<X509Certificate> certs, CertSelector selector) { 32973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if selector not specified, all certs match 33073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (selector == null) { 33173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return certs; 33273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root List<X509Certificate> matchedCerts = new ArrayList<>(certs.size()); 33473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (X509Certificate cert : certs) { 33573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (selector.match(cert)) { 33673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root matchedCerts.add(cert); 33773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return matchedCerts; 34073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 34173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 34273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 34373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns a <code>Collection</code> of <code>X509CRL</code>s that 34473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the specified selector. If no <code>X509CRL</code>s 34573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the selector, an empty <code>Collection</code> will be returned. 34673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 34773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param selector A <code>CRLSelector</code> used to select which 34873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <code>X509CRL</code>s should be returned. Specify <code>null</code> 34973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * to return all <code>X509CRL</code>s. 35073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return A <code>Collection</code> of <code>X509CRL</code>s that 35173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * match the specified selector 35273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws CertStoreException if an exception occurs 35373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 35473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 35573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @SuppressWarnings("unchecked") 35673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector) 35773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws CertStoreException { 35873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 35973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if ldap URI we wrap the CRLSelector in an LDAPCRLSelector to 36073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // avoid LDAP DN matching issues (see LDAPCRLSelector for more info) 36173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (ldap) { 36273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CRLSelector xsel = (X509CRLSelector) selector; 36373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 36473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root xsel = ldapHelper.wrap(xsel, null, ldapPath); 36573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 36673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertStoreException(ioe); 36773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 36873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Fetch the CRLs via LDAP. LDAPCertStore has its own 36973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // caching mechanism, see the class description for more info. 37073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Safe cast since xsel is an X509 certificate selector. 37173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 37273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (Collection<X509CRL>) ldapCertStore.getCRLs(xsel); 37373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertStoreException cse) { 37473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new PKIX.CertStoreTypeException("LDAP", cse); 37573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 37673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 37773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 37873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Return the CRLs for this entry. It returns the cached value 37973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if it is still current and fetches the CRLs otherwise. 38073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // For the caching details, see the top of this class. 38173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root long time = System.currentTimeMillis(); 38273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (time - lastChecked < CHECK_INTERVAL) { 38373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 38473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Returning CRL from cache"); 38573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 38673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCRLs(crl, selector); 38773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 38873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastChecked = time; 38973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 39073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URLConnection connection = uri.toURL().openConnection(); 39173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (lastModified != 0) { 39273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root connection.setIfModifiedSince(lastModified); 39373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 39473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root long oldLastModified = lastModified; 39573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root connection.setConnectTimeout(CRL_CONNECT_TIMEOUT); 39673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try (InputStream in = connection.getInputStream()) { 39773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastModified = connection.getLastModified(); 39873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (oldLastModified != 0) { 39973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (oldLastModified == lastModified) { 40073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 40173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Not modified, using cached copy"); 40273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 40373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCRLs(crl, selector); 40473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else if (connection instanceof HttpURLConnection) { 40573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // some proxy servers omit last modified 40673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root HttpURLConnection hconn = (HttpURLConnection)connection; 40773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (hconn.getResponseCode() 40873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root == HttpURLConnection.HTTP_NOT_MODIFIED) { 40973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 41073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Not modified, using cached copy"); 41173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCRLs(crl, selector); 41373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 41773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Downloading new CRL..."); 41873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root crl = (X509CRL) factory.generateCRL(in); 42073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 42173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getMatchingCRLs(crl, selector); 42273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException | CRLException e) { 42373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 42473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Exception fetching CRL:"); 42573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root e.printStackTrace(); 42673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 42773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // exception, forget previous values 42873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root lastModified = 0; 42973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root crl = null; 43073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new PKIX.CertStoreTypeException("URI", 43173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root new CertStoreException(e)); 43273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 43373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 43473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 43573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 43673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Checks if the specified X509CRL matches the criteria specified in the 43773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * CRLSelector. 43873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 43973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static Collection<X509CRL> getMatchingCRLs 44073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (X509CRL crl, CRLSelector selector) { 44173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (selector == null || (crl != null && selector.match(crl))) { 44273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return Collections.singletonList(crl); 44373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else { 44473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return Collections.emptyList(); 44573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 44673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 44773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 44873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 44973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * CertStoreParameters for the URICertStore. 45073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 45173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static class URICertStoreParameters implements CertStoreParameters { 45273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private final URI uri; 45373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private volatile int hashCode = 0; 45473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URICertStoreParameters(URI uri) { 45573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this.uri = uri; 45673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 45773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override public boolean equals(Object obj) { 45873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!(obj instanceof URICertStoreParameters)) { 45973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return false; 46073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URICertStoreParameters params = (URICertStoreParameters) obj; 46273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return uri.equals(params.uri); 46373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override public int hashCode() { 46573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (hashCode == 0) { 46673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int result = 17; 46773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root result = 37*result + uri.hashCode(); 46873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root hashCode = result; 46973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return hashCode; 47173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override public Object clone() { 47373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 47473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return super.clone(); 47573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CloneNotSupportedException e) { 47673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* Cannot happen */ 47773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new InternalError(e.toString(), e); 47873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 48073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 48173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 48273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 48373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This class allows the URICertStore to be accessed as a CertStore. 48473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 48573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static class UCS extends CertStore { 48673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root protected UCS(CertStoreSpi spi, Provider p, String type, 48773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CertStoreParameters params) { 48873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root super(spi, p, type, params); 48973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 49073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 49173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root} 492