tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search

RFC 2853

 
 
 

Generic Security Service API Version 2 : Java Bindings

Part 4 of 4, p. 74 to 96
Prev RFC Part

 


prevText      Top      Up      ToC       Page 74 
6.5.  public class MessageProp

   This is a utility class used within the per-message GSSContext
   methods to convey per-message properties.

   When used with the GSSContext interface's wrap and getMIC methods, an
   instance of this class is used to indicate the desired QOP and to
   request if confidentiality services are to be applied to caller
   supplied data (wrap only).  To request default QOP, the value of 0
   should be used for QOP.

   When used with the unwrap and verifyMIC methods of the GSSContext
   interface, an instance of this class will be used to indicate the
   applied QOP and confidentiality services over the supplied message.
   In the case of verifyMIC, the confidentiality state will always be
   "false".  Upon return from these methods, this object will also
   contain any supplementary status values applicable to the processed
   token.  The supplementary status values can indicate old tokens, out
   of sequence tokens, gap tokens or duplicate tokens.

6.5.1.  Constructors

   public MessageProp(boolean privState)

   Constructor which sets QOP to 0 indicating that the default QOP is
   requested.

   Parameters:

      privState The desired privacy state. "true" for privacy and
                "false" for integrity only.


   public MessageProp(int qop, boolean privState)

   Constructor which sets the values for the qop and privacy state.

   Parameters:

      qop       The desired QOP.  Use 0 to request a default QOP.

      privState The desired privacy state. "true" for privacy and
                "false" for integrity only.

Top      Up      ToC       Page 75 
6.5.2.  getQOP

   public int getQOP()

   Retrieves the QOP value.

6.5.3.  getPrivacy

   public boolean getPrivacy()

   Retrieves the privacy state.

6.5.4.  getMinorStatus

   public int getMinorStatus()

   Retrieves the minor status that the underlying mechanism might have
   set.

6.5.5.  getMinorString

   public String getMinorString()

   Returns a string explaining the mechanism specific error code. null
   will be returned when no mechanism error code has been set.

6.5.6.  setQOP

   public void setQOP(int qopVal)

   Sets the QOP value.

   Parameters:

      qopVal    The QOP value to be set.  Use 0 to request a default
                QOP value.

6.5.7.  setPrivacy

   public void setPrivacy(boolean privState)

   Sets the privacy state.

   Parameters:

      privState The privacy state to set.

Top      Up      ToC       Page 76 
6.5.8.  isDuplicateToken

   public boolean isDuplicateToken()

   Returns "true" if this is a duplicate of an earlier token.

6.5.9.  isOldToken

   public boolean isOldToken()

   Returns "true" if the token's validity period has expired.

6.5.10.  isUnseqToken

   public boolean isUnseqToken()

   Returns "true" if a later token has already been processed.

6.5.11.  isGapToken

   public boolean isGapToken()

   Returns "true" if an expected per-message token was not received.

6.5.12.  setSupplementaryStates

   public void setSupplementaryStates(boolean duplicate,
                   boolean old, boolean unseq, boolean gap,
                   int minorStatus, String minorString)

   This method sets the state for the supplementary information flags
   and the minor status in MessageProp.  It is not used by the
   application but by the GSS implementation to return this information
   to the caller of a per-message context method.

   Parameters:

      duplicate true if the token was a duplicate of an earlier token,
                false otherwise

      old       true if the token's validity period has expired, false
                otherwise

      unseq     true if a later token has already been processed,
                false otherwise

      gap       true if one or more predecessor tokens have not yet
                been successfully processed, false otherwise

Top      Up      ToC       Page 77 
      minorStatus   the integer minor status code that the underlying
                    mechanism wants to set

      minorString   the textual representation of the minorStatus
                    value

6.6.  public class ChannelBinding

   The GSS-API accommodates the concept of caller-provided channel
   binding information.  Channel bindings are used to strengthen the
   quality with which peer entity authentication is provided during
   context establishment.  They enable the GSS-API callers to bind the
   establishment of the security context to relevant characteristics
   like addresses or to application specific data.

   The caller initiating the security context must determine the
   appropriate channel binding values to set in the GSSContext object.
   The acceptor must provide an identical binding in order to validate
   that received tokens possess correct channel-related characteristics.

   Use of channel bindings is optional in GSS-API.  Since channel-
   binding information may be transmitted in context establishment
   tokens, applications should therefore not use confidential data as
   channel-binding components.

