KeyManagerFactory.java 9.69 KB
Newer Older
Tom Tromey committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
/* KeyManagerFactory.java -- factory for key managers.
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.net.ssl;

import gnu.java.security.Engine;

import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.security.UnrecoverableKeyException;

/**
 * A class that creates key manager implementations based on a
 * requested algorithm.
 *
 * @author Casey Marshall (rsdio@metastatic.org)
 */
public class KeyManagerFactory
{

  // Constants and fields.
  // ------------------------------------------------------------------

  /** The service name for key manager factories. */
  private static final String KEY_MANAGER_FACTORY = "KeyManagerFactory";

  /** The system default trust manager algorithm. */
  private static final String DEFAULT_ALGORITHM = "JessieX509";

  /** The underlying engine. */
  private final KeyManagerFactorySpi kmfSpi;

  /** The provider of this implementation. */
  private final Provider provider;

  /** The name of this algorithm. */
  private final String algorithm;

  // Constructor.
  // ------------------------------------------------------------------

  /**
   * Create a new key manager factory.
   *
   * @param kmfSpi The underlying engine.
   * @param provider The engine's provider.
   * @param algorithm The name of this algorithm.
   */
  protected KeyManagerFactory(KeyManagerFactorySpi kmfSpi,
                              Provider provider, String algorithm)
  {
    this.kmfSpi = kmfSpi;
    this.provider = provider;
    this.algorithm = algorithm;
  }

  // Class methods.
  // ------------------------------------------------------------------

  /**
   * Get the default algorithm name. This value may be specified at
   * run-time via the security property
   * "ssl.KeyManagerFactory.algorithm". If this property is
   * not specified, this method returns "JessieX509".
   *
   * @return The default key manager factory algorithm's name.
   */
  public static final String getDefaultAlgorithm()
  {
    String alg = null;
    try
      {
        alg = (String) AccessController.doPrivileged(
          new PrivilegedAction()
          {
            public Object run()
            {
              return Security.getProperty("ssl.KeyManagerFactory.algorithm");
            }
          }
        );
      }
    catch (SecurityException se)
      {
      }
    if (alg == null)
      alg = DEFAULT_ALGORITHM;
    return alg;
  }

  /**
135
   * Create an instance of the named key manager factory, from the first
Tom Tromey committed
136
   * provider that implements it.
137
   *
Tom Tromey committed
138 139
   * @param algorithm The type of key manager factory to get.
   * @return An appropriate implementation of that algoritm.
140 141 142 143
   * @throws NoSuchAlgorithmException If no provider implements the requested
   *           algorithm.
   * @throws IllegalArgumentException if <code>algorithm</code> is
   *           <code>null</code> or is an empty string.
Tom Tromey committed
144 145
   */
  public static final KeyManagerFactory getInstance(String algorithm)
146
      throws NoSuchAlgorithmException
Tom Tromey committed
147
  {
148 149 150 151 152 153 154 155 156 157 158 159 160
    Provider[] p = Security.getProviders();
    NoSuchAlgorithmException lastException = null;
    for (int i = 0; i < p.length; i++)
      try
        {
          return getInstance(algorithm, p[i]);
        }
      catch (NoSuchAlgorithmException x)
        {
          lastException = x;
        }
    if (lastException != null)
      throw lastException;
Tom Tromey committed
161 162 163 164
    throw new NoSuchAlgorithmException(algorithm);
  }

