draft-weltman-java-sasl-02.txt [plain text]
Internet Draft Rob Weltman
Netscape Communications Corp.
Rosanna Lee
draft-weltman-java-sasl-02.txt Sun Microsystems
Rob Earhart
Carnegie Mellon
June 4, 1999
The Java SASL Application Program Interface
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 12/99 [Page 1]
JAVA SASL API June 1999
1 Overview of the SASL classes..........................5
1.1 Interfaces .......................................5
1.2 Classes .......................................5
2 Overview of SASL API Use..............................6
3 The java SASL classes.................................7
3.1 public class Sasl.....................................7
3.1.1 createSaslClient.................................7
3.1.2 setSaslClientFactory.............................9
3.1.3 createSaslServer.................................9
3.1.4 setSaslServerFactory............................10
3.2 public interface SaslClient..........................11
3.2.1 createInitialResponse...........................11
3.2.2 evaluateChallenge...............................11
3.2.3 isComplete......................................11
3.2.4 getSecurityLayer................................11
3.2.5 getMechanismName................................12
3.3 public interface SaslClientFactory...................12
3.3.1 createSaslClient................................12
3.3.2 getMechanismNames...............................13
3.4 public interface SaslServer..........................13
3.4.1 evaluateResponse................................13
3.4.2 isComplete......................................14
3.4.3 getSecurityLayer................................14
3.4.4 getMechanismName................................14
3.4.5 getAuthorizationID..............................14
3.5 public interface SaslServerFactory...................15
3.5.1 createSaslServer................................15
3.5.2 getMechanismNames...............................16
3.6 public class SaslException...........................16
3.6.1 Constructors....................................16
3.6.2 getException....................................17
3.6.3 printStackTrace.................................17
3.7 public interface SecurityLayer.......................17
3.7.1 encode......................................17
3.7.2 decode......................................18
4 Security Considerations..............................19
5 Bibliography ......................................19
6 Authors' Addresses...................................19
7 Acknowledgements.....................................19
8 Appendix A - Sample java LDAP program using SASL.....20
9 Appendix B - Changes from java-sasl-01.txt...........24
Expires 12/99 [Page 2]
JAVA SASL API June 1999
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 a Security Layer object. From this point on,
any data exchanged throught the socket is passed to the Security
Layer object for encoding/decoding.
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
Expires 12/99 [Page 3]
JAVA SASL API June 1999
can supply a javax.security.auth.callback.CallbackHandler instance
[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.
A Security Layer Driver typically inherits 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.
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 |
----------------- | | -----------------
| |
----------------- | | -----------------
Expires 12/99 [Page 4]
JAVA SASL API June 1999
| 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.
1 Overview of the SASL classes
1.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
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.
SecurityLayer An interface for encoding and decoding
data.
1.2 Classes
Sasl A static class for creating SASL clients
and servers. It transparently locates
and uses any available
SaslClientFactory/SaslServerFactory
instances.
Expires 12/99 [Page 5]
JAVA SASL API June 1999
SaslException Exception thrown on errors and failures
in the authentication process.
2 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 a SecurityLayer object may be
obtained from it. If not, the SaslClient is queried for an
appropriate next response to the server. This continues until
authentication has completed.
- For the rest of the session, messages to the server are encoded
first by the Security Layer (if one has been provided by
SaslClient), and messages from the server are decoded by it
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
an 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
Expires 12/99 [Page 6]
JAVA SASL API June 1999
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 by the Security Layer, if one has been
provided by SaslServer.
The following sections describe the SASL classes in more detail.
3 The Java SASL classes
3.1 public class Sasl
A class capable of providing a SaslClient or SaslServer.
3.1.1 createSaslClient
public static 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.
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").
Expires 12/99 [Page 7]
JAVA SASL API June 1999
authorizationIDThe 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;
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
security layer
frames; default "0"
(client will
not use the
security layer).
Expires 12/99 [Page 8]
JAVA SASL API June 1999
javax.security.sasl.client.pkgs A space-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.
3.1.2 setSaslClientFactory
public static void
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.
3.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
Expires 12/99 [Page 9]
JAVA SASL API June 1999
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".
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.
3.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.
Expires 12/99 [Page 10]
JAVA SASL API June 1999
3.2 public interface SaslClient
An object implementing this interface can negotiate authentication
using one of the IANA-registered mechanisms.
3.2.1 createInitialResponse
public byte[]
createInitialResponse() throws SaslException
This method prepares a byte array to use for the initial response to
start the authentication process. A SaslException is thrown if the
driver cannot initiate authentication. The return value may be
null, indicating there is no initial response to send to the server.
3.2.2 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. A SaslException is thrown if an
error occurred while processing the challenge or generating a
response.
Parameters are:
challenge The non-null challenge received from the server.
3.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.
3.2.4 getSecurityLayer
public SecurityLayer
getSecurityLayer() throws SaslException
Expires 12/99 [Page 11]
JAVA SASL API June 1999
Once authentication is complete, this method may be called to obtain
an object capable of encoding/decoding data content for the rest of
the session. An exception is thrown if authentication is not yet
complete. It may return null if the mechanism does not define a
security layer, or if none was negotiated.
3.2.5 getMechanismName
public String
getMechanismName()
Report the IANA-registered name of the mechanism used by this
client, e.g. "GSSAPI" or "CRAM-MD5".
3.3 public interface SaslClientFactory
An object implementing this interface can provide a SaslClient.
Implementations must be thread-safe and handle multiple simultaneous
requests.
3.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
Expires 12/99 [Page 12]
JAVA SASL API June 1999
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 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.
3.3.2 getMechanismNames
public String[]
getMechanismNames()
Returns a non-null array of names of mechanisms supported by this
factory.
3.4 public interface SaslServer
An object implementing this interface can negotiate authentication
using one of the IANA-registered mechanisms.
3.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 to the client. It is non-null if the authentication must be
Expires 12/99 [Page 13]
JAVA SASL API June 1999
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.
3.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.
3.4.3 getSecurityLayer
public SecurityLayer
getSecurityLayer() throws SaslException
Once authentication is complete, this method may be called to obtain
an object capable of encoding/decoding data content for the rest of
the session. An exception is thrown if authentication is not yet
complete. It may return null if the mechanism does not define a
security layer, or if none was negotiated.
3.4.4 getMechanismName
public String
getMechanismName()
Returns the non-null IANA-registered name of the mechanism used by
this server, e.g. "GSSAPI" or "CRAM-MD5".
3.4.5 getAuthorizationID
public String
getAuthorizationID()
Report the authorization ID in effect for the client of this
session. If null, a protocol-dependent default is assumed.
Expires 12/99 [Page 14]
JAVA SASL API June 1999
3.5 public interface SaslServerFactory
An object implementing this interface can provide a SaslServer.
Implementations must be thread-safe and handle multiple simultaneous
requests.
3.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 SaslClient can be created using the parameters supplied.
Throws SaslException if it cannot create a SaslClient 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 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.
Expires 12/99 [Page 15]
JAVA SASL API June 1999
3.5.2 getMechanismNames
public String[]
getMechanismNames()
Returns a non-null array of names of mechanisms supported by this
factory.
3.6 public class SaslException
extends IOException
Exception thrown on errors and failures in authentication.
3.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 be 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 12/99 [Page 16]
JAVA SASL API June 1999
3.6.2 getException
public Throwable
getException()
Returns the possibly null root exception that caused this exception.
3.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.
3.7 public interface SecurityLayer
An object implementing this interface translates buffers back and
forth during a session, after the authentication process has
completed, to provide a security layer. The security layer may
provide data integrity and/or session privacy.
3.7.1 encode
public byte[]
encode(byte[] inVals, int offset, int count) throws SASLException
Take a protocol-dependent byte array and encode it (encrypt, for
example) for sending to the server.
Expires 12/99 [Page 17]
JAVA SASL API June 1999
Parameters are:
inVals A request to be encoded before sending to the
server.
offset The inclusive starting offset in the byte array
inVals to use. 0 <= offset < inVals.length.
count The number of bytes in inVals to use.
0 <= count < inVals.length-offset.
3.7.2 decode
public byte[]
decode(byte[] outVals, int offset, int count) throws SASLException
Take an encoded byte array received from the server and decode it.
Parameters are:
outVals A response received from the server, to be
decoded.
offset The inclusive starting offset in the byte array
outVals to use. 0 <= offset < outVals.length.
count The number of bytes in outVals to use.
0 <= count < outVals.length-offset.
Expires 12/99 [Page 18]
JAVA SASL API June 1999
4 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].
5 Bibliography
[JAAS] Java Software, Sun Microsystems, Inc., "Java Authentication
and Authorization Service," http://java.sun.com/security/jaas,
March 1999.
[SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
RFC 2222, October 1997
6 Authors' Addresses
Rob Weltman
Netscape Communications Corp.
501 E. Middlefield Rd.
Mail Stop MV-029
Mountain View, CA 94043-4042
USA
Email: rweltman@netscape.com
Rosanna Lee
Sun Microsystems
Mail Stop UCUP02-206
901 San Antonio Road
Palo Alto, CA 94303
USA
Email: rosanna.lee@eng.sun.com
Rob Earhart
Carnegie Mellon
5000 Forbes Ave.
Pittsburgh, PA 15213-3890
USA
Email: earhart@cmu.edu
7 Acknowledgements
Scott Seligman of Sun Microsystems, Inc. contributed to the
architecture and API proposed in this document.
Expires 12/99 [Page 19]
JAVA SASL API June 1999
8 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 class 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();
byte[] response = saslClnt.createInitialResponse();
// Create a bind request message, including the initial
// response (if any), and send it off
LDAPSASLBindResponse msg =
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) {
// No, get an appropriate next response and send it off
byte[] challenge = msg.getChallenge();
response = saslClnt.evaluateChallenge( challenge );
// May be a success message with no further challenge
if ( response != null ) {
// 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 ( !driver.isComplete() ) {
/* Authentication session hijacked! */
throw new SaslException( "SASL session hijacked!" );
}
// Get the negotiated security layer, if any
Expires 12/99 [Page 20]
JAVA SASL API June 1999
security = saslClnt.getSecurityLayer();
}
Expires 12/99 [Page 21]
JAVA SASL API June 1999
/****************************************************************
This might be in an application
****************************************************************/
/**
* A sample callback handler. This implementation is created by
* using the input that it will return. Other implementations are
* typically more sophisticated and might prompt the user on demand
* in order to satisfy the callbacks.
*/
class SimpleCallbackHandler implements CallbackHandler {
private char[] passwd;
private String authenticationID;
SimpleCallbackHandler(String principal, Object cred)
throws IOException {
authenticationID = principal;
if (cred instanceof String) {
passwd = ((String)cred).toCharArray();
} else if (cred instanceof char[]) {
passwd = (char[])((char[])cred).clone();
} else if (cred instanceof byte[]) {
// PasswordCallback expects char[]; assume UTF-8
// encoding
String orig = new String((byte[])cred, "UTF8");
passwd = orig.toCharArray();
} else {
throw new IOException("Unsupported password format: " +
cred);
}
}
public void invokeCallback(Callback[] callbacks)
throws java.io.IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
((NameCallback)callbacks[i]).setName(
authenticationID);
} else if (callbacks[i] instanceof PasswordCallback) {
((PasswordCallback)callbacks[i]).setPassword(
passwd);
} else {
throw new
UnsupportedCallbackException(callbacks[i]);
}
}
}
}
Expires 12/99 [Page 22]
JAVA SASL API June 1999
/***************************************************************
And so the application code to do authentication
***************************************************************/
// Set up all SASL parameters; some may have reasonable defaults
Hashtable props = new Hashtable();
props.add("javax.security.sasl.encryption.minimum", "40");
props.add("javax.security.sasl.encryption.maximum", "128");
props.add("javax.security.sasl.server_authentication", "true");
props.add("javax.security.sasl.maxbuffer", "4096");
// The following two for kerberos v4, only
//props.add("javax.security.sasl.ip.local", "192.68.1.10");
//props.add("javax.security.sasl.ip.remote", "192.68.1.50");
// What we want to authenticate as
String dn = "cn=Directory Manager";
// Create an object for possible use by the authentication
// process
SimpleCallbackHandler cbh = new SimpleCallbackHandler();
try {
// Note: cbh methods may be called during authentication
// Note: "connection" includes the SASL Protocol Driver
// functionality, and it will internally manage a Mechanism
// Driver for GSSAPI, and then a Security Layer object for
// data translation
String[] mechNames = { "GSSAPI" };
connection.authenticate( dn, mechNames, props, cbh );
} catch ( SaslException e ) {
// Abort, return, maybe try some other authentication
}
// Okay. From here on, everything goes through security, but the
// methods have the same signatures as if we were not using SASL
Expires 12/99 [Page 23]
JAVA SASL API June 1999
9 Appendix B - Changes from draft-weltman-java-sasl-01.txt
The class hierarchy defined in this document is entirely different
from that defined in the previous document.
For callback handling, the newly released
javax.security.auth.callback package is used.
Expires 12/99 [Page 24]