Network Working Group | B. Kaduk |
Internet-Draft | MIT |
Intended status: Standards Track | October 21, 2013 |
Expires: April 24, 2014 |
Structure of the GSS Negotiation Loop
draft-kaduk-kitten-gss-loop-00
This document specifies the generic structure of the negotiation loop to establish a GSS security context between initiator and acceptor. The control flow of the loop is indicated for both parties, including error conditions, and indications are given for where application-specific behavior must be specified.
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."
This Internet-Draft will expire on April 24, 2014.
Copyright (c) 2013 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
The Generic Security Service Application Program Intervace version 2 [RFC2743] provides a generic interface for security services, in the form of an abstraction layer over the underlying security mechanisms that an application may use. A GSS initiator and acceptor exchange messages, called tokens, until a security context is established. Such a security context allows for mutual authentication of the two parties, the passing of confidential or integrity-protected messages between the initiator and acceptor, the generation of identical pseudo-random bit strings by both participants [RFC4401], and more. The number of tokens which must be exchanged between initiator and acceptor in order to establish the security context is dependent on the underlying mechanism as well as the desired properties of the security context, and is in general not known to the application. Accordingly, the application's control flow must include a loop within which GSS security context tokens are exchanged, which terminates upon successful establishment of a security context (or an error condition).
The GSS-API C bindings [RFC2744] provide some example code for such a negotiation loop, but this code does not specify the application's behavior on unexpected or error conditions. As such, individual application protocol specifications have had to specify the structure of their GSS negotiation loops, including error handling, on a per-protocol basis. [RFC4462], [RFC3645], [RFC5801], [RFC4752], [RFC2203] This represents a substantial duplication of effort, and the various specifications go into different levels of detail and describe different possible error conditions. It is therefore preferable to have the structure of the GSS negotiation loop, including error conditions and token passing, described in a single specification, which can then be referred to from other documents in lieu of repeating the structure of the loop each time. This document will perform that role.
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 [RFC2119].
The loop is begun by the appropriately named initiator, which calls GSS_Init_sec_context() with an empty (zero-length) input_token and a fixed set of input flags containing the desired attributes for the security context. The initiator MUST NOT change any of the input parameters to GSS_Init_sec_context() between calls to it during the loop, with the exception of the input_token parameter, which will contain a message from the acceptor after the initial call, and the input_context_handle, which MUST be the result returned in the output_context_handle of the previous call to GSS_Init_sec_context() (or GSS_C_NO_CONTEXT for the first call).
The following subsections will describe the various steps of the loop, without special consideration to whether a call to GSS_Init_sec_context() or GSS_Accept_sec_context() is the first such call in the loop. For the first call to each routine in the loop, the major status code from the previous call to GSS_Init_sec_context() or GSS_Accept_sec_context() should be taken as GSS_S_CONTINUE_NEEDED.
If the initiator is requesting anonymity by setting the anon_req_flag input to GSS_Init_sec_context(), then on non-error returns from GSS_Init_sec_context() (that is, the major status is GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), the initiator MUST verify that the output value of anon_state from GSS_Init_sec_context() is true before sending the security context token to the acceptor. Failing to perform this check could cause the initiator to lose anonymity.
The initiator calls GSS_Init_sec_context(), using the input_context_handle for the current proto-security-context and its fixed set of input parameters, and the input_token received from the acceptor (if not the first iteration of the loop). The presence of a nonempty output_token and the value of the major status code are the indicators for how to proceed:
The establishment of a GSS security context between initiator and acceptor requires some communication channel by which to exchange the context negotiation tokens. The nature of this channel is not specified by the GSS specification -- it could be a synchronous TCP channel, a UDP-based RPC protocol, or any other sort of channel. In many cases, the channel will be multiplexed with non-GSS application data; the application protocol must provide some means by which the GSS context tokens can be identified and passed through to the mechanism accordingly. It is in such cases where the application protocol has a means to indicate error conditions that the initiator could indicate a failure to the acceptor, as mentioned in some of the above cases conditional on "an appropriate channel to do so".
However, even the presence of a communication channel does not necessarily indicate that it is appropriate for the initiator to indicate such errors. For example, if the acceptor is a stateless or near-stateless UDP server, there is probably no need for the initiator to explicitly indicate its failure to the acceptor. Conditions such as this can be treated in individual application protocol specifications.
If a regular security context output_token is produced by the call to GSS_Init_sec_context(), the initiator MUST transmit this token to the acceptor over the application's communication channel. If the call to GSS_Init_sec_context() returns an error token as output_token, it is RECOMMENDED that the intiator transmit this token to the acceptor over the application's communication channel.
The acceptor's half of the negotiation loop is triggered by the receipt of a context token from the initiator. Before calling GSS_Accept_sec_context(), the acceptor may find it useful to perform some sanity checks on the state of the negotiation loop.
If the acceptor receives a context token but was not expecting such a token (for example, if the acceptor's previous call to GSS_Accept_sec_context() returned GSS_S_COMPLETE), this is an error condition indicating that the initiator's state is invalid. It is likely appropriate for the acceptor to report this error condition to the acceptor via the application's communication channel.
If the acceptor is expecting a context token (e.g., if the previous call to GSS_Accept_sec_context() returned GSS_S_CONTINUE_NEEDED), but does not receive such a token within a reasonable amount of time after transmitting the previous output_token to the initiator, the acceptor should assume that the initiator's state is invalid and fail the GSS negotiation. Again, it is likely appropriate for the acceptor to report this error condition to the initiator via the application's communication channel.
[Are there other checks to perform here?]
The GSS acceptor responds to the actions of an initiator; as such, there should always be a nonempty input_token to calls to GSS_Accept_sec_context(). The input_context_handle parameter will always be given as the output_context_handle from the previous call to GSS_Accept_sec_context() in a given negotiation loop (or GSS_C_NO_CONTEXT on the first call), but the acceptor_cred_handle and chan_bindings arguments MUST remain fixed over the course of a given GSS negotiation loop.
The GSS acceptor calls GSS_Accept_sec_context(), using the input_context_handle for the current proto-security-context and the input_token received from the initiator. The presence of a nonempty output_token and the value of the major status code are the indicators for how to proceed:
The mechanism for sending the context token from acceptor to initiator will depend on the nature of the communication channel between the two parties. For a synchronous bidirectional channel, it can be just another piece of data sent over the link, but for a stateless UDP RPC acceptor, the token will probably end up being sent as an RPC output parameter. Application protocol specifications will need to specify the nature of this behavior.
If the application protocol has the initiator driving the application's control flow (with the acceptor just responding to actions from the initiator), it is particularly helpful for the acceptor to indicate a failure to the initiator, as mentioned in some of the above cases conditional on "an appropriate channel to do so".
If a regular security context output_token is produced by the call to GSS_Accept_sec_context(), the acceptor MUST transmit this token to the initiator over the application's communication channel. If the call to GSS_Accept_sec_context() returns an error token as output_token, it is RECOMMENDED that the acceptor transmit this token to the initiator over the application's communication channel.
The initiator's half of the negotiation loop is triggered (after the first call) by receipt of a context token from the acceptor. Before calling GSS_Init_sec_context(), the initiator may find it useful to perform some sanity checks on the state of the negotiation loop.
If the initiator receives a context token but was not expecting such a token (for example, if the initiator's previous call to GSS_Init_sec_context() returned GSS_S_COMPLETE), this is an error condition indicating that the acceptor's state is invalid. It may be appropriate for the initiator to report this error condition to the acceptor via the application's communication channel.
If the initiator is expecting a context token (that is, the previous call to GSS_Init_sec_context() returned GSS_S_CONTINUE_NEEDED), but does not receive such a token within a reasonable amount of time after transmitting the previous output_token to the acceptor, the initiator should assume that the acceptor's state is invalid and fail the GSS negotiation. Again, it may be appropriate for the initiator to report this error condition to the acceptor via the application's communication channel.
[Are there other checks to perform here?]
If the loop is in neither a success or failure condition, then the loop must continue. Control flow returns to Section 2.2.
Once a party has completed its half of the security context and fulfilled its obligations to the other party, the context is complete, but it is not necessarily ready and appropriate for use. (In some cases the context may be ready for use earlier than this, see Section 3.1.) In particular, the security context flags may not be appropriate for the given application's use.
The initiator specifies as part of its fixed set of inputs to GSS_Init_sec_context() values for the following booleans: deleg_req_flag, mutual_req_flag, replay_det_req_flag, sequence_req_flag, conf_req_flag, and integ_req_flag. Upon completion of security context negotiation, the initiator MUST verify the values of the deleg_state, mutual_state, replay_det_state, sequence_state, conf_avail, and integ_avail flags from the last call to GSS_Init_sec_context() corresponding to the requested flags. If a flag was requested but is not available, and that feature is necessary for the appplication protocol, the initiator MUST destroy the security context and not use the security context for application traffic.
Application protocol specifications citing this document MUST indicate which context flags are required for the application protocol.
The acceptor receives as output the following booleans: deleg_state, mutual_state, replay_det_state, sequence_state, anon_state, trans_state, conf_avail, and integ_avail. The acceptor MUST verify that any flags necessary for the application protocol are set. If a necessary flag is not set, the acceptor MUST destroy the security context and not use the security context for application traffic.
For mechanism/flag combinations that require multiple token exchanges, an application protocol may find it desirable to begin sending application data protected with GSS per-message operations while continuing to exchange security context tokens to complete the security context negotiation. The prot_ready_state output value from GSS_Init_sec_context() and GSS_Accept_sec_context() indicates when per-message operations are avaialble.
Applications requiring confidentiality and/or integrity protection from such messages MUST check the value of the conf_avail and/or integ_avail output flags from GSS_Init_sec_context()/GSS_Accept_sec_context() as well as the conf_state output of GSS_Wrap() (if GSS_Wrap() is used).
[RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. |
[RFC2743] | Linn, J., "Generic Security Service Application Program Interface Version 2, Update 1", RFC 2743, January 2000. |
[RFC2744] | Wray, J., "Generic Security Service API Version 2 : C-bindings", RFC 2744, January 2000. |
[RFC4401] | Williams, N., "A Pseudo-Random Function (PRF) API Extension for the Generic Security Service Application Program Interface (GSS-API)", RFC 4401, February 2006. |
[RFC4462] | Hutzelman, J., Salowey, J., Galbraith, J. and V. Welch, "Generic Security Service Application Program Interface (GSS-API) Authentication and Key Exchange for the Secure Shell (SSH) Protocol", RFC 4462, May 2006. |
[RFC3645] | Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead, J. and R. Hall, "Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-TSIG)", RFC 3645, October 2003. |
[RFC5801] | Josefsson, S. and N. Williams, "Using Generic Security Service Application Program Interface (GSS-API) Mechanisms in Simple Authentication and Security Layer (SASL): The GS2 Mechanism Family", RFC 5801, July 2010. |
[RFC4752] | Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple Authentication and Security Layer (SASL) Mechanism", RFC 4752, November 2006. |
[RFC2203] | Eisler, M., Chiu, A. and L. Ling, "RPCSEC_GSS Protocol Specification", RFC 2203, September 1997. |
Acknowledgements.