Simple Authentication and Security Layer, or SASL, is an Internet
standard (RFC
2222) that specifies a protocol for authentication and optional
establishment of a security layer between client and server
applications. SASL defines how authentication data is to be
exchanged but does not itself specify the contents of that data. It
is a framework into which specific authentication
mechanisms that specify the contents and semantics of the
authentication data can fit.

SASL is used by protocols, such as the Lightweight Directory
Access Protocol, version 3 (LDAP v3), and the
Internet Message Access Protocol, version 4 (IMAP v4) to enable
pluggable authentication. Instead of hardwiring an authentication
method into the protocol, LDAP v3 and IMAP v4 use SASL to perform
authentication, thus enabling authentication via various SASL
mechanisms.

There are a number of standard SASL mechanisms defined by the
Internet community for various levels of security and deployment
scenarios. These range from no security (e.g., anonymous
authentication) to high security (e.g., Kerberos authentication)
and levels in between.

The Java SASL API defines classes and interfaces for applications
that use SASL mechanisms. It is defined to be mechanism-neutral:
the application that uses the API need not be hardwired into using
any particular SASL mechanism. The API supports both client and
server applications. It allows applications to select the mechanism
to use based on desired security features, such as whether they are
susceptible to passive dictionary attacks or whether they accept
anonymous authentication.

The Java SASL API also allows developers to use their own,
custom SASL mechanisms. SASL mechanisms are installed by using the
Java
Cryptography Architecture (JCA).

SASL provides pluggable authentication and security layer for
network applications. There are other features in the Java SE that
provide similar functionality, including the Java Secure Socket Extension
(JSSE), and Java
Generic Security Service (Java GSS). JSSE provides a framework
and an implementation for a Java language version of the SSL and
TLS protocols.
Java GSS is the Java language bindings for the Generic Security
Service Application Programming Interface (GSS-API). The only
mechanism currently supported underneath this API on Java SE is
Kerberos v5.

When compared with JSSE and Java GSS, SASL is relatively
lightweight and is popular among more recent protocols. It also has
the advantage that several popular, lightweight (in terms
infrastructure support) SASL mechanisms have been defined. Primary
JSSE and Java GSS mechanisms, on the other hand, have relatively
heavyweight mechanisms that require more elaborate infrastructures
(Public Key Infrastructure and Kerberos, respectively).

SASL, JSSE, and Java GSS are often used together. For example, a
common pattern is for an application to use JSSE for establishing a
secure channel, and to use SASL for client, username/password-based
authentication. There are also SASL mechanisms layered on top of
GSS-API mechanisms; one popular example is a SASL GSS-API/Kerberos
v5 mechanism that is used with LDAP.

Except when defining and building protocols from scratch, often
the biggest factor determining which API to use is the protocol
definition. For example, LDAP and IMAP are defined to use SASL, so
software related to these protocols should use the Java SASL API.
When building Kerberos applications and services, the API to use is
Java GSS. When building applications and services that use SSL/TLS
as their protocol, the API to use is JSSE. See the Java Security Documentation
for further details about when to use JSSE versus Java GSS.

SASL is a challenge-response protocol. The server issues a
challenge to the client, and the client sends a response based on
the challenge. This exchange continues until the server is
satisfied and issues no further challenge. These challenges and
responses are binary tokens of arbitrary length. The encapsulating
protocol (such as LDAP or IMAP) specifies how these tokens are
encoded and exchanged. For example, LDAP specifies how SASL tokens
are encapsulated within LDAP bind requests and responses.

The Java SASL API is modeled according to this style of
interaction and usage. It has interfaces, SaslClient
and SaslServer,
that represent client-side and server-side mechanisms,
respectively. The application interacts with the mechanisms via
byte arrays that represent the challenges and responses. The
server-side mechanism iterates, issuing challenges and processing
responses, until it is satisfied, while the client-side mechanism
iterates, evaluating challenges and issuing responses, until the
server is satisfied. The application that is using the mechanism
drives each iteration. That is, it extracts the challenge or
response from a protocol packet and supplies it to the mechanism,
and then puts the response or challenge returned by the mechanism
into a protocol packet and sends it to the peer.

