001 /* GSSManager.java -- manager class for the GSS-API. 002 Copyright (C) 2004 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. 037 038 The documentation comments of this class are derived from the text 039 of RFC 2853: Generic Security Service API Version 2: Java Bindings. 040 That document is covered under the following license notice: 041 042 Copyright (C) The Internet Society (2000). All Rights Reserved. 043 044 This document and translations of it may be copied and furnished to 045 others, and derivative works that comment on or otherwise explain it 046 or assist in its implementation may be prepared, copied, published and 047 distributed, in whole or in part, without restriction of any kind, 048 provided that the above copyright notice and this paragraph are 049 included on all such copies and derivative works. However, this 050 document itself may not be modified in any way, such as by removing 051 the copyright notice or references to the Internet Society or other 052 Internet organizations, except as needed for the purpose of developing 053 Internet standards in which case the procedures for copyrights defined 054 in the Internet Standards process must be followed, or as required to 055 translate it into languages other than English. 056 057 The limited permissions granted above are perpetual and will not be 058 revoked by the Internet Society or its successors or assigns. 059 060 This document and the information contained herein is provided on an 061 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 062 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT 063 NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN 064 WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 065 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ 066 067 068 package org.ietf.jgss; 069 070 import java.security.Provider; 071 import java.security.Security; 072 073 /** 074 * <p>The GSSManager class is an abstract class that serves as a factory 075 * for three GSS interfaces: {@link GSSName}, {@link GSSCredential}, and 076 * {@link GSSContext}. It also provides methods for applications to determine 077 * what mechanisms are available from the GSS implementation and what 078 * nametypes these mechanisms support. An instance of the default GSSManager 079 * subclass may be obtained through the static method {@link #getInstance()}, 080 * but applications are free to instantiate other subclasses of GSSManager.</p> 081 * 082 * <p>All but one method in this class are declared abstract. This means 083 * that subclasses have to provide the complete implementation for those 084 * methods. The only exception to this is the static method {@link 085 * #getInstance()} which will have platform specific code to return an 086 * instance of the default subclass.</p> 087 * 088 * <p>Platform providers of GSS are required not to add any constructors to 089 * this class, private, public, or protected. This will ensure that all 090 * subclasses invoke only the default constructor provided to the base 091 * class by the compiler.</p> 092 * 093 * <p>A subclass extending the GSSManager abstract class may be implemented 094 * as a modular provider based layer that utilizes some well known 095 * service provider specification. The GSSManager API provides the 096 * application with methods to set provider preferences on such an 097 * implementation. These methods also allow the implementation to throw 098 * a well-defined exception in case provider based configuration is not 099 * 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 }