Source for org.ietf.jgss.GSSManager

   1: /* GSSManager.java -- manager class for the GSS-API.
   2:    Copyright (C) 2004 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.
  37: 
  38:    The documentation comments of this class are derived from the text
  39:    of RFC 2853:  Generic Security Service API Version 2: Java Bindings.
  40:    That document is covered under the following license notice:
  41: 
  42: Copyright (C) The Internet Society (2000).  All Rights Reserved.
  43: 
  44: This document and translations of it may be copied and furnished to
  45: others, and derivative works that comment on or otherwise explain it
  46: or assist in its implementation may be prepared, copied, published and
  47: distributed, in whole or in part, without restriction of any kind,
  48: provided that the above copyright notice and this paragraph are
  49: included on all such copies and derivative works.  However, this
  50: document itself may not be modified in any way, such as by removing
  51: the copyright notice or references to the Internet Society or other
  52: Internet organizations, except as needed for the purpose of developing
  53: Internet standards in which case the procedures for copyrights defined
  54: in the Internet Standards process must be followed, or as required to
  55: translate it into languages other than English.
  56: 
  57: The limited permissions granted above are perpetual and will not be
  58: revoked by the Internet Society or its successors or assigns.
  59: 
  60: This document and the information contained herein is provided on an
  61: "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
  62: TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
  63: NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
  64: WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
  65: MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
  66: 
  67: 
  68: package org.ietf.jgss;
  69: 
  70: import java.security.Provider;
  71: import java.security.Security;
  72: 
  73: /**
  74:  * <p>The GSSManager class is an abstract class that serves as a factory
  75:  * for three GSS interfaces: {@link GSSName}, {@link GSSCredential}, and
  76:  * {@link GSSContext}. It also provides methods for applications to determine
  77:  * what mechanisms are available from the GSS implementation and what
  78:  * nametypes these mechanisms support. An instance of the default GSSManager
  79:  * subclass may be obtained through the static method {@link #getInstance()},
  80:  * but applications are free to instantiate other subclasses of GSSManager.</p>
  81:  *
  82:  * <p>All but one method in this class are declared abstract. This means
  83:  * that subclasses have to provide the complete implementation for those
  84:  * methods. The only exception to this is the static method {@link
  85:  * #getInstance()} which will have platform specific code to return an
  86:  * instance of the default subclass.</p>
  87:  *
  88:  * <p>Platform providers of GSS are required not to add any constructors to
  89:  * this class, private, public, or protected. This will ensure that all
  90:  * subclasses invoke only the default constructor provided to the base
  91:  * class by the compiler.</p>
  92:  *
  93:  * <p>A subclass extending the GSSManager abstract class may be implemented
  94:  * as a modular provider based layer that utilizes some well known
  95:  * service provider specification. The GSSManager API provides the
  96:  * application with methods to set provider preferences on such an
  97:  * implementation. These methods also allow the implementation to throw
  98:  * a well-defined exception in case provider based configuration is not
  99:  * supported. Applications that expect to be portable should be aware of
 100:  * this and recover cleanly by catching the exception.</p>
 101:  *
 102:  * <p>It is envisioned that there will be three most common ways in which
 103:  * providers will be used:</p>
 104:  *
 105:  * <ol>
 106:  * <li>The application does not care about what provider is used (the
 107:  * default case).</li>
 108:  *
 109:  * <li>The application wants a particular provider to be used
 110:  * preferentially, either for a particular mechanism or all the
 111:  * time, irrespective of mechanism.</li>
 112:  *
 113:  * <li>The application wants to use the locally configured providers
 114:  * as far as possible but if support is missing for one or more
 115:  * mechanisms then it wants to fall back on its own provider.</li>
 116:  * </ol>
 117:  *
 118:  * <p>The GSSManager class has two methods that enable these modes of
 119:  * usage: {@link #addProviderAtFront(java.security.Provider,org.ietf.jgss.Oid)}
 120:  * and {@link #addProviderAtEnd(java.security.Provider,org.ietf.jgss.Oid)}.
 121:  * These methods have the effect of creating an ordered list of
 122:  * (<i>provider</i>, <i>oid</i>) pairs where each pair indicates a preference
 123:  * of provider for a given oid.</p>
 124:  *
 125:  * <p>The use of these methods does not require any knowledge of whatever
 126:  * service provider specification the GSSManager subclass follows. It is
 127:  * hoped that these methods will serve the needs of most applications.
 128:  * Additional methods may be added to an extended GSSManager that could
 129:  * be part of a service provider specification that is standardized
 130:  * later.</p>
 131:  *
 132:  * <h3>Example Code</h3>
 133:  *
 134:  * <pre>
 135: GSSManager mgr = GSSManager.getInstance();
 136: 
 137: // What mechs are available to us?
 138: Oid[] supportedMechs = mgr.getMechs();
 139: 
 140: // Set a preference for the provider to be used when support is needed
 141: // for the mechanisms "1.2.840.113554.1.2.2" and "1.3.6.1.5.5.1.1".
 142: 
 143: Oid krb = new Oid("1.2.840.113554.1.2.2");
 144: Oid spkm1 = new Oid("1.3.6.1.5.5.1.1");
 145: 
 146: Provider p = (Provider) (new com.foo.security.Provider());
 147: 
 148: mgr.addProviderAtFront(p, krb);
 149: mgr.addProviderAtFront(p, spkm1);
 150: 
 151: // What name types does this spkm implementation support?
 152: Oid[] nameTypes = mgr.getNamesForMech(spkm1);
 153: </pre>
 154:  */
 155: public abstract class GSSManager
 156: {
 157: 
 158:   // Constructor.
 159:   // -------------------------------------------------------------------------
 160: 
 161:   public GSSManager()
 162:   {
 163:   }
 164: 
 165:   // Class method.
 166:   // -------------------------------------------------------------------------
 167: 
 168:   /**
 169:    * Returns the default GSSManager implementation.
 170:    *
 171:    * @return The default GSSManager implementation.
 172:    */
 173:   public static synchronized GSSManager getInstance()
 174:   {
 175:     String impl = Security.getProperty("org.ietf.jgss.GSSManager");
 176:     if (impl == null)
 177:       impl = "gnu.crypto.gssapi.GSSManagerImpl";
 178:     try
 179:       {
 180:         ClassLoader loader = GSSManager.class.getClassLoader();
 181:         if (loader == null)
 182:           loader = ClassLoader.getSystemClassLoader();
 183:         Class c = loader.loadClass(impl);
 184:         return (GSSManager) c.newInstance();
 185:       }
 186:     catch (Exception x)
 187:       {
 188:         throw new RuntimeException(x.toString());
 189:       }
 190:   }
 191: 
 192:   // Abstract methods.
 193:   // -------------------------------------------------------------------------
 194: 
 195:   /**
 196:    * <p>This method is used to indicate to the GSSManager that the
 197:    * application would like a particular provider to be used if no other
 198:    * provider can be found that supports the given mechanism. When a value
 199:    * of null is used instead of an Oid for the mechanism, the GSSManager
 200:    * must use the indicated provider for any mechanism.</p>
 201:    *
 202:    * <p>Calling this method repeatedly preserves the older settings but
 203:    * raises them above newer ones in preference thus forming an ordered
 204:    * list of providers and Oid pairs that grows at the bottom. Thus the
 205:    * older provider settings will be utilized first before this one is.</p>
 206:    *
 207:    * <p>If there are any previously existing preferences that conflict with
 208:    * the preference being set here, then the GSSManager should ignore this
 209:    * request.</p>
 210:    *
 211:    * <p>If the GSSManager implementation does not support an SPI with a
 212:    * pluggable provider architecture it should throw a GSSException with
 213:    * the status code {@link GSSException#UNAVAILABLE} to indicate that the
 214:    * operation is unavailable.</p>
 215:    *
 216:    * @param p    The provider instance that should be used whenever
 217:    *             support is needed for <i>mech</i>.
 218:    * @param mech The mechanism for which the provider is being set.
 219:    * @throws GSSException If this service is unavailable.
 220:    */
 221:   public abstract void addProviderAtEnd(Provider p, Oid mech)
 222:     throws GSSException;
 223: 
 224:   /**
 225:    * <p>This method is used to indicate to the GSSManager that the
 226:    * application would like a particular provider to be used ahead of all
 227:    * others when support is desired for the given mechanism. When a value
 228:    * of null is used instead of an Oid for the mechanism, the GSSManager
 229:    * must use the indicated provider ahead of all others no matter what
 230:    * the mechanism is. Only when the indicated provider does not support
 231:    * the needed mechanism should the GSSManager move on to a different
 232:    * provider.</p>
 233:    *
 234:    * <p>Calling this method repeatedly preserves the older settings but
 235:    * lowers them in preference thus forming an ordered list of provider
 236:    * and Oid pairs that grows at the top.</p>
 237:    *
 238:    * <p>Calling addProviderAtFront with a null Oid will remove all previous
 239:    * preferences that were set for this provider in the GSSManager
 240:    * instance. Calling addProviderAtFront with a non-null Oid will remove
 241:    * any previous preference that was set using this mechanism and this
 242:    * provider together.</p>
 243:    *
 244:    * <p>If the GSSManager implementation does not support an SPI with a
 245:    * pluggable provider architecture it should throw a GSSException with
 246:    * the status code {@link GSSException#UNAVAILABLE} to indicate that the
 247:    * operation is unavailable.</p>
 248:    *
 249:    * @param p    The provider instance that should be used whenever
 250:    *             support is needed for <i>mech</i>.
 251:    * @param mech The mechanism for which the provider is being set.
 252:    * @throws GSSException If this service is unavailable.
 253:    */
 254:   public abstract void addProviderAtFront(Provider p, Oid mech)
 255:     throws GSSException;
 256: 
 257:   /**
 258:    * Factory method for creating a previously exported context.  The
 259:    * context properties will be determined from the input token and can't
 260:    * be modified through the set methods.
 261:    *
 262:    * @param interProcessToken The token previously emitted from the
 263:    *                          export method.
 264:    * @return The context.
 265:    * @throws GSSException If this operation fails.
 266:    */
 267:   public abstract GSSContext createContext(byte[] interProcessToken)
 268:     throws GSSException;
 269: 
 270:   /**
 271:    * Factory method for creating a context on the acceptor' side.  The
 272:    * context's properties will be determined from the input token supplied
 273:    * to the accept method.
 274:    *
 275:    * @param myCred Credentials for the acceptor.  Use <code>null</code> to
 276:    *               act as a default acceptor principal.
 277:    * @return The context.
 278:    * @throws GSSException If this operation fails.
 279:    */
 280:   public abstract GSSContext createContext(GSSCredential myCred)
 281:     throws GSSException;
 282: 
 283:   /**
 284:    * Factory method for creating a context on the initiator's side.
 285:    * Context flags may be modified through the mutator methods prior to
 286:    * calling {@link
 287:    * GSSContext#initSecContext(java.io.InputStream,java.io.OutputStream)}.
 288:    *
 289:    * @param peer     Name of the target peer.
 290:    * @param mech     Oid of the desired mechanism.  Use <code>null</code>
 291:    *                 to request default mechanism.
 292:    * @param myCred   Credentials of the initiator.  Use <code>null</code>
 293:    *                 default initiator principal.
 294:    * @param lifetime The request lifetime, in seconds, for the context.
 295:    *                 Use {@link GSSContext#INDEFINITE_LIFETIME} and
 296:    *                 {@link GSSContext#DEFAULT_LIFETIME} to request
 297:    *                 indefinite or default context lifetime.
 298:    * @return The context.
 299:    * @throws GSSException If this operation fails.
 300:    */
 301:   public abstract GSSContext createContext(GSSName peer, Oid mech,
 302:                                            GSSCredential myCred, int lifetime)
 303:     throws GSSException;
 304: 
 305:   /**
 306:    * Factory method for acquiring default credentials.  This will cause
 307:    * the GSS-API to use system specific defaults for the set of
 308:    * mechanisms, name, and a DEFAULT lifetime.
 309:    *
 310:    * @param usage The intended usage for this credential object.  The
 311:    *              value of this parameter must be one of:
 312:    *              {@link GSSCredential#ACCEPT_AND_INITIATE},
 313:    *              {@link GSSCredential#ACCEPT_ONLY},
 314:    *              {@link GSSCredential#INITIATE_ONLY}.
 315:    * @return The credential.
 316:    * @throws GSSException If this operation fails.
 317:    */
 318:   public abstract GSSCredential createCredential(int usage) throws GSSException;
 319: 
 320:   /**
 321:    * Factory method for acquiring a single mechanism credential.
 322:    *
 323:    * @param aName    Name of the principal for whom this credential is to
 324:    *                 be acquired.  Use <code>null</code> to specify the
 325:    *                 default principal.
 326:    * @param lifetime The number of seconds that credentials should remain
 327:    *                 valid.  Use {@link GSSCredential#INDEFINITE_LIFETIME}
 328:    *                 to request that the credentials have the maximum
 329:    *                 permitted lifetime.  Use {@link
 330:    *                 GSSCredential#DEFAULT_LIFETIME} to request default
 331:    *                 credential lifetime.
 332:    * @param mech     The oid of the desired mechanism.  Use <code>null</code>
 333:    *                 to request the default mechanism(s).
 334:    * @param usage    The intended usage for this credential object.  The
 335:    *                 value of this parameter must be one of:
 336:    *                 {@link GSSCredential#ACCEPT_AND_INITIATE},
 337:    *                 {@link GSSCredential#ACCEPT_ONLY},
 338:    *                 {@link GSSCredential#INITIATE_ONLY}.
 339:    * @return The credential.
 340:    * @throws GSSException If this operation fails.
 341:    */
 342:   public abstract GSSCredential createCredential(GSSName aName, int lifetime,
 343:                                                  Oid mech, int usage)
 344:     throws GSSException;
 345: 
 346:   /**
 347:    * Factory method for acquiring credentials over a set of mechanisms.
 348:    * Acquires credentials for each of the mechanisms specified in the
 349:    * array called mechs.  To determine the list of mechanisms' for which
 350:    * the acquisition of credentials succeeded, the caller should use the
 351:    * {@link GSSCredential#getMechs()} method.
 352:    *
 353:    * @param aName    Name of the principal for whom this credential is to
 354:    *                 be acquired.  Use <code>null</code> to specify the
 355:    *                 default principal.
 356:    * @param lifetime The number of seconds that credentials should remain
 357:    *                 valid.  Use {@link GSSCredential#INDEFINITE_LIFETIME}
 358:    *                 to request that the credentials have the maximum
 359:    *                 permitted lifetime.  Use {@link
 360:    *                 GSSCredential#DEFAULT_LIFETIME} to request default
 361:    *                 credential lifetime.
 362:    * @param mechs    The array of mechanisms over which the credential is
 363:    *                 to be acquired.  Use <code>null</code> for requesting
 364:    *                 a system specific default set of mechanisms.
 365:    * @param usage    The intended usage for this credential object.  The
 366:    *                 value of this parameter must be one of:
 367:    *                 {@link GSSCredential#ACCEPT_AND_INITIATE},
 368:    *                 {@link GSSCredential#ACCEPT_ONLY},
 369:    *                 {@link GSSCredential#INITIATE_ONLY}.
 370:    * @return The credential.
 371:    * @throws GSSException If this operation fails.
 372:    */
 373:   public abstract GSSCredential createCredential(GSSName aName, int lifetime,
 374:                                                  Oid[] mechs, int usage)
 375:     throws GSSException;
 376: 
 377:   /**
 378:    * Factory method to convert a contiguous byte array containing a name
 379:    * from the specified namespace to a {@link GSSName} object.  In general,
 380:    * the {@link GSSName} object created will not be an MN; two examples that
 381:    * are exceptions to this are when the namespace type parameter indicates
 382:    * {@link GSSName#NT_EXPORT_NAME} or when the GSS-API implementation is not
 383:    * multi-mechanism.
 384:    *
 385:    * @param name     The byte array containing the name to create.
 386:    * @param nameType The Oid specifying the namespace of the name supplied
 387:    *                 in the byte array.  Note that nameType serves to
 388:    *                 describe and qualify the interpretation of the input
 389:    *                 name byte array, it does not necessarily imply a type
 390:    *                 for the output GSSName implementation. "null" value
 391:    *                 can be used to specify that a mechanism specific
 392:    *                 default syntax should be assumed by each mechanism
 393:    *                 that examines the byte array.
 394:    * @return The name.
 395:    * @throws GSSException If this operation fails.
 396:    */
 397:   public abstract GSSName createName(byte[] name, Oid nameType)
 398:     throws GSSException;
 399: 
 400:   /**
 401:    * Factory method to convert a contiguous byte array containing a name
 402:    * from the specified namespace to a GSSName object that is an MN.  In
 403:    * other words, this method is a utility that does the equivalent of two
 404:    * steps: {@link #createName(byte[],org.ietf.jgss.Oid)} and then also
 405:    * {@link GSSName#canonicalize(org.ietf.jgss.Oid)}.
 406:    *
 407:    * @param name     The byte array representing the name to create.
 408:    * @param nameType The Oid specifying the namespace of the name supplied
 409:    *                 in the byte array.  Note that nameType serves to
 410:    *                 describe and qualify the interpretation of the input
 411:    *                 name byte array, it does not necessarily imply a type
 412:    *                 for the output GSSName implementation. "null" value
 413:    *                 can be used to specify that a mechanism specific
 414:    *                 default syntax should be assumed by each mechanism
 415:    *                 that examines the byte array.
 416:    * @param mech     Oid specifying the mechanism for which this name
 417:    *                 should be created.
 418:    * @return The name.
 419:    * @throws GSSException If this operation fails.
 420:    */
 421:   public abstract GSSName createName(byte[] name, Oid nameType, Oid mech)
 422:     throws GSSException;
 423: 
 424:   /**
 425:    * Factory method to convert a contiguous string name from the specified
 426:    * namespace to a {@link GSSName} object.  In general, the {@link GSSName}
 427:    * object created will not be an MN; two examples that are exceptions to
 428:    * this are when the namespace type parameter indicates {@link
 429:    * GSSName#NT_EXPORT_NAME} or when the GSS-API implementation is not
 430:    * multi-mechanism.
 431:    *
 432:    * @param nameStr  The string representing a printable form of the name
 433:    *                 to create.
 434:    * @param nameType The Oid specifying the namespace of the printable name
 435:    *                 supplied. Note that nameType serves to describe and
 436:    *                 qualify the interpretation of the input nameStr, it
 437:    *                 does not necessarily imply a type for the output
 438:    *                 GSSName implementation. "null" value can be used to
 439:    *                 specify that a mechanism specific default printable
 440:    *                 syntax should be assumed by each mechanism that
 441:    *                 examines nameStr.
 442:    * @return The name.
 443:    * @throws GSSException If this operation fails.
 444:    */
 445:   public abstract GSSName createName(String nameStr, Oid nameType)
 446:     throws GSSException;
 447: 
 448:   /**
 449:    * Factory method to convert a contiguous string name from the specified
 450:    * namespace to an GSSName object that is a mechanism name (MN).  In
 451:    * other words, this method is a utility that does the equivalent of two
 452:    * steps: the {@link #createName(java.lang.String,org.ietf.jgss.Oid)}
 453:    * and then also {@link GSSName#canonicalize(org.ietf.jgss.Oid)}.
 454:    *
 455:    * @param nameStr  The string representing a printable form of the name
 456:    *                 to create.
 457:    * @param nameType The Oid specifying the namespace of the printable name
 458:    *                 supplied.  Note that nameType serves to describe and
 459:    *                 qualify the interpretation of the input nameStr, it
 460:    *                 does not necessarily imply a type for the output
 461:    *                 GSSName implementation. "null" value can be used to
 462:    *                 specify that a mechanism specific default printable
 463:    *                 syntax should be assumed when the mechanism examines
 464:    *                 nameStr.
 465:    * @param mech     Oid specifying the mechanism for which this name
 466:    *                 should be created.
 467:    * @return The name.
 468:    * @throws GSSException If this operation fails.
 469:    */
 470:   public abstract GSSName createName(String nameStr, Oid nameType, Oid mech)
 471:     throws GSSException;
 472: 
 473:   /**
 474:    * Returns an array of {@link Oid} objects indicating mechanisms available
 475:    * to GSS-API callers.  A <code>null</code> value is returned when no
 476:    * mechanism are available (an example of this would be when mechanism are
 477:    * dynamically configured, and currently no mechanisms are installed).
 478:    *
 479:    * @return The array of available mechanisms, or <code>null</code>.
 480:    */
 481:   public abstract Oid[] getMechs();
 482: 
 483:   /**
 484:    * Returns an array of {@link Oid} objects corresponding to the mechanisms
 485:    * that support the specific name type. <code>null</code> is returned when
 486:    * no mechanisms are found to support the specified name type.
 487:    *
 488:    * @param name The Oid object for the name type.
 489:    * @return The array of mechanisms, or <code>null</code>.
 490:    */
 491:   public abstract Oid[] getMechsForName(Oid name);
 492: 
 493:   /**
 494:    * Returns name type Oid's supported by the specified mechanism.
 495:    *
 496:    * @param mechanism The Oid object for the mechanism to query.
 497:    * @return The name type Oid's supported by the mechanism.
 498:    * @throws GSSException If this operation fails.
 499:    */
 500:   public abstract Oid[] getNamesForMech(Oid mechanism) throws GSSException;
 501: }