<?xml version="1.0" encoding="UTF-8"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc tocindent="no"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc tocindent="no"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY rfc2119 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY rfc2743 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2743.xml">
<!ENTITY rfc2744 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2744.xml">
<!ENTITY rfc5056 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5056.xml">
<!ENTITY rfc5587 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5587.xml">
<!ENTITY rfc4121 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.4121.xml">
<!ENTITY rfc5653 PUBLIC "" "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5653.xml">
]>
<rfc docName="draft-ietf-kitten-channel-bound-flag-04" ipr="trust200902" category="std" updates="2743, 2744">
  <front>
    <title abbrev="GSS Channel Bound Flag">Channel Binding Signalling for the Generic Security Services Application Programming Interface</title>
    <author initials="R." surname="Harwood" fullname="Robbie Harwood">
      <organization abbrev="Red Hat">Red Hat, Inc.</organization>
      <address>
        <email>rharwood@redhat.com</email>
      </address>
    </author>
    <author initials="N." surname="Williams" fullname="Nicolas Williams">
      <organization abbrev="Cryptonector">Cryptonector, LLC</organization>
      <address>
        <email>nico@cryptonector.com</email>
      </address>
    </author>
    <date month="February" year="2019"/>
    <area>
Security Area
</area>
    <workgroup>
KITTEN
</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>
Channel binding is a technique that allows applications to use a secure
channel at a lower layer without having to use authentication at that
lower layer. The concept of channel binding comes from the Generic
Security Services Application Programming Interface (GSS-API). It turns
out that the semantics commonly implemented are different than those
specified in the base GSS-API RFC (RFC2743), and that that specification
has a serious bug. This document addresses both the inconsistency
as-implemented and the specification bug.</t>
      <t>
This Internet-Draft proposes the addition of a “channel bound” return
flag for the GSS_Init_sec_context() and GSS_Accept_sec_context()
functions. Two behaviors are specified: a default, safe behavior
reflecting existing implementation deployments, and a behavior that is
only safe when the application specifically tells the GSS-API that it
(the application) supports the new behavior. Additional API elements
related to this are also added, including a new security context
establishment API.</t>
    </abstract>
  </front>
  <middle>
    <section title="Introduction" anchor="d1e291">
      <t>
The GSS-API <xref target="RFC2743"/> supports “channel binding” <xref
  target="RFC5056"/>, a technique for detection of man-in-the-middle
(MITM) attacks in secure channels at lower network layers. This facility
is meant to be all-or-nothing: either both the initiator and acceptor
use it and it succeeds, or both must not use it. This has created a
negotiation problem when retrofitting the use of channel binding into
existing application protocols.</t>
        <t>
However, GSS-APIv2u1 <xref target="RFC2743"/> does not specify channel
binding behavior when only one party provides provides none.  In
practice, some mechanisms (such as Kerberos <xref target="RFC4121"/>)
ignore channel bindings when the acceptor provides none, but not when
the initiator provides none.  Note that it would be useless to allow
security context establishment to succeed when the initiator does not
provide channel bindings but the acceptor does, at least as long as
there's no outward indication of whether channel binding was used! Since
the GSS-APIv2u1 does not provide any such indication, this document
corrects that flaw.</t>
      <t>
Allowing the connection to succeed when an initiator provides bindings
but an acceptor does not has helped deployment of channel binding in
existing applications: first fix all the initiators, then fix all the
acceptors. But even this technique is insufficient when there are many
clients to fix, such that fixing them all will take a long time.
Additionally, it limits the usefulness of channel bindings, while
allowing the acceptor to provide but not enforce would protect against
man in the middle attacks (for channel binding aware initiators).</t>
      <t>
This document proposes a new method for deployment of channel binding
that allows the feature to be enabled on the acceptor side before fixing
all initiators. If the GSS-API had always had a return flag by which to
indicate channel binding state then we could have had a simpler method
of deploying channel binding: applications check that return flag and
act accordingly (e.g., fail when channel binding is required). We cannot
safely introduce this behavior now without an indication of support by
the application.</t>
      <t>
Additionally, there may be applications where it is important for
initiators to know that acceptors did use channel binding, and even to
know whether a mechanism is capable of indicating as much. We add a
request flag and a mechanism attribute for such applications.</t>
      <section title="Design and Future directions" anchor="d1e346">
        <t>
The design for signalling application flag support and empty contexts is
based on the Java Bindings of the GSS-API <xref target="RFC5653"/>. This
document begins introduction of additional context inquiry and mutation
functions, which eventually will also allow for simplified stepping to
replace the GSS_Init/Accept_sec_context() loop.</t>
      </section>
      <section title="Conventions used in this document" anchor="d1e398">
        <t>
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 <xref
  target="RFC2119"/>.</t>
      </section>
    </section>
    <section title="Channel Binding State Extension" anchor="d1e413">
      <t>