The client and server code that uses the SASL mechanisms are not
hardwired to use specific mechanism(s). In many protocols that use
SASL, the server advertises (either statically or dynamically) a
list of SASL mechanisms that it supports. The client then selects
one of these based on its security requirements.

The Sasl
class is used for creating instances of SaslClient
and SaslServer.
Here is an example of how an application creates a SASL client
mechanism using a list of possible SASL mechanisms.

Based on the availability of the mechanisms supported by the
platform and other configuration information provided via the
parameters, the Java SASL framework selects one of the listed
mechanisms and return an instance of SaslClient.

The name of the selected mechanism is usually transmitted to the
server via the application protocol. Upon receiving the mechanism
name, the server creates a corresponding SaslServer
object to process client-sent responses. Here is an example of how
the server would create an instance of SaslServer.

Because the Java SASL API is a general framework, it must be
able to accommodate many different types of mechanisms. Each
mechanism needs to be initialized with input and may need input to
make progress. The API provides three means by which an application
gives input to a mechanism.

Common input parameters. The application uses predefined
parameters to supply information that are defined by the SASL
specification and commonly required by mechanisms. For
SASL client mechanisms, the input parameters are authorization
id, protocol id, and server name. For
SASL server mechanisms, the common input parameters are
prototol id and (its own fully qualified) server name.

Properties parameter. The application uses the properties
parameter, a mapping of property names to (possibly non-string)
property values, to supply configuration information. The Java SASL
API defines some standard properties, such as quality-of-protection,
cipher
strength, and maximum
buffer size. The parameter can also be used to pass in
non-standard properties that are specific to particular
mechanisms.

Callbacks. The application uses the
callback handler parameter to supply input that cannot be
predetermined or might not be common across mechanisms. When a
mechanism requires input data, it uses the callback handler
supplied by the application to collect the data, possibly from the
end-user of the application. For example, a mechanism might require
the end-user of the application to supply a name and password.

Mechanisms can use the callbacks defined in the javax.security.auth.callback package; these are
generic callbacks useful for building applications that perform
authentication. Mechanisms might also need SASL-specific callbacks,
such as those for collecting realm and authorization information,
or even (non-standardized) mechanism-specific callbacks. The
application should be able to accommodate a variety of mechanisms.
Consequently, its callback handler must be able to service all of
the callbacks that the mechanisms might request. This is not
possible in general for arbitrary mechanisms, but is usually
feasible due to the limited number of mechanisms that are typically
deployed and used.

Once the application has created a mechanism, it uses the mechanism
to obtain SASL tokens to exchange with the peer. The client
typically indicates to the server via the application protocol
which mechanism to use. Some protocols allows the client to
accompany the request with an optional initial response
for mechanisms that have an initial response. This feature can be
used to lower the number of message exchanges required for
authentication. Here is an example of how a client might use
SaslClient
for authentication.

The client application iterates through each step of the
authentication by using the mechanism (sc) to evaluate the
challenge gotten from the server and to get a response to send back
to the server. It continues this cycle until either the mechanism
or application-level protocol indicates that the authentication has
completed, or if the mechanism cannot evaluate a challenge. If the
mechanism cannot evaluate the challenge, it throws an exception to
indicate the error and terminates the authentication. Disagreement
between the mechanism and protocol about the completion state must
be treated as an error because it might indicate a compromise of
the authentication exchange.

The server application iterates through each step of the
authentication by giving the client's response to the mechanism
(ss) to process. If the response is incorrect, the
mechanism indicates the error by throwing a SaslException
so that the server can report the error and terminate the
authentication. If the response is correct, the mechanism returns
challenge data to be sent to the client and indicates whether the
authentication is complete. Note that challenge data can accompany
a "success" indication. This might be used, for example, to tell
the client to finalize some negotiated state.

Some SASL mechanisms support only authentication while others
support use of a negotiated security layer after authentication.
The security layer feature is often not used when the application
uses some other means, such as SSL/TLS, to communicate securely
with the peer.

