Network Working Group                                        Rob Weltman
INTERNET-DRAFT                             Netscape Communications Corp.
                                                             Rosanna Lee
                                                        Sun Microsystems
                                                             March, 2000


              The Java SASL Application Program Interface
                     draft-weltman-java-sasl-03.txt


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 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.


Abstract

   This document defines a client-side and a server-side Java language
   interface for using the Simple Authentication and Security Layer
   (SASL) mechanisms for adding authentication support to connection-
   based protocols. The interface promotes sharing of SASL mechanism
   drivers and security layers between applications using different
   protocols. It complements but does not replace [SASL], which defines
   and exemplifies use of the SASL protocol in a language-independent
   way.













Expires September 2000                                        [Page 1]

JAVA SASL API                                              March, 2000



1.    Introduction....................................................3
2.    Overview of the SASL classes....................................5
2.1   Interfaces.....................................................5
2.2   Classes........................................................6
3.    Overview of SASL API Use........................................6
4.    The Java SASL classes...........................................7
4.1   public class Sasl..............................................7
4.1.1    createSaslClient............................................7
4.1.2    setSaslClientFactory........................................9
4.1.3    createSaslServer...........................................10
4.1.4    setSaslServerFactory.......................................11
4.2   public interface SaslClient...................................11
4.2.1    evaluateChallenge..........................................12
4.2.2    hasInitialResponse.........................................12
4.2.3    isComplete.................................................12
4.2.4    getInputStream.............................................13
4.2.5    getOutputStream............................................13
4.2.6    getMechanismName...........................................13
4.3   public interface SaslClientFactory............................14
4.3.1    createSaslClient...........................................14
4.3.2    getMechanismNames..........................................15
4.4   public interface SaslServer...................................15
4.4.1    evaluateResponse...........................................15
4.4.2    isComplete.................................................16
4.4.3    getInputStream.............................................16
4.4.4    getOutputStream............................................16
4.4.5    getMechanismName...........................................17
4.4.6    getAuthorizationID.........................................17
4.5   public interface SaslServerFactory............................17
4.5.1    createSaslServer...........................................17
4.5.2    getMechanismNames..........................................18
4.6   public class SaslException extends IOException................19
4.6.1    Constructors...............................................19
4.6.2    getException...............................................19
4.6.3    printStackTrace............................................20
5.    Security Considerations........................................20
6.    Copyright......................................................20
7.    Bibliography...................................................21
8.    Author's Addresses.............................................21
9.    Acknowledgements...............................................21
10.   Changes from draft-weltman-java-sasl-02.txt....................22
10.1  SecurityLayer.................................................22
10.2  SaslClient....................................................22
10.3  SaslClient and SaslServer.....................................22
11.   Appendix A - Sample Java LDAP program using SASL...............23