We propose a new return flag for GSS_Init_sec_context() and
GSS_Accept_sec_context(), as well as a pair of functions for a) creating
“empty” security context handles, b) requesting flags and indicating
which flags the application understands. We also add a new mechanism
attribute for supporting channel binding confirmation.</t>
      <t>
C bindings of these extensions are provided along the lines of <xref
  target="RFC2744"/> and <xref target="RFC5587"/>.</t>
      <t>
In the future we might move more of the many input (and output)
arguments to GSS_Init_sec_context() and GSS_Accept_sec_context() into
mutators on empty security context handles.</t>
      <section title="GSS_Create_sec_context()" anchor="d1e440">
        <t>
Inputs:</t>
        <t>
          <list style="symbols">
            <t>
&lt;none&gt;</t>
          </list>
        </t>
        <t>
Outputs:</t>
        <t>
          <list style="symbols">
            <t>
major_status INTEGER</t>
            <t>
minor_status INTEGER -- note: mostly useless, but we should keep it</t>
            <t>
context SECURITY CONTEXT -- “empty” security context</t>
          </list>
        </t>
        <t>
Return major status codes:</t>
        <t>
          <list style="symbols">
            <t>
GSS_S_COMPLETE indicates success.</t>
            <t>
GSS_S_UNAVAILABLE indicates that memory is not available, for
example.</t>
            <t>
GSS_S_FAILURE indicates a general failure.</t>
          </list>
        </t>
        <t>
This function creates an “empty” security context handle that can be
passed to GSS_Init_sec_context() or GSS_Accept_sec_context() where they
expect GSS_C_NO_CONTEXT.</t>
        <section title="C-Bindings" anchor="d1e483">
          <t>
</t>
          <t>
            <figure suppress-title="true" align="center">
              <artwork> OM_uint32
 gss_create_sec_context(OM_uint32 *minor_status,
                        gss_ctx_id_t *context);</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="GSS_Set_context_flags()" anchor="d1e495">
        <t>
Inputs:</t>
        <t>
          <list style="hanging">
            <t hangText="context CONTEXT HANDLE">
 </t>
            <t hangText="req_flags FLAGS">
 Requested flags. Applicable to acceptors and initiators.</t>
            <t hangText="ret_flags_understood FLAGS">
 The set of return flags understood by the caller.</t>
          </list>
        </t>
        <t>
Outputs:</t>
        <t>
          <list style="symbols">
            <t>
major_status INTEGER</t>
            <t>
minor_status INTEGER</t>
          </list>
        </t>
        <t>
Return major status codes:</t>
        <t>
          <list style="symbols">
            <t>
GSS_S_COMPLETE indicates success.</t>
            <t>
GSS_S_FAILURE indicates a general failure.</t>
          </list>
        </t>
        <t>
This function tells the mechanism (when one is eventually chosen and
invoked) that the application requests the given req_flags and is
prepared to check the flags in the given ret_flags_understood.
Mechanisms SHOULD NOT limit flags returned to those in
ret_flags_understood, but MAY alter behavior accordingly. Initiators can
override the req_flags in their GSS_Init_sec_context() call, but if no
flags are requested there then the req_flags set on the empty context
will be used. GSS_Accept_sec_context() is not required to perform any
action based on req_flags at this time.</t>
        <t>
NOTE: The abstract GSS-API <xref target="RFC2743"/> uses individual
elements--one per-flag--instead of a “FLAGS” type. This is unwieldy,
therefore we introduce an abstract type named “FLAGS” to act as a set of
all the request/return flags defined for the abstract GSS-API.</t>
        <section title="C-Bindings" anchor="d1e553">
          <t>
</t>
          <t>
            <figure suppress-title="true" align="center">
              <artwork> OM_uint32
 gss_set_context_flags(OM_uint32 *minor_status,
                       gss_ctx_id_t context,
                       uint64_t req_flags,
                       uint64_t ret_flags_understood);</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="Return Flag for Channel Binding State Signalling" anchor="d1e565">
        <t>
Whenever both the initiator and the acceptor provide matching channel
bindings to GSS_Init_sec_context() and GSS_Accept_sec_context(),
respectively, then the mechanism SHALL indicate that the context is
channel bound via an output flag, ret_channel_bound_flag, for the
established context. Note that some mechanisms have no way for the
acceptor to signal CB success to the initiator, in which case
GSS_Init_sec_context() MUST NOT output the ret_channel_bound_flag.</t>
        <section title="C-Bindings" anchor="d1e574">
          <t>
</t>
          <t>
            <figure suppress-title="true" align="center">
              <artwork> #define GSS_C_CHANNEL_BOUND_FLAG 2048 /* 0x00000800 */</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="New Mechanism Attribute" anchor="sub_New_Mechanism_Attribute">
        <t>
          <list style="symbols">
            <t>