When a security layer has been negotiated, all subsequent
communication with the peer must take place using the security
layer. To determine whether a security layer has been negotiated,
get the negotiated quality-of-protection
(QOP) from the mechanism. Here is an example of how to determine
whether a security layer has been negotiated.

A security layer has been negotiated if the Sasl.QOP
property indicates that either integrity and/or confidentiality has
been negotiated.

To communicate with the peer using the negotiated layer, the
application first uses the wrap method to encode the data to be sent to the peer
to produce a "wrapped" buffer. It then transfers a length field
representing the number of octets in the wrapped buffer followed by
the contents of the wrapped buffer to the peer. The peer receiving
the stream of octets passes the buffer (without the length field)
to unwrap to obtain the decoded bytes sent by the peer.
Details of this protocol are described in RFC 2222. Here is an
example of how a client application sends and receives application
data using a security layer.

SASL mechanism implementations are provided by SASL security
providers. Each provider may support one or more SASL mechanisms
and is registered with the Java
Cryptography Architecture (JCA). By default, in J2SE 5, the
SunSASL provider is automatically registered as a JCA provider. To
remove it or reorder its priority as a JCA provider, change the
line

To add or remove a SASL provider, you add or remove the
corresponding line in the Security Properties file. For example, if
you want to add a SASL provider and have its mechanisms be chosen
over the same ones implemented by the SunSASL provider, then you
would add a line to the Security Properties file with a lower
number.

Alternatively, you can programmatically add your own provider
using the java.security.Security
class. For example, the following sample code registers the
com.example.MyProvider to the list of available SASL
security providers.

Security.addProvider(new com.example.MyProvider());

When an application requests a SASL mechanism by supplying one or
more mechanism names, the SASL framework looks for registered SASL
providers that support that mechanism by going through, in order,
the list of registered providers. The providers must then determine
whether the requested mechanism matches the selection
policy properties and if so, return an implementation for the
mechanism.

The selection policy properties specify the security aspects of
a mechanism, such as its susceptibility to certain attacks. These
are characteristics of the mechanism (definition), rather than its
implementation so all providers should come to the same conclusion
about a particular mechanism. For example, the PLAIN mechanism is
susceptible to plaintext attacks regardless of how it is
implemented. If no selection policy properties are supplied, there
are no restrictions on the selected mechanism. Using these
properties, an application can ensure that it does not use
unsuitable mechanisms that might be deployed in the execution
environment. For example, an application might use the following
sample code if it does not want to allow the use of mechanisms
susceptible to plaintext attacks.

An application that uses these mechanisms from the SunSASL
provider must supply the required parameters, callbacks and
properties. The properties have reasonable defaults and only need
to be set if the application wants to override the defaults. Most
of the parameters, callbacks, and properties are described in the
API documentation. The following sections describe
mechanism-specific behaviors and parameters not already covered by
the API documentation.

The Cram-MD5 client mechanism uses the authorization id
parameter, if supplied, as the default username in the
NameCallback to solicit the application/end-user for the
authentication id. The authorization id is otherwise not used by
the Cram-MD5 mechanism; only the authentication id is exchanged
with the server.

The Digest-MD5 mechanism is used for digest authentication and
optional establishment of a security layer. It specifies the
following ciphers for use with the security layer: Triple DES, DES
and RC4 (128, 56, and 40 bits). The Digest-MD5 mechanism can
support only ciphers that are available on the platform. For
example, if the platform does not support the RC4 ciphers, then the
Digest-MD5 mechanism will not use those ciphers.

The Sasl.STRENGTH
property supports "high", "medium", and "low" settings; its default
is "high,medium,low". The ciphers are mapped to the strength
settings as follows.

Strength

Cipher

Cipher Id

high

Triple DES
RC4 128 bits

3des rc4

medium

DES
RC4 56 bits

des rc4-56

low

RC4 40 bits

rc4-40

