Internet-Draft M. Smith Common Authentication technology WG TIAA-CREF April 1999 Expires: September 1, 1999 A Service Provider API for GSS mechanisms in Java 1. Status of this Memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet- Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. 2. Abstract This document specifies a "provider API" by which GSS mechanisms implemented in Java can be accessed through an intermediate "broker" or "shim" layer. 3. Acknowledgments This document is the result of work done in the Common Authentication Technology (CAT) working group of the IETF. Special thanks are due to Mayank Upadhyay and Jack Kabat. Thanks also are due to John Linn for helpful comments on a preliminary version of this document. All errors and imbecilities, of course, remain the author's own. Smith Document Expiration: 1 Sept 1999 [Page 1] Java-GSS Service Provider API April 1999 4. Introduction The Generic Security Service API (GSS-API)[1], a product of the CAT working group, specifies a language- and mechanism-independent interface by which application programs can use security services (e.g. authentication and privacy). Companion documents specify "language bindings" of the abstract GSS-API to particular languages. For the Java language binding, it seems appropriate to define a GSS implementation consisting of a "shim" or "broker" layer, providing no security services itself. Actual security services would be provided by mechanism implementations ("providers"). These providers would register themselves with the "shim" layer, and be accessed by the shim layer through a "provider" API. This document specifies the interfaces between the "shim" layer and the mechanism provider implementations. The interface exposed by the shim layer to application programs consists of the Java GSS binding; the proposal for that binding referenced in this document is described in [2]. A slightly different proposal may be found in [3]. The interfaces of the Java-GSS binding remain the object of ongoing work; this document will be aligned with the final state of those interfaces when the various proposals under discussion have converged. It is not expected that this alignment will involve changes to this document above the level of detail. 5. The shim layer 5.1. Name The shim layer will consist of a Java "package" named org.ietf.GSS.GSSShim. This package will include classes implementing the interfaces defined in [2], and the classes described in section 5.2 below. 5.2. Classes required The package org.ietf.GSS.GSSShim must include the following classes: public class GSSShimException extends java.lang.Exception; public class GSSShimManager; public class GSSShimName implements GSSname; public class GSSShimCredential implements GSSCredential; Smith Document Expiration: 1 Sept 1999 [Page 2] Java-GSS Service Provider API April 1999 5.2.1. GSSShimException 5.2.1.1. Class constants The class org.ietf.GSS.GSSShimException must define the following constants: static public short GSSMechanismAlreadyRegistered static public short GSSShimFailureOther static public short GSSMechanismNotRegistered 5.2.1.2. Methods The class org.ietf.GSS.GSSShimException must implement the following methods: public short getFailureCode() 5.2.2. GSSShimManager 5.2.2.1. Methods The class org.ietf.GSS.GSSShim.GSSShimManager must implement methods with the signatures public static void register(GSSProviderImplementation) throws GSSShimException; public static void unregister(GSSOIDString) throws GSSShimException; public static void setDefault(GSSOIDString) throws GSSShimException; public static void setDefault() throws GSSShimException; public static GSSProviderImplementation getProvider(GSSOIDString) throws GSSShimException; See section 6.2.1 below for the interface GSSProviderImplementation. See [2] for the class GSSOIDString. Smith Document Expiration: 1 Sept 1999 [Page 3] Java-GSS Service Provider API April 1999 5.2.3. GSSShimName implements GSSMechName GSSShimName must be able to serve as a container class for one (or more) objects of type GSSProviderName (v. 6.2.2 below) and mediate the methods defined in GSSMechName[2] to methods of GSSProviderName. 5.2.3.1. Methods 5.2.3.1.1. public GSSShimName(GSSProviderName) GSSShimName must provide a constructor which takes as parameter an object implementing the interface GSSProviderName (see 6.2.2 below). 5.2.4. GSSShimCredential implements GSSCredential GSSShimCredential must be able to serve as a container class for one (or more) objects of type GSSProviderCredential (see 6.2.3) and mediate the methods defined in GSSCredential[2] to methods of GSSProviderCredential. 5.2.4.1. Methods 5.2.4.1.1. public GSSShimCredential(GSSProviderCredential) GSSShimCredential must provide a constructor which takes as parameter an object implementing the interface GSSProviderCredential (see 6.2.3 below). 5.3. Provider registration A mechanism provider is registered with the shim by calling the method org.ietf.GSS.GSSShimManager.register() with a reference to a class instance implementing the interface GSSProviderImplementation (see section 6.2.1 below). The method returns silently if the implementation was successfully registered; otherwise a GSSShimException is thrown. The method register() will call the GSSProviderImplementation object's indicateMechs() method to determine what mechanism the object implements. If an implementation is already registered for that method, GSSShimException will be thrown, and the GSSShimException's getFailureCode() method will return the value GSSMechanismAlreadyRegistered. Registrations unsuccessful for any Smith Document Expiration: 1 Sept 1999 [Page 4] Java-GSS Service Provider API April 1999 other reason will throw a GSSShimException whose getFailureCode() method will return the value GSSShimFailureOther. A provider may be "unregistered" by calling the method unregister() with the mechanism OID. 5.4. Setting the default mechanism GSS has a notion of a "default" mechanism, which is the one used by a GSS implementation for applications which do not request a specific mechanism. The default mechanism used by the shim layer is set by calling the method setDefault with the OID string of the mechanism to be used. A provider must already have been registered for this mechanism; if not, a GSSShimException will be thrown whose getFailureCode() method will return the value GSSMechanismNotRegistered. The default mechanism may be "unset" by calling setDefault without a parameter. Unless the default is explicitly set, the shim layer has no default mechanism, and GSS calls which do not specify a mechanism will fail with a major status of GSS_S_BAD_MECH. 6. The provider layer 6.1. Classes and interfaces referenced Classes and interfaces referred to but not defined in this section are defined in [2]. 6.2. Interfaces of the provider layer Generally speaking, a mechanism implementation at the provider layer looks very much like a single-mechanism GSS implementation, with certain limitations and extensions. Such an implementation must implement the three interfaces described below, and the interface GSSSecurityContext from [2]. Each of the three interfaces defined in this section resembles an interface defined in [2] (its "model"), and provides most of the same methods as the model interface. However, because the GSS objects themselves are designed, in general, to encapsulate multiple mechanisms, and the interfaces at the provider layer are designed only in encapsulate a single mechanism, the signatures of the methods Smith Document Expiration: 1 Sept 1999 [Page 5] Java-GSS Service Provider API April 1999 in the SPI package will in many cases be different, as regards the number and type of parameters, the return value, and sometimes the repertoire of exceptions generated. Thus it is not appropriate for the interfaces described in this document to "extend" (in the technical, Java sense) their model interfaces in [2]. GSSSecurityContext, however, contains no methods presupposing multi- mechanism functionality, and thus can be implemented directly by the mechanism provider. It also seems desirable from the standpoint of performance to minimize the code path length for the relatively often-called methods of GSSSecurityContext, and thus to permit a mechanism to return an unmediated GSSSecurityContext directly to application code upon context creation, which involves narrowing to a specific mechanism in any case. The container classes GSSShimName and GSSShimCredential are provided so that mechanism implementations can return objects implementing the GSSName and GSSCredential interfaces directly to calling applications. For the sake of brevity, and to avoid duplication, the semantics of methods in the provider interfaces will be described only to the extent that they differ from the methods with the same names in the model interfaces. Methods which do not differ as to signature, functionality, or exception generation will not be re-described here. 6.2.1. GSSProviderImplementation (model: GSSImplementation) 6.2.1.1. Extensions to GSSImplementation In addition to the methods defined in [2] for GSSImplementation, implementations of this interface must provide the following additional methods. 6.2.1.1.1. No-parameter constructor Classes that implement GSSProviderImplementation must provide a no- parameter constructor. 6.2.1.1.2. public boolean acceptable(Object); This method indicates whether the Object passed as the parameter is usable by the implementing mechanism as a context-establishment token. It is intended to be used by the getContextForAccept() method of the shim layer in determining which of the registered mechanism implementations to use when a context-establishment token is submitted and a context is to be initially created. Smith Document Expiration: 1 Sept 1999 [Page 6] Java-GSS Service Provider API April 1999 6.2.1.2. Methods of GSSProviderImplementation different from those of the model 6.2.1.2.1. acquireCredential GSSProviderImplementation defines two versions of this method: GSSProviderCredential acquireCredential(int lifetimeReq, int credentialUsage) GSSProviderCredential acquireCredential(GSSProviderName, int lifetimeReq, int credentialUsage) The first version returns a credential corresponding to the default identity for this mechanism, the second for an explicit identity, which must be a GSSProviderName rather than a GSSName. This method differs from its model in not allowing a parameter specifying the mechanism to be used. 6.2.1.2.2. getContextForInit() The model class provides three versions of this call: GSSSecurityContext getContextForInit(GSSName targname) GSSSecurityContext getContextForInit(GSSName targname, GSSCredential cred) GSSSecurityContext getContextForInit(GSSName targname, GSSCredential cred, GSSOIDstring mech) Since GSSProviderImplementation is not multi-mechanism, no equivalent is provided for the third of these. For the first two, a GSSProviderName replaces the GSSName, and for the second, a GSSProviderCredential replaces the GSSCredential. 6.2.1.2.3. GSSProviderCredential GSS_C_NO_CREDENTIAL() This method differs from its model in returning a GSSProviderCredential rather than a GSSCredential. 6.2.1.2.4. GSSProviderName GSS_C_NO_NAME() This method differs from its model in returning a GSSProviderName rather than a GSSName. Smith Document Expiration: 1 Sept 1999 [Page 7] Java-GSS Service Provider API April 1999 6.2.1.2.5. GSSProviderName importName(byte[] externalrep, GSSOIDString nametype) This method differs from its model in returning a GSSProviderName rather than a GSSName. 6.2.1.2.6. GSSOIDString[] inquireNamesForMech() This method differs from its model in not allowing a parameter specifying the mechanism to be used. 6.2.2. GSSProviderName (model: GSSMechName) 6.2.2.1. Methods of GSSMechName omitted from GSSProviderName 6.2.2.1.1. canonicalize() There is no canonicalize() method, since a GSSProviderName is not multi-mechanism. 6.2.2.2. Other methods All other methods of GSSProviderName are identical with those of its model. 6.2.3. GSSProviderCredential (model: GSSCredential) 6.2.3.1. Methods of GSSCredential omitted from GSSProviderCredential 6.2.3.1.1. addCredential The method addCredential of the model is not implemented for GSSProviderCredential since the latter is not multi-mechanism. 6.2.3.1.2. addCredentialInPlace The method addCredentialInPlace of the model is not implemented for GSSProviderCredential since the latter is not multi-mechanism. 6.2.3.1.3. getName(GSSOIDString mechoid) The version of the getName method which takes an OID designating the mechanism is not provided by GSSproviderCredential, although the no- parameter version is (see section 6.2.3.2.3 below). Smith Document Expiration: 1 Sept 1999 [Page 8] Java-GSS Service Provider API April 1999 6.2.3.1.4. getUsage(GSSOIDString mechoid) The version of the getUsage method which takes an OID designating the mechanism is not provided by GSSproviderCredential, although the no- parameter version is. 6.2.3.2. Methods of GSSProviderCredential different from those of the model 6.2.3.2.1. getLifetimeAccept() This method differs from the model in not taking a parameter designating the mechanism. 6.2.3.2.2. getLifetimeInitiate() This method differs from the model in not taking a parameter designating the mechanism. 6.2.3.2.3. GSSProviderName getName() This method differs from its model in returning a GSSProviderName rather than a GSSName. 7. Implications for the GSS-API binding In the course of elaborating this proposal, it became apparent that the provider API could be made cleaner and more efficient if certain adjustments were made to the binding originally devised for the GSS- API itself. In particular, it is a requirement that a mechanism be chosen at the time a context is created; this semantic requirement of abstract GSS is reinforced by the desire to return, from the context creation process, a direct implementation of GSSSecurityContext rather than a "container" class, implemented in the shim layer, and holding provider security context objects, which in turn would implement some provider interface modelled on GSSSecurityContext but not identical with it. That is, it seemed preferable not to follow the analogy of GSSName/GSSProviderName, GSSCredential/GSSProviderCredential, and GSSImplementation/GSSProviderImplementation in the case of GSSSecurityContext, but to permit mechanisms to implement the latter interface directly. The original Java binding interfaces devised by the present author [2] proved to be unsatisfactory for this purpose, since they defined Smith Document Expiration: 1 Sept 1999 [Page 9] Java-GSS Service Provider API April 1999 methods which created a GSSSecurityContext object without having available the information (credential, target name, etc.) which would permit a multi-mechanism implementation to pick a mechanism appropriately; this information was to be made available to the context using "set" methods after its creation but before its init() or accept() methods were called. Actual mechanism choice was to have been made at the time init() or accept() were called on the context. In order to ensure that the information needed for mechanism choice is available at the time a context is created, the interfaces referred to in [2] have been revised so that the methods of GSSImplementation which create and return a context object (getContextFor Init() and getContextForAccept()) take parameters which will permit the implementation (in this case, the shim) to select an appropriate mechanism. 8. Topics for further discussion 8.1. Default management The procedure for defining a single, global default mechanism to be used by the shim (see 5.4 above) is arguably too restrictive; as John Linn recently observed on the CAT WG's mailing list, "In general [...] the operation to determine what concrete mechanism a GSS request for 'default' will map to can be deferred until context establishment time. This allows an implementation to take advantage of other information then available (e.g., initiator identity, contents of presented credentials, target of context request) to apply local policy and resolve 'default' accordingly. [....] Therefore, [...] the value resolved for 'default' may differ for different prospective contexts." Perhaps it is sufficient to indicate that the "default" mechanism configured by the technique in 5.4 above will be used absent any other factor in the parameters supplied, but is not guaranteed to be the actual default mechanism used in every case where a mechanism is not explicitly indicated. 8.2. SPNEGO One early reader of this document has raised the question whether SPNEGO should be regarded as "just another mechanism provider," or be included in the shim implementation. Either approach is possible with the interfaces defined in this document. In favor of including SPNEGO in the shim are arguments from performance and interoperability. On the opposite side of the question is the desire to minimize the size Smith Document Expiration: 1 Sept 1999 [Page 10] Java-GSS Service Provider API April 1999 and complexity of the shim. The author sees no clear-cut case for either approach; comments are sought from interested parties. 9. Security Considerations This entire document deals with security. 10. Conclusion This document specifies a "provider API" by which GSS mechanisms implemented in Java can be accessed through an intermediate "broker" or "shim" layer. 11. References [1] RFC 2078, The Generic Security Services API, Version 2. [2] A Java GSS binding (work in progress): [3] Jack Kabat, "Generic Security Service API Version 2 : Java bind- ings," Internet-Draft, , August 1998 12. Author's Address Michael Smith TIAA-CREF 730 Third Avenue Mailstop 485-27-02 New York, NY 10017 USA Phone: 212 490 9000 x 1760 Email: ms@gf.org Smith Document Expiration: 1 Sept 1999 [Page 11]