6.6.1.  Constructors

   public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr,
                   byte[] appData)

   Create a ChannelBinding object with user supplied address information
   and data.  "null" values can be used for any fields which the
   application does not want to specify.

   Parameters:

      initAddr  The address of the context initiator.  "null" value
                can be supplied to indicate that the application does
                not want to set this value.

      acceptAddrThe address of the context acceptor.  "null" value can
                be supplied to indicate that the application does not
                want to set this value.

      appData   Application supplied data to be used as part of the
                channel bindings.  "null" value can be supplied to
                indicate that the application does not want to set
                this value.

Top      Up      ToC       Page 78 
   public ChannelBinding(byte[] appData)

   Creates a ChannelBinding object without any addressing information.

   Parameters:

      appData   Application supplied data to be used as part of the
                channel bindings.

6.6.2.  getInitiatorAddress

   public InetAddress getInitiatorAddress()

   Returns the initiator's address for this channel binding. "null" is
   returned if the address has not been set.

6.6.3.  getAcceptorAddress

   public InetAddress getAcceptorAddress()

   Returns the acceptor's address for this channel binding. "null" is
   returned if the address has not been set.

6.6.4.  getApplicationData

   public byte[] getApplicationData()

   Returns application data being used as part of the ChannelBinding.
   "null" is returned if no application data has been specified for the
   channel binding.

6.6.5.  equals

   public boolean equals(Object obj)

   Returns "true" if two channel bindings match. (Note that the Java
   language specification requires that two objects that are equal
   according to the equals(Object) method must return the same integer
   result when the hashCode() method is called on them.)

   Parameters:

      obj       Another channel binding to compare with.

Top      Up      ToC       Page 79 
6.7.  public class Oid

   This class represents Universal Object Identifiers (Oids) and their
   associated operations.

   Oids are hierarchically globally-interpretable identifiers used
   within the GSS-API framework to identify mechanisms and name formats.

   The structure and encoding of Oids is defined in ISOIEC-8824 and
   ISOIEC-8825.  For example the Oid representation of Kerberos V5
   mechanism is "1.2.840.113554.1.2.2"

   The GSSName name class contains public static Oid objects
   representing the standard name types defined in GSS-API.

6.7.1.  Constructors

   public Oid(String strOid) throws GSSException

   Creates an Oid object from a string representation of its integer
   components (e.g. "1.2.840.113554.1.2.2").

   Parameters:

      strOid    The string representation for the oid.

   public Oid(InputStream derOid) throws GSSException

   Creates an Oid object from its DER encoding.  This refers to the full
   encoding including tag and length.  The structure and encoding of
   Oids is defined in ISOIEC-8824 and ISOIEC-8825.  This method is
   identical in functionality to its byte array counterpart.

   Parameters:

      derOid    Stream containing the DER encoded oid.

   public Oid(byte[] DEROid) throws GSSException

   Creates an Oid object from its DER encoding.  This refers to the full
   encoding including tag and length.  The structure and encoding of
   Oids is defined in ISOIEC-8824 and ISOIEC-8825.  This method is
   identical in functionality to its byte array counterpart.

   Parameters:

      derOid    Byte array storing a DER encoded oid.

Top      Up      ToC       Page 80 
6.7.2.  toString

   public String toString()

   Returns a string representation of the oid's integer components in
   dot separated notation (e.g. "1.2.840.113554.1.2.2").

6.7.3.  equals

   public boolean equals(Object Obj)

   Returns "true" if the two Oid objects represent the same oid value.
   (Note that the Java language specification requires that two objects
   that are equal according to the equals(Object) method must return the
   same integer result when the hashCode() method is called on them.)

   Parameters:

      obj       Another Oid object to compare with.

6.7.4.  getDER

   public byte[] getDER()

   Returns the full ASN.1 DER encoding for this oid object, which
   includes the tag and length.

6.7.5.  containedIn

   public boolean containedIn(Oid[] oids)

   A utility method to test if an Oid object is contained within the
   supplied Oid object array.

   Parameters:

      oids      An array of oids to search.

