jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java
changeset 10785 1d42311b6355
parent 10782 01689c7b34ac
child 22089 ba496138fa35
equal deleted inserted replaced
10783:de98ed66757c 10785:1d42311b6355
     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);
   281         private Map<String, byte[][]> valueMap;
   282         private Map<String, byte[][]> valueMap;
   282         private final List<String> requestedAttributes;
   283         private final List<String> requestedAttributes;
   283 
   284 
   284         LDAPRequest(String name) {
   285         LDAPRequest(String name) {
   285             this.name = name;
   286             this.name = name;
   286             requestedAttributes = new ArrayList<String>(5);
   287             requestedAttributes = new ArrayList<>(5);
   287         }
   288         }
   288 
   289 
   289         String getName() {
   290         String getName() {
   290             return name;
   291             return name;
   291         }
   292         }
   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() {