author | sherman |
Tue, 30 Aug 2011 11:53:11 -0700 | |
changeset 10419 | 12c063b39232 |
parent 10336 | 0bb1999251f8 |
child 10782 | 01689c7b34ac |
permissions | -rw-r--r-- |
2 | 1 |
/* |
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
2 |
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.security.provider.certpath; |
|
27 |
||
28 |
import java.io.InputStream; |
|
29 |
import java.io.IOException; |
|
30 |
import java.net.HttpURLConnection; |
|
31 |
import java.net.URI; |
|
32 |
import java.net.URLConnection; |
|
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
33 |
import java.security.AccessController; |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
34 |
import java.security.PrivilegedAction; |
2 | 35 |
import java.security.InvalidAlgorithmParameterException; |
36 |
import java.security.NoSuchAlgorithmException; |
|
37 |
import java.security.Provider; |
|
38 |
import java.security.cert.CertificateException; |
|
39 |
import java.security.cert.CertificateFactory; |
|
40 |
import java.security.cert.CertSelector; |
|
41 |
import java.security.cert.CertStore; |
|
42 |
import java.security.cert.CertStoreException; |
|
43 |
import java.security.cert.CertStoreParameters; |
|
44 |
import java.security.cert.CertStoreSpi; |
|
45 |
import java.security.cert.CRLException; |
|
46 |
import java.security.cert.CRLSelector; |
|
47 |
import java.security.cert.X509Certificate; |
|
48 |
import java.security.cert.X509CertSelector; |
|
49 |
import java.security.cert.X509CRL; |
|
50 |
import java.security.cert.X509CRLSelector; |
|
51 |
import java.util.ArrayList; |
|
52 |
import java.util.Collection; |
|
53 |
import java.util.Collections; |
|
54 |
import java.util.List; |
|
6122
16fa7ed7ff1b
6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID
xuelei
parents:
5506
diff
changeset
|
55 |
import java.util.Locale; |
2 | 56 |
import sun.security.x509.AccessDescription; |
57 |
import sun.security.x509.GeneralNameInterface; |
|
58 |
import sun.security.x509.URIName; |
|
59 |
import sun.security.util.Cache; |
|
60 |
import sun.security.util.Debug; |
|
61 |
||
62 |
/** |
|
63 |
* A <code>CertStore</code> that retrieves <code>Certificates</code> or |
|
64 |
* <code>CRL</code>s from a URI, for example, as specified in an X.509 |
|
65 |
* AuthorityInformationAccess or CRLDistributionPoint extension. |
|
66 |
* <p> |
|
67 |
* For CRLs, this implementation retrieves a single DER encoded CRL per URI. |
|
68 |
* For Certificates, this implementation retrieves a single DER encoded CRL or |
|
69 |
* a collection of Certificates encoded as a PKCS#7 "certs-only" CMS message. |
|
70 |
* <p> |
|
71 |
* This <code>CertStore</code> also implements Certificate/CRL caching. |
|
72 |
* Currently, the cache is shared between all applications in the VM and uses a |
|
73 |
* hardcoded policy. The cache has a maximum size of 185 entries, which are held |
|
74 |
* by SoftReferences. A request will be satisfied from the cache if we last |
|
75 |
* checked for an update within CHECK_INTERVAL (last 30 seconds). Otherwise, |
|
76 |
* we open an URLConnection to download the Certificate(s)/CRL using an |
|
77 |
* If-Modified-Since request (HTTP) if possible. Note that both positive and |
|
78 |
* negative responses are cached, i.e. if we are unable to open the connection |
|
79 |
* or the Certificate(s)/CRL cannot be parsed, we remember this result and |
|
80 |
* additional calls during the CHECK_INTERVAL period do not try to open another |
|
81 |
* connection. |
|
82 |
* <p> |
|
83 |
* The URICertStore is not currently a standard CertStore type. We should |
|
84 |
* consider adding a standard "URI" CertStore type. |
|
85 |
* |
|
86 |
* @author Andreas Sterbenz |
|
87 |
* @author Sean Mullan |
|
88 |
* @since 7.0 |
|
89 |
*/ |
|
90 |
class URICertStore extends CertStoreSpi { |
|
91 |
||
92 |
private static final Debug debug = Debug.getInstance("certpath"); |
|
93 |
||
94 |
// interval between checks for update of cached Certificates/CRLs |
|
95 |
// (30 seconds) |
|
96 |
private final static int CHECK_INTERVAL = 30 * 1000; |
|
97 |
||
98 |
// size of the cache (see Cache class for sizing recommendations) |
|
99 |
private final static int CACHE_SIZE = 185; |
|
100 |
||
101 |
// X.509 certificate factory instance |
|
102 |
private final CertificateFactory factory; |
|
103 |
||
104 |
// cached Collection of X509Certificates (may be empty, never null) |
|
105 |
private Collection<X509Certificate> certs = |
|
106 |
Collections.<X509Certificate>emptySet(); |
|
107 |
||
108 |
// cached X509CRL (may be null) |
|
109 |
private X509CRL crl; |
|
110 |
||
111 |
// time we last checked for an update |
|
112 |
private long lastChecked; |
|
113 |
||
114 |
// time server returned as last modified time stamp |
|
115 |
// or 0 if not available |
|
116 |
private long lastModified; |
|
117 |
||
118 |
// the URI of this CertStore |
|
119 |
private URI uri; |
|
120 |
||
121 |
// true if URI is ldap |
|
122 |
private boolean ldap = false; |
|
123 |
private CertStore ldapCertStore; |
|
124 |
private String ldapPath; |
|
125 |
||
126 |
/** |
|
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
127 |
* Holder class to lazily load LDAPCertStoreHelper if present. |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
128 |
*/ |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
129 |
private static class LDAP { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
130 |
private static final String CERT_STORE_HELPER = |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
131 |
"sun.security.provider.certpath.ldap.LDAPCertStoreHelper"; |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
132 |
private static final CertStoreHelper helper = |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
133 |
AccessController.doPrivileged( |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
134 |
new PrivilegedAction<CertStoreHelper>() { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
135 |
public CertStoreHelper run() { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
136 |
try { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
137 |
Class<?> c = Class.forName(CERT_STORE_HELPER, true, null); |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
138 |
return (CertStoreHelper)c.newInstance(); |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
139 |
} catch (ClassNotFoundException cnf) { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
140 |
return null; |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
141 |
} catch (InstantiationException e) { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
142 |
throw new AssertionError(e); |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
143 |
} catch (IllegalAccessException e) { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
144 |
throw new AssertionError(e); |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
145 |
} |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
146 |
}}); |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
147 |
static CertStoreHelper helper() { |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
148 |
return helper; |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
149 |
} |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
150 |
} |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
151 |
|
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
152 |
/** |
2 | 153 |
* Creates a URICertStore. |
154 |
* |
|
155 |
* @param parameters specifying the URI |
|
156 |
*/ |
|
157 |
URICertStore(CertStoreParameters params) |
|
158 |
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { |
|
159 |
super(params); |
|
160 |
if (!(params instanceof URICertStoreParameters)) { |
|
161 |
throw new InvalidAlgorithmParameterException |
|
162 |
("params must be instanceof URICertStoreParameters"); |
|
163 |
} |
|
164 |
this.uri = ((URICertStoreParameters) params).uri; |
|
165 |
// if ldap URI, use an LDAPCertStore to fetch certs and CRLs |
|
6122
16fa7ed7ff1b
6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID
xuelei
parents:
5506
diff
changeset
|
166 |
if (uri.getScheme().toLowerCase(Locale.ENGLISH).equals("ldap")) { |
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
167 |
if (LDAP.helper() == null) |
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
168 |
throw new NoSuchAlgorithmException("LDAP not present"); |
2 | 169 |
ldap = true; |
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
170 |
ldapCertStore = LDAP.helper().getCertStore(uri); |
2 | 171 |
ldapPath = uri.getPath(); |
172 |
// strip off leading '/' |
|
173 |
if (ldapPath.charAt(0) == '/') { |
|
174 |
ldapPath = ldapPath.substring(1); |
|
175 |
} |
|
176 |
} |
|
177 |
try { |
|
178 |
factory = CertificateFactory.getInstance("X.509"); |
|
179 |
} catch (CertificateException e) { |
|
180 |
throw new RuntimeException(); |
|
181 |
} |
|
182 |
} |
|
183 |
||
184 |
/** |
|
185 |
* Returns a URI CertStore. This method consults a cache of |
|
186 |
* CertStores (shared per JVM) using the URI as a key. |
|
187 |
*/ |
|
188 |
private static final Cache certStoreCache = |
|
189 |
Cache.newSoftMemoryCache(CACHE_SIZE); |
|
190 |
static synchronized CertStore getInstance(URICertStoreParameters params) |
|
191 |
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { |
|
192 |
if (debug != null) { |
|
193 |
debug.println("CertStore URI:" + params.uri); |
|
194 |
} |
|
195 |
CertStore ucs = (CertStore) certStoreCache.get(params); |
|
196 |
if (ucs == null) { |
|
197 |
ucs = new UCS(new URICertStore(params), null, "URI", params); |
|
198 |
certStoreCache.put(params, ucs); |
|
199 |
} else { |
|
200 |
if (debug != null) { |
|
201 |
debug.println("URICertStore.getInstance: cache hit"); |
|
202 |
} |
|
203 |
} |
|
204 |
return ucs; |
|
205 |
} |
|
206 |
||
207 |
/** |
|
208 |
* Creates a CertStore from information included in the AccessDescription |
|
209 |
* object of a certificate's Authority Information Access Extension. |
|
210 |
*/ |
|
211 |
static CertStore getInstance(AccessDescription ad) { |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
212 |
if (!ad.getAccessMethod().equals((Object) |
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
213 |
AccessDescription.Ad_CAISSUERS_Id)) { |
2 | 214 |
return null; |
215 |
} |
|
216 |
GeneralNameInterface gn = ad.getAccessLocation().getName(); |
|
217 |
if (!(gn instanceof URIName)) { |
|
218 |
return null; |
|
219 |
} |
|
220 |
URI uri = ((URIName) gn).getURI(); |
|
221 |
try { |
|
222 |
return URICertStore.getInstance |
|
223 |
(new URICertStore.URICertStoreParameters(uri)); |
|
224 |
} catch (Exception ex) { |
|
225 |
if (debug != null) { |
|
226 |
debug.println("exception creating CertStore: " + ex); |
|
227 |
ex.printStackTrace(); |
|
228 |
} |
|
229 |
return null; |
|
230 |
} |
|
231 |
} |
|
232 |
||
233 |
/** |
|
234 |
* Returns a <code>Collection</code> of <code>X509Certificate</code>s that |
|
235 |
* match the specified selector. If no <code>X509Certificate</code>s |
|
236 |
* match the selector, an empty <code>Collection</code> will be returned. |
|
237 |
* |
|
238 |
* @param selector a <code>CertSelector</code> used to select which |
|
239 |
* <code>X509Certificate</code>s should be returned. Specify |
|
240 |
* <code>null</code> to return all <code>X509Certificate</code>s. |
|
241 |
* @return a <code>Collection</code> of <code>X509Certificate</code>s that |
|
242 |
* match the specified selector |
|
243 |
* @throws CertStoreException if an exception occurs |
|
244 |
*/ |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
245 |
@SuppressWarnings("unchecked") |
2 | 246 |
public synchronized Collection<X509Certificate> engineGetCertificates |
247 |
(CertSelector selector) throws CertStoreException { |
|
248 |
||
249 |
// if ldap URI we wrap the CertSelector in an LDAPCertSelector to |
|
250 |
// avoid LDAP DN matching issues (see LDAPCertSelector for more info) |
|
251 |
if (ldap) { |
|
252 |
X509CertSelector xsel = (X509CertSelector) selector; |
|
253 |
try { |
|
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
254 |
xsel = LDAP.helper().wrap(xsel, xsel.getSubject(), ldapPath); |
2 | 255 |
} catch (IOException ioe) { |
256 |
throw new CertStoreException(ioe); |
|
257 |
} |
|
258 |
// Fetch the certificates via LDAP. LDAPCertStore has its own |
|
259 |
// caching mechanism, see the class description for more info. |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
260 |
// Safe cast since xsel is an X509 certificate selector. |
2 | 261 |
return (Collection<X509Certificate>) |
262 |
ldapCertStore.getCertificates(xsel); |
|
263 |
} |
|
264 |
||
265 |
// Return the Certificates for this entry. It returns the cached value |
|
266 |
// if it is still current and fetches the Certificates otherwise. |
|
267 |
// For the caching details, see the top of this class. |
|
268 |
long time = System.currentTimeMillis(); |
|
269 |
if (time - lastChecked < CHECK_INTERVAL) { |
|
270 |
if (debug != null) { |
|
271 |
debug.println("Returning certificates from cache"); |
|
272 |
} |
|
273 |
return getMatchingCerts(certs, selector); |
|
274 |
} |
|
275 |
lastChecked = time; |
|
276 |
InputStream in = null; |
|
277 |
try { |
|
278 |
URLConnection connection = uri.toURL().openConnection(); |
|
279 |
if (lastModified != 0) { |
|
280 |
connection.setIfModifiedSince(lastModified); |
|
281 |
} |
|
282 |
in = connection.getInputStream(); |
|
283 |
long oldLastModified = lastModified; |
|
284 |
lastModified = connection.getLastModified(); |
|
285 |
if (oldLastModified != 0) { |
|
286 |
if (oldLastModified == lastModified) { |
|
287 |
if (debug != null) { |
|
288 |
debug.println("Not modified, using cached copy"); |
|
289 |
} |
|
290 |
return getMatchingCerts(certs, selector); |
|
291 |
} else if (connection instanceof HttpURLConnection) { |
|
292 |
// some proxy servers omit last modified |
|
293 |
HttpURLConnection hconn = (HttpURLConnection) connection; |
|
294 |
if (hconn.getResponseCode() |
|
295 |
== HttpURLConnection.HTTP_NOT_MODIFIED) { |
|
296 |
if (debug != null) { |
|
297 |
debug.println("Not modified, using cached copy"); |
|
298 |
} |
|
299 |
return getMatchingCerts(certs, selector); |
|
300 |
} |
|
301 |
} |
|
302 |
} |
|
303 |
if (debug != null) { |
|
304 |
debug.println("Downloading new certificates..."); |
|
305 |
} |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
306 |
// Safe cast since factory is an X.509 certificate factory |
2 | 307 |
certs = (Collection<X509Certificate>) |
308 |
factory.generateCertificates(in); |
|
309 |
return getMatchingCerts(certs, selector); |
|
310 |
} catch (IOException e) { |
|
311 |
if (debug != null) { |
|
312 |
debug.println("Exception fetching certificates:"); |
|
313 |
e.printStackTrace(); |
|
314 |
} |
|
315 |
} catch (CertificateException e) { |
|
316 |
if (debug != null) { |
|
317 |
debug.println("Exception fetching certificates:"); |
|
318 |
e.printStackTrace(); |
|
319 |
} |
|
320 |
} finally { |
|
321 |
if (in != null) { |
|
322 |
try { |
|
323 |
in.close(); |
|
324 |
} catch (IOException e) { |
|
325 |
// ignore |
|
326 |
} |
|
327 |
} |
|
328 |
} |
|
329 |
// exception, forget previous values |
|
330 |
lastModified = 0; |
|
331 |
certs = Collections.<X509Certificate>emptySet(); |
|
332 |
return certs; |
|
333 |
} |
|
334 |
||
335 |
/** |
|
336 |
* Iterates over the specified Collection of X509Certificates and |
|
337 |
* returns only those that match the criteria specified in the |
|
338 |
* CertSelector. |
|
339 |
*/ |
|
340 |
private static Collection<X509Certificate> getMatchingCerts |
|
341 |
(Collection<X509Certificate> certs, CertSelector selector) { |
|
342 |
// if selector not specified, all certs match |
|
343 |
if (selector == null) { |
|
344 |
return certs; |
|
345 |
} |
|
346 |
List<X509Certificate> matchedCerts = |
|
347 |
new ArrayList<X509Certificate>(certs.size()); |
|
348 |
for (X509Certificate cert : certs) { |
|
349 |
if (selector.match(cert)) { |
|
350 |
matchedCerts.add(cert); |
|
351 |
} |
|
352 |
} |
|
353 |
return matchedCerts; |
|
354 |
} |
|
355 |
||
356 |
/** |
|
357 |
* Returns a <code>Collection</code> of <code>X509CRL</code>s that |
|
358 |
* match the specified selector. If no <code>X509CRL</code>s |
|
359 |
* match the selector, an empty <code>Collection</code> will be returned. |
|
360 |
* |
|
361 |
* @param selector A <code>CRLSelector</code> used to select which |
|
362 |
* <code>X509CRL</code>s should be returned. Specify <code>null</code> |
|
363 |
* to return all <code>X509CRL</code>s. |
|
364 |
* @return A <code>Collection</code> of <code>X509CRL</code>s that |
|
365 |
* match the specified selector |
|
366 |
* @throws CertStoreException if an exception occurs |
|
367 |
*/ |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
368 |
@SuppressWarnings("unchecked") |
2 | 369 |
public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector) |
370 |
throws CertStoreException { |
|
371 |
||
372 |
// if ldap URI we wrap the CRLSelector in an LDAPCRLSelector to |
|
373 |
// avoid LDAP DN matching issues (see LDAPCRLSelector for more info) |
|
374 |
if (ldap) { |
|
375 |
X509CRLSelector xsel = (X509CRLSelector) selector; |
|
376 |
try { |
|
4039
afadb206ca44
6889552: Sun provider should not require LDAP CertStore to be present
alanb
parents:
2
diff
changeset
|
377 |
xsel = LDAP.helper().wrap(xsel, null, ldapPath); |
2 | 378 |
} catch (IOException ioe) { |
379 |
throw new CertStoreException(ioe); |
|
380 |
} |
|
381 |
// Fetch the CRLs via LDAP. LDAPCertStore has its own |
|
382 |
// caching mechanism, see the class description for more info. |
|
10336
0bb1999251f8
7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents:
9734
diff
changeset
|
383 |
// Safe cast since xsel is an X509 certificate selector. |
2 | 384 |
return (Collection<X509CRL>) ldapCertStore.getCRLs(xsel); |
385 |
} |
|
386 |
||
387 |
// Return the CRLs for this entry. It returns the cached value |
|
388 |
// if it is still current and fetches the CRLs otherwise. |
|
389 |
// For the caching details, see the top of this class. |
|
390 |
long time = System.currentTimeMillis(); |
|
391 |
if (time - lastChecked < CHECK_INTERVAL) { |
|
392 |
if (debug != null) { |
|
393 |
debug.println("Returning CRL from cache"); |
|
394 |
} |
|
395 |
return getMatchingCRLs(crl, selector); |
|
396 |
} |
|
397 |
lastChecked = time; |
|
398 |
InputStream in = null; |
|
399 |
try { |
|
400 |
URLConnection connection = uri.toURL().openConnection(); |
|
401 |
if (lastModified != 0) { |
|
402 |
connection.setIfModifiedSince(lastModified); |
|
403 |
} |
|
404 |
in = connection.getInputStream(); |
|
405 |
long oldLastModified = lastModified; |
|
406 |
lastModified = connection.getLastModified(); |
|
407 |
if (oldLastModified != 0) { |
|
408 |
if (oldLastModified == lastModified) { |
|
409 |
if (debug != null) { |
|
410 |
debug.println("Not modified, using cached copy"); |
|
411 |
} |
|
412 |
return getMatchingCRLs(crl, selector); |
|
413 |
} else if (connection instanceof HttpURLConnection) { |
|
414 |
// some proxy servers omit last modified |
|
415 |
HttpURLConnection hconn = (HttpURLConnection) connection; |
|
416 |
if (hconn.getResponseCode() |
|
417 |
== HttpURLConnection.HTTP_NOT_MODIFIED) { |
|
418 |
if (debug != null) { |
|
419 |
debug.println("Not modified, using cached copy"); |
|
420 |
} |
|
421 |
return getMatchingCRLs(crl, selector); |
|
422 |
} |
|
423 |
} |
|
424 |
} |
|
425 |
if (debug != null) { |
|
426 |
debug.println("Downloading new CRL..."); |
|
427 |
} |
|
428 |
crl = (X509CRL) factory.generateCRL(in); |
|
429 |
return getMatchingCRLs(crl, selector); |
|
430 |
} catch (IOException e) { |
|
431 |
if (debug != null) { |
|
432 |
debug.println("Exception fetching CRL:"); |
|
433 |
e.printStackTrace(); |
|
434 |
} |
|
435 |
} catch (CRLException e) { |
|
436 |
if (debug != null) { |
|
437 |
debug.println("Exception fetching CRL:"); |
|
438 |
e.printStackTrace(); |
|
439 |
} |
|
440 |
} finally { |
|
441 |
if (in != null) { |
|
442 |
try { |
|
443 |
in.close(); |
|
444 |
} catch (IOException e) { |
|
445 |
// ignore |
|
446 |
} |
|
447 |
} |
|
448 |
} |
|
449 |
// exception, forget previous values |
|
450 |
lastModified = 0; |
|
451 |
crl = null; |
|
452 |
return Collections.<X509CRL>emptyList(); |
|
453 |
} |
|
454 |
||
455 |
/** |
|
456 |
* Checks if the specified X509CRL matches the criteria specified in the |
|
457 |
* CRLSelector. |
|
458 |
*/ |
|
459 |
private static Collection<X509CRL> getMatchingCRLs |
|
460 |
(X509CRL crl, CRLSelector selector) { |
|
461 |
if (selector == null || (crl != null && selector.match(crl))) { |
|
462 |
return Collections.<X509CRL>singletonList(crl); |
|
463 |
} else { |
|
464 |
return Collections.<X509CRL>emptyList(); |
|
465 |
} |
|
466 |
} |
|
467 |
||
468 |
/** |
|
469 |
* CertStoreParameters for the URICertStore. |
|
470 |
*/ |
|
471 |
static class URICertStoreParameters implements CertStoreParameters { |
|
472 |
private final URI uri; |
|
473 |
private volatile int hashCode = 0; |
|
474 |
URICertStoreParameters(URI uri) { |
|
475 |
this.uri = uri; |
|
476 |
} |
|
477 |
public boolean equals(Object obj) { |
|
478 |
if (!(obj instanceof URICertStoreParameters)) { |
|
479 |
return false; |
|
480 |
} |
|
481 |
URICertStoreParameters params = (URICertStoreParameters) obj; |
|
482 |
return uri.equals(params.uri); |
|
483 |
} |
|
484 |
public int hashCode() { |
|
485 |
if (hashCode == 0) { |
|
486 |
int result = 17; |
|
487 |
result = 37*result + uri.hashCode(); |
|
488 |
hashCode = result; |
|
489 |
} |
|
490 |
return hashCode; |
|
491 |
} |
|
492 |
public Object clone() { |
|
493 |
try { |
|
494 |
return super.clone(); |
|
495 |
} catch (CloneNotSupportedException e) { |
|
496 |
/* Cannot happen */ |
|
10419
12c063b39232
7084245: Update usages of InternalError to use exception chaining
sherman
parents:
10336
diff
changeset
|
497 |
throw new InternalError(e.toString(), e); |
2 | 498 |
} |
499 |
} |
|
500 |
} |
|
501 |
||
502 |
/** |
|
503 |
* This class allows the URICertStore to be accessed as a CertStore. |
|
504 |
*/ |
|
505 |
private static class UCS extends CertStore { |
|
506 |
protected UCS(CertStoreSpi spi, Provider p, String type, |
|
507 |
CertStoreParameters params) { |
|
508 |
super(spi, p, type, params); |
|
509 |
} |
|
510 |
} |
|
511 |
} |