ONC RPC Working Group                                      M. Eisler
Internet Draft                                             A. Chiu
Document: draft-oncrpc-rpcsec_gss-00.txt                   L. Ling
                                                            22 July 1996


                   RPCSEC_GSS Protocol Specification

Abstract

   This memo describes an ONC/RPC security flavor that allows RPC
   protocols to access the Generic Security Services Application
   Programming Interface (referred to henceforth as GSS-API).

Status of this Memo

   This document is an Internet-Draft.  Internet-Drafts are working
   documents of the Internet Engineering 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.  This Internet-Draft expires on January 22, 1997.  Internet-
   Drafts may be updated, replaced, or obsoleted by other documents at
   any time. It is not appropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   To learn the current status of any Internet-Draft, please check the
   "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
   Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
   munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
   ftp.isi.edu (US West Coast).

   Distribution of this memo is unlimited.


Table of Contents

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
   2.  Review of the RPC Message Protocol . . . . . . . . . . . . . . 2
   3.  Flavor number assignment . . . . . . . . . . . . . . . . . . . 5
   4.  New auth_stat values . . . . . . . . . . . . . . . . . . . . . 6
   5.  Elements of the RPCSEC_GSS Security Protocol . . . . . . . . . 6
   5.1.  Version Negotiation  . . . . . . . . . . . . . . . . . . . . 7
   5.1.1.  Version Inquiry Requests . . . . . . . . . . . . . . . . . 7
   5.1.2.  Version Inquiry Responses  . . . . . . . . . . . . . . . . 8
   5.1.2.1.  Normal Version Inquiry Responses . . . . . . . . . . . . 8
   5.1.2.2.  Abnormal Version Inquiry Responses . . . . . . . . . . . 9



Expires: January 22, 1997                                       [Page 1]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   5.2.  Context Creation . . . . . . . . . . . . . . . . . . . . .  10
   5.2.1.  Context Creation Requests  . . . . . . . . . . . . . . .  10
   5.2.2.  Context Creation Responses . . . . . . . . . . . . . . .  11
   5.2.2.1.  Context Creation Response - Successful Acceptance  . .  11
   5.2.2.1.1.  Client Processing of Successful Context Creation
               Responses  . . . . . . . . . . . . . . . . . . . . .  12
   5.2.2.2.  Context Creation Response - Unsuccessful Cases . . . .  13
   5.3.  RPC Data Exchange  . . . . . . . . . . . . . . . . . . . .  13
   5.3.1.  RPC Request Header . . . . . . . . . . . . . . . . . . .  13
   5.3.2.  RPC Request Data . . . . . . . . . . . . . . . . . . . .  14
   5.3.2.1.  RPC Request Data - No Data Integrity . . . . . . . . .  14
   5.3.2.2.  RPC Request Data - With Data Integrity . . . . . . . .  14
   5.3.2.3.  RPC Request Data - With Data Privacy . . . . . . . . .  15
   5.3.3.  Server Processing of RPC Data Requests . . . . . . . . .  16
   5.3.3.1.  Context Management . . . . . . . . . . . . . . . . . .  16
   5.3.3.2.  Server Reply - Request Accepted  . . . . . . . . . . .  17
   5.3.3.3.  Server Reply - Request Denied  . . . . . . . . . . . .  18
   5.4.  Context Destruction  . . . . . . . . . . . . . . . . . . .  19
   6.  Security Considerations  . . . . . . . . . . . . . . . . . .  19
   6.1.  Privacy of Call Header . . . . . . . . . . . . . . . . . .  19
   6.2.  Sequence number attacks  . . . . . . . . . . . . . . . . .  20
   6.3.  Message stealing attacks . . . . . . . . . . . . . . . . .  20
   7.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . .  20
   8.  References . . . . . . . . . . . . . . . . . . . . . . . . .  21
   9.  Authors' Addresses . . . . . . . . . . . . . . . . . . . . .  21

1.  Introduction

   This document describes the protocol used by the RPCSEC_GSS security
   flavor.  Security flavors have been called authentication flavors for
   historical reasons. This memo recognizes that there are two other
   security services besides authentication, integrity, and privacy, and
   so defines a new RPCSEC_GSS security flavor.

   The protocol is described using the XDR language [Srinivasan-xdr].
   The reader is assumed to be familiar with ONC RPC and the security
   flavor mechanism [Srinivasan-rpc].  The reader is also assumed to be
   familiar with the GSS-API framework [Linn].  The RPCSEC_GSS security
   flavor uses GSS-API interfaces to provide security services that are
   independent of the underlying security mechanism.

2.  Review of the RPC Message Protocol

   This memo refers to several fields of the RPC protocol. For
   convenience, the XDR language description of the RPC message protocol
   is reproduced here.

      /* RPC message type */