6.8.  public class GSSException extends Exception

   This exception is thrown whenever a fatal GSS-API error occurs
   including mechanism specific errors.  It may contain both, the major
   and minor, GSS-API status codes.  The mechanism implementers are
   responsible for setting appropriate minor status codes when throwing
   this exception.  Aside from delivering the numeric error code(s) to
   the caller, this class performs the mapping from their numeric values
   to textual representations.  All Java GSS-API methods are declared
   throwing this exception.

Top      Up      ToC       Page 81 
   All implementations are encouraged to use the Java
   internationalization techniques to provide local translations of the
   message strings.

6.8.1.  Static Constants

   All valid major GSS-API error code values are declared as constants
   in this class.

   public static final int BAD_BINDINGS

   Channel bindings mismatch error.


   public static final int BAD_MECH

   Unsupported mechanism requested error.


   public static final int BAD_NAME

   Invalid name provided error.


   public static final int BAD_NAMETYPE

   Name of unsupported type provided error.


   public static final int BAD_STATUS

   Invalid status code error - this is the default status value.


   public static final int BAD_MIC

   Token had invalid integrity check error.


   public static final int CONTEXT_EXPIRED

   Specified security context expired error.


   public static final int CREDENTIALS_EXPIRED

   Expired credentials detected error.

Top      Up      ToC       Page 82 
   public static final int DEFECTIVE_CREDENTIAL

   Defective credential error.


   public static final int DEFECTIVE_TOKEN

   Defective token error.


   public static final int FAILURE

   General failure, unspecified at GSS-API level.


   public static final int NO_CONTEXT

   Invalid security context error.


   public static final int NO_CRED

   Invalid credentials error.


   public static final int BAD_QOP

   Unsupported QOP value error.


   public static final int UNAUTHORIZED

   Operation unauthorized error.


   public static final int UNAVAILABLE

   Operation unavailable error.


   public static final int DUPLICATE_ELEMENT

   Duplicate credential element requested error.


   public static final int NAME_NOT_MN

   Name contains multi-mechanism elements error.

Top      Up      ToC       Page 83 
   public static final int DUPLICATE_TOKEN

   The token was a duplicate of an earlier token.  This is a fatal error
   code that may occur during context establishment.  It is not used to
   indicate supplementary status values.  The MessageProp object is used
   for that purpose.

   public static final int OLD_TOKEN

   The token's validity period has expired.  This is a fatal error code
   that may occur during context establishment.  It is not used to
   indicate supplementary status values.  The MessageProp object is used
   for that purpose.

   public static final int UNSEQ_TOKEN

   A later token has already been processed.  This is a fatal error code
   that may occur during context establishment.  It is not used to
   indicate supplementary status values.  The MessageProp object is used
   for that purpose.

   public static final int GAP_TOKEN

   An expected per-message token was not received.  This is a fatal
   error code that may occur during context establishment.  It is not
   used to indicate supplementary status values.  The MessageProp object
   is used for that purpose.

6.8.2.  Constructors

   public GSSException(int majorCode)

   Creates a GSSException object with a specified major code.

   Parameters:

      majorCode The GSS error code causing this exception to be
                thrown.

   public GSSException(int majorCode, int minorCode, String minorString)

   Creates a GSSException object with the specified major code, minor
   code, and minor code textual explanation.  This constructor is to be
   used when the exception is originating from the security mechanism.
   It allows to specify the GSS code and the mechanism code.

Top      Up      ToC       Page 84 
   Parameters:

      majorCode      The GSS error code causing this exception to be
                     thrown.

      minorCode      The mechanism error code causing this exception
                     to be thrown.

      minorString    The textual explanation of the mechanism error
                     code.

6.8.3.  getMajor

   public int getMajor()

   Returns the major code representing the GSS error code that caused
   this exception to be thrown.

6.8.4.  getMinor

   public int getMinor()

   Returns the mechanism error code that caused this exception.  The
   minor code is set by the underlying mechanism.  Value of 0 indicates
   that mechanism error code is not set.

6.8.5.  getMajorString

   public String getMajorString()

   Returns a string explaining the GSS major error code causing this
   exception to be thrown.

6.8.6.  getMinorString

   public String getMinorString()

   Returns a string explaining the mechanism specific error code.  null
   will be returned when no mechanism error code has been set.

6.8.7.  setMinor

   public void setMinor(int minorCode, String message)

   Used internally by the GSS-API implementation and the underlying
   mechanisms to set the minor code and its textual representation.

