2 Internet Draft Rob Weltman
3 Netscape Communications Corp.
5 draft-weltman-java-sasl-02.txt Sun Microsystems
11 The Java SASL Application Program Interface
16 This document is an Internet-Draft and is in full conformance with
17 all provisions of Section 10 of RFC2026.
19 Internet-Drafts are working documents of the Internet Task Force
20 (IETF), its areas, and its working groups. Note that other groups
21 may also distribute working documents as Internet-Drafts.
23 Internet-Drafts are draft documents valid for a maximum of six
24 months and may be updated, replaced, or obsoleted by other documents
25 at any time. It is inappropriate to use Internet Drafts as
26 reference material or to cite them other than as "work in progress."
28 The list of current Internet-Drafts can be accessed at
29 http://www.ietf.org/ietf/1id-abstracts.txt
31 The list of Internet-Draft Shadow Directories can be accessed at
32 http://www.ietf.org/shadow.html.
38 This document defines a client-side and a server-side Java language
39 interface for using the Simple Authentication and Security Layer
40 (SASL) mechanisms for adding authentication support to connection-
41 based protocols. The interface promotes sharing of SASL mechanism
42 drivers and security layers between applications using different
43 protocols. It complements but does not replace [SASL], which defines
44 and exemplifies use of the SASL protocol in a language-independent
58 Expires 12/99 [Page 1]
60 JAVA SASL API June 1999
63 1 Overview of the SASL classes..........................5
64 1.1 Interfaces .......................................5
65 1.2 Classes .......................................5
66 2 Overview of SASL API Use..............................6
67 3 The java SASL classes.................................7
68 3.1 public class Sasl.....................................7
69 3.1.1 createSaslClient.................................7
70 3.1.2 setSaslClientFactory.............................9
71 3.1.3 createSaslServer.................................9
72 3.1.4 setSaslServerFactory............................10
73 3.2 public interface SaslClient..........................11
74 3.2.1 createInitialResponse...........................11
75 3.2.2 evaluateChallenge...............................11
76 3.2.3 isComplete......................................11
77 3.2.4 getSecurityLayer................................11
78 3.2.5 getMechanismName................................12
79 3.3 public interface SaslClientFactory...................12
80 3.3.1 createSaslClient................................12
81 3.3.2 getMechanismNames...............................13
82 3.4 public interface SaslServer..........................13
83 3.4.1 evaluateResponse................................13
84 3.4.2 isComplete......................................14
85 3.4.3 getSecurityLayer................................14
86 3.4.4 getMechanismName................................14
87 3.4.5 getAuthorizationID..............................14
88 3.5 public interface SaslServerFactory...................15
89 3.5.1 createSaslServer................................15
90 3.5.2 getMechanismNames...............................16
91 3.6 public class SaslException...........................16
92 3.6.1 Constructors....................................16
93 3.6.2 getException....................................17
94 3.6.3 printStackTrace.................................17
95 3.7 public interface SecurityLayer.......................17
96 3.7.1 encode......................................17
97 3.7.2 decode......................................18
98 4 Security Considerations..............................19
99 5 Bibliography ......................................19
100 6 Authors' Addresses...................................19
101 7 Acknowledgements.....................................19
102 8 Appendix A - Sample java LDAP program using SASL.....20
103 9 Appendix B - Changes from java-sasl-01.txt...........24
118 Expires 12/99 [Page 2]
120 JAVA SASL API June 1999
125 See [SASL], section 3, for an introduction to and overview of the
126 SASL framework for authentication and negotiation of a security
127 layer. The following presents an outline of the concepts.
129 --------------- ------------------- -----------------
130 | Application |-----| Protocol Driver |------| MD5 |
131 --------------- ------------------- | -----------------
147 An application chooses a Protocol Driver specific to the protocol it
148 wants to use, and specifies one or more acceptable mechanisms. The
149 Protocol Driver controls the socket, and knows the format/packaging
150 of bytes sent down and received from the socket, but does not know
151 how to authenticate or to encrypt/ decrypt the bytes. It uses one of
152 the Mechanism Drivers to help it perform authentication. The
153 Protocol Driver examines each byte string received from the server
154 during the authentication in a protocol-specific way to determine if
155 the authentication process has been completed. If not, the byte
156 string is passed to the Mechanism Driver to be interpreted as a
157 server challenge; the Mechanism Driver returns an appropriate
158 response, which the Protocol Driver can encode in a protocol-
159 specific way and return to the server.
161 If the Protocol Driver concludes from the byte string received from
162 the server that authentication is complete, it may query the
163 Mechanism Driver if it considers the authentication process
164 complete, in order to thwart early completion messages inserted by
167 On completed authentication, the Protocol Driver may receive from
168 the Mechanism Driver a Security Layer object. From this point on,
169 any data exchanged throught the socket is passed to the Security
170 Layer object for encoding/decoding.
172 A complication here is that some authentication methods may require
173 additional user/application input. That means that a Mechanism
174 Driver may need to call up to an application during the
175 authentication process. To satisfy this requirement, the application
178 Expires 12/99 [Page 3]
180 JAVA SASL API June 1999
182 can supply a javax.security.auth.callback.CallbackHandler instance
183 [JAAS] that can be used by the Mechanism Driver to prompt the user
184 for additional input.
186 Protocol Drivers are protocol-dependent, and may be built in to a
187 protocol package or an application. There is a generalized framework
188 for registering and finding Mechanism Drivers. The framework uses a
189 factory to produce an appropriate Mechanism Driver. The factory may
190 be preconfigured, explicitly specified by the caller, specified as a
191 list of packages by the caller, or be identified based on a list of
192 packages in the System properties.
194 The Mechanism Drivers are protocol-independent, and don't deal
195 directly with network connections, just byte arrays, so they can be
196 implemented in a generalizable way for all protocols.
198 A Security Layer Driver typically inherits a state object from the
199 Mechanism Driver, where parameters and resolutions reached during
200 authentication have been stored.
202 Different Mechanism Drivers may require different parameters to
203 carry out the authentication process. This is handled by passing a
204 java.util.Hashtable object as an argument to instantiation methods.
206 In the following discussion, 'client' refers to the client-side
207 protocol driver that is using the SASL mechanism while 'server'
208 refers to the server-side protocol driver that is using the SASL
211 In the Java SASL environment, the SaslClient interface represents
212 the client's view of the Mechanism Driver, while the SaslServer
213 interface represents the server's view.
215 --------------- ---------------
216 | Application |--+ +--| Server |
217 --------------- | | ---------------
219 ------------------- -------------------
220 | Protocol Driver |--+ <- - - - -> +--| Protocol Driver |
221 ------------------- | | -------------------
223 ------------------- -------------------
224 | SaslClient | | SaslServer |
225 ------------------- -------------------
227 ----------------- | | -----------------
228 | MD5 |----| |---| MD5 |
229 ----------------- | | -----------------
231 ----------------- | | -----------------
232 | Kerberos v5 |----| |---| Kerberos v5 |
233 ----------------- | | -----------------
235 ----------------- | | -----------------
238 Expires 12/99 [Page 4]
240 JAVA SASL API June 1999
242 | PKCS-11 |----| |---| PKCS-11 |
243 ----------------- | | -----------------
245 - - - - - - - - - | | - - - - - - - - -
246 | xxxYYYxxx |----+ +---| xxxYYYxxx |
247 - - - - - - - - - - - - - - - - - -
249 A client using the Java SASL API may communicate with any server
250 implementing the SASL protocol, and a server may use the API to
251 process authentication requests from any client using the SASL
252 protocol. It is not required that both sides use the same language
255 1 Overview of the SASL classes
261 SaslClient Performs SASL authentication as a
264 SaslClientFactory An interface for creating instances of
265 SaslClient. It is not normally accessed
266 directly by a client, which will use the
267 Sasl static methods instead. However, a
268 particular environment may provide and
269 install a new or different
272 SaslServer Performs SASL authentication as a
275 SaslServerFactory An interface for creating instances of
276 SaslServer. It is not normally accessed
277 directly by a server, which will use the
278 Sasl static methods instead. However, a
279 particular environment may provide and
280 install a new or different
283 SecurityLayer An interface for encoding and decoding
290 Sasl A static class for creating SASL clients
291 and servers. It transparently locates
292 and uses any available
293 SaslClientFactory/SaslServerFactory
298 Expires 12/99 [Page 5]
300 JAVA SASL API June 1999
302 SaslException Exception thrown on errors and failures
303 in the authentication process.
306 2 Overview of SASL API Use
308 An application generally uses the SASL API as follows:
310 - Pass a list of acceptable or known Mechanisms to
311 Sasl.createSaslClient. The method returns an object
312 implementing SaslClient on success.
314 - Create an object implementing the client authentication
315 callback interfaces, which can provide credentials when
316 required by the SaslClient.
318 - Have the SaslClient object begin the authentication process by
319 providing an initial server response, if the protocol supports
322 - Responses/challenges are exchanged with the server. If a
323 response indicates authentication has completed, SaslClient is
324 queried for validation, and a SecurityLayer object may be
325 obtained from it. If not, the SaslClient is queried for an
326 appropriate next response to the server. This continues until
327 authentication has completed.
329 - For the rest of the session, messages to the server are encoded
330 first by the Security Layer (if one has been provided by
331 SaslClient), and messages from the server are decoded by it
332 before processing in the application.
335 A server generally uses the SASL API as follows:
337 - It receives a request from the client requesting authentication
338 for a particular SASL mechanism, accompanied by an optional
341 - It processes the initial response and generates a challenge
342 specific for the SASL mechanism to be sent back to the client
343 if the response is processed successfully. If the response is
344 not processed successfully, it sends an error to the client and
345 terminates the authentication session.
347 - Responses/challenges are exchanged with the client. If the
348 server cannot successful process a response, the server sends
349 an error to the client and terminates the authentication. If
350 the server has completed the authentication and has no more
351 challenges to send, it sends a success indication to the
354 - If the authentication has completed successfully, the server
355 extracts the authorization ID of the client from the SaslServer
358 Expires 12/99 [Page 6]
360 JAVA SASL API June 1999
362 instance (if appropriate) to be used for subsequent access
365 - For the rest of the session, messages to and from the client
366 are encoded and decoded by the Security Layer, if one has been
367 provided by SaslServer.
369 The following sections describe the SASL classes in more detail.
372 3 The Java SASL classes
375 3.1 public class Sasl
377 A class capable of providing a SaslClient or SaslServer.
380 3.1.1 createSaslClient
382 public static SaslClient
383 createSaslClient(String[] mechanisms,
384 String authorizationID,
388 javax.security.auth.callback.CallbackHandler cbh)
391 Creates a SaslClient using the parameters supplied. It returns null
392 if no SaslClient can be created using the parameters supplied.
393 Throws SaslException if it cannot create a SaslClient because of an
396 The algorithm for selection is as follows:
398 1.If a factory has been installed via setSaslClientFactory(), try
399 it first. If non-null answer produced, return it.
400 2.Use the packages listed in the javax.security.sasl.client.pkgs
401 property from props to load in a factory and try to create a
402 SaslClient, by looking for a class named ClientFactory. Repeat
403 this for each package on the list until a non-null answer is
404 produced. If non-null answer produced, return it.
405 3.Repeat previous step using the javax.security.sasl.client.pkgs
407 4.If no non-null answer produced, return null.
411 mechanisms The non-null list of mechanism names to try. Each
412 is the IANA-registered name of a SASL mechanism.
413 (e.g. "GSSAPI", "CRAM-MD5").
418 Expires 12/99 [Page 7]
420 JAVA SASL API June 1999
422 authorizationIDThe possibly null protocol-dependent
423 identification to be used for authorization, e.g.
424 user name or distinguished name. When the SASL
425 authentication completes successfully, the entity
426 named by authorizationId is granted access. If
427 null, access is granted to a protocol-dependent
428 default (for example, in LDAP this is the DN in
431 protocol The non-null string name of the protocol for
432 which the authentication is being performed, e.g
435 serverName The non-null fully qualified host name of the
436 server to authenticate to.
438 props The possibly null additional configuration
439 properties for the session, e.g.
441 javax.security.sasl.encryption.minimum Minimum key length;
448 javax.security.sasl.encryption.maximum Maximum key length;
451 javax.security.sasl.server.authentication "true" if
457 javax.security.sasl.ip.local IP address in
463 javax.security.sasl.ip.remote IP address in
469 javax.security.sasl.maxbuffer Maximum size of
478 Expires 12/99 [Page 8]
480 JAVA SASL API June 1999
482 javax.security.sasl.client.pkgs A space-separated
488 cbh The possibly null callback handler to used by the
489 SASL mechanisms to get further information from
490 the application/library to complete the
491 authentication. For example, a SASL mechanism
492 might require the authentication ID and password
493 from the caller. The authentication ID may be
494 requested with a NameCallback, and the password
495 with a PasswordCallback.
498 3.1.2 setSaslClientFactory
501 setSaslClientFactory(SaslClientFactory fac)
503 Sets the default SaslClientFactory to use. This method sets fac to
504 be the default factory. It can only be called with a non-null value
505 once per VM. If a factory has been set already, this method throws
506 IllegalStateException.
510 fac The possibly null factory to set. If null, it
515 3.1.3 createSaslServer
517 public static SaslServer
518 createSaslServer(String mechanism,
522 javax.security.auth.callback.CallbackHandler cbh)
525 This method creates a SaslServer for the specified mechanism. It
526 returns null if no SaslServer can be created for the specified
529 The algorithm for selection is as follows:
531 1.If a factory has been installed via setSaslServerFactory(), try
532 it first. If non-null answer produced, return it.
533 2.Use the packages listed in the javax.security.sasl.server.pkgs
534 property in props, if present, to load in a factory and try to
535 create a SaslServer, by looking for a class named
538 Expires 12/99 [Page 9]
540 JAVA SASL API June 1999
542 ServerFactory. Repeat this for each package on the list until a
543 non-null answer is produced. If non-null answer produced,
545 3.Use the packages listed in the javax.security.sasl.server.pkgs
546 System property to load in a factory and try to create a
547 SaslServer. Repeat this for each package on the list until a
548 non-null answer is produced. If non-null answer produced,
550 4.If no non-null answer produced, return null.
554 mechanism A non-null IANA-registered name of a SASL
555 mechanism (e.g. "GSSAPI", "CRAM-MD5").
557 protocol The non-null string name of the protocol for
558 which the authentication is being performed, e.g
561 serverName The non-null fully qualified host name of the
562 server to authenticate to.
564 props The possibly null properties to be used by the
565 SASL mechanisms to configure the authentication
566 exchange. See Sasl.createSaslClient for examples
569 cbh The possibly null callback handler to used by the
570 SASL mechanisms to get further information from
571 the application/library to complete the
572 authentication. For example, a SASL mechanism
573 might require the authentication ID and password
574 from the caller. The authentication ID may be
575 requested with a NameCallback, and the password
576 with a PasswordCallback.
579 3.1.4 setSaslServerFactory
582 setSaslServerFactory(SaslServerFactory fac)
584 Sets the default SaslServerFactory to use. This method sets fac to
585 be the default factory. It can only be called with a non-null value
586 once per VM. If a factory has been set already, this method throws
587 IllegalStateException.
591 fac The possibly null factory to set. If null, it
598 Expires 12/99 [Page 10]
600 JAVA SASL API June 1999
602 3.2 public interface SaslClient
604 An object implementing this interface can negotiate authentication
605 using one of the IANA-registered mechanisms.
608 3.2.1 createInitialResponse
611 createInitialResponse() throws SaslException
613 This method prepares a byte array to use for the initial response to
614 start the authentication process. A SaslException is thrown if the
615 driver cannot initiate authentication. The return value may be
616 null, indicating there is no initial response to send to the server.
619 3.2.2 evaluateChallenge
622 evaluateChallenge(byte[] challenge)
625 If a challenge is received from the server during the authentication
626 process, this method is called to prepare an appropriate next
627 response to submit to the server. The response is null if the
628 challenge accompanied a "SUCCESS" status and the challenge only
629 contains data for the client to update its state and no response
630 needs to be sent to the server. A SaslException is thrown if an
631 error occurred while processing the challenge or generating a
636 challenge The non-null challenge received from the server.
644 This method may be called at any time to determine if the
645 authentication process is finished. Typically, the protocol driver
646 will not do this until it has received something from the server
647 which indicates (in a protocol-specific manner) that the process has
650 3.2.4 getSecurityLayer
653 getSecurityLayer() throws SaslException
658 Expires 12/99 [Page 11]
660 JAVA SASL API June 1999
662 Once authentication is complete, this method may be called to obtain
663 an object capable of encoding/decoding data content for the rest of
664 the session. An exception is thrown if authentication is not yet
665 complete. It may return null if the mechanism does not define a
666 security layer, or if none was negotiated.
669 3.2.5 getMechanismName
674 Report the IANA-registered name of the mechanism used by this
675 client, e.g. "GSSAPI" or "CRAM-MD5".
679 3.3 public interface SaslClientFactory
681 An object implementing this interface can provide a SaslClient.
682 Implementations must be thread-safe and handle multiple simultaneous
686 3.3.1 createSaslClient
689 createSaslClient(String[] mechanisms,
690 String authorizationID,
694 javax.security.auth.callback.CallbackHandler cbh)
697 Creates a SaslClient using the parameters supplied. It returns null
698 if no SaslClient can be created using the parameters supplied.
699 Throws SaslException if it cannot create a SaslClient because of an
702 Returns a possibly null SaslClient created using the parameters
703 supplied. If null, this factory cannot produce a SaslClient using
704 the parameters supplied.
708 mechanisms The non-null list of mechanism names to try. Each
709 is the IANA-registered name of a SASL mechanism.
710 (e.g. "GSSAPI", "CRAM-MD5").
712 authorizationID The possibly null protocol-dependent
713 identification to be used for authorization, e.g.
714 user name or distinguished name. When the SASL
715 authentication completes successfully, the entity
718 Expires 12/99 [Page 12]
720 JAVA SASL API June 1999
722 named by authorizationId is granted access. If
723 null, access is granted to a protocol-dependent
724 default (for example, in LDAP this is the DN in
727 protocol The non-null string name of the protocol for
728 which the authentication is being performed, e.g
731 serverName The non-null fully qualified host name of the
732 server to authenticate to.
734 props The possibly null properties to be used by the
735 SASL mechanisms to configure the authentication
736 exchange. See Sasl.createSaslClient for examples
739 cbh The possibly null callback handler to used by the
740 SASL mechanisms to get further information from
741 the application/library to complete the
742 authentication. For example, a SASL mechanism
743 might require the authentication ID and password
744 from the caller. The authentication ID may be
745 requested with a NameCallback, and the password
746 with a PasswordCallback.
750 3.3.2 getMechanismNames
755 Returns a non-null array of names of mechanisms supported by this
759 3.4 public interface SaslServer
761 An object implementing this interface can negotiate authentication
762 using one of the IANA-registered mechanisms.
765 3.4.1 evaluateResponse
768 evaluateResponse(byte[] response)
771 If a response is received from the client during the authentication
772 process, this method is called to prepare an appropriate next
773 challenge to submit to the client. The challenge is null if the
774 authentication has succeeded and no more challenge data is to be
775 sent to the client. It is non-null if the authentication must be
778 Expires 12/99 [Page 13]
780 JAVA SASL API June 1999
782 continued by sending a challenge to the client, or if the
783 authentication has succeeded but challenge data needs to be
784 processed by the client. A SaslException is thrown if an error
785 occurred while processing the response or generating a challenge.
786 isComplete() should be called after each call to evaluateResponse(),
787 to determine if any further response is needed from the client. The
788 protocol driver will send an indication (in a protocol-specific
789 manner) as to whether the authentication has succeeded, failed, or
790 should be continued, and any accompanying challenge data.
794 response Non-null response received from client.
802 This method may be called at any time to determine if the
803 authentication process is finished. This method is typically called
804 after each invocation of evaluateResponse() to determine whether the
805 authentication has completed successfully or should be continued.
808 3.4.3 getSecurityLayer
811 getSecurityLayer() throws SaslException
813 Once authentication is complete, this method may be called to obtain
814 an object capable of encoding/decoding data content for the rest of
815 the session. An exception is thrown if authentication is not yet
816 complete. It may return null if the mechanism does not define a
817 security layer, or if none was negotiated.
820 3.4.4 getMechanismName
825 Returns the non-null IANA-registered name of the mechanism used by
826 this server, e.g. "GSSAPI" or "CRAM-MD5".
829 3.4.5 getAuthorizationID
834 Report the authorization ID in effect for the client of this
835 session. If null, a protocol-dependent default is assumed.
838 Expires 12/99 [Page 14]
840 JAVA SASL API June 1999
845 3.5 public interface SaslServerFactory
847 An object implementing this interface can provide a SaslServer.
848 Implementations must be thread-safe and handle multiple simultaneous
852 3.5.1 createSaslServer
855 createSaslServer(String mechanism,
859 javax.security.auth.callback.CallbackHandler cbh)
862 Creates a SaslServer using the mechanism supplied. It returns null
863 if no SaslClient can be created using the parameters supplied.
864 Throws SaslException if it cannot create a SaslClient because of an
867 Returns a possibly null SaslServer which supports the specified
868 mechanism. If null, this factory cannot produce a SaslServer for the
873 mechanism The non-null IANA-registered name of a SASL
874 mechanism (e.g. "GSSAPI", "CRAM-MD5").
876 protocol The non-null string name of the protocol for
877 which the authentication is being performed, e.g
880 serverName The non-null fully qualified host name of the
883 props The possibly null properties to be used by the
884 SASL mechanisms to configure the authentication
885 exchange. See Sasl.createSaslClient for examples
888 cbh The possibly null callback handler to used by the
889 SASL mechanisms to get further information from
890 the application/library to complete the
891 authentication. For example, a SASL mechanism
892 might require the authentication ID and password
893 from the caller. The authentication ID may be
894 requested with a NameCallback, and the password
895 with a PasswordCallback.
898 Expires 12/99 [Page 15]
900 JAVA SASL API June 1999
904 3.5.2 getMechanismNames
909 Returns a non-null array of names of mechanisms supported by this
913 3.6 public class SaslException
916 Exception thrown on errors and failures in authentication.
921 public SaslException()
923 Constructs a new instance of SaslException. The root exception and
924 the detailed message are null.
927 public SaslException(String message)
930 Constructs a default exception with a detailed message and no root
934 public SaslException(String messag,
937 Constructs a new instance of SaslException with a detailed message
938 and a root exception. For example, a SaslException might result from
939 a problem with the callback handler, which might throw a
940 NoSuchCallbackException if it does not support the requested
941 callback, or throw an IOException if it had problems obtaining data
942 for the callback. The SaslException's root exception would be then
943 be the exception thrown by the callback handler.
948 message Possibly null additional detail about the
951 ex A possibly null root exception that caused this
958 Expires 12/99 [Page 16]
960 JAVA SASL API June 1999
967 Returns the possibly null root exception that caused this exception.
970 3.6.3 printStackTrace
975 Prints this exception's stack trace to System.err. If this
976 exception has a root exception, the stack trace of the root
977 exception is printed to System.err instead.
980 printStackTrace(PrintStream ps)
982 Prints this exception's stack trace to a print stream. If this
983 exception has a root exception, the stack trace of the root
984 exception is printed to the print stream instead.
987 printStackTrace(PrintWriter pw)
989 Prints this exception's stack trace to a print writer. If this
990 exception has a root exception, the stack trace of the root
991 exception is printed to the print writer instead.
995 ps The non-null print stream to which to print.
997 pw The non-null print writer to which to print.
1000 3.7 public interface SecurityLayer
1002 An object implementing this interface translates buffers back and
1003 forth during a session, after the authentication process has
1004 completed, to provide a security layer. The security layer may
1005 provide data integrity and/or session privacy.
1011 encode(byte[] inVals, int offset, int count) throws SASLException
1013 Take a protocol-dependent byte array and encode it (encrypt, for
1014 example) for sending to the server.
1018 Expires 12/99 [Page 17]
1020 JAVA SASL API June 1999
1025 inVals A request to be encoded before sending to the
1028 offset The inclusive starting offset in the byte array
1029 inVals to use. 0 <= offset < inVals.length.
1031 count The number of bytes in inVals to use.
1032 0 <= count < inVals.length-offset.
1038 decode(byte[] outVals, int offset, int count) throws SASLException
1040 Take an encoded byte array received from the server and decode it.
1044 outVals A response received from the server, to be
1047 offset The inclusive starting offset in the byte array
1048 outVals to use. 0 <= offset < outVals.length.
1050 count The number of bytes in outVals to use.
1051 0 <= count < outVals.length-offset.
1078 Expires 12/99 [Page 18]
1080 JAVA SASL API June 1999
1082 4 Security Considerations
1084 When SASL authentication is performed over unsecured connections, it
1085 is possible for an active attacker to spoof the server's protocol-
1086 specific indication that authentication is complete. Clients should
1087 protect against this attack by verifying the completion of
1088 authentication with the mechanism driver by calling the driver's
1089 isComplete() method.
1091 Additional security considerations are discussed in [SASL].
1096 [JAAS] Java Software, Sun Microsystems, Inc., "Java Authentication
1097 and Authorization Service," http://java.sun.com/security/jaas,
1100 [SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
1101 RFC 2222, October 1997
1104 6 Authors' Addresses
1107 Netscape Communications Corp.
1108 501 E. Middlefield Rd.
1110 Mountain View, CA 94043-4042
1112 Email: rweltman@netscape.com
1116 Mail Stop UCUP02-206
1117 901 San Antonio Road
1120 Email: rosanna.lee@eng.sun.com
1125 Pittsburgh, PA 15213-3890
1127 Email: earhart@cmu.edu
1132 Scott Seligman of Sun Microsystems, Inc. contributed to the
1133 architecture and API proposed in this document.
1138 Expires 12/99 [Page 19]
1140 JAVA SASL API June 1999
1142 8 Appendix A - Sample java LDAP program using SASL
1144 /****************************************************************
1145 It might look like this in LDAP. The Protocol Driver is
1146 implemented as part of the authenticate method of
1148 ****************************************************************/
1150 public class LDAPConnection {
1151 public void authenticate( String dn,
1154 CallbackHandler cbh )
1155 throws SaslException {
1157 // Create SASL client to use for authentication
1158 SaslClient saslClnt = Sasl.createSaslClient(
1159 mechs, dn, "ldap", getHost(), props, cbh);
1161 if (saslClnt == null) {
1162 throw new SaslException("SASL client not available");
1165 String mechName = saslClnt.getMechanismName();
1166 byte[] response = saslClnt.createInitialResponse();
1168 // Create a bind request message, including the initial
1170 // response (if any), and send it off
1172 LDAPSASLBindResponse msg =
1174 writeRequest( new LDAPSASLBindRequest( dn, mechName,
1178 // Get the server challenge
1179 LDAPSASLBindResponse msg = (LDAPSASLBindResponse)readResponse();
1180 // Authentication done?
1181 while (!saslClnt.isComplete() &&
1182 msg.getStatus() == LDAP_SASL_BIND_IN_PROGRESS) {
1183 // No, get an appropriate next response and send it off
1184 byte[] challenge = msg.getChallenge();
1185 response = saslClnt.evaluateChallenge( challenge );
1186 // May be a success message with no further challenge
1187 if ( response != null ) {
1188 // Wrap the response in another bind request and
1190 writeRequest( new LDAPSASLBindRequest( dn,
1191 mechName, response ) );
1192 msg = (LDAPSASLBindResponse)readResponse();
1195 // Make sure authentication REALLY is complete
1196 if ( !driver.isComplete() ) {
1197 /* Authentication session hijacked! */
1198 throw new SaslException( "SASL session hijacked!" );
1200 // Get the negotiated security layer, if any
1203 Expires 12/99 [Page 20]
1205 JAVA SASL API June 1999
1207 security = saslClnt.getSecurityLayer();
1263 Expires 12/99 [Page 21]
1265 JAVA SASL API June 1999
1267 /****************************************************************
1268 This might be in an application
1269 ****************************************************************/
1272 * A sample callback handler. This implementation is created by
1273 * using the input that it will return. Other implementations are
1274 * typically more sophisticated and might prompt the user on demand
1275 * in order to satisfy the callbacks.
1277 class SimpleCallbackHandler implements CallbackHandler {
1278 private char[] passwd;
1279 private String authenticationID;
1281 SimpleCallbackHandler(String principal, Object cred)
1282 throws IOException {
1283 authenticationID = principal;
1285 if (cred instanceof String) {
1286 passwd = ((String)cred).toCharArray();
1287 } else if (cred instanceof char[]) {
1288 passwd = (char[])((char[])cred).clone();
1289 } else if (cred instanceof byte[]) {
1290 // PasswordCallback expects char[]; assume UTF-8
1292 String orig = new String((byte[])cred, "UTF8");
1293 passwd = orig.toCharArray();
1295 throw new IOException("Unsupported password format: " +
1300 public void invokeCallback(Callback[] callbacks)
1301 throws java.io.IOException, UnsupportedCallbackException {
1302 for (int i = 0; i < callbacks.length; i++) {
1303 if (callbacks[i] instanceof NameCallback) {
1304 ((NameCallback)callbacks[i]).setName(
1307 } else if (callbacks[i] instanceof PasswordCallback) {
1308 ((PasswordCallback)callbacks[i]).setPassword(
1312 UnsupportedCallbackException(callbacks[i]);
1323 Expires 12/99 [Page 22]
1325 JAVA SASL API June 1999
1327 /***************************************************************
1328 And so the application code to do authentication
1329 ***************************************************************/
1331 // Set up all SASL parameters; some may have reasonable defaults
1332 Hashtable props = new Hashtable();
1333 props.add("javax.security.sasl.encryption.minimum", "40");
1334 props.add("javax.security.sasl.encryption.maximum", "128");
1335 props.add("javax.security.sasl.server_authentication", "true");
1336 props.add("javax.security.sasl.maxbuffer", "4096");
1337 // The following two for kerberos v4, only
1338 //props.add("javax.security.sasl.ip.local", "192.68.1.10");
1339 //props.add("javax.security.sasl.ip.remote", "192.68.1.50");
1341 // What we want to authenticate as
1342 String dn = "cn=Directory Manager";
1344 // Create an object for possible use by the authentication
1346 SimpleCallbackHandler cbh = new SimpleCallbackHandler();
1349 // Note: cbh methods may be called during authentication
1350 // Note: "connection" includes the SASL Protocol Driver
1351 // functionality, and it will internally manage a Mechanism
1352 // Driver for GSSAPI, and then a Security Layer object for
1354 String[] mechNames = { "GSSAPI" };
1355 connection.authenticate( dn, mechNames, props, cbh );
1356 } catch ( SaslException e ) {
1357 // Abort, return, maybe try some other authentication
1360 // Okay. From here on, everything goes through security, but the
1361 // methods have the same signatures as if we were not using SASL
1383 Expires 12/99 [Page 23]
1385 JAVA SASL API June 1999
1387 9 Appendix B - Changes from draft-weltman-java-sasl-01.txt
1389 The class hierarchy defined in this document is entirely different
1390 from that defined in the previous document.
1392 For callback handling, the newly released
1393 javax.security.auth.callback package is used.
1443 Expires 12/99 [Page 24]