Expires September 2000                                         [Page 2

JAVA SASL API                                              March, 2000


1. Introduction

   See [SASL], section 3, for an introduction to and overview of the
   SASL framework for authentication and negotiation of a security
   layer. The following presents an outline of the concepts.

       ---------------     -------------------      -----------------
       | Application |-----| Protocol Driver |------| MD5           |
       ---------------     -------------------   |  -----------------
                                                 |
                                                 |  -----------------
                                                 |--| Kerberos v5   |
                                                 |  -----------------
                                                 |
                                                 |  -----------------
                                                 |--| PKCS-11       |
                                                 |  -----------------
                                                 |
                                                 |
                                                 |
                                                 |  - - - - - - - - -
                                                 |--| xxxYYYxxx     |
                                                    - - - - - - - - -

   An application chooses a Protocol Driver specific to the protocol it
   wants to use, and specifies one or more acceptable mechanisms. The
   Protocol Driver controls the socket, and knows the format/packaging
   of bytes sent down and received from the socket, but does not know
   how to authenticate or to encrypt/ decrypt the bytes. It uses one of
   the Mechanism Drivers to help it perform authentication. The Protocol
   Driver examines each byte string received from the server during the
   authentication in a protocol-specific way to determine if the
   authentication process has been completed. If not, the byte string is
   passed to the Mechanism Driver to be interpreted as a server
   challenge; the Mechanism Driver returns an appropriate response,
   which the Protocol Driver can encode in a protocol-specific way and
   return to the server.

   If the Protocol Driver concludes from the byte string received from
   the server that authentication is complete, it may query the
   Mechanism Driver if it considers the authentication process complete,
   in order to thwart early completion messages inserted by an intruder.

   On completed authentication, the Protocol Driver may receive from the
   Mechanism Driver input and output streams that encapsulate the
   negotiated security layer. From this point on, any data exchanged
   through the socket is passed to these input and output streams.

   A complication here is that some authentication methods may require
   additional user/application input.  That means that a Mechanism
   Driver may need to call up to an application during the
   authentication process. To satisfy this requirement, the application
   can supply a javax.security.auth.callback.CallbackHandler instance

Expires September 2000                                         [Page 3

JAVA SASL API                                              March, 2000


   [JAAS] that can be used by the Mechanism Driver to prompt the user
   for additional input.

   Protocol Drivers are protocol-dependent, and may be built in to a
   protocol package or an application. There is a generalized framework
   for registering and finding Mechanism Drivers. The framework uses a
   factory to produce an appropriate Mechanism Driver. The factory may
   be preconfigured, explicitly specified by the caller, specified as a
   list of packages by the caller, or be identified based on a list of
   packages in the System properties.

   The Mechanism Drivers are protocol-independent, and don't deal
   directly with network connections, just byte arrays, so they can be
   implemented in a generalizable way for all protocols.

   The negotiated security layer is encapsulated in input and output
   streams, which typically inherit a state object from the
   Mechanism Driver, where parameters and resolutions reached during
   authentication have been stored.

   Different Mechanism Drivers may require different parameters to carry
   out the authentication process. This is handled by passing a
   java.util.Hashtable object as an argument to instantiation methods.

   In the following discussion, 'client' refers to the client-side
   protocol driver that is using the SASL mechanism while 'server'
   refers to the server-side protocol driver that is using the SASL
   mechanism.


























Expires September 2000                                         [Page 4

JAVA SASL API                                              March, 2000


   In the Java SASL environment, the SaslClient interface represents the
   client's view of the Mechanism Driver, while the SaslServer interface
   represents the server's view.

   ---------------                                     ---------------
   | Application |--+                               +--|   Server    |
   ---------------  |                               |  ---------------
                    |                               |
       -------------------                       -------------------
       | Protocol Driver |--+   <- - - - ->   +--| Protocol Driver |
       -------------------  |                 |  -------------------
                            |                 |
                 -------------------     -------------------
                 |   SaslClient    |     |    SaslServer   |
                 -------------------     -------------------
                               |              |
          -----------------    |              |   -----------------
          | MD5           |----|              |---| MD5           |
          -----------------    |              |   -----------------
                               |              |
          -----------------    |              |   -----------------
          | Kerberos v5   |----|              |---| Kerberos v5   |
          -----------------    |              |   -----------------
                               |              |
          -----------------    |              |   -----------------
          | PKCS-11       |----|              |---| PKCS-11       |
          -----------------    |              |   -----------------
                               |              |
          - - - - - - - - -    |              |   - - - - - - - - -
          | xxxYYYxxx     |----+              +---| xxxYYYxxx     |
          - - - - - - - - -                       - - - - - - - - -

   A client using the Java SASL API may communicate with any server
   implementing the SASL protocol, and a server may use the API to
   process authentication requests from any client using the SASL
   protocol. It is not required that both sides use the same language
   bindings.


2. Overview of the SASL classes


2.1 Interfaces


   SaslClient                  Performs SASL authentication as a
                               client.

   SaslClientFactory           An interface for creating instances of
                               SaslClient. It is not normally accessed
                               directly by a client, which will use the
                               Sasl static methods instead. However, a
                               particular environment may provide and


Expires September 2000                                         [Page 5

JAVA SASL API                                              March, 2000


                               install a new or different
                               SaslClientFactory.

   SaslServer                  Performs SASL authentication as a
                               server.

   SaslServerFactory           An interface for creating instances of
                               SaslServer. It is not normally accessed
                               directly by a server, which will use the
                               Sasl static methods instead. However, a
                               particular environment may provide and
                               install a new or different
                               SaslServerFactory.


2.2 Classes



   Sasl                        A static class for creating SASL clients
                               and servers. It transparently locates
                               and uses any available
                               SaslClientFactory/SaslServerFactory
                               instances.


   SaslException               Exception thrown on errors and failures
                               in the authentication process.




3. Overview of SASL API Use

   An application generally uses the SASL API as follows:

   -    Pass a list of acceptable or known Mechanisms to
        Sasl.createSaslClient. The method returns an object
        implementing SaslClient on success.

   -    Create an object implementing the client authentication
        callback interfaces, which can provide credentials when
        required by the SaslClient.

   -    Have the SaslClient object begin the authentication process by
        providing an initial server response, if the protocol supports
        an initial response.

   -    Responses/challenges are exchanged with the server. If a
        response indicates authentication has completed, SaslClient is
        queried for validation, and input and output streams that
        encapsulate the negotiated security layer may be obtained from
        it. If not, the SaslClient is queried for an appropriate next


Expires September 2000                                         [Page 6

JAVA SASL API                                              March, 2000


        response to the server. This continues until authentication has
        completed.

   -    For the rest of the session, messages to the server are written
        to the output stream which encodes the data (if a security
        layer has been negotiated), and  messages from the server are
        read from the input stream which decodes the data before
        processing in the application.


   A server generally uses the SASL API as follows:

   -    It receives a request from the client requesting authentication
        for a particular SASL mechanism, accompanied by an optional
        initial response.

   -    It processes the initial response and generates a challenge
        specific for the SASL mechanism to be sent back to the client
        if the response is processed successfully. If the response is
        not processed successfully, it sends an error to the client and
           terminates the authentication session.

   -    Responses/challenges are exchanged with the client. If the
        server cannot successful process a response, the server sends
        an error to the client and terminates the authentication. If
        the server has completed the authentication and has no more
        challenges to send, it sends a success indication to the
        client.

   -    If the authentication has completed successfully, the server
        extracts the authorization ID of the client from the SaslServer
        instance (if appropriate) to be used for subsequent access
        control checks.

   -    For the rest of the session, messages to and from the client are
        encoded and decoded using the input and output streams that
        encapsulate the negotiated security layer (if any).

      The following sections describe the SASL classes in more detail.


4. The Java SASL classes


4.1 public class Sasl


A class capable of providing a SaslClient or SaslServer.


4.1.1 createSaslClient


   public static SaslClient


Expires September 2000                                         [Page 7

JAVA SASL API                                              March, 2000


   createSaslClient(String[] mechanisms,
                    String authorizationID,
                    String protocol,
                    String serverName,
                    Hashtable props,
                    javax.security.auth.callback.CallbackHandler cbh)
                    throws SaslException

   Creates a SaslClient using the parameters supplied. It returns null
   if no SaslClient can be created using the parameters supplied. Throws
   SaslException if it cannot create a SaslClient because of an error.

   The algorithm for selection is as follows:

   1. If a factory has been installed via setSaslClientFactory(), try it
      first. If non-null answer produced, return it.
   2. Use the packages listed in the javax.security.sasl.client.pkgs
      property from props to load in a factory and try to create a
      SaslClient, by looking for a class named ClientFactory. Repeat
      this for each package on the list until a non-null answer is
      produced. If non-null answer produced, return it.
   3. Repeat previous step using the javax.security.sasl.client.pkgs
      System property.
   4. If no non-null answer produced, return null.

   Parameters are:

      mechanisms     The non-null list of mechanism names to try. Each
                     is the IANA-registered name of a SASL mechanism.
                     (e.g. "GSSAPI", "CRAM-MD5").



      authorizationID The possibly null protocol-dependent
                     identification to be used for authorization, e.g.
                     user name or distinguished name. When the SASL
                     authentication completes successfully, the entity
                     named by authorizationId is granted access. If
                     null, access is granted to a protocol-dependent
                     default (for example, in LDAP this is the DN in
                     the bind request).

      protocol       The non-null string name of the protocol for
                     which the authentication is being performed, e.g
                     "pop", "ldap".

      serverName     The non-null fully qualified host name of the
                     server to authenticate to.

      props          The possibly null additional configuration
                     properties for the session, e.g.

             javax.security.sasl.encryption.minimum  Minimum key length;

Expires September 2000                                         [Page 8

JAVA SASL API                                              March, 2000


                                                     default "0" (no
                                                     session
                                                     protection). "1"
                                                     means integrity
                                                     protection only.

             javax.security.sasl.encryption.maximum  Maximum key length;
                                                     default "256".

             javax.security.sasl.server.authentication  "true" if
                                                      server must
                                                      authenticate to
                                                      client; default
                                                      "false".

             javax.security.sasl.ip.local            IP address in
                                                     dotted decimal
                                                     format, for
                                                     kerberos v4; no
                                                     default.

             javax.security.sasl.ip.remote           IP address in
                                                     dotted decimal
                                                     format, for
                                                     kerberos v4; no
                                                     default.

             javax.security.sasl.maxbuffer           Maximum size of
                                                     receive buffer
                                                     in bytes of
                                                     SaslClient;
                                                     default "4096".

             javax.security.sasl.client.pkgs         A |-separated
                                                     list of package
                                                     names to use when
                                                     locating a
                                                     SaslClientFactory.

      cbh            The possibly null callback handler to used by the
                     SASL mechanisms to get further information  from
                     the application/library to complete the
                     authentication. For example, a SASL mechanism
                     might require the authentication ID and password
                     from the caller. The authentication ID may be
                     requested with a NameCallback, and the password
                     with a PasswordCallback.


4.1.2 setSaslClientFactory


   public static void


Expires September 2000                                         [Page 9

JAVA SASL API                                              March, 2000


   setSaslClientFactory(SaslClientFactory fac)

   Sets the default SaslClientFactory to use. This method sets fac to be
   the default factory. It can only be called with a non-null value once
   per VM. If a factory has been set already, this method throws
   IllegalStateException.

   Parameters are:

      fac            The possibly null factory to set. If null, it
                     doesn't do anything.



4.1.3 createSaslServer


   public static SaslServer
   createSaslServer(String mechanism,
                    String protocol,
                    String serverName,
                    Hashtable props,
                    javax.security.auth.callback.CallbackHandler cbh)
                    throws SaslException

   This method creates a SaslServer for the specified mechanism. It
   returns null if no SaslServer can be created for the specified
   mechanism.

   The algorithm for selection is as follows:

   1. If a factory has been installed via setSaslServerFactory(), try it
      first. If non-null answer produced, return it.
   2. Use the packages listed in the javax.security.sasl.server.pkgs
      property in props, if present, to load in a factory and try to
      create a SaslServer, by looking for a class named ServerFactory.
      Repeat this for each package on the list until a non-null answer
      is produced. If non-null answer produced, return it.
   3. Use the packages listed in the javax.security.sasl.server.pkgs
      System property to load in a factory and try to create a
      SaslServer. Repeat this for each package on the list until a non-
      null answer is produced. If non-null answer produced, return it.
   4. If no non-null answer produced, return null.

   Parameters are:

      mechanism      A non-null IANA-registered name of a SASL mechanism
                    (e.g. "GSSAPI", "CRAM-MD5").

      protocol       The non-null string name of the protocol for which
                    the authentication is being performed, e.g "pop",
                    "ldap".



Expires September 2000                                        [Page 10

JAVA SASL API                                              March, 2000


      serverName     The non-null fully qualified host name of the
                    server.

      props          The possibly null properties to be used by the SASL
                    mechanism to configure the authentication exchange,
                    e.g.

             javax.security.sasl.maxbuffer           Maximum size of
                                                     receive buffer
                                                     in bytes of
                                                     SaslServer;
                                                     default "4096".

             javax.security.sasl.server.pkgs         A |-separated
                                                     list of package
                                                     names to use when
                                                     locating a
                                                     SaslServerFactory.

                     See Sasl.createSaslClient for examples of
                    additional properties.

      cbh            The possibly null callback handler to used by the
                    SASL mechanism to get further information  from the
                    application/library to complete the authentication.
                    For example, a SASL mechanism might require the
                    authentication ID and password from the caller. The
                    authentication ID may be requested with a
                    NameCallback, and the password with a
                    PasswordCallback.


4.1.4 setSaslServerFactory


   public static void
   setSaslServerFactory(SaslServerFactory fac)

   Sets the default SaslServerFactory to use. This method sets fac to
   be the default factory. It can only be called with a non-null value
   once per VM. If a factory has been set already, this method throws
   IllegalStateException.

   Parameters are:

      fac            The possibly null factory to set. If null, it
                     doesn't do anything.



4.2 public interface SaslClient




Expires September 2000                                        [Page 11

JAVA SASL API                                              March, 2000


An object implementing this interface can negotiate authentication using
one of the IANA-registered mechanisms.



4.2.1 evaluateChallenge


   public byte[]
   evaluateChallenge(byte[] challenge)
                     throws SaslException

   If a challenge is received from the server during the authentication
   process, this method is called to prepare an appropriate next
   response to submit to the server. The response is null if the
   challenge accompanied a "SUCCESS" status and the challenge only
   contains data for the client to update its state and no response
   needs to be sent to the server. The response is a zero-length byte
   array if the client is to send a response with no data. A
   SaslException is thrown if an error occurred while processing the
   challenge or generating a response. The challenge array may have zero
   length.


   Parameters are:

      challenge      The non-null challenge received from the server.



4.2.2 hasInitialResponse


   public boolean hasInitialResponse()

   Determines whether this mechanism has an optional initial response.
   If true, caller should call evaluateChallenge() with an empty array
   to get the initial response.


4.2.3 isComplete


   public boolean
   isComplete()

   This method may be called at any time to determine if the
   authentication process is finished. Typically, the protocol driver
   will not do this until it has received something from the server
   which indicates (in a protocol-specific manner) that the process has
   completed.






Expires September 2000                                        [Page 12

JAVA SASL API                                              March, 2000


4.2.4 getInputStream


   public InputStream
   getInputStream(InputStream source)
                  throws IOException

   Retrieves an input stream for the session. It may return the same
   stream that is passed in, if no processing is to be done by the
   client. This method can only be called if isComplete() returns true.

   The octets from the resulting input stream must have already gone
   through any integrity checking or other processing applied to the
   data from "source," as negotiated through the authentication session.

   From the mechanism provider's perspective, if a security layer has
   been negotiated, 'source' is expected to contain SASL buffers, as
   defined in RFC 2222. Four octets in network byte order in the front
   of each buffer identify the length of the buffer. The provider is
   responsible for performing any integrity checking or other processing
   on the buffer before returning the data as a stream of octets. For
   example, the protocol driver's request for a single octet from the
   stream might result in an entire SASL buffer being read and processed
   before that single octet can be returned.

   Parameters are:

      source    The original input stream for reading from the server.



4.2.5 getOutputStream


   public OutputStream
   getOutputStream(OutputStream dest)
                   throws IOException

   Retrieves an output stream for the session. It may return the same
   stream that is passed in, if no processing is to be done by the
   client. This method can only be called if isComplete() returns true.

   When writing octets to the resulting stream, if a security layer has
   been negotiated, each piece of data written (by a single invocation
   of write()) will be encapsulated as a SASL buffer, as defined in RFC
   2222, and then written to the underlying 'dest' output stream.

   From the mechanism provider's perspective, the data from each
   invocation of write() should be processed separately, resulting in
   the transmission of a single SASL buffer whose first four octets in
   network byte order denote the length of the buffer to the underlying
   'dest' output stream.

   Parameters are:


Expires September 2000                                        [Page 13

JAVA SASL API                                              March, 2000



      dest      The original output stream for writing to the server.



4.2.6 getMechanismName


   public String
   getMechanismName()

   Reports the IANA-registered name of the mechanism used by this
   client, e.g. "GSSAPI" or "CRAM-MD5".



4.3 public interface SaslClientFactory


An object implementing this interface can provide a SaslClient.
Implementations must be thread-safe and handle multiple simultaneous
requests.


4.3.1 createSaslClient


   public SaslClient
   createSaslClient(String[] mechanisms,
                    String authorizationID,
                    String protocol,
                    String serverName,
                    Hashtable props,
                    javax.security.auth.callback.CallbackHandler cbh)
                    throws SaslException

   Creates a SaslClient using the parameters supplied. It returns null
   if no SaslClient can be created using the parameters supplied. Throws
   SaslException if it cannot create a SaslClient because of an error.

   Returns a possibly null SaslClient created using the parameters
   supplied. If null, this factory cannot produce a SaslClient using the
   parameters supplied.

   Parameters are:

      mechanisms      The non-null list of mechanism names to try. Each
                      is the IANA-registered name of a SASL mechanism
                      (e.g. "GSSAPI", "CRAM-MD5").

      authorizationID The possibly null protocol-dependent
                      identification to be used for authorization, e.g.
                      user name or distinguished name. When the SASL
                      authentication completes successfully, the entity
                      named by authorizationId is granted access. If


Expires September 2000                                        [Page 14

JAVA SASL API                                              March, 2000


                      null, access is granted to a protocol-dependent
                      default (for example, in LDAP this is the DN in
                      the bind request).

      protocol        The non-null string name of the protocol for
                      which the authentication is being performed, e.g
                      "pop", "ldap".

      serverName      The non-null fully qualified host name of the
                      server to authenticate to.

      props           The possibly null properties to be used by the
                      SASL mechanisms to configure the authentication
                      exchange. See Sasl.createSaslClient for examples
                      of properties.

      cbh             The possibly null callback handler to used by the
                      SASL mechanisms to get further information  from
                      the application/library to complete the
                      authentication. For example, a SASL mechanism
                      might require the authentication ID and password
                      from the caller. The authentication ID may be
                      requested with a NameCallback, and the password
                      with a PasswordCallback.


4.3.2 getMechanismNames


   public String[]
   getMechanismNames()

   Returns a non-null array of names of mechanisms supported by this
   factory.



4.4 public interface SaslServer


An object implementing this interface can negotiate authentication using
one of the IANA-registered mechanisms.


4.4.1 evaluateResponse


   public byte[]
   evaluateResponse(byte[] response)
                    throws SaslException

   If a response is received from the client during the authentication
   process, this method is called to prepare an appropriate next
   challenge to submit to the client. The challenge is null if the
   authentication has succeeded and no more challenge data is to be sent


Expires September 2000                                        [Page 15

JAVA SASL API                                              March, 2000


   to the client. It is non-null if the authentication must be continued
   by sending a challenge to the client, or if the authentication has
   succeeded but challenge data needs to be processed by the client. A
   SaslException is thrown if an error occurred while processing the
   response or generating a challenge. isComplete() should be called
   after each call to evaluateResponse(),to determine if any further
   response is needed from the client. The protocol driver will send an
   indication (in a protocol-specific manner) as to whether the
   authentication has succeeded, failed, or should be continued, and any
   accompanying challenge data.

   Parameters are:

      response       Non-null response received from client.


4.4.2 isComplete


   public boolean
   isComplete()

   This method may be called at any time to determine if the
   authentication process is finished. This method is typically called
   after each invocation of evaluateResponse() to determine whether the
   authentication has completed successfully or should be continued.



4.4.3 getInputStream


   public InputStream
   getInputStream(InputStream source)
                  throws IOException

   Retrieves an input stream for the session. It may return the same
   stream that is passed in, if no processing is to be done by the
   server. This method can only be called if isComplete() returns true.

   The octets from the resulting input stream must have already gone
   through any integrity checking or other processing applied to the
   data from "source," as negotiated through the authentication session.

   From the mechanism provider's perspective, if a security layer has
   been negotiated, 'source' is expected to contain SASL buffers, as
   defined in RFC 2222. Four octets in network byte order in the front
   of each buffer identify the length of the buffer. The provider is
   responsible for performing any integrity checking or other processing
   on the buffer before returning the data as a stream of octets. For
   example, the protocol driver's request for a single octet from the
   stream might result in an entire SASL buffer being read and processed
   before that single octet can be returned.



Expires September 2000                                        [Page 16

JAVA SASL API                                              March, 2000


   Parameters are:

      source    The original input stream for reading from the client.



4.4.4 getOutputStream


   public OutputStream
   getOutputStream(OutputStream dest)
                   throws IOException

   Retrieves an output stream for the session. It may return the same
   stream that is passed in, if no processing is to be done by the
   server. This method can only be called if isComplete() returns true.

   When writing octets to the resulting stream, if a security layer has
   been negotiated, each piece of data written (by a single invocation
   of write()) will be encapsulated as a SASL buffer, as defined in RFC
   2222, and then written to the underlying 'dest' output stream.

   From the mechanism provider's perspective, the data from each
   invocation of write() should be processed separately, resulting in
   the transmission of a single SASL buffer whose first four octets in
   network byte order denote the length of the buffer to the underlying
   'dest' output stream.

   Parameters are:

      dest      The original output stream for writing to the client.



4.4.5 getMechanismName


   public String
   getMechanismName()

   Returns the non-null IANA-registered name of the mechanism used by
   this server, e.g. "GSSAPI" or "CRAM-MD5".


4.4.6 getAuthorizationID


   public String
   getAuthorizationID() throws SaslException

   Reports the authorization ID in effect for the client of this
   session. If null, a protocol-dependent default is assumed. Can only
   be called if isComplete() returns true; throws SaslException if
   called before authentication completes.



Expires September 2000                                        [Page 17

JAVA SASL API                                              March, 2000




4.5 public interface SaslServerFactory


An object implementing this interface can provide a SaslServer.
Implementations must be thread-safe and handle multiple simultaneous
requests.


4.5.1 createSaslServer


   public SaslServer
   createSaslServer(String mechanism,
                    String protocol,
                    String serverName,
                    Hashtable props,
                    javax.security.auth.callback.CallbackHandler cbh)
                    throws SaslException

   Creates a SaslServer using the mechanism supplied. It returns null if
   no SaslServer can be created using the parameters supplied. Throws
   SaslException if it cannot create a SaslServer because of an error.

   Returns a possibly null SaslServer which supports the specified
   mechanism. If null, this factory cannot produce a SaslServer for the
   specified mechanism.

   Parameters are:

      mechanism      The non-null IANA-registered name of a SASL
                    mechanism (e.g. "GSSAPI", "CRAM-MD5").

      protocol       The non-null string name of the protocol for which
                    the authentication is being performed, e.g "pop",
                    "ldap".

      serverName     The non-null fully qualified host name of the
                    server.

      props          The possibly null properties to be used by the SASL
                    mechanism to configure the authentication exchange.
                    See Sasl.createSaslServer for examples of
                    properties.

      cbh            The possibly null callback handler to used by the
                    SASL mechanism to get further information from the
                    application/library to complete the authentication.
                    For example, a SASL mechanism might require the
                    authentication ID and password from the caller. The
                    authentication ID may be requested with a
                    NameCallback, and the password with a
                    PasswordCallback.


Expires September 2000                                        [Page 18

JAVA SASL API                                              March, 2000





4.5.2 getMechanismNames


   public String[]
   getMechanismNames()

   Returns a non-null array of names of mechanisms supported by this
   factory.



4.6 public class SaslException extends IOException


Exception thrown on errors and failures in authentication.


4.6.1 Constructors


   public SaslException()

   Constructs a new instance of SaslException. The root exception and
   the detailed message are null.


   public SaslException(String message)


   Constructs a default exception with a detailed message and no root
   exception.


   public SaslException(String messag,
                        Throwable ex)

   Constructs a new instance of SaslException with a detailed message
   and a root exception. For example, a SaslException might result from
   a problem with the callback handler, which might throw a
   NoSuchCallbackException if it does not support the requested
   callback, or throw an IOException if it had problems obtaining data
   for the callback. The SaslException's root exception would then be
   the exception thrown by the callback handler.


   Parameters are:

      message        Possibly null additional detail about the
                     exception.

      ex             A possibly null root exception that caused this
                     exception.


Expires September 2000                                        [Page 19

JAVA SASL API                                              March, 2000





4.6.2 getException


   public Throwable
   getException()

   Returns the possibly null root exception that caused this exception.


4.6.3 printStackTrace


   public void
   printStackTrace()

   Prints this exception's stack trace to System.err. If this exception
   has a root exception, the stack trace of the root exception is
   printed to System.err instead.

   public void
   printStackTrace(PrintStream ps)

   Prints this exception's stack trace to a print stream. If this
   exception has a root exception, the stack trace of the root exception
   is printed to the print stream instead.

   public void
   printStackTrace(PrintWriter pw)

   Prints this exception's stack trace to a print writer. If this
   exception has a root exception, the stack trace of the root exception
   is printed to the print writer instead.

   Parameters are:

      ps             The non-null print stream to which to print.

      pw             The non-null print writer to which to print.


5. Security Considerations

   When SASL authentication is performed over unsecured connections, it
   is possible for an active attacker to spoof the server's protocol-
   specific indication that authentication is complete.  Clients should
   protect against this attack by verifying the completion of
   authentication with the mechanism driver by calling the driver's
   isComplete() method.

   Additional security considerations are discussed in [SASL].



Expires September 2000                                        [Page 20

JAVA SASL API                                              March, 2000




6. Copyright

   Copyright (C) The Internet Society (2000). All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implementation may be prepared, copied, published
   and distributed, in whole or in part, without restriction of any
   kind, provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Internet organizations, except as needed for the  purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be
   followed, or as required to translate it into languages other than
   English.

   The limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.

   This document and the information contained herein is provided on an
   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


7. Bibliography

   [JAAS] Java Software, Sun Microsystems, Inc., "Java Authentication
        and Authorization Service, "http://java.sun.com/security/jaas,
        Jan 2000.

   [SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
        RFC 2222, October 1997


8. Author's Addresses

   Rob Weltman
   Netscape Communications Corp.
   MV-068
   501 E. Middlefield Rd.
   Mountain View, CA 94043
   USA
   +1 650 937-3301
   rweltman@netscape.com



Expires September 2000                                        [Page 21

JAVA SASL API                                              March, 2000


   Rosanna Lee
   Sun Microsystems
   Mail Stop UCUP02-206
   901 San Antonio Road
   Palo Alto, CA  94303
   USA
   Email: rosanna.lee@eng.sun.com


9. Acknowledgements

   Rob Earhart, then of Carnegie Mellon University, was a coauthor of
   the preceding draft.

   Scott Seligman of Sun Microsystems, Inc. contributed to the
   architecture and API proposed in this document.


10. Changes from draft-weltman-java-sasl-02.txt


10.1 SecurityLayer


   The SecurityLayer interface was removed.


10.2 SaslClient


   createInitialResponse() was removed. evaluateChallenge() accepts an
   empty challenge and can return an initial response.
   hasInitialResponse() was added to determine if the mechanism allows
   for an initial client response.


10.3 SaslClient and SaslServer


   getSecurityLayer() was replaced with getInputStream() and
   getOutputStream().

   Package names are |-delimited, not space-delimited, in the pkgs
   properties.













Expires September 2000                                        [Page 22

JAVA SASL API                                              March, 2000


11. Appendix A - Sample Java LDAP program using SASL

   /****************************************************************
     It might look like this in LDAP. The Protocol Driver is
     implemented as part of the authenticate method of
     LDAPConnection.
    ****************************************************************/

       public void authenticate( String dn,
                                 String[] mechs,
                                 Hashtable props,
                                 CallbackHandler cbh )
                                 throws SaslException {

           // Create SASL client to use for authentication
           SaslClient saslClnt = Sasl.createSaslClient(
                         mechs, dn, "ldap", getHost(), props, cbh);

           if (saslClnt == null) {
               throw new SaslException("SASL client not available");
           }

           String mechName = saslClnt.getMechanismName();

           // Get initial response, if any
           byte[] response = (saslClnt.hasInitialResponse() ?
                              saslClnt.evaluateChallenge(new byte[0]) :
                              null);


           // Create a bind request message, including the initial
           // response (if any), and send it off
           writeRequest( new LDAPSASLBindRequest( dn, mechName,
                                                  response ) );

           // Get the server challenge
           LDAPSASLBindResponse msg =
                                 (LDAPSASLBindResponse)readResponse();

           // Authentication done?
           while (!saslClnt.isComplete() &&
                  (msg.getStatus() == LDAP_SASL_BIND_IN_PROGRESS ||
                   msg.getStatus() == LDAP_SUCCESS)) {

               // No, process challenge to get an appropriate next
               // response
               byte[] challenge = msg.getChallenge();
               response = saslClnt.evaluateChallenge( challenge );

               // May be a success message with no further response
               if ( msg.getStatus() == LDAP_SUCCESS) {
                   if ( response != null ) {
                       // Protocol error; supposed to be done already

Expires September 2000                                        [Page 23

JAVA SASL API                                              March, 2000


                       throw new SaslException("Protocol error in " +
                                               "SASL session");
                   }
                   break; // done
               }

               // Wrap the response in another bind request and send
               // it off
               writeRequest( new LDAPSASLBindRequest( dn, mechName,
                                                      response ) );
               msg = (LDAPSASLBindResponse)readResponse();
           }

           // Make sure authentication REALLY is complete
           if ( !saslClnt.isComplete() ) {
               // Authentication session hijacked!
               throw new SaslException( "SASL session hijacked!" );
           }

           // Get input and output stream processes, if any
           InputStream is = saslClnt.getInputStream(getInputStream());
           OutputStream os =
                            saslClnt.getOutputStream(getOutputStream());
       }






























Expires September 2000                                        [Page 24