Top      Up      ToC       Page 85 
   Parameters:

      minorCode The mechanism specific error code.

      message   A textual explanation of the mechanism error code.

6.8.8.  toString

   public String toString()

   Returns a textual representation of both the major and minor status
   codes.

6.8.9.  getMessage

   public String getMessage()

   Returns a detailed message of this exception.  Overrides
   Throwable.getMessage.  It is customary in Java to use this method to
   obtain exception information.

7.  Sample Applications

7.1.  Simple GSS Context Initiator

   import org.ietf.jgss.*;

   /**
    * This is a partial sketch for a simple client program that acts
    * as a GSS context initiator.  It illustrates how to use the Java
    * bindings for the GSS-API specified in
    * Generic Security Service API Version 2 : Java bindings
    *
    *
    * This code sketch assumes the existence of a GSS-API
    * implementation that supports the mechanism that it will need and
    * is present as a library package (org.ietf.jgss) either as part of
    * the standard JRE or in the CLASSPATH the application specifies.
    */

   public class SimpleClient {

       private String serviceName; // name of peer (ie. server)
       private GSSCredential clientCred = null;
       private GSSContext context = null;
       private Oid mech; // underlying mechanism to use

       private GSSManager mgr = GSSManager.getInstance();

Top      Up      ToC       Page 86 
       ...
       ...

       private void clientActions() {
           initializeGSS();
           establishContext();
           doCommunication();
       }

       /**
        * Acquire credentials for the client.
        */
       private void initializeGSS() {

           try {

               clientCred = mgr.createCredential(null /*default princ*/,
                   GSSCredential.INDEFINITE_LIFETIME /* max lifetime */,
                   mech /* mechanism  to use */,
                   GSSCredential.INITIATE_ONLY /* init context */);

               print("GSSCredential created for " +
                     cred.getName().toString());
               print("Credential lifetime (sec)=" +
                     cred.getRemainingLifetime());
           } catch (GSSException e) {
                   print("GSS-API error in credential acquisition: "
                         + e.getMessage());
                   ...
                   ...
           }

           ...
           ...
       }

       /**
        * Does the security context establishment with the
        * server.
        */
       private void establishContext() {

           byte[] inToken = new byte[0];
           byte[] outToken = null;

           try {

               GSSName peer = mgr.createName(serviceName,

Top      Up      ToC       Page 87 
                                  GSSName.NT_HOSTBASED_SERVICE);

               context = mgr.createContext(peer, mech, gssCred,
                        GSSContext.INDEFINITE_LIFETIME/*lifetime*/);

               // Will need to support confidentiality
               context.requestConf(true);

               while (!context.isEstablished()) {

                   outToken = context.initSecContext(inToken, 0,
                                                     inToken.length);

                   if (outToken != null)
                       writeGSSToken(outToken);

                   if (!context.isEstablished())
                       inToken = readGSSToken();
               }

               GSSName peer = context.getSrcName();
               print("Security context established with " + peer +
                     " using underlying mechanism " + mech.toString());
           } catch (GSSException e) {
                   print("GSS-API error during context establishment: "
                         + e.getMessage());
               ...
               ...
           }

           ...
           ...
       }

       /**
        * Sends some data to the server and reads back the
        * response.
        */
       private void doCommunication()  {
               byte[] inToken = null;
               byte[] outToken = null;
               byte[] buffer;

               // Container for multiple input-output arguments to and
               // from the per-message routines (e.g., wrap/unwrap).
               MessageProp messgInfo = new MessageProp();

               try {

Top      Up      ToC       Page 88 
                   /*
                    * Now send some bytes to the server to be
                    * processed. They will be integrity protected but
                    * not encrypted for privacy.
                    */

                   buffer = readFromFile();

                   // Set privacy to false and use the default QOP
                   messgInfo.setPrivacy(false);

                   outToken = context.wrap(buffer, 0, buffer.length,
                                           messgInfo);

                   writeGSSToken(outToken);

                   /*
                    * Now read the response from the server.
                    */

                   inToken = readGSSToken();
                   buffer = context.unwrap(inToken, 0, inToken.length,
                                           messgInfo);
                   // All ok if no exception was thrown!

                   GSSName peer = context.getSrcName();

                   print("Message from "       + peer.toString()
                         + " arrived.");
                   print("Was it encrypted? "  +
                         messgInfo.getPrivacy());
                   print("Duplicate Token? "   +
                         messgInfo.isDuplicateToken());
                   print("Old Token? "         +
                         messgInfo.isOldToken());
                   print("Unsequenced Token? " +
                         messgInfo.isUnseqToken());
                   print("Gap Token? "         +
                         messgInfo.isGapToken());

                   ...
                   ...

               } catch (GSSException e) {
                   print("GSS-API error in per-message calls: "
                         + e.getMessage());
                   ...
                   ...

Top      Up      ToC       Page 89 
               }

               ...

               ...

       } // end of doCommunication method

       ...
       ...

   } // end of class SimpleClient