Expires: January 22, 1997                                       [Page 2]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


      enum msg_type {
          CALL  = 0,
          REPLY = 1
      };

      /* Reply types */

      enum reply_stat {
          MSG_ACCEPTED = 0,
          MSG_DENIED   = 1
      };

      /* Security flavors */

      enum auth_flavor {
          AUTH_NONE = 0,
          AUTH_SYS = 1,
          AUTH_SHORT = 2
      };

      /* Status of accepted messages */

      enum accept_stat {
          SUCCESS = 0,
          PROG_UNAVAIL = 1,
          PROG_MISMATCH = 2,
          PROC_UNAVAIL = 3,
          GARBAGE_ARGS = 4,
          SYSTEM_ERR = 5
      };

      /* Status of rejected messages */

      enum reject_stat {
          RPC_MISMATCH = 0,
          AUTH_ERROR = 1
      };

      /* Why authentication failed */

      enum auth_stat {
          AUTH_OK = 0,

          /* failed at remote end */

          AUTH_BADCRED = 1,
          AUTH_REJECTEDCRED = 2,
          AUTH_BADVERF = 3,



Expires: January 22, 1997                                       [Page 3]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


          AUTH_REJECTEDVERF = 4,
          AUTH_TOOWEAK = 5,

          /* failed locally */

          AUTH_INVALIDRESP = 6,
          AUTH_FAILED = 7
      };

      /* Opaque structure of credential and verifier */

      struct opaque_auth {
          auth_flavor flavor;
          opaque body<400>;
      };

      /* The RPC message */

      struct rpc_msg {
          unsigned int xid;
          union switch (msg_type mtype) {
          case CALL:
              call_body cbody;
          case REPLY:
              reply_body rbody;
          } body;
      };

      /* Body of RPC call */

      struct call_body {
          unsigned int rpcvers;
          unsigned int prog;
          unsigned int vers;
          unsigned int proc;
          opaque_auth  cred;
          opaque_auth  verf;

          /* procedure specific parameters start here */
      };

      /* Body of RPC reply */

      union reply_body switch (reply_stat stat) {
      case MSG_ACCEPTED:
          accepted_reply areply;
      case MSG_DENIED:
          rejected_reply rreply;



Expires: January 22, 1997                                       [Page 4]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


      } reply;

      /* Accepted reply */

      struct accepted_reply {
          opaque_auth verf;
          union switch (accept_stat stat) {
          case SUCCESS:
              opaque results[0];

              /* procedure-specific results start here */

          case PROG_MISMATCH:
              struct {
                  unsigned int low;
                  unsigned int high;
              } mismatch_info;

          default:

              /*
               * Void.  Cases include PROG_UNAVAIL,
               * PROC_UNAVAIL, GARBAGE_ARGS, and
               * SYSTEM_ERR.
               */

              void;
          } reply_data;
      };

      /* Rejected reply */

      union rejected_reply switch (reject_stat stat) {
      case RPC_MISMATCH:
          struct {
              unsigned int low;
              unsigned int high;
          } mismatch_info;
      case AUTH_ERROR:
          auth_stat stat;
      };

3.  Flavor number assignment

   The RPCSEC_GSS security flavor has been assigned the value of 6:

      enum auth_flavor {
          ...



Expires: January 22, 1997                                       [Page 5]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


          RPCSEC_GSS = 6      /* RPCSEC_GSS security flavor */
      };

4.  New auth_stat values

   RPCSEC_GSS requires the addition of two new values to the auth_stat
   enumerated type definition:

      enum auth_stat {
              ...
              /*
               * GSS related errors
               */
              RPCSEC_GSS_NOCRED = 13,
              RPCSEC_GSS_FAILED = 14
      };
   The descriptions of these two new values are defined later in this
   memo.

5.  Elements of the RPCSEC_GSS Security Protocol

   An RPC session based on the RPCSEC_GSS security flavor consists of
   four phases: version negotiation, context creation, RPC data
   exchange, and context destruction.  In the following discussion,
   protocol elements for these four phases are described.

   The following description of the RPCSEC_GSS protocol uses some of the
   definitions within XDR language description of the RPC protocol.

   Version negotiation, context creation and destruction use control
   messages that are not dispatched to service procedures registered by
   an RPC server.  The program and version numbers used in these control
   messages are the same as the service program and version numbers.
   The procedure number used is NULLPROC (zero).  A field in the
   credential information (the gss_proc field) specifies whether a
   message is to be interpreted as a control message or a regular RPC
   message.  If this field is set to RPCSEC_GSS_DATA, no control action
   is implied; in this case, it is a regular data message.  If this
   field is set to any other value, a control action is implied.  This
   is described in the following sections.

   The following definitions are used for describing the protocol.

      /* RPCSEC_GSS control procedures */

      #define RPCSEC_GSS_DATA 0
      #define RPCSEC_GSS_INIT 1
      #define RPCSEC_GSS_CONTINUE_INIT 2