We add a new mechanism attribute, GSS_C_MA_CBINDING_CONFIRM, to indicate
that the initiator can and always does learn whether the acceptor
application supplied channel bindings (assuming mutual auth has been
requested). Mechanisms advertising this attribute MUST always indicate
acceptor channel bound state to the initiator.</t>
          </list>
        </t>
        <t>
OID assignments TBD.</t>
      </section>
      <section title="Request Flag for Acceptor Confirmation of Channel Binding" anchor="d1e605">
        <t>
We add a new request flag for GSS_Init_sec_context(),
req_cb_confirmation_flag, to be used by initiators that insist on
acceptors providing channel bindings.  If set, the mechanism MUST prefer
establishment of contexts which provide channel binding confirmation.  It
SHOULD NOT fail to negotiate just because it cannot provide the
GSS_C_MA_CBINDING_CONFIRM attribute.</t>
        <section title="C-Bindings" anchor="d1e620">
          <t>
Because GSS_C_CHANNEL_BOUND_FLAG is a return flag only, and this flag is
a request flag only, and to save on precious flag bits, we use the same
flag bit assignment for both flags:</t>
          <t>
</t>
          <t>
            <figure suppress-title="true" align="center">
              <artwork> #define GSS_C_CB_CONFIRM_FLAG 2048 /* 0x00000800 */</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="Handling Empty Contexts in Other GSS-API Functions" anchor="d1e636">
        <t>
          GSS_Init_sec_context() and GSS_Accept_sec_context() operate on
          empty security contexts as specified above (i.e., examining
          flags).
        </t>
        <t>
          All other GSS-API functions MUST treat empty contexts as they
          would GSS_C_NO_CONTEXT as well. For most functions, this will
          result in returning GSS status code GSS_S_NO_CONTEXT.
        </t>
        <t>
          GSS_Delete_sec_context() MUST NOT output a context deletion
          token when applied to empty security contexts.
        </t>
      </section>
    </section>
    <section title="Modified Channel Binding Semantics" anchor="d1e645">
      <t>
The channel binding semantics of the base GSS-API are modified as
follows:</t>
      <t>
        <list style="symbols">
          <t>
Whenever both the initiator and acceptor have provided
input_channel_bindings to GSS_Init/Accept_sec_context() and the channel
bindings do not match, then the mechanism MUST fail to establish a
security context token. (This is a restatement of an existing
requirement in the base specification.)</t>
          <t>
Whenever the acceptor application has a) provided channel bindings to
GSS_Accept_sec_context(), and b) not indicated support for the
ret_channel_bound_flag flag, then the mechanism MUST fail to establish a
security context if the initiator did not provide channel bindings data.
This requirement is critical for security purposes, to make applications
predating this document secure, and this requirement reflects actual
implementations as deployed.</t>
          <t>
Whenever the initiator application has a) provided channel bindings to
GSS_Init_sec_context(), and b) not indicated support for the
ret_channel_bound_flag flag, then the mechanism SHOULD NOT fail to
establish a security context just because the acceptor failed to provide
channel bindings data.  This strong sugestion is for interoperability
purposes, and reflects actual implementations that have been
deployed.</t>
          <t>
Whenever the application has a) provided channel bindings to
GSS_Init_sec_context() or GSS_Accept_sec_context(), and b) indicated
support for the ret_channel_bound_flag flag, then the mechanism SHOULD
NOT fail to establish a security context just because the peer did not
provide channel bindings data.  The mechanism MUST output the
ret_channel_bound_flag if both peers provided the same
input_channel_bindings to GSS_Init_sec_context() and
GSS_Accept_sec_context(). The mechanism MUST NOT output the
ret_channel_bound_flag if either (or both) peer did not provide
input_channel_bindings to GSS_Init/Accept_sec_context(). This requirement
restores the original base GSS-API specified behavior, with the addition
of the ret_channel_bound_flag flag.</t>
        </list>
      </t>
    </section>
    <section title="Security Considerations" anchor="d1e667">
      <t>
This document deals with security. There are no security considerations
that should be documented separately in this section. To recap, this
document fixes a significant flaw in the base GSS-API <xref
  target="RFC2743"/> specification that fortunately has not been
implemented, and it adds a feature (that should have been in the base
specification) for improved negotiation of use of channel binding <xref
  target="RFC5056"/>.</t>
    </section>
    <section title="IANA Considerations" anchor="d1e688">
      <t>
The GSS-API mechanism attribute is to be added to the “SMI Security for
Mechanism gsscma Codes” registry established by RFC5587 <xref
  target="RFC5587"/>. See  <xref
  target="sub_New_Mechanism_Attribute"/>.</t>
    </section>
  </middle>
  <back>
    <references title="Normative References">&rfc2119;
&rfc2743;
&rfc2744;
&rfc5056;
&rfc5587;
</references>
    <references title="Informative References">&rfc4121;
&rfc5653;
</references>
  </back>
</rfc>