  /**
165
   * Create an instance of the named key manager factory, from the named
Tom Tromey committed
166
   * provider.
167
   *
Tom Tromey committed
168
   * @param algorithm The type of key manager factory to get.
169
   * @param provider The name of the provider to get the implementation from.
Tom Tromey committed
170
   * @return An appropriate implementation of that algorithm.
171 172 173 174 175 176
   * @throws NoSuchAlgorithmException If the provider does not implement the
   *           requested algorithm.
   * @throws NoSuchProviderException If the named provider does not exist.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>algorithm</code> is an empty string.
Tom Tromey committed
177
   */
178 179 180
  public static final KeyManagerFactory getInstance(String algorithm,
                                                    String provider)
      throws NoSuchAlgorithmException, NoSuchProviderException
Tom Tromey committed
181 182
  {
    if (provider == null)
183
      throw new IllegalArgumentException("provider MUST NOT be null");
Tom Tromey committed
184 185 186 187 188 189 190
    Provider p = Security.getProvider(provider);
    if (p == null)
      throw new NoSuchProviderException(provider);
    return getInstance(algorithm, p);
  }

  /**
191
   * Create an instance of the named key manager factory, from the given
Tom Tromey committed
192
   * provider.
193
   *
Tom Tromey committed
194 195 196
   * @param algorithm The type of key manager factory to get.
   * @param provider The provider to get the implementation from.
   * @return An appropriate implementation of that algorithm.
197 198 199 200 201
   * @throws NoSuchAlgorithmException If the provider does not implement the
   *           requested algorithm.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>algorithm</code> is an empty string.
Tom Tromey committed
202
   */
203 204 205
  public static final KeyManagerFactory getInstance(String algorithm,
                                                    Provider provider)
      throws NoSuchAlgorithmException
Tom Tromey committed
206
  {
207 208 209 210
    StringBuilder sb = new StringBuilder("KeyManagerFactory algorithm [")
        .append(algorithm).append("] from provider[")
        .append(provider).append("] could not be created");
    Throwable cause;
Tom Tromey committed
211 212
    try
      {
213 214
        Object spi = Engine.getInstance(KEY_MANAGER_FACTORY, algorithm, provider);
        return new KeyManagerFactory((KeyManagerFactorySpi) spi, provider, algorithm);
Tom Tromey committed
215
      }
216
    catch (InvocationTargetException x)
Tom Tromey committed
217
      {
218 219 220 221 222
        cause = x.getCause();
        if (cause instanceof NoSuchAlgorithmException)
          throw (NoSuchAlgorithmException) cause;
        if (cause == null)
          cause = x;
Tom Tromey committed
223
      }
224
    catch (ClassCastException x)
Tom Tromey committed
225
      {
226
        cause = x;
Tom Tromey committed
227
      }
228 229 230
    NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
    x.initCause(cause);
    throw x;
Tom Tromey committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
  }

  /**
   * Returns the name of this key manager factory algorithm.
   *
   * @return The name of this key manager factory algorithm.
   */
  public final String getAlgorithm()
  {
    return algorithm;
  }

  /**
   * Get an array of key managers appropriate for this algorithm, with
   * the most preferred manager first.
   *
   * @return The array of key managers.
   */
  public final KeyManager[] getKeyManagers()
  {
    return kmfSpi.engineGetKeyManagers();
  }

  /**
   * Returns the provider of this implementation.
   *
   * @return The provider of this implementation.
   */
  public final Provider getProvider()
  {
    return provider;
  }

  /**
   * Initialize this instance with an implementation-dependent
   * parameter object.
   *
   * @param params The parameters to initialize with.
   * @throws InvalidAlgorithmParameterException If the specified
   *   parameters are inappropriate.
   */
  public final void init(ManagerFactoryParameters params)
    throws InvalidAlgorithmParameterException
  {
    kmfSpi.engineInit(params);
  }

  /**
   * Initialize this instance with a key store and a password for
   * private key entries.
   *
   * @param store The key store to read.
   * @param passwd The password protecting private keys in the store.
   * @throws KeyStoreException If an error occurs reading the keys.
   * @throws NoSuchAlgorithmException If an algorithm (such as a
   *   certificate algorithm) is not available.
   * @throws UnrecoverableKeyException If the password is incorrect.
   */
  public final void init(KeyStore store, char[] passwd)
    throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
  {
    kmfSpi.engineInit(store, passwd);
  }
}