Expires: January 22, 1997                                       [Page 6]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


      #define RPCSEC_GSS_DESTROY 3

      /* RPCSEC_GSS services */

      enum rpc_gss_service_t {
          /* Note: the enumerated value for 0 is reserved. */
          rpc_gss_svc_none = 1,
          rpc_gss_svc_integrity = 2,
          rpc_gss_svc_privacy = 3
      };

      /* Credential */

      #define RPCSEC_GSS_INQUIRE_VERS 0 /* version negotiation */
      #define RPCSEC_GSS_VERS_1 1

      struct rpc_gss_cred_t {
          union switch (unsigned int version) { /* version of RPCSEC_GSS */
          case RPCSEC_GSS_INQUIRE_VERS
              struct {
                  unsigned int inquire_vers;
              } rpc_gss_cred_vers_0_t;

          case RPCSEC_GSS_VERS_1:
              struct {
                  unsigned int gss_proc;  /* control procedure */
                  unsigned int seq_num;   /* sequence number */
                  rpc_gss_service_t service; /* service used */
                  opaque handle<>;       /* context handle */
              } rpc_gss_cred_vers_1_t;
          }
      };

      /* Maximum sequence number value */

      #define MAXSEQ 0x80000000

5.1.  Version Negotiation

   Before establishing a context, the RPC client needs to know which
   version of the RPCSEC_GSS protocol the client and server both use.
   Currently, aside from version zero (a control version) there is only
   one version (RPCSEC_GSS_VERS_1), so this part of RPCSEC_GSS is
   allowing for the possibility of future versions.

5.1.1.  Version Inquiry Requests

   The first RPC request from the client to the server inquires the



Expires: January 22, 1997                                       [Page 7]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   versions of RPCSEC_GSS supported on the server.  Within the RPC
   message protocol's call_body structure, rpcvers is set to 2. prog and
   vers are always those for the service being accessed.  The proc is
   always set to NULLPROC (zero).

   Within the RPC message protocol's cred structure, flavor is set to
   RPCSEC_GSS (6).  The opaque data of the cred structure (the body
   field) constituting the credential encodes the rpc_gss_cred_t
   structured defined previously.  The version field of rpc_gss_cred_t
   struct is set to RPCSEC_GSS_INQUIRE_VERS (zero). The inquire_vers
   field is set to version of RPCSEC_GSS that the client wishes to use.
   inquire_ver must be equal to 1. As is normal for NULLPROC requests,
   the call arguments are void.

5.1.2.  Version Inquiry Responses

5.1.2.1.  Normal Version Inquiry Responses

   A normal response to a version inquiry request has the RPC message's
   stat field in the reply_body set to an MSG_ACCEPTED response with a
   status of SUCCESS.  The verifier (the verf element in the response)
   has the flavor field set to RPCSEC_GSS, and body field encodes the
   following structure:

      struct rpc_gss_vers_verf_t {
          union switch (bool_t inquire_vers_supported)
          case TRUE:
              void;
          case FALSE:
              boot_t inquire_vers_in_hole;
              unsigned int low;
              unsigned int high;
      };

   The server must use the following algorithm to compute the contents
   of the verifier:

      if (version in credential is one of server's supported versions) {
          inquire_vers_supported = TRUE;
      } else if (version < server's lowest supported version) {
          inquire_vers_supported = FALSE;
          inquire_vers_in_hole = FALSE;
          low = server's lowest supported version;
          high = server's highest support version;
      } else if (version > server's highest supported version) {
          inquire_vers_supported = FALSE;
          inquire_vers_in_hole = FALSE;
          low = server's lowest supported version;



Expires: January 22, 1997                                       [Page 8]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


          high = server's highest supported version;
      } else {
          /*
           * client has hit a "hole" in range of server's
           * support versions
           */

          inquire_vers_supported = FALSE;
          inquire_vers_in_hole = TRUE;
          low = server's highest supported version
              that is < inquire_vers;
          high = server's lowest supported version
              that is > inquire_vers;
      }

   The server must never return values for low and high that are equal
   to 0.  As is normal for NULLPROC responses, the server must encode
   void results after the verifier.

   In the event inquire_ver_supported is FALSE, the client selects a
   version it supports within the range specified by low and high, and
   retries the version inquiry request.  If there are holes in range of
   versions the server supports, it is possible another mismatch
   indication will be returned. The client and server can then iterate
   to find a common version, or until the client determines that it and
   the server have no common version of the RPCSEC_GSS protocol.  The
   client should initially be optimistic and use the highest version of
   RPCSEC_GSS it supports when setting the inquire_vers field in the
   version inquiry request.

5.1.2.2.  Abnormal Version Inquiry Responses

   An MSG_ACCEPTED reply (to a version inquiry request) with an
   acceptance status of other than SUCCESS has a NULL verifier (flavor
   of AUTH_NONE and zero octets of data in the body field), and is
   formulated as usual for different status values.

   An MSG_DENIED reply (to a version inquiry request) is also formulated
   as usual.  Note that MSG_DENIED could be returned because the
   server's RPC implementation does not recognize the RPCSEC_GSS
   security flavor.  RFC 1831 does not specify the appropriate reply
   status in this instance.  Solaris 2 implementations return a
   rejection status of AUTH_ERROR with an auth_stat of
   AUTH_REJECTEDCRED. Even though two new values (RPCSEC_GSS_NOCRED and
   RPCSEC_GSS_FAILED) have been defined for the auth_stat type, neither
   of these two can be returned in responses to version inquiry
   requests.  The new values are relevant to for responses to normal
   (data) requests.  This is described later.



