1 /* |
1 /* |
2 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
158 /** |
158 /** |
159 * Flag indicating whether we should prefetch CRLs. |
159 * Flag indicating whether we should prefetch CRLs. |
160 */ |
160 */ |
161 private boolean prefetchCRLs = false; |
161 private boolean prefetchCRLs = false; |
162 |
162 |
163 private final Cache valueCache; |
163 private final Cache<String, byte[][]> valueCache; |
164 |
164 |
165 private int cacheHits = 0; |
165 private int cacheHits = 0; |
166 private int cacheMisses = 0; |
166 private int cacheMisses = 0; |
167 private int requests = 0; |
167 private int requests = 0; |
168 |
168 |
205 |
205 |
206 /** |
206 /** |
207 * Returns an LDAP CertStore. This method consults a cache of |
207 * Returns an LDAP CertStore. This method consults a cache of |
208 * CertStores (shared per JVM) using the LDAP server/port as a key. |
208 * CertStores (shared per JVM) using the LDAP server/port as a key. |
209 */ |
209 */ |
210 private static final Cache certStoreCache = Cache.newSoftMemoryCache(185); |
210 private static final Cache<LDAPCertStoreParameters, CertStore> |
|
211 certStoreCache = Cache.newSoftMemoryCache(185); |
211 static synchronized CertStore getInstance(LDAPCertStoreParameters params) |
212 static synchronized CertStore getInstance(LDAPCertStoreParameters params) |
212 throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { |
213 throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { |
213 CertStore lcs = (CertStore) certStoreCache.get(params); |
214 CertStore lcs = certStoreCache.get(params); |
214 if (lcs == null) { |
215 if (lcs == null) { |
215 lcs = CertStore.getInstance("LDAP", params); |
216 lcs = CertStore.getInstance("LDAP", params); |
216 certStoreCache.put(params, lcs); |
217 certStoreCache.put(params, lcs); |
217 } else { |
218 } else { |
218 if (debug != null) { |
219 if (debug != null) { |
230 * @throws InvalidAlgorithmParameterException if creation fails |
231 * @throws InvalidAlgorithmParameterException if creation fails |
231 */ |
232 */ |
232 private void createInitialDirContext(String server, int port) |
233 private void createInitialDirContext(String server, int port) |
233 throws InvalidAlgorithmParameterException { |
234 throws InvalidAlgorithmParameterException { |
234 String url = "ldap://" + server + ":" + port; |
235 String url = "ldap://" + server + ":" + port; |
235 Hashtable<String,Object> env = new Hashtable<String,Object>(); |
236 Hashtable<String,Object> env = new Hashtable<>(); |
236 env.put(Context.INITIAL_CONTEXT_FACTORY, |
237 env.put(Context.INITIAL_CONTEXT_FACTORY, |
237 "com.sun.jndi.ldap.LdapCtxFactory"); |
238 "com.sun.jndi.ldap.LdapCtxFactory"); |
238 env.put(Context.PROVIDER_URL, url); |
239 env.put(Context.PROVIDER_URL, url); |
239 try { |
240 try { |
240 ctx = new InitialDirContext(env); |
241 ctx = new InitialDirContext(env); |
309 if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) { |
310 if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) { |
310 System.out.println("Cache hits: " + cacheHits + "; misses: " |
311 System.out.println("Cache hits: " + cacheHits + "; misses: " |
311 + cacheMisses); |
312 + cacheMisses); |
312 } |
313 } |
313 String cacheKey = name + "|" + attrId; |
314 String cacheKey = name + "|" + attrId; |
314 byte[][] values = (byte[][])valueCache.get(cacheKey); |
315 byte[][] values = valueCache.get(cacheKey); |
315 if (values != null) { |
316 if (values != null) { |
316 cacheHits++; |
317 cacheHits++; |
317 return values; |
318 return values; |
318 } |
319 } |
319 cacheMisses++; |
320 cacheMisses++; |
345 requests++; |
346 requests++; |
346 if (requests % 5 == 0) { |
347 if (requests % 5 == 0) { |
347 System.out.println("LDAP requests: " + requests); |
348 System.out.println("LDAP requests: " + requests); |
348 } |
349 } |
349 } |
350 } |
350 valueMap = new HashMap<String, byte[][]>(8); |
351 valueMap = new HashMap<>(8); |
351 String[] attrIds = requestedAttributes.toArray(STRING0); |
352 String[] attrIds = requestedAttributes.toArray(STRING0); |
352 Attributes attrs; |
353 Attributes attrs; |
353 try { |
354 try { |
354 attrs = ctx.getAttributes(name, attrIds); |
355 attrs = ctx.getAttributes(name, attrIds); |
355 } catch (NameNotFoundException e) { |
356 } catch (NameNotFoundException e) { |
427 throw new CertStoreException(namingEx); |
428 throw new CertStoreException(namingEx); |
428 } |
429 } |
429 |
430 |
430 int n = encodedCert.length; |
431 int n = encodedCert.length; |
431 if (n == 0) { |
432 if (n == 0) { |
432 return Collections.<X509Certificate>emptySet(); |
433 return Collections.emptySet(); |
433 } |
434 } |
434 |
435 |
435 List<X509Certificate> certs = new ArrayList<X509Certificate>(n); |
436 List<X509Certificate> certs = new ArrayList<>(n); |
436 /* decode certs and check if they satisfy selector */ |
437 /* decode certs and check if they satisfy selector */ |
437 for (int i = 0; i < n; i++) { |
438 for (int i = 0; i < n; i++) { |
438 ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]); |
439 ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]); |
439 try { |
440 try { |
440 Certificate cert = cf.generateCertificate(bais); |
441 Certificate cert = cf.generateCertificate(bais); |
475 throw new CertStoreException(namingEx); |
476 throw new CertStoreException(namingEx); |
476 } |
477 } |
477 |
478 |
478 int n = encodedCertPair.length; |
479 int n = encodedCertPair.length; |
479 if (n == 0) { |
480 if (n == 0) { |
480 return Collections.<X509CertificatePair>emptySet(); |
481 return Collections.emptySet(); |
481 } |
482 } |
482 |
483 |
483 List<X509CertificatePair> certPairs = |
484 List<X509CertificatePair> certPairs = new ArrayList<>(n); |
484 new ArrayList<X509CertificatePair>(n); |
|
485 /* decode each cert pair and add it to the Collection */ |
485 /* decode each cert pair and add it to the Collection */ |
486 for (int i = 0; i < n; i++) { |
486 for (int i = 0; i < n; i++) { |
487 try { |
487 try { |
488 X509CertificatePair certPair = |
488 X509CertificatePair certPair = |
489 X509CertificatePair.generateCertificatePair(encodedCertPair[i]); |
489 X509CertificatePair.generateCertificatePair(encodedCertPair[i]); |
526 // Get the cert pairs |
526 // Get the cert pairs |
527 Collection<X509CertificatePair> certPairs = |
527 Collection<X509CertificatePair> certPairs = |
528 getCertPairs(request, CROSS_CERT); |
528 getCertPairs(request, CROSS_CERT); |
529 |
529 |
530 // Find Certificates that match and put them in a list |
530 // Find Certificates that match and put them in a list |
531 ArrayList<X509Certificate> matchingCerts = |
531 ArrayList<X509Certificate> matchingCerts = new ArrayList<>(); |
532 new ArrayList<X509Certificate>(); |
|
533 for (X509CertificatePair certPair : certPairs) { |
532 for (X509CertificatePair certPair : certPairs) { |
534 X509Certificate cert; |
533 X509Certificate cert; |
535 if (forward != null) { |
534 if (forward != null) { |
536 cert = certPair.getForward(); |
535 cert = certPair.getForward(); |
537 if ((cert != null) && forward.match(cert)) { |
536 if ((cert != null) && forward.match(cert)) { |
585 } |
584 } |
586 X509CertSelector xsel = (X509CertSelector) selector; |
585 X509CertSelector xsel = (X509CertSelector) selector; |
587 int basicConstraints = xsel.getBasicConstraints(); |
586 int basicConstraints = xsel.getBasicConstraints(); |
588 String subject = xsel.getSubjectAsString(); |
587 String subject = xsel.getSubjectAsString(); |
589 String issuer = xsel.getIssuerAsString(); |
588 String issuer = xsel.getIssuerAsString(); |
590 HashSet<X509Certificate> certs = new HashSet<X509Certificate>(); |
589 HashSet<X509Certificate> certs = new HashSet<>(); |
591 if (debug != null) { |
590 if (debug != null) { |
592 debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: " |
591 debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: " |
593 + basicConstraints); |
592 + basicConstraints); |
594 } |
593 } |
595 |
594 |
704 throw new CertStoreException(namingEx); |
703 throw new CertStoreException(namingEx); |
705 } |
704 } |
706 |
705 |
707 int n = encodedCRL.length; |
706 int n = encodedCRL.length; |
708 if (n == 0) { |
707 if (n == 0) { |
709 return Collections.<X509CRL>emptySet(); |
708 return Collections.emptySet(); |
710 } |
709 } |
711 |
710 |
712 List<X509CRL> crls = new ArrayList<X509CRL>(n); |
711 List<X509CRL> crls = new ArrayList<>(n); |
713 /* decode each crl and check if it matches selector */ |
712 /* decode each crl and check if it matches selector */ |
714 for (int i = 0; i < n; i++) { |
713 for (int i = 0; i < n; i++) { |
715 try { |
714 try { |
716 CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i])); |
715 CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i])); |
717 if (sel.match(crl)) { |
716 if (sel.match(crl)) { |
763 } |
762 } |
764 if (!(selector instanceof X509CRLSelector)) { |
763 if (!(selector instanceof X509CRLSelector)) { |
765 throw new CertStoreException("need X509CRLSelector to find CRLs"); |
764 throw new CertStoreException("need X509CRLSelector to find CRLs"); |
766 } |
765 } |
767 X509CRLSelector xsel = (X509CRLSelector) selector; |
766 X509CRLSelector xsel = (X509CRLSelector) selector; |
768 HashSet<X509CRL> crls = new HashSet<X509CRL>(); |
767 HashSet<X509CRL> crls = new HashSet<>(); |
769 |
768 |
770 // Look in directory entry for issuer of cert we're checking. |
769 // Look in directory entry for issuer of cert we're checking. |
771 Collection<Object> issuerNames; |
770 Collection<Object> issuerNames; |
772 X509Certificate certChecking = xsel.getCertificateChecking(); |
771 X509Certificate certChecking = xsel.getCertificateChecking(); |
773 if (certChecking != null) { |
772 if (certChecking != null) { |
774 issuerNames = new HashSet<Object>(); |
773 issuerNames = new HashSet<>(); |
775 X500Principal issuer = certChecking.getIssuerX500Principal(); |
774 X500Principal issuer = certChecking.getIssuerX500Principal(); |
776 issuerNames.add(issuer.getName(X500Principal.RFC2253)); |
775 issuerNames.add(issuer.getName(X500Principal.RFC2253)); |
777 } else { |
776 } else { |
778 // But if we don't know which cert we're checking, try the directory |
777 // But if we don't know which cert we're checking, try the directory |
779 // entries of all acceptable CRL issuers |
778 // entries of all acceptable CRL issuers |
794 } |
793 } |
795 } else { |
794 } else { |
796 issuerName = (String)nameObject; |
795 issuerName = (String)nameObject; |
797 } |
796 } |
798 // If all we want is CA certs, try to get the (probably shorter) ARL |
797 // If all we want is CA certs, try to get the (probably shorter) ARL |
799 Collection<X509CRL> entryCRLs = Collections.<X509CRL>emptySet(); |
798 Collection<X509CRL> entryCRLs = Collections.emptySet(); |
800 if (certChecking == null || certChecking.getBasicConstraints() != -1) { |
799 if (certChecking == null || certChecking.getBasicConstraints() != -1) { |
801 LDAPRequest request = new LDAPRequest(issuerName); |
800 LDAPRequest request = new LDAPRequest(issuerName); |
802 request.addRequestedAttribute(CROSS_CERT); |
801 request.addRequestedAttribute(CROSS_CERT); |
803 request.addRequestedAttribute(CA_CERT); |
802 request.addRequestedAttribute(CA_CERT); |
804 request.addRequestedAttribute(ARL); |
803 request.addRequestedAttribute(ARL); |
1026 LDAPCRLSelector(X509CRLSelector selector, |
1025 LDAPCRLSelector(X509CRLSelector selector, |
1027 Collection<X500Principal> certIssuers, String ldapDN) |
1026 Collection<X500Principal> certIssuers, String ldapDN) |
1028 throws IOException { |
1027 throws IOException { |
1029 this.selector = selector == null ? new X509CRLSelector() : selector; |
1028 this.selector = selector == null ? new X509CRLSelector() : selector; |
1030 this.certIssuers = certIssuers; |
1029 this.certIssuers = certIssuers; |
1031 issuerNames = new HashSet<Object>(); |
1030 issuerNames = new HashSet<>(); |
1032 issuerNames.add(ldapDN); |
1031 issuerNames.add(ldapDN); |
1033 issuers = new HashSet<X500Principal>(); |
1032 issuers = new HashSet<>(); |
1034 issuers.add(new X500Name(ldapDN).asX500Principal()); |
1033 issuers.add(new X500Name(ldapDN).asX500Principal()); |
1035 } |
1034 } |
1036 // we only override the get (accessor methods) since the set methods |
1035 // we only override the get (accessor methods) since the set methods |
1037 // will not be invoked by the code that uses this LDAPCRLSelector. |
1036 // will not be invoked by the code that uses this LDAPCRLSelector. |
1038 public Collection<X500Principal> getIssuers() { |
1037 public Collection<X500Principal> getIssuers() { |