RFC 4462:Generic Security Service Application Prog...
RFC-Ref

2. GSS-API-Authenticated Diffie-Hellman Key Exchange


   This section defines a class of key exchange methods that combine the
   Diffie-Hellman key exchange from Section 8 of [SSH-TRANSPORT] with
   mutual authentication using GSS-API.

   Since the GSS-API key exchange methods described in this section do
   not require the use of public key signature or encryption algorithms,
   they MAY be used with any host key algorithm, including the "null"
   algorithm described in Section 5.


2.1. Generic GSS-API Key Exchange


   The following symbols are used in this description:

   o  C is the client, and S is the server

   o  p is a large safe prime, g is a generator for a subgroup of GF(p),
      and q is the order of the subgroup

   o  V_S is S's version string, and V_C is C's version string

   o  I_C is C's KEXINIT message, and I_S is S's KEXINIT message

   1.  C generates a random number x (1 < x < q) and computes e = g^x
       mod p.

   2.  C calls GSS_Init_sec_context(), using the most recent reply token
       received from S during this exchange, if any.  For this call, the
       client MUST set mutual_req_flag to "true" to request that mutual
       authentication be performed.  It also MUST set integ_req_flag to
       "true" to request that per-message integrity protection be
       supported for this context.  In addition, deleg_req_flag MAY be
       set to "true" to request access delegation, if requested by the
       user.  Since the key exchange process authenticates only the
       host, the setting of anon_req_flag is immaterial to this process.
       If the client does not support the "gssapi-keyex" user
       authentication method described in Section 4, or does not intend
       to use that method in conjunction with the GSS-API context
       established during key exchange, then anon_req_flag SHOULD be set
       to "true".  Otherwise, this flag MAY be set to true if the client
       wishes to hide its identity.  Since the key exchange process will
       involve the exchange of only a single token once the context has
       been established, it is not necessary that the GSS-API context
       support detection of replayed or out-of-sequence tokens.  Thus,
       replay_det_req_flag and sequence_req_flag need not be set for
       this process.  These flags SHOULD be set to "false".

       *  If the resulting major_status code is GSS_S_COMPLETE and the
          mutual_state flag is not true, then mutual authentication has
          not been established, and the key exchange MUST fail.

       *  If the resulting major_status code is GSS_S_COMPLETE and the
          integ_avail flag is not true, then per-message integrity
          protection is not available, and the key exchange MUST fail.

       *  If the resulting major_status code is GSS_S_COMPLETE and both
          the mutual_state and integ_avail flags are true, the resulting
          output token is sent to S.

       *  If the resulting major_status code is GSS_S_CONTINUE_NEEDED,
          the output_token is sent to S, which will reply with a new
          token to be provided to GSS_Init_sec_context().

       *  The client MUST also include "e" with the first message it
          sends to the server during this process; if the server
          receives more than one "e" or none at all, the key exchange
          fails.

       *  It is an error if the call does not produce a token of non-
          zero length to be sent to the server.  In this case, the key
          exchange MUST fail.

   3.  S calls GSS_Accept_sec_context(), using the token received from
       C.

       *  If the resulting major_status code is GSS_S_COMPLETE and the
          mutual_state flag is not true, then mutual authentication has
          not been established, and the key exchange MUST fail.

       *  If the resulting major_status code is GSS_S_COMPLETE and the
          integ_avail flag is not true, then per-message integrity
          protection is not available, and the key exchange MUST fail.

       *  If the resulting major_status code is GSS_S_COMPLETE and both
          the mutual_state and integ_avail flags are true, then the
          security context has been established, and processing
          continues with step 4.

       *  If the resulting major_status code is GSS_S_CONTINUE_NEEDED,
          then the output token is sent to C, and processing continues
          with step 2.

       *  If the resulting major_status code is GSS_S_COMPLETE, but a
          non-zero-length reply token is returned, then that token is
          sent to the client.

   4.  S generates a random number y (0 < y < q) and computes f = g^y
       mod p.  It computes K = e ^ y mod p, and H = hash(V_C || V_S ||
       I_C || I_S || K_S || e || f || K).  It then calls GSS_GetMIC() to
       obtain a GSS-API message integrity code for H.  S then sends f
       and the message integrity code (MIC) to C.

   5.  This step is performed only (1) if the server's final call to
       GSS_Accept_sec_context() produced a non-zero-length final reply
       token to be sent to the client and (2) if no previous call by the
       client to GSS_Init_sec_context() has resulted in a major_status
       of GSS_S_COMPLETE.  Under these conditions, the client makes an

       additional call to GSS_Init_sec_context() to process the final
       reply token.  This call is made exactly as described above.
       However, if the resulting major_status is anything other than
       GSS_S_COMPLETE, or a non-zero-length token is returned, it is an
       error and the key exchange MUST fail.

   6.  C computes K = f^x mod p, and H = hash(V_C || V_S || I_C || I_S
       || K_S || e || f || K).  It then calls GSS_VerifyMIC() to verify
       that the MIC sent by S matches H.  If the MIC is not successfully
       verified, the key exchange MUST fail.

   Either side MUST NOT send or accept e or f values that are not in the
   range [1,p-1].  If this condition is violated, the key exchange
   fails.

   If any call to GSS_Init_sec_context() or GSS_Accept_sec_context()
   returns a major_status other than GSS_S_COMPLETE or
   GSS_S_CONTINUE_NEEDED, or any other GSS-API call returns a
   major_status other than GSS_S_COMPLETE, the key exchange fails.  In
   this case, several mechanisms are available for communicating error
   information to the peer before terminating the connection as required
   by [SSH-TRANSPORT]:

   o  If the key exchange fails due to any GSS-API error on the server
      (including errors returned by GSS_Accept_sec_context()), the
      server MAY send a message informing the client of the details of
      the error.  In this case, if an error token is also sent (see
      below), then this message MUST be sent before the error token.

   o  If the key exchange fails due to a GSS-API error returned from the
      server's call to GSS_Accept_sec_context(), and an "error token" is
      also returned, then the server SHOULD send the error token to the
      client to allow completion of the GSS security exchange.

   o  If the key exchange fails due to a GSS-API error returned from the
      client's call to GSS_Init_sec_context(), and an "error token" is
      also returned, then the client SHOULD send the error token to the
      server to allow completion of the GSS security exchange.

   As noted in Section 9, it may be desirable under site security policy
   to obscure information about the precise nature of the error; thus,
   it is RECOMMENDED that implementations provide a method to suppress
   these messages as a matter of policy.

   This is implemented with the following messages.  The hash algorithm
   for computing the exchange hash is defined by the method name, and is
   called HASH.  The group used for Diffie-Hellman key exchange and the
   underlying GSS-API mechanism are also defined by the method name.

   After the client's first call to GSS_Init_sec_context(), it sends the
   following:

           byte      SSH_MSG_KEXGSS_INIT
           string    output_token (from GSS_Init_sec_context())
           mpint     e

   Upon receiving the SSH_MSG_KEXGSS_INIT message, the server MAY send
   the following message, prior to any other messages, to inform the
   client of its host key.

           byte      SSH_MSG_KEXGSS_HOSTKEY
           string    server public host key and certificates (K_S)

   Since this key exchange method does not require the host key to be
   used for any encryption operations, this message is OPTIONAL.  If the
   "null" host key algorithm described in Section 5 is used, this
   message MUST NOT be sent.  If this message is sent, the server public
   host key(s) and/or certificate(s) in this message are encoded as a
   single string, in the format specified by the public key type in use
   (see [SSH-TRANSPORT], Section 6.6).

   In traditional SSH deployments, host keys are normally expected to
   change infrequently, and there is often no mechanism for validating
   host keys not already known to the client.  As a result, the use of a
   new host key by an already-known host is usually considered an
   indication of a possible man-in-the-middle attack, and clients often
   present strong warnings and/or abort the connection in such cases.

   By contrast, when GSS-API-based key exchange is used, host keys sent
   via the SSH_MSG_KEXGSS_HOSTKEY message are authenticated as part of
   the GSS-API key exchange, even when previously unknown to the client.
   Further, in environments in which GSS-API-based key exchange is used
   heavily, it is possible and even likely that host keys will change
   much more frequently and/or without advance warning.

   Therefore, when a new key for an already-known host is received via
   the SSH_MSG_KEXGSS_HOSTKEY message, clients SHOULD NOT issue strong
   warnings or abort the connection, provided the GSS-API-based key
   exchange succeeds.

   In order to facilitate key re-exchange after the user's GSS-API
   credentials have expired, client implementations SHOULD store host
   keys received via SSH_MSG_KEXGSS_HOSTKEY for the duration of the
   session, even when such keys are not stored for long-term use.

   Each time the server's call to GSS_Accept_sec_context() returns a
   major_status code of GSS_S_CONTINUE_NEEDED, it sends the following
   reply to the client:

           byte      SSH_MSG_KEXGSS_CONTINUE
           string    output_token (from GSS_Accept_sec_context())

   If the client receives this message after a call to
   GSS_Init_sec_context() has returned a major_status code of
   GSS_S_COMPLETE, a protocol error has occurred and the key exchange
   MUST fail.

   Each time the client receives the message described above, it makes
   another call to GSS_Init_sec_context().  It then sends the following:

           byte      SSH_MSG_KEXGSS_CONTINUE
           string    output_token (from GSS_Init_sec_context())

   The server and client continue to trade these two messages as long as
   the server's calls to GSS_Accept_sec_context() result in major_status
   codes of GSS_S_CONTINUE_NEEDED.  When a call results in a
   major_status code of GSS_S_COMPLETE, it sends one of two final
   messages.

   If the server's final call to GSS_Accept_sec_context() (resulting in
   a major_status code of GSS_S_COMPLETE) returns a non-zero-length
   token to be sent to the client, it sends the following:

           byte      SSH_MSG_KEXGSS_COMPLETE
           mpint     f
           string    per_msg_token (MIC of H)
           boolean   TRUE
           string    output_token (from GSS_Accept_sec_context())

   If the client receives this message after a call to
   GSS_Init_sec_context() has returned a major_status code of
   GSS_S_COMPLETE, a protocol error has occurred and the key exchange
   MUST fail.

   If the server's final call to GSS_Accept_sec_context() (resulting in
   a major_status code of GSS_S_COMPLETE) returns a zero-length token or
   no token at all, it sends the following:

           byte      SSH_MSG_KEXGSS_COMPLETE
           mpint     f
           string    per_msg_token (MIC of H)
           boolean   FALSE

   If the client receives this message when no call to
   GSS_Init_sec_context() has yet resulted in a major_status code of
   GSS_S_COMPLETE, a protocol error has occurred and the key exchange
   MUST fail.

   If either the client's call to GSS_Init_sec_context() or the server's
   call to GSS_Accept_sec_context() returns an error status and produces
   an output token (called an "error token"), then the following SHOULD
   be sent to convey the error information to the peer:

           byte      SSH_MSG_KEXGSS_CONTINUE
           string    error_token

   If a server sends both this message and an SSH_MSG_KEXGSS_ERROR
   message, the SSH_MSG_KEXGSS_ERROR message MUST be sent first, to
   allow clients to record and/or display the error information before
   processing the error token.  This is important because a client
   processing an error token will likely disconnect without reading any
   further messages.

   In the event of a GSS-API error on the server, the server MAY send
   the following message before terminating the connection:

           byte      SSH_MSG_KEXGSS_ERROR
           uint32    major_status
           uint32    minor_status
           string    message
           string    language tag

   The message text MUST be encoded in the UTF-8 encoding described in
   [UTF8].  Language tags are those described in [LANGTAG].  Note that
   the message text may contain multiple lines separated by carriage
   return-line feed (CRLF) sequences.  Application developers should
   take this into account when displaying these messages.

   The hash H is computed as the HASH hash of the concatenation of the
   following:

           string    V_C, the client's version string (CR, NL excluded)
           string    V_S, the server's version string (CR, NL excluded)
           string    I_C, the payload of the client's SSH_MSG_KEXINIT
           string    I_S, the payload of the server's SSH_MSG_KEXINIT
           string    K_S, the host key
           mpint     e, exchange value sent by the client
           mpint     f, exchange value sent by the server
           mpint     K, the shared secret

   This value is called the exchange hash, and it is used to
   authenticate the key exchange.  The exchange hash SHOULD be kept
   secret.  If no SSH_MSG_KEXGSS_HOSTKEY message has been sent by the
   server or received by the client, then the empty string is used in
   place of K_S when computing the exchange hash.

   The GSS_GetMIC call MUST be applied over H, not the original data.