Expires: January 22, 1997                                       [Page 9]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


5.2.  Context Creation

   Before RPC data is exchanged on a session using the RPCSEC_GSS
   flavor, a context must be set up between the client and the server.
   Context creation may involve zero or more RPC exchanges.  The number
   of exchanges depends on the security mechanism.

5.2.1.  Context Creation Requests

   The first RPC request from the client to the server initiates context
   creation for those mechanisms that require context creation messages.
   Within the RPC message protocol's call_body structure, rpcvers is set
   to 2. prog and vers are always those for the service being accessed.
   The proc is always set to NULLPROC (zero).

   Within the RPC message protocol's cred structure, flavor is set to
   RPCSEC_GSS (6).  The opaque data of the cred structure (the body
   field) constituting the credential encodes the rpc_gss_cred_t
   structured defined previously.

   The values of the fields contained in the rpc_gss_cred_t structure
   are set as follows.  The version field is set to the version of the
   RPCSEC_GSS protocol that was determined in the version negotiation
   phase.  The remainder of this memo documents version
   RPCSEC_GSS_VERS_1 of RPCSEC_GSS, and so the version field would be
   set to RPCSEC_GSS_VERS_1. The gss_proc field must be set to
   RPCSEC_GSS_INIT for the first creation request.  In subsequent
   creation requests, the gss_proc field must be set to
   RPCSEC_GSS_CONTINUE_INIT.  In a creation request, the seq_num and
   service fields are undefined and both must be ignored by the server.
   In the first creation request, the handle field is NULL (opaque data
   of zero length).  In subsequent creation requests, handle must be
   equal to the value returned by the server.  The handle field serves
   as the identifier for the context, and will not change for the
   duration of the context, including responses to
   RPCSEC_GSS_CONTINUE_INIT.

   The verifier field in the RPC message header is also described by the
   opaque_auth structure.  All creation requests have the NULL verifier
   (AUTH_NONE flavor with zero length opaque data).

   Following the verifier are the call data (procedure specific
   parameters).  Note that the proc field of the call_body structure is
   set to NULLPROC, and thus normally there would be zero octets
   following the verifier.  However, since there is no RPC data exchange
   during a context creation, it is safe to transfer information
   following the verifier.  It is necessary to "overload" the call data
   in this way, rather than pack the GSS-API token into the RPC header,



Expires: January 22, 1997                                      [Page 10]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   because RPC Version 2 restricts the amount of data that can be sent
   in the header.  The opaque body of the credential and verifier fields
   can be each at most 400 octets long, and GSS tokens can be longer
   than 800 octets.

   The call data for a context creation request is described by the
   following structure for all creation requests:

      struct rpc_gss_init_arg {
          opaque gss_token<>;
          unsigned int qop;
          rpc_gss_service_t service;
      };

   Here, gss_token is the token returned by the call to  GSS-API's
   gss_init_sec_context() routine, opaquely encoded.  The value of this
   field will likely be different in each creation request, if there is
   more than one creation request.  If no token is returned by the call
   to gss_init_sec_context(), the context must have been created
   (assuming no errors), and there will not be any more creation
   requests.

   The qop and service fields must be set to the GSS-API quality-of-
   protection (QOP) and service the client wishes to use for the
   session.  Some services will need this information before they will
   allow the context to be setup.  Although the client can change the
   QOP and service used on a per request basis, this may not be
   acceptable to all RPC based services - such services may choose to
   enforce the QOP and service specified during context creation for the
   rest of the session.  If there is more than one creation request, all
   of them must use the same values for qop and service.

   Note that QOPs are specific to the security mechanism that the call
   to gss_init_sec_context() specified when the gss_token was created.
   Because the specification in this memo is meant to be generic, this
   memo does not specifically define valid QOPs. It is up to the
   definers of GSS-API mechanisms to define valid QOPs.

5.2.2.  Context Creation Responses

