The Simple and Protected Generic Security Service Application Program Interface (GSS-API) Negotiation Mechanism
obsoletes
- rfc-2478 — The Simple and Protected GSS-API Negotiation Mechanism
Extracted elements (25)
MIC tokens are made optional when the selected mechanism is the most preferred of both peers, allowing interoperability with legacy Windows SPNEGO implementations that never produce or process mechlistMIC tokens, while still protecting the negotiation between new implementations.
RFC 4178 intentionally breaks compatibility with correct RFC 2478 implementations because the working group valued interoperability with widely-deployed Microsoft Windows SPNEGO implementations. A critical encoding flaw in RFC 2478's mechanism list description also made RFC 2478 implementations unlikely to interoperate with each other anyway.
The first context token of the initiator's preferred mechanism SHOULD be embedded in the initial negotiation message (optimistic mechanism token) to avoid an extra round trip. In cases where generating the first token is costly and the mechanism is unlikely to be selected by the acceptor, implementations MAY omit it.
An implementation conforming to RFC 4178 will not interoperate with a strict RFC 2478 implementation. Even if the new implementation always sends a mechlistMIC token, a server will fail because it requests a mechlistMIC using request-mic which older implementations do not support.
Microsoft Windows 2000/XP/Server 2003 SPNEGO implementations do not produce or process mechlistMIC tokens and may use the incorrect OID 1.2.840.48018.1.2.2 to identify Kerberos V5 instead of the correct OID 1.2.840.113554.1.2.2. If at least one peer implements RFC 4178, the negotiation is protected despite legacy peer behavior.
Acceptors MUST demand the MIC token exchange if they support negotiation of mechanism attributes not available in the initiator's preferred mechanism, regardless of whether the initiator actually requested those attributes.
If none of the proposed mechanisms are acceptable to the target, the negotiation SHALL be terminated; GSS_Accept_sec_context indicates GSS_S_BAD_MECH. The acceptor MAY output a negotiation token containing a reject state.
Implementations receiving unknown fields in the ASN.1 structures MUST ignore those fields, providing forward extensibility. IETF standards action MAY expand the ASN.1 structures.
In the absence of application-specified preference order or other policy, the target SHALL choose the first mechanism in the initiator's proposed list for which it has valid credentials.
MIC tokens MUST be exchanged after mechanism context establishment in all cases where the selected mechanism supports integrity and the accepted mechanism is not the most preferred of both peers. The mechlistMIC is computed using GSS_GetMIC() over the DER encoding of the MechTypeList value (not the [0] tag/length wrapper) from the NegTokenInit.
Subsequent negotiation tokens (after the initial NegTokenInit) MUST NOT be encapsulated in the GSS-API generic token framing (initialContextToken wrapper); only the initial token uses that framing.
The mechTypes list in NegTokenInit MUST NOT contain the SPNEGO mechanism itself or any mechanism for which the initiator does not have appropriate credentials.
The reqFlags field in NegTokenInit is inherited from RFC 2478 and is not integrity-protected; the initiator SHOULD omit it and the acceptor MUST ignore it.
The supportedMech field in the first NegTokenResp SHALL only be present in the first reply from the target and MUST be one of the mechanisms offered by the initiator.
To avoid conflicts with SPNEGO's use of MIC tokens, the prot_ready_state MUST be set to false on return from GSS_Init_sec_context() and GSS_Accept_sec_context(), even if the underlying mechanism returned true, so that partially-established contexts cannot be used for per-message calls.
When the initiator's preferred mechanism is not accepted or is not the acceptor's most preferred (requiring MIC exchange), the acceptor MUST output a negotiation token containing a request-mic state and indicate GSS_S_CONTINUE_NEEDED.
SPNEGO is a pseudo GSS-API security mechanism (OID 1.3.6.1.5.5.2) that allows peers to negotiate a common security mechanism in-band. The initiator proposes an ordered list of mechanisms; the acceptor selects one or rejects all. Subsequent mechanism-specific context tokens are then carried within the negotiation messages.
The mechListMIC computation input is the DER encoding of the value of type MechTypeList (the contents of the 'mechTypes' field), NOT the DER encoding of the '[0] MechTypeList' tagged type. The identifier and length octets for constructed [0] (A0 nn) are excluded from the MIC computation.
Two additional GSS-API calls are defined: GSS_Set_neg_mechs() lets a caller restrict the set of negotiable mechanisms for a given credential handle, and GSS_Get_neg_mechs() retrieves the currently available negotiable mechanisms for a credential handle. Mechanism order in GSS_Set_neg_mechs() implies relative preference.
When per-message integrity services are available and the mechanism list was altered by an adversary to force a non-mutually-preferred mechanism: if the initiator sends the last token, both peers fail; if the acceptor sends the last token, the acceptor will not complete and the initiator will at worst complete with its preferred mechanism selected.
When the selected mechanism does not support integrity protection, the negotiation is vulnerable: an active attacker can force selection of a security mechanism that is not mutually preferred but is acceptable to the target. The strength of SPNEGO is bounded by the integrity protection strength of the weakest mechanism acceptable to both peers.
Where multiple mechanisms share similar context token syntax and an OID in a pseudo-ASN.1/DER wrapper that is not integrity-protected, downgrade attacks may be possible between mechanism variants. SPNEGO does not defeat such attacks. All communicating peers are also exposed to denial-of-service threats.
The negotiation response carries one of four states: accept-completed (context established, no further tokens needed), accept-incomplete (more tokens needed, MIC exchange optional), reject (negotiation terminated), or request-mic (MIC exchange REQUIRED if integrity available). negState is REQUIRED in the first reply and OPTIONAL thereafter; when absent, state is inferred from the negotiated mechanism context.
NegTokenInit is the ASN.1 DER-encoded initial negotiation token containing: mechTypes ([0] MechTypeList, mandatory), reqFlags ([1] ContextFlags, OPTIONAL), mechToken ([2] OCTET STRING, OPTIONAL optimistic mechanism token), and mechListMIC ([3] OCTET STRING, OPTIONAL). All SPNEGO messages use EXPLICIT TAGS and DER encoding per X.690.
NegTokenResp is the ASN.1 DER-encoded token for all subsequent negotiation messages containing: negState ([0] ENUMERATED: accept-completed/accept-incomplete/reject/request-mic, OPTIONAL), supportedMech ([1] MechType, OPTIONAL, first reply only), responseToken ([2] OCTET STRING, OPTIONAL), and mechListMIC ([3] OCTET STRING, OPTIONAL).