2.2. Group Exchange


   This section describes a modification to the generic GSS-API-
   authenticated Diffie-Hellman key exchange to allow the negotiation of
   the group to be used, using a method based on that described in
   [GROUP-EXCHANGE].

   The server keeps a list of safe primes and corresponding generators
   that it can select from.  These are chosen as described in Section 3
   of [GROUP-EXCHANGE].  The client requests a modulus from the server,
   indicating the minimum, maximum, and preferred sizes; the server
   responds with a suitable modulus and generator.  The exchange then
   proceeds as described in Section 2.1 above.

   This description uses the following symbols, in addition to those
   defined above:

   o  n is the size of the modulus p in bits that the client would like
      to receive from the server

   o  min and max are the minimal and maximal sizes of p in bits that
      are acceptable to the client

   1.  C sends "min || n || max" to S, indicating the minimal acceptable
       group size, the preferred size of the group, and the maximal
       group size in bits the client will accept.

   2.  S finds a group that best matches the client's request, and sends
       "p || g" to C.

   3.  The exchange proceeds as described in Section 2.1 above,
       beginning with step 1, except that the exchange hash is computed
       as described below.

   Servers and clients SHOULD support groups with a modulus length of k
   bits, where 1024 <= k <= 8192.  The recommended values for min and
   max are 1024 and 8192, respectively.

   This is implemented using the following messages, in addition to
   those described above:

   First, the client sends:

           byte      SSH_MSG_KEXGSS_GROUPREQ
           uint32    min, minimal size in bits of an acceptable group
           uint32    n, preferred size in bits of the group the server
                     should send
           uint32    max, maximal size in bits of an acceptable group

   The server responds with:

           byte      SSH_MSG_KEXGSS_GROUP
           mpint     p, safe prime
           mpint     g, generator for subgroup in GF(p)

   This is followed by the message exchange described above in
   Section 2.1, except that the exchange hash H is computed as the HASH
   hash of the concatenation of the following:

           string    V_C, the client's version string (CR, NL excluded)
           string    V_S, the server's version string (CR, NL excluded)
           string    I_C, the payload of the client's SSH_MSG_KEXINIT
           string    I_S, the payload of the server's SSH_MSG_KEXINIT
           string    K_S, the host key
           uint32    min, minimal size in bits of an acceptable group
           uint32    n, preferred size in bits of the group the server
                     should send
           uint32    max, maximal size in bits of an acceptable group
           mpint     p, safe prime
           mpint     g, generator for subgroup in GF(p)
           mpint     e, exchange value sent by the client
           mpint     f, exchange value sent by the server
           mpint     K, the shared secret