5.2.2.1.  Context Creation Response - Successful Acceptance

   The response to a successful creation request has an MSG_ACCEPTED
   response with a status of SUCCESS.  The results field encodes result
   argument that has the following structure:

      struct rpc_gss_init_res {
              opaque handle<>;



Expires: January 22, 1997                                      [Page 11]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


              unsigned int gss_major;
              unsigned int gss_minor;
              unsigned int seq_window;
              opaque gss_token<>;
      };

   Here, handle is non-NULL opaque data that serves as the context
   identifier. The client must use this value in all subsequent requests
   (whether control messages or otherwise).  The server must generate
   handles such that they will be generated again for the same pair of
   client and server principals.  Otherwise, the server could be
   vulnerable to a replay attacker by an attacker that sends requests
   from a previous context.  The gss_major and gss_minor fields contain
   the results of the call to gss_accept_sec_context() executed by the
   server.  If gss_major is not one of GSS_S_COMPLETE or
   GSS_S_CONTINUE_NEEDED, the context setup has failed; in this case
   handle and gss_token must be set to NULL by the server.  The value of
   gss_minor is dependent on the value of gss_major and the security
   mechanism used.  The gss_token field contains any token returned by
   the gss_accept_sec_context() call executed by the server.  A token
   may be returned for both successful values of gss_major.  If the
   value is GSS_S_COMPLETE, it indicates that the server is not
   expecting any more tokens, and the RPC Data Exchange phase must begin
   on the subsequent request from the client. If the value is
   GSS_S_CONTINUE_NEEDED, the server is expecting another token.  Hence
   the client must send at least one more creation request (with
   gss_proc set to RPCSEC_GSS_CONTINUE_INIT in the request's credential)
   carrying the required token.

   In a successful response, the seq_window field is set to the sequence
   window length supported by the server for this context.  This window
   specifies the maximum number of client requests that may be
   outstanding for this context. The server will accept seq_window
   requests at a time, and these may be out of order.  The client may
   use this number to determine the number of threads that can
   simultaneously send requests on this context.

   The verifier used for a successful context creation response is the
   NULL verifier (AUTH_NONE flavor with zero-length opaque data).

5.2.2.1.1.  Client Processing of Successful Context Creation Responses

   If the value of gss_major in the response is GSS_S_CONTINUE_NEEDED,
   then the client, per the GSS-API specification, must invoke
   gss_init_sec_context() using the token returned in gss_token in the
   context creation response. The client must then generate a context
   creation request, with gss_proc set to RPCSEC_GSS_CONTINUE_INIT.




Expires: January 22, 1997                                      [Page 12]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   If the value of gss_major in the response is GSS_S_COMPLETE, and if
   the client's previous invocation of gss_init_sec_context() returned a
   gss_major value of GSS_S_CONTINUE_NEEDED, then the client, per the
   GSS-API specification, must invoke gss_init_sec_context() using the
   token returned in gss_token in the context creation response. If
   gss_init_sec_sec_context() returns GSS_S_COMPLETE, the context is
   successfully set up, and the RPC data exchange phase must begin on
   the subsequent request from the client.

5.2.2.2.  Context Creation Response - Unsuccessful Cases

   An MSG_ACCEPTED reply (to a creation request) with an acceptance
   status of other than SUCCESS has a NULL verifier (flavor set to
   AUTH_NONE, and zero length opaque data in the body field), and is
   formulated as usual for different status values.

   An MSG_DENIED reply (to a creation request) is also formulated as
   usual.  Note that MSG_DENIED could be returned because the server's
   RPC implementation does not recognize the RPCSEC_GSS security flavor.
   RFC 1831 does not specify the appropriate reply status in this
   instance.  Solaris 2 implementations return a rejection status of
   AUTH_ERROR with an auth_stat of AUTH_REJECTEDCRED. Even though two
   new values (RPCSEC_GSS_NOCRED and RPCSEC_GSS_FAILED) have been
   defined for the auth_stat type, neither of these two can be returned
   in responses to context creation requests.  The new values are
   relevant to for responses to normal (data) requests.  This is
   described later.

   MSG_DENIED might also be returned if the RPCSEC_GSS version number in
   the credential is not supported on the server. In the case, the
   server returns a rejection status of AUTH_ERROR, with an auth_stat of
   AUTH_REJECTED_CRED.

5.3.  RPC Data Exchange

   The data exchange phase is entered after a context has been
   successfully set up. The format of the data exchanged depends on the
   security service used for the request.  Although clients can change
   the security service and QOP used on a per-request basis, this may
   not be acceptable to all RPC services.  For all three modes of
   service (no data integrity, data integrity, data privacy), the RPC
   request header has the same format.

5.3.1.  RPC Request Header

   The credential has the opaque_auth structure described earlier.  The
   flavor field is set to RPCSEC_GSS.  The credential body is created by
   XDR encoding the rpc_gss_cred_t structure listed earlier into an



Expires: January 22, 1997                                      [Page 13]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   octet stream, and then opaquely encoding this octet stream as the
   body field.

   Values of the fields contained in the rpc_gss_cred_t structure are
   set as follows.  The version field is set to same version value that
   was used to create the context, which within the scope of this memo
   will always be RPCSEC_GSS_VERS_1.  The gss_proc field is set to
   RPCSEC_GSS_DATA.  The service field is set to indicate the desired
   service (one of rpc_gss_svc_none, rpc_gss_svc_integrity, or
   rpc_gss_svc_privacy).  The handle field is set to the context handle
   value received from the RPC server during context creation.  The
   seq_num field can start at any value below MAXSEQ, and must be
   incremented (by one or more) for successive requests.  Use of
   sequence numbers is described in detail when server processing of the
   request is discussed.

   The verifier has the opaque_auth structure described earlier.  The
   flavor field is set to RPCSEC_GSS.  The body field is set as follows.
   The checksum of the RPC header (up to and including the credential)
   is computed using the gss_sign() call with the desired QOP.  This
   returns the checksum as an opaque octet stream and its length.  This
   is encoded into the body field.  Note that the QOP is not explicitly
   specified anywhere in the request.  It is implicit in the checksum or
   encrypted data.  The same QOP value as is used for the header
   checksum must also be used for the data (for checksumming or
   encrypting), unless the service used for the request is
   rpc_gss_svc_none.

5.3.2.  RPC Request Data

5.3.2.1.  RPC Request Data - No Data Integrity

   If the service specified is rpc_gss_svc_none, the data (procedure
   arguments) are not integrity or privacy protected.  They are sent in
   exactly the same way as they would be if the AUTH_NONE flavor were
   used (following the verifier).  Note, however, that since the RPC
   header is integrity protected, the sender will still be authenticated
   in this case.

5.3.2.2.  RPC Request Data - With Data Integrity

   When data integrity is used, the request data is represented as
   follows:

      struct rpc_gss_integ_data {
          opaque databody_integ<>;
          opaque checksum<>;
      };



Expires: January 22, 1997                                      [Page 14]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   The databody_integ field is created as follows.  A structure
   consisting of a sequence number followed by the procedure arguments
   is constructed. This is shown below as the type rpc_gss_data_t:


      struct rpc_gss_data_t {
          unsigned int seq_num;
          proc_req_arg_t arg;
      };

   Here, seq_num must have the same value as in the credential.  The
   type proc_req_arg_t is the procedure specific XDR type describing the
   procedure arguments (and so is not specified here).  The octet stream
   corresponding to the XDR encoded rpc_gss_data_t structure and its
   length are placed in the databody_integ field. Note that because the
   XDR type of databody_integ is opaque, the XDR encoding of
   databody_integ will include an initial four octet length field,
   followed by the XDR encoded octet stream of rpc_gss_data_t.

   The checksum field represents the checksum of the XDR encoded octet
   stream corresponding to the XDR encoded rpc_gss_data_t structure
   (note, this is not the checksum of the databody_integ field).  This
   is obtained using the gss_sign() call, with the same QOP as was used
   to compute the header checksum (in the verifier). The gss_sign() call
   returns the checksum as an opaque octet stream and its length. The
   checksum field of struct rpc_gss_integ_data has an XDR type of
   opaque. Thus the checksum length from gss_sign() is encoded as a four
   octet  length field, followed by the checksum, padded to a multiple
   of four octets.

5.3.2.3.  RPC Request Data - With Data Privacy

   When data privacy is used, the request data is represented as
   follows:

      struct rpc_gss_priv_data {
          opaque databody_priv<>
      };

   The databody_priv field is created as follows.  The rpc_gss_data_t
   structure described earlier is constructed again in the same way as
   for the case of data integrity.  Next, the gss_seal() call is invoked
   to encrypt the octet stream corresponding to the rpc_gss_data_t
   structure, using the same value for QOP as was used for the header
   checksum (in the verifier).  The gss_seal() call returns an opaque
   octet stream (representing the encrypted rpc_gss_data_t structure)
   and its length, and this is encoded as the databody_priv field. Since
   databody_priv has an XDR type of opaque, the length returned by



Expires: January 22, 1997                                      [Page 15]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   gss_seal() is encoded as the four octet length, followed by the
   encrypted octet stream (padded to a multiple of four octets).

5.3.3.  Server Processing of RPC Data Requests

5.3.3.1.  Context Management

   When a request is received by the server, the following are verified
   to be acceptable:

   *    the version number in the credential

   *    the service specified in the credential

   *    the context handle specified in the credential

   *    the header checksum in the verifier

   *    the sequence number (seq_num) specified in the credential (more
        on this follows)

   The gss_proc field in the credential must be set to RPCSEC_GSS_DATA
   for data requests (otherwise, the message will be interpreted as a
   control message).

   The server maintains a window of "seq_window" sequence numbers,
   starting with the last sequence number seen and extending backwards.
   If a sequence number higher than the last number seen is received,
   the window is moved forward to the new sequence number.  If the last
   sequence number seen is N, the server is prepared to receive requests
   with sequence numbers in the range N through (N - seq_window + 1),
   both inclusive.  If the sequence number received falls below this
   range, it is silently discarded.  If the sequence number is within
   this range, and the server has not seen it, the request is accepted,
   and the server turns on a bit to "remember" that this sequence number
   has been seen.  If the server determines that it has already seen a
   sequence number within the window, the request is silently discarded.
   The server should select a seq_window value based on the number
   requests it expects to process simultaneously. For example, in a
   threaded implementation seq_window might be equal to the number of
   server threads. There are no known security issues with selecting a
   large window. The primary issue is how much space the server is
   willing to allocate to keep track of requests received within the
   window.

   The reason for discarding requests silently is that the server is
   unable to determine if the duplicate or out of range request was due
   to a sequencing problem in the client, network, or the operating



Expires: January 22, 1997                                      [Page 16]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   system, or due to some quirk in routing, or a replay attack by an
   intruder.  Discarding the request allows the client to recover after
   timing out, if indeed the duplication was unintentional or well
   intended.  Note that a consequence of the silent discard is that
   clients may increment the seq_num by more than one. The effect of
   this is that the window will move forward more quickly. It is not
   believed that there is any benefit to doing this.

   Note that the sequence number algorithm requires that the client
   increment the sequence number even if it is retrying a request with
   the same RPC transaction identifier.  It is not infrequent for
   clients to get into a situation where they send two or more attempts
   and a slow server sends the reply for the first attempt. With
   RPCSEC_GSS, each request and reply will have a unique sequence
   number. If the client wishes to improve turn around time on the RPC
   call, it can cache the RPCSEC_GSS sequence number of each request it
   sends. Then when it receives a response with a matching RPC
   transaction identifier, it can compute the checksum of each sequence
   number in the cache to try to match the checksum in the reply's
   verifier.

   The data is decoded according to the service specified in the
   credential.  In the case of integrity or privacy, the server ensures
   that the QOP value is acceptable, and that it is the same as that
   used for the header checksum in the verifier.  Also, in the case of
   integrity or privacy, the server will reject the message (with a
   reply status of MSG_ACCEPTED, and an acceptance status of
   GARBAGE_ARGS) if the sequence number embedded in the request body is
   different from the sequence number in the credential.

5.3.3.2.  Server Reply - Request Accepted

   An MSG_ACCEPTED reply to a request in the data exchange phase will
   have the verifier's (the verf element in the response) flavor field
   set to RPCSEC_GSS, and the body field set to the checksum of the
   sequence number (in network order) of the corresponding request.  The
   QOP used is the same as the QOP used for the corresponding request.

   If the status of the reply is not SUCCESS, the rest of the message is
   formatted as usual.

   If the status of the message is SUCCESS, the format of the rest of
   the message depends on the service specified in the corresponding
   request message. Basically, what follows the verifier in this case
   are the procedure results, formatted in different ways depending on
   the requested service.

   If no data integrity was requested, the procedure results are



Expires: January 22, 1997                                      [Page 17]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   formatted as for the AUTH_NONE security flavor.

   If data integrity was requested, the results are encoded in exactly
   the same way as the procedure arguments were in the corresponding
   request.  See the section 'RPC Request Data - With Data Integrity.'
   The only difference is that the structure representing the
   procedure's result - proc_res_arg_t - must be substituted in place of
   the request argument structure proc_req_arg_t.  The QOP used for the
   checksum must be the same as that used for constructing the reply
   verifier.

   If data privacy was requested, the results are encoded in exactly the
   same way as the procedure arguments were in the corresponding
   request.  See the section 'RPC Request Data - With Data Privacy.'
   The QOP used for  encryption must be the same as that used for
   constructing the reply verifier.

5.3.3.3.  Server Reply - Request Denied

   An MSG_DENIED reply (to a data request) is formulated as usual.  Two
   new values (RPCSEC_GSS_NOCRED and RPCSEC_GSS_FAILED) have been
   defined for the auth_stat type.  When the reason for denial of the
   request is a reject_stat of AUTH_ERROR, one of the two new auth_stat
   values could be returned in addition to the existing values.  These
   two new values have special significance from the existing reasons
   for denial of a request.

   The server maintains a list of contexts for the clients that are
   currently in session with it.  Normally, a context is destroyed when
   the client ends the session corresponding to it.  However, due to
   resource constraints, the server may destroy a context prematurely
   (on an LRU basis, or if the server machine is rebooted, for example).
   In this case, when a client request comes in, there may not be a
   context corresponding to its handle. The server rejects the request,
   with the reason RPCSEC_GSS_NOCRED in this case.  Upon receiving this
   error, the client must refresh the context - that is, reestablish it
   after destroying the old one - and try the request again.  This error
   is also returned if the context handle matches that of a different
   context that was allocated after the client's context was destroyed
   (this will be detected by a failure in verifying the header
   checksum).

   When the client's sequence number exceeds the maximum the server will
   allow, the server will reject the request with the reason
   RPCSEC_GSS_FAILED.  Also, if security credentials become stale while
   in use (due to ticket expiry in the case of the Kerberos V5
   mechanism, for example), the failures which result cause the
   RPCSEC_GSS_FAILED reason to be returned.  In these cases also, the



Expires: January 22, 1997                                      [Page 18]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   client must refresh the context, and retry the request.

   For other errors, retrying will not rectify the problem and the
   client must not refresh the context until the problem causing the
   client request to be denied is rectified.

   If the version field in the credential does not match the version of
   RPCSEC_GSS that was used when the context was created, the
   AUTH_BADCRED value is returned.

   If there is a problem with the credential, such a bad length, illegal
   control procedure, or an illegal service, the appropriate auth_stat
   status is AUTH_BADCRED.

   Other errors can be returned as appropriate.

5.4.  Context Destruction

   When the client is done using the session, it must send a control
   message informing the server that it no longer requires the context.
   This message is formulated just like a data request packet, with the
   following differences:  the credential has gss_proc set to
   RPCSEC_GSS_DESTROY, the procedure specified in the header is
   NULLPROC, and there are no procedure arguments.  The sequence number
   in the request must be valid, and the header checksum in the verifier
   must be valid, for the server to accept the message.

   The server sends a response as it would to a data request.  The
   client and server must then destroy the context for the session.

   If the request to destroy the context fails for some reason, the
   client need not take any special action.  The server must be prepared
   to deal with situations where clients never inform the server that
   they no longer are in session and so don't need the server to
   maintain a context.  An LRU mechanism or an aging mechanism should be
   employed by the server to clean up in such cases.

6.  Security Considerations

6.1.  Privacy of Call Header

   The reader will note that for the privacy option, only the call
   arguments and results are encrypted. Information about the
   application in the form of RPC program number, program version
   number, and program procedure number is transmitted in the clear.
   Encrypting these fields in the RPC call header would have changed the
   size and format of the call header. This would have required revising
   the RPC protocol which was beyond the scope of this proposal. Storing



Expires: January 22, 1997                                      [Page 19]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   the encrypted numbers in the credential would have obviated a
   protocol change, but would have introduced more overloading of fields
   and would have made implementations of RPC more complex. Even if the
   fields were encrypted somehow, in most cases an attacker can
   determine the program number and version number by examining the
   destination address of the request and querying the rpcbind service
   on the destination host [Srinivasan-bind].  In any case, even by not
   encrypting the three numbers, RPCSEC_GSS still improves the state of
   security over what existing RPC services have had available
   previously. Implementors of new RPC services that are concerned about
   this risk may opt to design in a "sub-procedure" field that is
   included in the service specific call arguments.

6.2.  Sequence number attacks

   An attacker cannot coax the server into raising the sequence number
   beyond the range the legitimate client is aware of (and thus engineer
   a denial of server attack) without constructing an RPC request that
   will pass the header checksum. If the cost of verifying the header
   checksum is sufficiently large (depending on the speed of the
   processor doing the checksum and the cost of checksum algorithm), it
   is possible to envision a denial of service attack whereby the
   attacker sends requests that are outside the window. The most trivial
   one, would be one where the attacker sends a request with a sequence
   number that is below the window. In this case, even if the header
   checksum were successfully verified, the server would silently
   discard it. To guard against this kind of denial of service (stealing
   processing resources), one might implement a server to examine
   request's the sequence number to see if it is below the window before
   verifying the checksum.

6.3.  Message stealing attacks

   This proposal does not address attacks where an attacker can block or
   steal messages without being detected by the server. To implement
   such protection would be tantamount to assuming a state in the RPC
   service. RPCSEC_GSS does not worsen this situation.

7.  Acknowledgements

   Much of protocol was based on the AUTH_GSSAPI security flavor
   developed by Open Vision Technologies [Jaspan].  In particular, we
   acknowledge Barry Jaspan, Marc Horowitz, John Linn, and Ellen
   McDermott.

   Raj Srinivasan designed RPCSEC_GSS [Eisler] with input from Mike
   Eisler.  Raj, Roland Schemers, Lin Ling, and Alex Chiu contributed to
   SunSoft's implementation of RPCSEC_GSS.



Expires: January 22, 1997                                      [Page 20]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   Barry Jaspan, Marc Horowitz, Hilarie Orman, Martin Rex, and John
   Wroclawski analyzed the specification and gave valuable feedback.

   Kathy Slattery proof read the specification.

8.  References


[Eisler]            Eisler, M., Schemers, R., and Srinivasan, R. (1996).
                    "Security Mechanism Independence in ONC RPC," To be
                    published in the Proceedings of 1996 Usenix Security
                    Symposium.

[Jaspan]            Jaspan, B. (1995). "GSS-API Security for ONC RPC,"
                    `95 Proceedings of The Internet Society Symposium on
                    Network and Distributed System Security, pp. 144-
                    151.

[Linn]              Linn, J. (1993). RFC 1508, "Generic Security Service
                    Application Program Interface."

[Srinivasan-bind]   Srinivasan, R. (1995). RFC 1833, "Binding Protocols
                    for ONC RPC Version 2."

[Srinivasan-rpc]    Srinivasan, R. (1995). RFC 1831, "RPC: Remote
                    Procedure Call Protocol Specification Version 2."

[Srinivasan-xdr]    Srinivasan, R. (1995). RFC 1832, "XDR: External Data
                    Representation Standard."


9.  Authors' Addresses

   Michael Eisler
   Sun Microsystems, Inc.
   M/S UCOS03
   2550 Garcia Avenue
   Mountain View, CA 94043

   Phone: +1 (719) 599-9026

   E-mail: mre@eng.sun.com

   Alex Chiu
   Sun Microsystems, Inc.
   M/S UMPK17-203
   2550 Garcia Avenue
   Mountain View, CA 94043



Expires: January 22, 1997                                      [Page 21]


Internet Draft     RPCSEC_GSS Protocol Specification        22 July 1996


   Phone: +1 (415) 786-6465

   E-mail: hacker@eng.sun.com

   Lin Ling
   Sun Microsystems, Inc.
   M/S UMPK17-201
   2550 Garcia Avenue
   Mountain View, CA 94043

   Phone: +1 (415) 786-5084

   E-mail: lling@eng.sun.com






































Expires: January 22, 1997                                      [Page 22]