RFC 5403

RPCSEC_GSS Version 2

๐Ÿ“… published February 2009, from ietf

RFC 5403: RPCSEC_GSS Version 2 ๐ŸŽ€

okay bestie, let's get the vibes straight before we dive in ๐Ÿ’… this one is from February 2009 and it's a Standards Track doc, so it's the real deal, not just a suggestion ๐Ÿ‘‘ the author is M. Eisler from NetApp ๐Ÿฆ‹ and it's marked as an update to RFC 2203 (it updates 2203, it doesn't obsolete it, so 2203 is still around ๐ŸŒธ). it's part of the Network Working Group, and the whole point is describing version 2 of RPCSEC_GSS โœจ


Status of This Memo โœจ

ok so this section is basically the official "here's what kind of doc this is" part ๐Ÿ’– it says this is an Internet standards track protocol spec for the internet community, and that they're asking for discussion and suggestions for improvements ๐Ÿซถ for the current standardization state, you check the "Internet Official Protocol Standards" (STD 1) ๐Ÿงš and yes, distribution of this memo is unlimited ๐ŸŒˆ

the IETF Trust and the document authors own the copyright, copyright (c) 2009, all rights reserved ๐Ÿ’œ it's subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as of the publication date ๐Ÿ“ literally go read those, because they spell out your rights and restrictions ๐Ÿ™ˆ

Abstract โœจ

so the big picture: this doc describes version 2 of RPCSEC_GSS ๐ŸŽ€ it's basically identical to version 1 (which lives in RFC 2203) except v2 adds channel bindings support ๐Ÿ’… RPCSEC_GSS is the thing that lets remote procedure call (RPC) protocols tap into the Generic Security Services Application Programming Interface (GSS-API) ๐Ÿ”ฅ it's giving "security layer for RPC" energy, no cap ๐Ÿ‘‘

Table of Contents โœจ

here's the map of everything so you don't get lost ๐Ÿ—บ๏ธ the TOC is kept exactly as the original, because the numbers matter for cross-references ๐Ÿ’–

   1. Introduction and Motivation .....................................2
      1.1. Requirements Language ......................................3
   2. Channel Bindings Explained ......................................3
   3. The RPCSEC_GSSv2 Protocol .......................................4
      3.1. Compatibility with RPCSEC_GSSv1 ............................4
      3.2. New Version Number .........................................5
      3.3. New Procedure - RPCSEC_GSS_BIND_CHANNEL ....................7
      3.4. New Security Service - rpc_gss_svc_channel_prot ...........10
   4. Version Negotiation ............................................11
   5. Native GSS Channel Bindings ....................................11
   6. Operational Recommendation for Deployment ......................11
   7. Implementation Notes ...........................................11
   8. Acknowledgments ................................................11
   9. Security Considerations ........................................11
   10. References ....................................................13
      10.1. Normative References .....................................13
      10.2. Informative References ...................................14

1. Introduction and Motivation ๐Ÿฆ‹

okay so this is the setup, and it's kinda juicy ๐ŸŒธ this doc describes RPCSEC_GSS version 2 (RPCSEC_GSSv2) ๐Ÿ’… v2 is the same as v1 (RFC 2203 [1]) except it adds support for channel bindings [2] โœจ

the main reason channel bindings exist is to safely take advantage of hardware-assisted encryption that might live at lower layers of the stack, like at the Internet Protocol (IP) layer via IPsec (see [7] and [8] for info on IPsec channel bindings) ๐Ÿ”ฅ there's also a secondary motivation, and it's lowkey clever: even if the lower layers aren't any more efficient at encryption than RPCSEC_GSS itself, if encryption is already happening lower down, it can be redundant at the RPCSEC_GSS level ๐Ÿ™ˆ

RPCSEC_GSSv2 and RPCSEC_GSSv1 both exchange tokens emitted by the Generic Security Services (GSS) framework, which is defined in [3] ๐Ÿงš they differ only in the GSS channel binding support in v2 ๐Ÿ’– GSS itself supports channel bindings, and in theory RPCSEC_GSSv2 could just use native GSS channel bindings to get the effects described in this section ๐ŸŒˆ but as Section 1.1.6 of [3] says, not every implementation of every GSS mechanism supports channel bindings ๐Ÿ’€ so that's the justification for this approach: modify the RPCSEC_GSS protocol so it supports channel bindings independent of the capabilities of the GSS mechanism being used ๐Ÿ‘‘

once an RPCSEC_GSS target and initiator are mutually assured that they're each using the same secure, end-to-end channel, the overhead of computing message integrity codes (MICs) for authenticating and integrity-protecting RPC requests and replies can be eliminated, because the channel is already doing that job ๐Ÿซถ and if the channel also provides confidentiality, the overhead of RPCSEC_GSS privacy protection can be eliminated too โœจ

the External Data Representation (XDR) [4] description is written in a way that's super easy to pull out into a ready-to-compile form ๐ŸŽ€ you can feed this document into the following shell script to get the machine-readable XDR description of RPCSEC_GSSv2:

#!/bin/sh
grep "^  *///" | sed 's?^  *///??'

so if that script is saved as "extract.sh" and this doc is saved as "spec.txt", you run:

sh extract.sh < spec.txt > rpcsec_gss_v2.x

the script basically strips leading white space from each line, plus the sentinel sequence "///" ๐Ÿ“

1.1. Requirements Language ๐Ÿ’œ

this is the part where the capital letters matter ๐Ÿ”ฅ the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [5] ๐Ÿ’…

2. Channel Bindings Explained ๐ŸŒˆ

okay so this is the big idea, and it's honestly iconic ๐Ÿ‘‘ if a channel between two parties is secure, there has to be shared information between the two of them ๐Ÿฆ‹ that info might be secret or might not, and whether it needs to be secret depends on the specifics of the channel ๐ŸŒธ

for example, the shared info could be the concatenation of the public keys of the source and destination of the channel (each public key has a matching private key) โœจ now suppose the channel isn't end-to-end, so there's a man-in-the-middle (MITM) and there are two channels: one from the initiator to the MITM, and one from the MITM to the target ๐Ÿ’€ the MITM can't just force each channel to use the same public keys, because a public key comes from a private key, and each node's key management system will surely assign unique or random private keys ๐Ÿ™ˆ at most, the MITM can force one end of each channel to use the same public key ๐Ÿ’–

the MIC of the public keys from the initiator won't get verified by the target, because at least one of those public keys will be different ๐Ÿ”ฅ and similarly, the MIC of the public keys from the target won't get verified by the initiator, because at least one of those keys will also be different ๐Ÿ˜ญ

a higher-layer protocol can safely exploit the secure channel for the mutual benefit of the higher-level parties, if each higher-level party can prove two things ๐Ÿซถ

  • they each know the channel's shared information.
  • the proof of knowing that shared information is actually being conveyed by each of the higher-level parties, and not by some other entities.

so RPCSEC_GSSv2 adds an optional round-trip ๐Ÿงš the initiator computes a GSS MIC on the channel binding's shared information and sends it to the target ๐Ÿ’… the target verifies that MIC, then sends its own MIC of the shared information back to the initiator, who verifies the target's MIC โœจ this accomplishes three things ๐ŸŽ€:

  1. the initiator and target are mutually authenticated.
  2. the initiator and target prove they know the channel's shared information, and therefore are using the same channel.
  3. the first and second things are done simultaneously.

3. The RPCSEC_GSSv2 Protocol ๐ŸŒธ

so the RPCSEC_GSSv2 protocol is about to get explained ๐Ÿ’– the whole protocol is not presented here, instead the doc shows just the differences between v2 and v1 ๐Ÿซถ

3.1. Compatibility with RPCSEC_GSSv1 ๐Ÿฆ‹

the functionality of RPCSEC_GSSv1 is fully supported by RPCSEC_GSSv2 โœจ no drama, no cap ๐Ÿ’…


okay bestie that's the first chunk of the RFC ๐ŸŽ€ we're only through section 3.1 right now, so there's more coming in part 2 ๐Ÿ‘‘ stay tuned, I'm obsessed already ๐Ÿ’œ๐ŸŒˆ

3.2. New Version Number ๐ŸŽ€

/// /*
///  * Copyright (c) 2009 IETF Trust and the persons identified
///  * as the document authors. All rights reserved.
///  *
///  * The document authors are identified in [RFC2203] and
///  * [RFC5403].
///  *
///  * Redistribution and use in source and binary forms, with
///  * or without modification, are permitted provided that the
///  * following conditions are met:
///  *
///  * o Redistributions of source code must retain the above
///  *   copyright notice, this list of conditions and the
///  *   following disclaimer.
///  *
///  * o Redistributions in binary form must reproduce the above
///  *   copyright notice, this list of conditions and the
///  *   following disclaimer in the documentation and/or other
///  *   materials provided with the distribution.
///  *
///  * o Neither the name of Internet Society, IETF or IETF
///  *   Trust, nor the names of specific contributors, may be
///  *   used to endorse or promote products derived from this
///  *   software without specific prior written permission.
///  *
///  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
///  *   AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
///  *   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
///  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
///  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
///  *   EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
///  *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
///  *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
///  *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
///  *   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
///  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
///  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
///  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
///  *   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
///  *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
///  */
/// /*
///  * This code was derived from [RFC2203]. Please
///  * reproduce this note if possible.

///  */
///
///  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,
///    rpc_gss_svc_channel_prot = 4 /* new */
///  };
///
///   enum rpc_gss_proc_t {
///     RPCSEC_GSS_DATA          = 0,
///     RPCSEC_GSS_INIT          = 1,
///     RPCSEC_GSS_CONTINUE_INIT = 2,
///     RPCSEC_GSS_DESTROY       = 3,
///     RPCSEC_GSS_BIND_CHANNEL  = 4 /* new */
///  };
///
///  struct rpc_gss_cred_vers_1_t {
///    rpc_gss_proc_t    gss_proc; /* control procedure */
///    unsigned int      seq_num;  /* sequence number */
///    rpc_gss_service_t service;  /* service used */
///    opaque            handle<>; /* context handle */
///  };
///
///  const RPCSEC_GSS_VERS_1 = 1;
///  const RPCSEC_GSS_VERS_2 = 2; /* new */
///
///  union rpc_gss_cred_t switch (unsigned int rgc_version) {
///    case RPCSEC_GSS_VERS_1:
///    case RPCSEC_GSS_VERS_2: /* new */
///      rpc_gss_cred_vers_1_t rgc_cred_v1;
///  };
///

Figure 1

Okay so look at Figure 1 ๐Ÿ’… the RPCSEC_GSSv2 credential has the exact same shape as the RPCSEC_GSSv1 credential, which is so satisfying โœจ The one tweak is that they cleaned up the definition so it's legal XDR description language that's also compatible with [9]. That's why the field "version" (a keyword in RFC 1831 ๐Ÿ™ˆ) got renamed to "rgc_version". And setting rgc_version to 2 is how you tell everyone the initiator and target support channel bindings ๐Ÿซถ

3.3. New Procedure - RPCSEC_GSS_BIND_CHANNEL ๐Ÿฆ‹

///  struct rgss2_bind_chan_MIC_in_args {
///    opaque          rbcmia_bind_chan_hash<>;
///  };
///
///  typedef opaque    rgss2_chan_pref<>;
///  typedef opaque    rgss2_oid<>;
///
///  struct rgss2_bind_chan_verf_args {
///    rgss2_chan_pref rbcva_chan_bind_prefix;
///    rgss2_oid       rbcva_chan_bind_oid_hash;
///    opaque          rbcva_chan_mic<>;
///  };
///

Figure 2

Once an RPCSEC_GSSv2 handle has been established over a secure channel, the initiator MAY issue RPCSEC_GSS_BIND_CHANNEL (Figure 1). Targets MUST support RPCSEC_GSS_BIND_CHANNEL. Like RPCSEC_GSS_INIT and RPCSEC_GSS_CONTINUE_INIT requests, the NULL RPC procedure MUST be used. Unlike those two requests, the arguments of the NULL procedure are not overloaded, because the verifier is of sufficient size for the purpose of RPCSEC_GSS_BIND_CHANNEL. The gss_proc field is set to RPCSEC_GSS_BIND_CHANNEL. The seq_num field is set as if gss_proc were set to RPCSEC_GSS_DATA. The service field is set to rpc_gss_svc_none. The handle field is set to that of an RPCSEC_GSS handle as returned by RPCSEC_GSS_INIT or RPCSEC_GSS_CONTINUE_INIT.

The RPCSEC_GSS_BIND_CHANNEL request is similar to the RPCSEC_GSS_DATA request in that the verifiers of both contain MICs. As described in Section 5.3.1 of [1], when gss_proc is RPCSEC_GSS_DATA, the verifier of an RPC request is set to the output of GSS_GetMIC() on the RPC header. When gss_proc is RPCSEC_GSS_BIND_CHANNEL the verifier of an RPC request is set to the XDR encoding on a value of data type rgss2_bind_chan_verf_args, which includes a MIC as described below. The rgss2_bind_chan_verf_args data type consists of three fields:

  • rbcva_chan_bind_prefix. This is the channel binding prefix as described in [2] up to, but excluding, the colon (ASCII 0x3A) that separates the prefix from the suffix.
  • rbcva_chan_bind_hash_oid. This is the object identifier (OID) of the hash algorithm used to compute rbcmia_bind_chan_hash. This field contains an OID encoded in ASN.1 as used by GSS-API in the mech_type argument to GSS_Init_sec_context ([3]). See [6] for the OIDs of the SHA one-way hash algorithms.
  • rbcva_chan_mic. This is the output of GSS_GetMIC() on the concatenation of the XDR-encoded RPC header ("up to and including the credential" as per [1]) and the XDR encoding of an instance of type data rgss2_bind_chan_MIC_in_args. The data type rgss2_bind_chan_MIC_in_args consists of one field, rbcmia_bind_chan_hash, which is a hash of the channel bindings as defined in [2]. The channel bindings are a "canonical octet string encoding of the channel bindings", starting "with the channel bindings prefix followed by a colon (ASCII 0x3A)". The reason a hash of the channel bindings and not the actual channel bindings are used to compute rbcva_chan_mic is that some channel bindings, such as those composed of public keys, can be relatively large, and thus place a higher space burden on the implementations to manage. One way hashes consume less space.
///  enum rgss2_bind_chan_status {
///    RGSS2_BIND_CHAN_OK           = 0,
///    RGSS2_BIND_CHAN_PREF_NOTSUPP = 1,
///    RGSS2_BIND_CHAN_HASH_NOTSUPP = 2
///  };
///
///  union rgss2_bind_chan_res switch
///     (rgss2_bind_chan_status rbcr_stat) {
///
///    case RGSS2_BIND_CHAN_OK:
///      void;
///
///    case RGSS2_BIND_CHAN_PREF_NOTSUPP:
///      rgss2_chan_pref rbcr_pref_list<>;
///
///    case RGSS2_BIND_CHAN_HASH_NOTSUPP:
///      rgss2_oid       rbcr_oid_list<>;
///  };
///
///  struct rgss2_bind_chan_MIC_in_res {
///    unsigned int        rbcmr_seq_num;
///    opaque              rbcmr_bind_chan_hash<>;
///    rgss2_bind_chan_res rbcmr_res;
///  };
///
///  struct rgss2_bind_chan_verf_res {
///    rgss2_bind_chan_res rbcvr_res;
///    opaque              rbcvr_mic<>;
///  };
///

Figure 3

The RPCSEC_GSS_BIND_CHANNEL reply is similar to the RPCSEC_GSS_DATA reply in that the verifiers of both contain MICs. When gss_proc is RPCSEC_GSS_DATA, the verifier of an RPC reply is set to the output of GSS_GetMIC() on the seq_num of the credential of the corresponding request (as described in Section 5.3.3.2 of [1]). When gss_proc is RPCSEC_GSS_BIND_CHANNEL, the verifier of an RPC reply is set to the XDR encoding of an instance of data type rgss2_bind_chan_verf_res, which includes a MIC as described below. The data type rgss2_bind_chan_verf_res consists of two fields.

  • rbcvr_res. The data type of this field is rgss2_bind_chan_res. The rgss2_bind_chan_res data type is a switched union consisting of three cases switched on the status contained in the rbcr_stat field.
    • RGSS2_BIND_CHAN_OK. If this status is returned, the target accepted the channel bindings, and successfully verified rbcva_chan_mic in the request. No additional results will be in rbcvr_res.
    • RGSS2_BIND_CHAN_PREF_NOTSUPP. If this status is returned, the target did not support the prefix in the rbcva_chan_bind_prefix field of the arguments, and thus the RPCSEC_GSS_BIND_CHANNEL request was rejected. The target returned a list of prefixes it does support in the field rbcr_pref_list. Note that a channel can have multiple channel bindings each with different prefixes. The initiator is free to pick its preferred prefix. If the target does not support the prefix, the status RGSS2_BIND_CHAN_PREF_NOTSUPP will be returned, and the initiator can select its next most preferred prefix among the prefixes the target does support.
    • RGSS2_BIND_CHAN_HASH_NOTSUPP. If this status is returned, the target did not support the hash algorithm identified in the rbcva_chan_bind_hash_oid field of the arguments, and thus the RPCSEC_GSS_BIND_CHANNEL request was rejected. The target returned a list of OIDs of hash algorithms it does support in the field rbcr_oid_list. The array rbcr_oid_list MUST have one or more elements.
  • rbcvr_mic. The value of this field is equal to the output of GSS_GetMIC() on the XDR encoding of an instance of data type rgss2_bind_chan_MIC_in_res. The data type rgss2_bind_chan_MIC_in_res consists of three fields.
    • rbcmr_seq_num. The value of this field is equal to the field seq_num in the RPCSEC_GSS credential (data type rpc_gss_cred_vers_1_t).
    • rbcmr_bind_chan_hash. This is the result of the one way hash of the channel bindings (including the prefix). If rbcr_stat is not RGSS2_BIND_CHAN_HASH_NOTSUPP, then the hash algorithm that is used to compute rbcmr_bind_chan_hash is that identified by the rbcva_chan_bind_oid_hash field in the arguments to RPCSEC_GSS_BIND_CHANNEL. If rbcr_stat is RGSS2_BIND_CHAN_HASH_NOTSUPP, then the hash algorithm used to compute rbcmr_bind_chan_hash is that identified by rbcr_oid_list[0] in the results.
    • rbcmr_res. The value of this field is equal to the value of the rbcvr_res field.

3.4. New Security Service - rpc_gss_svc_channel_prot โœจ

okay bestie, the new service is rpc_gss_svc_channel_prot ๐ŸŽ€ and RPCSEC_GSSv2 targets MUST support it, no exceptions ๐Ÿ’…

so rpc_gss_svc_channel_prot (Figure 1) is only valid when three things are true ๐Ÿ‘‘: you're using RPCSEC_GSSv2, an RPCSEC_GSS_BIND_CHANNEL procedure already ran successfully, and the secure channel still exists ๐Ÿฆ‹. when it's in play, requests and replies look a lot like rpc_gss_svc_none, except the verifiers on both the request and the reply always have the flavor set to AUTH_NONE and their contents are zero length ๐Ÿซถ

ngl this part is a little plot twist ๐Ÿ™ˆ: even though the verifiers are NULL, you still use non-NULL RPCSEC_GSS credentials. to identify who's sending the request, you use the same credential as before, just with the service field set to rpc_gss_svc_channel_prot โœจ


4. Version Negotiation ๐Ÿงš

an initiator that supports version 2 of RPCSEC_GSS just sends an RPCSEC_GSS request with the rgc_version field set to RPCSEC_GSS_VERS_2 ๐Ÿ’–. if the target doesn't recognize RPCSEC_GSS_VERS_2, the target will return an RPC error per Section 5.1 of [1] ๐Ÿฅบ

no mixing handles, bestie ๐Ÿšซ: the initiator MUST NOT attempt to use an RPCSEC_GSS handle returned by version 2 of a target with version 1 of the same target. the initiator MUST NOT attempt to use an RPCSEC_GSS handle returned by version 1 of a target with version 2 of the same target.


5. Native GSS Channel Bindings ๐Ÿ”ฅ

to keep everything interoperable ๐Ÿซถ, implementations of RPCSEC_GSSv2 SHOULD NOT transfer tokens between the initiator and target that use native GSS channel bindings (as defined in Section 1.1.6 of [3]).


6. Operational Recommendation for Deployment ๐Ÿ“

RPCSEC_GSSv2 is a superset of RPCSEC_GSSv1, so it can be used in all the situations where RPCSEC_GSSv1 is used ๐Ÿ’…. RPCSEC_GSSv2 should be used when the new functionality, channel bindings, is desired or needed โœจ


7. Implementation Notes ๐Ÿ“

once a successful RPCSEC_GSS_BIND_CHANNEL procedure has been performed on an RPCSEC_GSSv2 context handle, the initiator's implementation may map application requests for rpc_gss_svc_none and rpc_gss_svc_integrity to rpc_gss_svc_channel_prot credentials. and if the secure channel has privacy enabled, requests for rpc_gss_svc_privacy can also be mapped to rpc_gss_svc_channel_prot ๐ŸŒˆ


8. Acknowledgments ๐Ÿ’œ

Nicolas Williams had the idea for extending RPCSEC_GSS to support channel bindings ๐Ÿ‘‘. Alex Burlyga, Lars Eggert, Pasi Eronen, and Dan Romascanu reviewed the document and gave valuable feedback for improving its readability ๐Ÿซถ


9. Security Considerations ๐Ÿ”

okay bestie, this section is SERIOUS ๐Ÿ˜ญ, so read it carefully:

The base security considerations consist of:

  • All security considerations from [1].
  • All security considerations from [2].
  • All security considerations from the actual secure channel being used.

even though RPCSEC_GSS_DATA requests that use rpc_gss_svc_channel_prot protection don't involve constructing more GSS tokens, the target SHOULD stop allowing RPCSEC_GSS_DATA requests with rpc_gss_svc_channel_prot protection once the GSS context expires ๐Ÿฅ€

with channel bindings in the mix, it becomes extremely critical ๐Ÿšจ that the message integrity code (MIC) used by the GSS mechanism that RPCSEC_GSS is using be difficult to forge. this is true for RPCSEC_GSSv1 too, and honestly for any protocol that uses GSS MICs, but the seriousness is different. for RPCSEC_GSSv1, forging a single MIC at most lets the attacker inject one bogus request. with RPCSEC_GSSv2 plus channel bindings, forging a single MIC lets the attacker inject bogus requests for as long as the channel exists ๐Ÿ˜ฑ

let's walk through an example ๐Ÿ•ต๏ธ. we have an RPCSEC_GSSv1 initiator, a man-in-the-middle (MITM), an RPCSEC_GSSv1 target, and an RPCSEC_GSSv2 target. the attack goes like this:

  • The MITM intercepts the initiator's RPCSEC_GSSv1 RPCSEC_GSS_INIT message and changes the version number from 1 to 2 before forwarding to the RPCSEC_GSSv2 target, and changes the reply's version number from 2 to 1 before forwarding to the RPCSEC_GSSv1 initiator. Neither the client nor the server notice.
  • Once the RPCSEC_GSS handle is in an established state, the initiator sends its first RPCSEC_GSS_DATA request. The MITM constructs an RPCSEC_GSS_BIND_CHANNEL request, using the message integrity code (MIC) of the RPCSEC_GSS_DATA request. It is likely the RPCSEC_GSSv2 target will reject the request. The MITM continues to reiterate each time the initiator sends another RPCSEC_GSS_DATA request. With enough iterations, the probability of a MIC from an RPCSEC_GSS_DATA being successfully verified in the forged RPCSEC_GSS_BIND_CHANNEL increases. Once the MITM succeeds, it can send RPCSEC_GSS_DATA requests with a security service of rpc_gss_svc_channel_prot, which does not have MICs in the RPC request's verifier.

the implementation of RPCSEC_GSSv2 can use at least two methods to thwart these attacks ๐Ÿ›ก๏ธ

  • The target SHOULD require a stronger MIC when sending an RPCSEC_GSS_BIND_CHANNEL request instead of an RPCSEC_GSS_DATA request -- e.g., if HMACs are used for the MICs, require the widest possible HMAC (in terms of bit length) that the GSS mechanism supports. If HMACs are being used, and the target expects N RPCSEC_GSS_DATA requests to be sent on the context before it expires, then the target SHOULD require an HMAC for RPCSEC_GSS_BIND_CHANNEL that is log base 2 N bits longer than what it normally requires for RPCSEC_GSS_DATA requests. If a long enough MIC is not available, then the target could artificially limit the number of RPCSEC_GSS_DATA requests it will allow on the context before deleting the context.
  • Each time an RPCSEC_GSSv2 target experiences a failure to verify the MIC of an RPCSEC_GSS_BIND_CHANNEL request, it SHOULD reduce the lifetime of the underlying GSS context, by a significant fraction, thereby preventing the MITM from using the established context for its attack. A possible heuristic is that if the target believes the possibility that failure to verify the MIC was because of an attack is X percent, then the context's lifetime would be reduced by X percent. For simplicity, an implementer might set X to be 50 percent, so that the context lifetime is halved on each failed verification of an RPCSEC_GSS_BIND_CHANNEL request and thus rapidly reduced to zero on subsequent requests. For example, with a context lifetime of 8 hours (or 28800 seconds), 15 failed attempts by the MITM would cause the context to be destroyed.

a method of mitigation that was considered was to protect the RPCSEC_GSS version number with RPCSEC_GSSv2's RPCSEC_GSS_INIT and RPCSEC_GSS_CONTINUE_INIT tokens. Thus, the version number of RPCSEC_GSS would be in the tokens. This method does not completely mitigate the attack; it just moves the MIC guessing to the RPCSEC_GSS_INIT message. In addition, without changing GSS, or the GSS mechanism, there is no way to include the RPCSEC_GSS version number in the tokens. So for these reasons, this method was not selected.


10. References ๐Ÿ“š

10.1. Normative References

  • [1] Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol Specification", RFC 2203, September 1997.
  • [2] Williams, N., "On the Use of Channel Bindings to Secure Channels", RFC 5056, November 2007.
  • [3] Linn, J., "Generic Security Service Application Program Interface Version 2, Update 1", RFC 2743, January 2000.
  • [4] Eisler, M., "XDR: External Data Representation Standard", STD 67, RFC 4506, May 2006.
  • [5] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [6] Schaad, J., Kaliski, B., and R. Housley, "Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 4055, June 2005.

10.2. Informative References

  • [7] Williams, N., "IPsec Channels: Connection Latching", Work in Progress, November 2008.
  • [8] Williams, N., "End-Point Channel Bindings for IPsec Using IKEv2 and Public Keys", Work in Progress, April 2008.
  • [9] Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification Version 2", RFC 1831, August 1995.

Author's Address ๐Ÿ“ฎ

Mike Eisler
NetApp
5765 Chase Point Circle
Colorado Springs, CO  80919
US

Phone: +1-719-599-9026
EMail: mike@eisler.com
๐Ÿ“ฆ where this page comes from