7.2.  Simple GSS Context Acceptor

   import org.ietf.jgss.*;

   /**
    * This is a partial sketch for a simple server program that acts
    * as a GSS context acceptor. It illustrates how to use the Java
    * bindings for the GSS-API specified in
    * Generic Security Service API Version 2 : Java bindings
    *
    * This code sketch assumes the existence of a GSS-API
    * implementation that supports the mechanisms that it will need and
    * is present as a library package (org.ietf.jgss) either as part of
    * the standard JRE or in the CLASSPATH the application specifies.
    */

   import org.ietf.jgss.*;

   public class SimpleServer {

       private String serviceName;
       private GSSName name;
       private GSSCredential cred;

       private GSSManager mgr;

       ...
       ...

       /**
        * Wait for client connections, establish security contexts and
        * provide service.
        */
       private void loop() {

Top      Up      ToC       Page 90 
       ...
       ...

           mgr = GSSManager.getInstance();

           name = mgr.createName(serviceName,
                      GSSName.NT_HOSTBASED_SERVICE);

           cred = mgr.createCredential(name,
                      GSSCredential.INDEFINITE_LIFETIME,
                      null,
                      GSSCredential.ACCEPT_ONLY);


           // Loop infinitely
           while (true) {

               Socket s = serverSock.accept();

               // Start a new thread to serve this connection
               Thread serverThread = new ServerThread(s);
               serverThread.start();

           }
       }

       /**
        * Inner class ServerThread whose run() method provides the
        * secure service to a connection.
        */

       private class ServerThread extends Thread {

       ...
       ...

           /**
            * Deals with the connection from one client. It also
            * handles all GSSException's thrown while talking to
            * this client.
            */
           public void run() {

               byte[] inToken = null;
               byte[] outToken = null;
               byte[] buffer;

               GSSName peer;

Top      Up      ToC       Page 91 
               // Container for multiple input-output arguments to and
               // from the per-message routines (ie. wrap/unwrap).
               MessageProp supplInfo = new MessageProp();

               GSSContext secContext = null;

               try {


                   // Now do the context establishment loop

                   GSSContext context = mgr.createContext(cred);

                   while (!context.isEstablished()) {

                       inToken = readGSSToken();

                       outToken = context.acceptSecContext(inToken, 0,
                                                   inToken.length);

                       if (outToken != null)
                           writeGSSToken(outToken);

                   }


                   // SimpleServer wants confidentiality to be
                   // available. Check for it.
                   if (!context.getConfState()){
                       ...
                       ...
                   }

                   GSSName peer = context.getSrcName();
                   Oid mech = context.getMech();
                   print("Security context established with " +
                         peer.toString() +
                         " using underlying mechanism " +
                         mech.toString() +
                         " from Provider " +
                         context.getProvider().getName());


                   // Now read the bytes sent by the client to be
                   // processed.
                   inToken = readGSSToken();

                   // Unwrap the message

Top      Up      ToC       Page 92 
                   buffer = context.unwrap(inToken, 0, inToken.length,
                                             supplInfo);
                   // All ok if no exception was thrown!

                   // Print other supplementary per-message status
                   // information

                   print("Message from " +
                           peer.toString() + " arrived.");
                   print("Was it encrypted? " +
                           supplInfo.getPrivacy());
                   print("Duplicate Token? " +
                           supplInfo.isDuplicateToken());
                   print("Old Token? "  + supplInfo.isOldToken());
                   print("Unsequenced Token? " +
                           supplInfo.isUnseqToken());
                   print("Gap Token? "  + supplInfo.isGapToken());

                   /*
                    * Now process the bytes and send back an encrypted
                    * response.
                    */

                   buffer = serverProcess(buffer);

                   // Encipher it and send it across

                   supplInfo.setPrivacy(true); // privacy requested
                   supplInfo.setQOP(0); // default QOP
                   outToken = context.wrap(buffer, 0, buffer.length,
                                              supplInfo);
                   writeGSSToken(outToken);

               } catch (GSSException e) {
                   print("GSS-API Error: " + e.getMessage());
                   // Alternatively, could call e.getMajorMessage()
                   // and e.getMinorMessage()
                   print("Abandoning security context.");

                   ...
                   ...

               }

               ...
               ...

           } // end of run method in ServerThread

Top      Up      ToC       Page 93 
       } // end of inner class ServerThread

       ...
       ...

   } // end of class SimpleServer