2.3. gss-group1-sha1-*


   Each of these methods specifies GSS-API-authenticated Diffie-Hellman
   key exchange as described in Section 2.1 with SHA-1 as HASH, and the
   group defined in Section 8.1 of [SSH-TRANSPORT].  The method name for
   each method is the concatenation of the string "gss-group1-sha1-"
   with the Base64 encoding of the MD5 hash [MD5] of the ASN.1
   Distinguished Encoding Rules (DER) encoding [ASN1] of the underlying
   GSS-API mechanism's Object Identifier (OID).  Base64 encoding is
   described in Section 6.8 of [MIME].

   Each and every such key exchange method is implicitly registered by
   this specification.  The IESG is considered to be the owner of all
   such key exchange methods; this does NOT imply that the IESG is
   considered to be the owner of the underlying GSS-API mechanism.


2.4. gss-group14-sha1-*


   Each of these methods specifies GSS-API authenticated Diffie-Hellman
   key exchange as described in Section 2.1 with SHA-1 as HASH, and the
   group defined in Section 8.2 of [SSH-TRANSPORT].  The method name for
   each method is the concatenation of the string "gss-group14-sha1-"
   with the Base64 encoding of the MD5 hash [MD5] of the ASN.1 DER
   encoding [ASN1] of the underlying GSS-API mechanism's OID.  Base64
   encoding is described in Section 6.8 of [MIME].

   Each and every such key exchange method is implicitly registered by
   this specification.  The IESG is considered to be the owner of all
   such key exchange methods; this does NOT imply that the IESG is
   considered to be the owner of the underlying GSS-API mechanism.


2.5. gss-gex-sha1-*


   Each of these methods specifies GSS-API-authenticated Diffie-Hellman
   key exchange as described in Section 2.2 with SHA-1 as HASH.  The
   method name for each method is the concatenation of the string "gss-
   gex-sha1-" with the Base64 encoding of the MD5 hash [MD5] of the
   ASN.1 DER encoding [ASN1] of the underlying GSS-API mechanism's OID.
   Base64 encoding is described in Section 6.8 of [MIME].

   Each and every such key exchange method is implicitly registered by
   this specification.  The IESG is considered to be the owner of all
   such key exchange methods; this does NOT imply that the IESG is
   considered to be the owner of the underlying GSS-API mechanism.


2.6. Other GSS-API Key Exchange Methods


   Key exchange method names starting with "gss-" are reserved for key
   exchange methods that conform to this document; in particular, for
   those methods that use the GSS-API-authenticated Diffie-Hellman key
   exchange algorithm described in Section 2.1, including any future
   methods that use different groups and/or hash functions.  The intent
   is that the names for any such future methods be defined in a similar
   manner to that used in Section 2.3.



Google
Web
RFC-Ref