When there is more than one choice for a particular strength,
the cipher selected depends on the availability of the ciphers in
the underlying platform. To explicitly name the cipher to use, set
the "com.sun.security.sasl.digest.cipher" property to the
corresponding cipher id. Note that this property setting must be
compatible with Sasl.STRENGTH
and the ciphers available in the underlying platform. For example,
Sasl.STRENGTH
being set to "low" and "com.sun.security.sasl.digest.cipher" being
set to "3des" are incompatible. The
"com.sun.security.sasl.digest.cipher" property has no default.

The "javax.security.sasl.sendmaxbuffer" property specifies (the
string representation of) the maximum send buffer size in bytes.
The default is 65536. The actual maximum number of bytes will be
the minimum of this number and the peer's maximum receive buffer
size.

The GSSAPI mechanism is used for Kerberos v5 authentication and
optional establishment of a security layer. The mechanism expects
the calling thread's Subject
to contain the client's Kerberos credentials or that the
credentials could be obtained by implicitly logging in to Kerberos.
To obtain the client's Kerberos credentials, use the Java Authentication and
Authorization Service (JAAS) to log in using the Kerberos login
module. See the Java GSS-API
and JAAS Tutorials for Use with Kerberos for details and
examples. After using JAAS authentication to obtain the Kerberos
credentials, you put the code that uses the SASL GSSAPI mechanism
within doAs or doAsPrivileged.

The "javax.security.sasl.sendmaxbuffer" property specifies (the
string representation of) the maximum send buffer size in bytes.
The default is 65536. The actual maximum number of bytes will be
the minimum of this number and the peer's maximum receive buffer
size.

An application that uses these mechanisms from the SunSASL
provider must supply the required parameters, callbacks and
properties. The properties have reasonable defaults and only need
to be set if the application wants to override the defaults.

All users of server mechanisms must have a callback handler that
deals with the AuthorizeCallback.
This is used by the mechanisms to determine whether the
authenticated user is allowed to act on behalf of the requested
authorization id, and also to obtain the canonicalized name of the
authorized user (if canonicalization is applicable).

Most of the parameters, callbacks, and properties are described
in the API documentation. The following sections describe
mechanism-specific behaviors and parameters not already covered by
the API documentation.

The "javax.security.sasl.sendmaxbuffer" property is described in
the Digest-MD5 client section.

The "com.sun.security.sasl.digest.realm" property is used to
specify a list of space-separated realm names that the server
supports. The list is sent to the client as part of the challenge.
If this property has not been set, the default realm is the
server's name (supplied as a parameter).

The "com.sun.security.sasl.digest.utf8" property is used to
specify the character encoding to use. "true" means to use UTF-8
encoding; "false" means to use ISO Latin 1 (ISO-8859-1). The
default is "true".

The SunSASL provider uses the Logging APIs to provide
implementation logging output. This output can be controlled by
using the logging configuration file and
programmatic API (java.util.logging).
The logger name used by the SunSASL provider is
"javax.security.sasl". Here is a sample logging
configuration file that enables the FINEST
logging level for the SunSASL provider.

The first step involves providing an implementation for the SASL
mechanism. To implement a client mechanism, you need to implement
the methods declared in the SaslClient
interface. Similarly, for a server mechanism, you need to implement
the methods declared in the SaslServer
interface. For the purposes of this discussion, suppose you are
developing an implementation for the client mechanism
"SAMPLE-MECH", implemented by the class,
com.example.SampleMechClient. You must decide what input
are needed by the mechanism and how the implementation is going to
collect them. For example, if the mechanism is
username/password-based, then the implementation would likely need
to collect that information via the callback handler parameter.

The next step involves providing a factory class that will
create instances of com.example.SampleMechClient. The
factory needs to determine the characteristics of the mechanism
that it supports (as described by the
Sasl.POLICY_* properties) so that it can return an
instance of the mechanism when the API user requests it using
compatible policy properties. The factory may also check for
validity of the parameters before creating the mechanism. For the
purposes of this discussion, suppose the factory class is named
com.example.MySampleClientFactory. Although our sample
factory is responsible for only one mechanism, a single factory can
be responsible for any number of mechanisms.

A single SASL provider might be responsible for many mechanisms.
Therefore, it might have many invocations of put to register the relevant factories. The completed
SASL provider can then be made available to applications using the
instructions given previously.