8.  Security Considerations

   The Java language security model allows platform providers to have
   policy based fine-grained access control over any resource that an
   application wants. When using a Java security manager (such as, but
   not limited to, the case of applets running in browsers) the
   application code is in a sandbox by default.

   Administrators of the platform JRE determine what permissions, if
   any, are to be given to source from different codebases. Thus the
   administrator has to be aware of any special requirements that the
   GSS provider might have for system resources. For instance, a
   Kerberos provider might wish to make a network connection to the KDC
   to obtain initial credentials. This would not be allowed under the
   sandbox unless the administrator had granted permissions for this.
   Also note that this granting and checking of permissions happens
   transparently to the application and is outside the scope of this
   document.

   The Java language allows administrators to pre-configure a list of
   security service providers in the <JRE>/lib/security/java.security
   file. At runtime, the system approaches these providers in order of
   preference when looking for security related services. Applications
   have a means to modify this list through methods in the "Security"
   class in the "java.security" package. However, since these
   modifications would be visible in the entire JVM and thus affect all
   code executing in it, this operation is not available in the sandbox
   and requires special permissions to perform. Thus when a GSS
   application has special needs that are met by a particular security
   provider, it has two choices:

      1) To install the provider on a JVM wide basis using the
         java.security.Security class and then depend on the system to
         find the right provider automatically when the need arises.
         (This would require the application to be granted a
         "insertProvider SecurityPermission".)

      2) To pass an instance of the provider to the local instance of
         GSSManager so that only factory calls going through that
         GSSManager use the desired provider. (This would not require
         any permissions.)

Top      Up      ToC       Page 94 
9.  Acknowledgments

   This proposed API leverages earlier work performed by the IETF's CAT
   WG as outlined in both RFC 2743 and RFC 2744.  Many conceptual
   definitions, implementation directions, and explanations have been
   included from these documents.

   We would like to thank Mike Eisler, Lin Ling, Ram Marti, Michael
   Saltz and other members of Sun's development team for their helpful
   input, comments and suggestions.

   We would also like to thank Joe Salowey, and Michael Smith for many
   insightful ideas and suggestions that have contributed to this
   document.

10.  Bibliography

   [GSSAPIv2]        Linn, J., "Generic Security Service Application
                     Program Interface, Version 2", RFC 2078, January
                     1997.

   [GSSAPIv2-UPDATE] Linn, J., "Generic Security Service Application
                     Program Interface, Version 2, Update 1", RFC 2743,
                     January 2000.

   [GSSAPI-Cbind]    Wray, J., "Generic Security Service API Version 2 :
                     C-bindings", RFC 2744, January 2000.

   [KERBV5]          Linn, J., "The Kerberos Version 5 GSS-API
                     Mechanism", RFC 1964, June 1996.

   [SPKM]            Adams, C., "The Simple Public-Key GSS-API
                     Mechanism", RFC 2025, October 1996.

Top      Up      ToC       Page 95 
11.  Authors' Addresses

   Address comments related to this memorandum to:

        <cat-ietf@mit.edu>

   Jack Kabat
   ValiCert, Inc.
   339 N. Bernardo Avenue
   Mountain View, CA
   94043, USA

   Phone: +1-650-567-5496
   EMail: jackk@valicert.com


   Mayank Upadhyay
   Sun Microsystems, Inc.
   901 San Antonio Road, MS CUP02-102
   Palo Alto, CA 94303

   Phone: +1-408-517-5956
   EMail: mdu@eng.sun.com

Top      Up      ToC       Page 96 
12.  Full Copyright Statement

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

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

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

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

Acknowledgement

   Funding for the RFC Editor function is currently provided by the
   Internet Society.