Save This Page
Home » openjdk-7 » javax.security » sasl » [javadoc | source]
    1   /*
    2    * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
    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
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   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    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.security.sasl;
   27   
   28   import javax.security.auth.callback.CallbackHandler;
   29   
   30   import java.util.Enumeration;
   31   import java.util.Iterator;
   32   import java.util.Map;
   33   import java.util.Set;
   34   import java.util.HashSet;
   35   import java.util.Collections;
   36   import java.security.Provider;
   37   import java.security.Security;
   38   
   39   /**
   40    * A static class for creating SASL clients and servers.
   41    *<p>
   42    * This class defines the policy of how to locate, load, and instantiate
   43    * SASL clients and servers.
   44    *<p>
   45    * For example, an application or library gets a SASL client by doing
   46    * something like:
   47    *<blockquote><pre>
   48    * SaslClient sc = Sasl.createSaslClient(mechanisms,
   49    *     authorizationId, protocol, serverName, props, callbackHandler);
   50    *</pre></blockquote>
   51    * It can then proceed to use the instance to create an authentication connection.
   52    *<p>
   53    * Similarly, a server gets a SASL server by using code that looks as follows:
   54    *<blockquote><pre>
   55    * SaslServer ss = Sasl.createSaslServer(mechanism,
   56    *     protocol, serverName, props, callbackHandler);
   57    *</pre></blockquote>
   58    *
   59    * @since 1.5
   60    *
   61    * @author Rosanna Lee
   62    * @author Rob Weltman
   63    */
   64   public class Sasl {
   65       // Cannot create one of these
   66       private Sasl() {
   67       }
   68   
   69       /**
   70        * The name of a property that specifies the quality-of-protection to use.
   71        * The property contains a comma-separated, ordered list
   72        * of quality-of-protection values that the
   73        * client or server is willing to support.  A qop value is one of
   74        * <ul>
   75        * <li><tt>"auth"</tt> - authentication only</li>
   76        * <li><tt>"auth-int"</tt> - authentication plus integrity protection</li>
   77        * <li><tt>"auth-conf"</tt> - authentication plus integrity and confidentiality
   78        * protection</li>
   79        * </ul>
   80        *
   81        * The order of the list specifies the preference order of the client or
   82        * server. If this property is absent, the default qop is <tt>"auth"</tt>.
   83        * The value of this constant is <tt>"javax.security.sasl.qop"</tt>.
   84        */
   85       public static final String QOP = "javax.security.sasl.qop";
   86   
   87       /**
   88        * The name of a property that specifies the cipher strength to use.
   89        * The property contains a comma-separated, ordered list
   90        * of cipher strength values that
   91        * the client or server is willing to support. A strength value is one of
   92        * <ul>
   93        * <li><tt>"low"</tt></li>
   94        * <li><tt>"medium"</tt></li>
   95        * <li><tt>"high"</tt></li>
   96        * </ul>
   97        * The order of the list specifies the preference order of the client or
   98        * server.  An implementation should allow configuration of the meaning
   99        * of these values.  An application may use the Java Cryptography
  100        * Extension (JCE) with JCE-aware mechanisms to control the selection of
  101        * cipher suites that match the strength values.
  102        * <BR>
  103        * If this property is absent, the default strength is
  104        * <tt>"high,medium,low"</tt>.
  105        * The value of this constant is <tt>"javax.security.sasl.strength"</tt>.
  106        */
  107       public static final String STRENGTH = "javax.security.sasl.strength";
  108   
  109       /**
  110        * The name of a property that specifies whether the
  111        * server must authenticate to the client. The property contains
  112        * <tt>"true"</tt> if the server must
  113        * authenticate the to client; <tt>"false"</tt> otherwise.
  114        * The default is <tt>"false"</tt>.
  115        * <br>The value of this constant is
  116        * <tt>"javax.security.sasl.server.authentication"</tt>.
  117        */
  118       public static final String SERVER_AUTH =
  119       "javax.security.sasl.server.authentication";
  120   
  121       /**
  122        * The name of a property that specifies the maximum size of the receive
  123        * buffer in bytes of <tt>SaslClient</tt>/<tt>SaslServer</tt>.
  124        * The property contains the string representation of an integer.
  125        * <br>If this property is absent, the default size
  126        * is defined by the mechanism.
  127        * <br>The value of this constant is <tt>"javax.security.sasl.maxbuffer"</tt>.
  128        */
  129       public static final String MAX_BUFFER = "javax.security.sasl.maxbuffer";
  130   
  131       /**
  132        * The name of a property that specifies the maximum size of the raw send
  133        * buffer in bytes of <tt>SaslClient</tt>/<tt>SaslServer</tt>.
  134        * The property contains the string representation of an integer.
  135        * The value of this property is negotiated between the client and server
  136        * during the authentication exchange.
  137        * <br>The value of this constant is <tt>"javax.security.sasl.rawsendsize"</tt>.
  138        */
  139       public static final String RAW_SEND_SIZE = "javax.security.sasl.rawsendsize";
  140   
  141       /**
  142        * The name of a property that specifies whether to reuse previously
  143        * authenticated session information. The property contains "true" if the
  144        * mechanism implementation may attempt to reuse previously authenticated
  145        * session information; it contains "false" if the implementation must
  146        * not reuse previously authenticated session information.  A setting of
  147        * "true" serves only as a hint: it does not necessarily entail actual
  148        * reuse because reuse might not be possible due to a number of reasons,
  149        * including, but not limited to, lack of mechanism support for reuse,
  150        * expiration of reusable information, and the peer's refusal to support
  151        * reuse.
  152        *
  153        * The property's default value is "false".  The value of this constant
  154        * is "javax.security.sasl.reuse".
  155        *
  156        * Note that all other parameters and properties required to create a
  157        * SASL client/server instance must be provided regardless of whether
  158        * this property has been supplied. That is, you cannot supply any less
  159        * information in anticipation of reuse.
  160        *
  161        * Mechanism implementations that support reuse might allow customization
  162        * of its implementation, for factors such as cache size, timeouts, and
  163        * criteria for reuseability. Such customizations are
  164        * implementation-dependent.
  165        */
  166        public static final String REUSE = "javax.security.sasl.reuse";
  167   
  168       /**
  169        * The name of a property that specifies
  170        * whether mechanisms susceptible to simple plain passive attacks (e.g.,
  171        * "PLAIN") are not permitted. The property
  172        * contains <tt>"true"</tt> if such mechanisms are not permitted;
  173        * <tt>"false"</tt> if such mechanisms are permitted.
  174        * The default is <tt>"false"</tt>.
  175        * <br>The value of this constant is
  176        * <tt>"javax.security.sasl.policy.noplaintext"</tt>.
  177        */
  178       public static final String POLICY_NOPLAINTEXT =
  179       "javax.security.sasl.policy.noplaintext";
  180   
  181       /**
  182        * The name of a property that specifies whether
  183        * mechanisms susceptible to active (non-dictionary) attacks
  184        * are not permitted.
  185        * The property contains <tt>"true"</tt>
  186        * if mechanisms susceptible to active attacks
  187        * are not permitted; <tt>"false"</tt> if such mechanisms are permitted.
  188        * The default is <tt>"false"</tt>.
  189        * <br>The value of this constant is
  190        * <tt>"javax.security.sasl.policy.noactive"</tt>.
  191        */
  192       public static final String POLICY_NOACTIVE =
  193       "javax.security.sasl.policy.noactive";
  194   
  195       /**
  196        * The name of a property that specifies whether
  197        * mechanisms susceptible to passive dictionary attacks are not permitted.
  198        * The property contains <tt>"true"</tt>
  199        * if mechanisms susceptible to dictionary attacks are not permitted;
  200        * <tt>"false"</tt> if such mechanisms are permitted.
  201        * The default is <tt>"false"</tt>.
  202        *<br>
  203        * The value of this constant is
  204        * <tt>"javax.security.sasl.policy.nodictionary"</tt>.
  205        */
  206       public static final String POLICY_NODICTIONARY =
  207       "javax.security.sasl.policy.nodictionary";
  208   
  209       /**
  210        * The name of a property that specifies whether mechanisms that accept
  211        * anonymous login are not permitted. The property contains <tt>"true"</tt>
  212        * if mechanisms that accept anonymous login are not permitted;
  213        * <tt>"false"</tt>
  214        * if such mechanisms are permitted. The default is <tt>"false"</tt>.
  215        *<br>
  216        * The value of this constant is
  217        * <tt>"javax.security.sasl.policy.noanonymous"</tt>.
  218        */
  219       public static final String POLICY_NOANONYMOUS =
  220       "javax.security.sasl.policy.noanonymous";
  221   
  222        /**
  223         * The name of a property that specifies whether mechanisms that implement
  224         * forward secrecy between sessions are required. Forward secrecy
  225         * means that breaking into one session will not automatically
  226         * provide information for breaking into future sessions.
  227         * The property
  228         * contains <tt>"true"</tt> if mechanisms that implement forward secrecy
  229         * between sessions are required; <tt>"false"</tt> if such mechanisms
  230         * are not required. The default is <tt>"false"</tt>.
  231         *<br>
  232         * The value of this constant is
  233         * <tt>"javax.security.sasl.policy.forward"</tt>.
  234         */
  235       public static final String POLICY_FORWARD_SECRECY =
  236       "javax.security.sasl.policy.forward";
  237   
  238       /**
  239        * The name of a property that specifies whether
  240        * mechanisms that pass client credentials are required. The property
  241        * contains <tt>"true"</tt> if mechanisms that pass
  242        * client credentials are required; <tt>"false"</tt>
  243        * if such mechanisms are not required. The default is <tt>"false"</tt>.
  244        *<br>
  245        * The value of this constant is
  246        * <tt>"javax.security.sasl.policy.credentials"</tt>.
  247        */
  248       public static final String POLICY_PASS_CREDENTIALS =
  249       "javax.security.sasl.policy.credentials";
  250   
  251       /**
  252        * The name of a property that specifies the credentials to use.
  253        * The property contains a mechanism-specific Java credential object.
  254        * Mechanism implementations may examine the value of this property
  255        * to determine whether it is a class that they support.
  256        * The property may be used to supply credentials to a mechanism that
  257        * supports delegated authentication.
  258        *<br>
  259        * The value of this constant is
  260        * <tt>"javax.security.sasl.credentials"</tt>.
  261        */
  262       public static final String CREDENTIALS = "javax.security.sasl.credentials";
  263   
  264       /**
  265        * Creates a <tt>SaslClient</tt> using the parameters supplied.
  266        *
  267        * This method uses the
  268   <a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#Provider">JCA Security Provider Framework</a>, described in the
  269        * "Java Cryptography Architecture API Specification & Reference", for
  270        * locating and selecting a <tt>SaslClient</tt> implementation.
  271        *
  272        * First, it
  273        * obtains an ordered list of <tt>SaslClientFactory</tt> instances from
  274        * the registered security providers for the "SaslClientFactory" service
  275        * and the specified SASL mechanism(s). It then invokes
  276        * <tt>createSaslClient()</tt> on each factory instance on the list
  277        * until one produces a non-null <tt>SaslClient</tt> instance. It returns
  278        * the non-null <tt>SaslClient</tt> instance, or null if the search fails
  279        * to produce a non-null <tt>SaslClient</tt> instance.
  280        *<p>
  281        * A security provider for SaslClientFactory registers with the
  282        * JCA Security Provider Framework keys of the form <br>
  283        * <tt>SaslClientFactory.<em>mechanism_name</em></tt>
  284        * <br>
  285        * and values that are class names of implementations of
  286        * <tt>javax.security.sasl.SaslClientFactory</tt>.
  287        *
  288        * For example, a provider that contains a factory class,
  289        * <tt>com.wiz.sasl.digest.ClientFactory</tt>, that supports the
  290        * "DIGEST-MD5" mechanism would register the following entry with the JCA:
  291        * <tt>SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory</tt>
  292        *<p>
  293        * See the
  294        * "Java Cryptography Architecture API Specification & Reference"
  295        * for information about how to install and configure security service
  296        *  providers.
  297        *
  298        * @param mechanisms The non-null list of mechanism names to try. Each is the
  299        * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
  300        * @param authorizationId The possibly null protocol-dependent
  301        * identification to be used for authorization.
  302        * If null or empty, the server derives an authorization
  303        * ID from the client's authentication credentials.
  304        * When the SASL authentication completes successfully,
  305        * the specified entity is granted access.
  306        *
  307        * @param protocol The non-null string name of the protocol for which
  308        * the authentication is being performed (e.g., "ldap").
  309        *
  310        * @param serverName The non-null fully-qualified host name of the server
  311        * to authenticate to.
  312        *
  313        * @param props The possibly null set of properties used to
  314        * select the SASL mechanism and to configure the authentication
  315        * exchange of the selected mechanism.
  316        * For example, if <tt>props</tt> contains the
  317        * <code>Sasl.POLICY_NOPLAINTEXT</code> property with the value
  318        * <tt>"true"</tt>, then the selected
  319        * SASL mechanism must not be susceptible to simple plain passive attacks.
  320        * In addition to the standard properties declared in this class,
  321        * other, possibly mechanism-specific, properties can be included.
  322        * Properties not relevant to the selected mechanism are ignored,
  323        * including any map entries with non-String keys.
  324        *
  325        * @param cbh The possibly null callback handler to used by the SASL
  326        * mechanisms to get further information from the application/library
  327        * to complete the authentication. For example, a SASL mechanism might
  328        * require the authentication ID, password and realm from the caller.
  329        * The authentication ID is requested by using a <tt>NameCallback</tt>.
  330        * The password is requested by using a <tt>PasswordCallback</tt>.
  331        * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list
  332        * of realms to choose from, and by using a <tt>RealmCallback</tt> if
  333        * the realm must be entered.
  334        *
  335        *@return A possibly null <tt>SaslClient</tt> created using the parameters
  336        * supplied. If null, cannot find a <tt>SaslClientFactory</tt>
  337        * that will produce one.
  338        *@exception SaslException If cannot create a <tt>SaslClient</tt> because
  339        * of an error.
  340        */
  341       public static SaslClient createSaslClient(
  342           String[] mechanisms,
  343           String authorizationId,
  344           String protocol,
  345           String serverName,
  346           Map<String,?> props,
  347           CallbackHandler cbh) throws SaslException {
  348   
  349           SaslClient mech = null;
  350           SaslClientFactory fac;
  351           String className;
  352           String mechName;
  353   
  354           for (int i = 0; i < mechanisms.length; i++) {
  355               if ((mechName=mechanisms[i]) == null) {
  356                   throw new NullPointerException(
  357                       "Mechanism name cannot be null");
  358               } else if (mechName.length() == 0) {
  359                   continue;
  360               }
  361               String mechFilter = "SaslClientFactory." + mechName;
  362               Provider[] provs = Security.getProviders(mechFilter);
  363               for (int j = 0; provs != null && j < provs.length; j++) {
  364                   className = provs[j].getProperty(mechFilter);
  365                   if (className == null) {
  366                       // Case is ignored
  367                       continue;
  368                   }
  369   
  370                   fac = (SaslClientFactory) loadFactory(provs[j], className);
  371                   if (fac != null) {
  372                       mech = fac.createSaslClient(
  373                           new String[]{mechanisms[i]}, authorizationId,
  374                           protocol, serverName, props, cbh);
  375                       if (mech != null) {
  376                           return mech;
  377                       }
  378                   }
  379               }
  380           }
  381   
  382           return null;
  383       }
  384   
  385       private static Object loadFactory(Provider p, String className)
  386           throws SaslException {
  387           try {
  388               /*
  389                * Load the implementation class with the same class loader
  390                * that was used to load the provider.
  391                * In order to get the class loader of a class, the
  392                * caller's class loader must be the same as or an ancestor of
  393                * the class loader being returned. Otherwise, the caller must
  394                * have "getClassLoader" permission, or a SecurityException
  395                * will be thrown.
  396                */
  397               ClassLoader cl = p.getClass().getClassLoader();
  398               Class implClass;
  399               implClass = Class.forName(className, true, cl);
  400               return implClass.newInstance();
  401           } catch (ClassNotFoundException e) {
  402               throw new SaslException("Cannot load class " + className, e);
  403           } catch (InstantiationException e) {
  404               throw new SaslException("Cannot instantiate class " + className, e);
  405           } catch (IllegalAccessException e) {
  406               throw new SaslException("Cannot access class " + className, e);
  407           } catch (SecurityException e) {
  408               throw new SaslException("Cannot access class " + className, e);
  409           }
  410       }
  411   
  412   
  413       /**
  414        * Creates a <tt>SaslServer</tt> for the specified mechanism.
  415        *
  416        * This method uses the
  417   <a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#Provider">JCA Security Provider Framework</a>,
  418        * described in the
  419        * "Java Cryptography Architecture API Specification & Reference", for
  420        * locating and selecting a <tt>SaslServer</tt> implementation.
  421        *
  422        * First, it
  423        * obtains an ordered list of <tt>SaslServerFactory</tt> instances from
  424        * the registered security providers for the "SaslServerFactory" service
  425        * and the specified mechanism. It then invokes
  426        * <tt>createSaslServer()</tt> on each factory instance on the list
  427        * until one produces a non-null <tt>SaslServer</tt> instance. It returns
  428        * the non-null <tt>SaslServer</tt> instance, or null if the search fails
  429        * to produce a non-null <tt>SaslServer</tt> instance.
  430        *<p>
  431        * A security provider for SaslServerFactory registers with the
  432        * JCA Security Provider Framework keys of the form <br>
  433        * <tt>SaslServerFactory.<em>mechanism_name</em></tt>
  434        * <br>
  435        * and values that are class names of implementations of
  436        * <tt>javax.security.sasl.SaslServerFactory</tt>.
  437        *
  438        * For example, a provider that contains a factory class,
  439        * <tt>com.wiz.sasl.digest.ServerFactory</tt>, that supports the
  440        * "DIGEST-MD5" mechanism would register the following entry with the JCA:
  441        * <tt>SaslServerFactory.DIGEST-MD5  com.wiz.sasl.digest.ServerFactory</tt>
  442        *<p>
  443        * See the
  444        * "Java Cryptography Architecture API Specification & Reference"
  445        * for information about how to install and configure security
  446        * service providers.
  447        *
  448        * @param mechanism The non-null mechanism name. It must be an
  449        * IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
  450        * @param protocol The non-null string name of the protocol for which
  451        * the authentication is being performed (e.g., "ldap").
  452        * @param serverName The non-null fully qualified host name of the server.
  453        * @param props The possibly null set of properties used to
  454        * select the SASL mechanism and to configure the authentication
  455        * exchange of the selected mechanism.
  456        * For example, if <tt>props</tt> contains the
  457        * <code>Sasl.POLICY_NOPLAINTEXT</code> property with the value
  458        * <tt>"true"</tt>, then the selected
  459        * SASL mechanism must not be susceptible to simple plain passive attacks.
  460        * In addition to the standard properties declared in this class,
  461        * other, possibly mechanism-specific, properties can be included.
  462        * Properties not relevant to the selected mechanism are ignored,
  463        * including any map entries with non-String keys.
  464        *
  465        * @param cbh The possibly null callback handler to used by the SASL
  466        * mechanisms to get further information from the application/library
  467        * to complete the authentication. For example, a SASL mechanism might
  468        * require the authentication ID, password and realm from the caller.
  469        * The authentication ID is requested by using a <tt>NameCallback</tt>.
  470        * The password is requested by using a <tt>PasswordCallback</tt>.
  471        * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list
  472        * of realms to choose from, and by using a <tt>RealmCallback</tt> if
  473        * the realm must be entered.
  474        *
  475        *@return A possibly null <tt>SaslServer</tt> created using the parameters
  476        * supplied. If null, cannot find a <tt>SaslServerFactory</tt>
  477        * that will produce one.
  478        *@exception SaslException If cannot create a <tt>SaslServer</tt> because
  479        * of an error.
  480        **/
  481       public static SaslServer
  482           createSaslServer(String mechanism,
  483                       String protocol,
  484                       String serverName,
  485                       Map<String,?> props,
  486                       javax.security.auth.callback.CallbackHandler cbh)
  487           throws SaslException {
  488   
  489           SaslServer mech = null;
  490           SaslServerFactory fac;
  491           String className;
  492   
  493           if (mechanism == null) {
  494               throw new NullPointerException("Mechanism name cannot be null");
  495           } else if (mechanism.length() == 0) {
  496               return null;
  497           }
  498   
  499           String mechFilter = "SaslServerFactory." + mechanism;
  500           Provider[] provs = Security.getProviders(mechFilter);
  501           for (int j = 0; provs != null && j < provs.length; j++) {
  502               className = provs[j].getProperty(mechFilter);
  503               if (className == null) {
  504                   throw new SaslException("Provider does not support " +
  505                       mechFilter);
  506               }
  507               fac = (SaslServerFactory) loadFactory(provs[j], className);
  508               if (fac != null) {
  509                   mech = fac.createSaslServer(
  510                       mechanism, protocol, serverName, props, cbh);
  511                   if (mech != null) {
  512                       return mech;
  513                   }
  514               }
  515           }
  516   
  517           return null;
  518       }
  519   
  520       /**
  521        * Gets an enumeration of known factories for producing <tt>SaslClient</tt>.
  522        * This method uses the same algorithm for locating factories as
  523        * <tt>createSaslClient()</tt>.
  524        * @return A non-null enumeration of known factories for producing
  525        * <tt>SaslClient</tt>.
  526        * @see #createSaslClient
  527        */
  528       public static Enumeration<SaslClientFactory> getSaslClientFactories() {
  529           Set<Object> facs = getFactories("SaslClientFactory");
  530           final Iterator<Object> iter = facs.iterator();
  531           return new Enumeration<SaslClientFactory>() {
  532               public boolean hasMoreElements() {
  533                   return iter.hasNext();
  534               }
  535               public SaslClientFactory nextElement() {
  536                   return (SaslClientFactory)iter.next();
  537               }
  538           };
  539       }
  540   
  541       /**
  542        * Gets an enumeration of known factories for producing <tt>SaslServer</tt>.
  543        * This method uses the same algorithm for locating factories as
  544        * <tt>createSaslServer()</tt>.
  545        * @return A non-null enumeration of known factories for producing
  546        * <tt>SaslServer</tt>.
  547        * @see #createSaslServer
  548        */
  549       public static Enumeration<SaslServerFactory> getSaslServerFactories() {
  550           Set<Object> facs = getFactories("SaslServerFactory");
  551           final Iterator<Object> iter = facs.iterator();
  552           return new Enumeration<SaslServerFactory>() {
  553               public boolean hasMoreElements() {
  554                   return iter.hasNext();
  555               }
  556               public SaslServerFactory nextElement() {
  557                   return (SaslServerFactory)iter.next();
  558               }
  559           };
  560       }
  561   
  562       private static Set<Object> getFactories(String serviceName) {
  563           HashSet<Object> result = new HashSet<Object>();
  564   
  565           if ((serviceName == null) || (serviceName.length() == 0) ||
  566               (serviceName.endsWith("."))) {
  567               return result;
  568           }
  569   
  570   
  571           Provider[] providers = Security.getProviders();
  572           HashSet<String> classes = new HashSet<String>();
  573           Object fac;
  574   
  575           for (int i = 0; i < providers.length; i++) {
  576               classes.clear();
  577   
  578               // Check the keys for each provider.
  579               for (Enumeration e = providers[i].keys(); e.hasMoreElements(); ) {
  580                   String currentKey = (String)e.nextElement();
  581                   if (currentKey.startsWith(serviceName)) {
  582                       // We should skip the currentKey if it contains a
  583                       // whitespace. The reason is: such an entry in the
  584                       // provider property contains attributes for the
  585                       // implementation of an algorithm. We are only interested
  586                       // in entries which lead to the implementation
  587                       // classes.
  588                       if (currentKey.indexOf(" ") < 0) {
  589                           String className = providers[i].getProperty(currentKey);
  590                           if (!classes.contains(className)) {
  591                               classes.add(className);
  592                               try {
  593                                   fac = loadFactory(providers[i], className);
  594                                   if (fac != null) {
  595                                       result.add(fac);
  596                                   }
  597                               }catch (Exception ignore) {
  598                               }
  599                           }
  600                       }
  601                   }
  602               }
  603           }
  604           return Collections.unmodifiableSet(result);
  605       }
  606   }

Save This Page
Home » openjdk-7 » javax.security » sasl » [javadoc | source]