RFC 5801

Using Generic Security Service Application Program Interface (GSS-API) Mechanisms in Simple Authentication and Security Layer (SASL): The GS2 Mechanism Family

๐Ÿ“… published July 2010, from ietf

RFC 5801 ๐ŸŽ€ Using GSS-API Mechanisms in SASL: The GS2 Mechanism Family

Okay bestie, let's get into this ๐Ÿฆ‹ RFC 5801 is a Standards Track doc from July 2010 (ISSN 2070-1721). The authors are S. Josefsson of SJD AB and N. Williams of Oracle. The title block doesn't list anything it Obsoletes or Updates, so it isn't replacing or patching any earlier RFC โœจ

Using Generic Security Service Application Program Interface (GSS-API) Mechanisms in Simple Authentication and Security Layer (SASL): The GS2 Mechanism Family ๐Ÿ’–

Abstract โœจ

This doc explains how to use a GSS-API mechanism inside the SASL framework ๐Ÿ” It does that by defining a brand-new SASL mechanism family called GS2 ๐Ÿ’… GS2 comes with some upgrades over the older "SASL/GSSAPI" mechanism. It's more general, it uses fewer messages for the authentication phase in some cases, and it supports negotiable use of channel binding. Only GSS-API mechanisms that support channel binding and mutual authentication are supported. ๐Ÿซถ


Status of This Memo ๐Ÿ“œ

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc5801.

Copyright (c) 2010 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.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.

Table of Contents ๐Ÿ—‚๏ธ

1. Introduction ....................................................4
2. Conventions Used in This Document ...............................5
3. Mechanism Name ..................................................5
   3.1. Generating SASL Mechanism Names from GSS-API OIDs ..........5
   3.2. Computing Mechanism Names Manually .........................6
   3.3. Examples ...................................................6
   3.4. Grandfathered Mechanism Names ..............................7
4. SASL Authentication Exchange Message Format .....................8
5. Channel Bindings ...............................................10
   5.1. Content of GSS-CHANNEL-BINDINGS Structure .................11
   5.2. Default Channel Binding ...................................12
6. Examples .......................................................12
7. Authentication Conditions ......................................14
8. GSS-API Parameters .............................................15
9. Naming .........................................................15
10. GSS_Inquire_SASLname_for_mech Call ............................15
   10.1. gss_inquire_saslname_for_mech ............................16
11. GSS_Inquire_mech_for_SASLname Call ............................18
   11.1. gss_inquire_mech_for_saslname ............................19
12. Security Layers ...............................................20
13. Interoperability with the SASL GSSAPI Mechanism ...............20
   13.1. The Interoperability Problem .............................20
   13.2. Resolving the Problem ....................................20
   13.3. Additional Recommendations ...............................20
14. GSS-API Mechanisms That Negotiate Other Mechanisms ............21
   14.1. The Interoperability Problem .............................21
   14.2. Security Problem .........................................21
   14.3. Resolving the Problems ...................................21
15. IANA Considerations ...........................................22
16. Security Considerations .......................................22
17. Acknowledgements ..............................................24
18. References ....................................................24
   18.1. Normative References .....................................24
   18.2. Informative References ...................................25

1. Introduction ๐Ÿฆ‹

GSS-API [RFC2743] is a framework that gives security services to applications using a whole variety of authentication mechanisms. SASL [RFC4422] is a framework that provides authentication and security layers for connection-based protocols, also using a variety of mechanisms. This document describes how to use a GSS-API mechanism as though it were a SASL mechanism. This facility is called GS2, a moniker that indicates this is the second GSS-API->SASL mechanism bridge. The original GSS-API->SASL mechanism bridge was specified by [RFC2222], now [RFC4752]; we shall sometimes refer to the original bridge as GS1 in this document. ๐ŸŒธ

All GSS-API mechanisms are implicitly registered for use within SASL by this specification. The SASL mechanisms defined in this document are known as the GS2 family of mechanisms. โœจ

The GS1 bridge failed to gain wide deployment for any GSS-API mechanism other than "The Kerberos Version 5 GSS-API Mechanism" [RFC1964] [RFC4121], and it has a number of problems that led to a desire for a new bridge. Specifically, a) GS1 was not round-trip optimized and b) GS1 did not support channel binding [RFC5056]. These problems, plus the opportunity to create the next SASL password-based mechanism, "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms" [RFC5802], as a GSS-API mechanism used by SASL applications via GS2, are what provide the motivation for GS2. ๐Ÿ’œ

In particular, the current consensus of the SASL community appears to be that SASL "security layers" (i.e., confidentiality and integrity protection of application data after authentication) are too complex and redundant, because SASL applications tend to have an option to run over a Transport Layer Security (TLS) [RFC5246] channel. Use of SASL security layers is best replaced with channel binding to a TLS channel. ๐Ÿ”ฅ

GS2 is designed to be as simple as possible. ๐Ÿงš It adds to GSS-API security context token exchanges only the bare minimum needed to support SASL semantics and negotiation of use of channel binding. Specifically, GS2 adds a small header (a few bytes plus the length of the client-requested SASL authorization identity) to the initial GSS-API context token and to the application channel binding data. GS2 uses SASL mechanism negotiation to implement channel binding negotiation. Security-relevant GS2 plaintext is protected via the use of GSS-API channel binding. Additionally, to simplify the implementation of GS2 mechanisms for implementors who will not implement a GSS-API framework, we compress the initial security context token header required by [RFC2743], Section 3.1. ๐ŸŽ€

GS2 does not protect any plaintext exchanged outside GS2, such as SASL mechanism negotiation plaintext, or application messages following authentication. But using channel binding to a secure channel over which all SASL and application plaintext is sent will cause all that plaintext to be authenticated. ๐Ÿ›ก๏ธ

2. Conventions Used in This Document ๐Ÿ“š

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 document uses many terms and function names defined in [RFC2743], as updated by [RFC5554]. ๐Ÿง 

3. Mechanism Name ๐Ÿท๏ธ

There are two SASL mechanism names for any GSS-API mechanism used through this facility. One denotes that the server supports channel binding. The other denotes that it does not. ๐Ÿ‘ฏ

The SASL mechanism name for a GSS-API mechanism is that which is provided by that mechanism when it was specified, if one was specified. This name denotes that the server does not support channel binding. Add the suffix "-PLUS" and the resulting name denotes that the server does support channel binding. SASL implementations can use the GSS_Inquire_SASLname_for_mech call (see below) to query for the SASL mechanism name of a GSS-API mechanism. ๐Ÿ”

If the GSS_Inquire_SASLname_for_mech interface is not used, the GS2 implementation needs some other mechanism to map mechanism Object Identifiers (OIDs) to SASL names internally. In this case, the implementation can only support the mechanisms for which it knows the SASL name. If GSS_Inquire_SASLname_for_mech() fails and the GS2 implementation cannot map the OID to a SASL mechanism name via some other means, then the GS2 implementation MUST NOT use the given GSS-API mechanism. ๐Ÿšซ

3.1. Generating SASL Mechanism Names from GSS-API OIDs ๐Ÿงฎ

For GSS-API mechanisms whose SASL names are not defined together with the GSS-API mechanism or in this document, the SASL mechanism name is the concatenation of the string "GS2-" and the Base32 encoding [RFC4648] (with an uppercase alphabet) of the first 55 bits of the binary SHA-1 hash [FIPS.180-1.1995] string. That hash is computed over the ASN.1 DER encoding [CCITT.X690.2002], including the tag and length octets, of the GSS-API mechanism's Object Identifier. ๐Ÿ”ข

The Base32 rules on padding characters and characters outside of the Base32 alphabet are not relevant to this use of Base32. If any padding or non-alphabet characters are encountered, the name is not a GS2 family mechanism name. ๐Ÿ™ˆ

This name denotes that the server does not support channel binding. Add the suffix "-PLUS" and the resulting name denotes that the server does support channel binding. ๐Ÿ’ซ

A GS2 mechanism that has a non-OID-derived SASL mechanism name is said to have a "user-friendly SASL mechanism name". ๐ŸŒˆ

3.2. Computing Mechanism Names Manually ๐Ÿ› ๏ธ

The hash-derived GS2 SASL mechanism name may be computed manually. This is useful when the set of supported GSS-API mechanisms is known in advance. This eliminates the need to implement Base32, SHA-1, and DER in the SASL mechanism. The computed mechanism name can be used directly in the implementation, and the implementation need not be concerned if the mechanism is part of a mechanism family. ๐Ÿ’…

3.3. Examples ๐Ÿงฎ

Okay bestie, this is the fun part where we actually do the math ๐Ÿค“โœจ. The OID for the Simple Public-Key GSS-API Mechanism (SPKM-1) [RFC2025] is 1.3.6.1.5.5.1.1. Its ASN.1 DER encoding, tag and length included, is 06 07 2b 06 01 05 05 01 01. The SHA-1 hash of that encoding is 1c f8 f4 2b 5a 9f 80 fa e9 f8 31 22 6d 5d 9d 56 27 86 61 ad. We take the first 7 octets, turn them into binary, drop the last bit, regroup everything into chunks of 5, and convert those back to decimal ๐Ÿ’…. Here's the whole glow-up:

hex:
1c f8 f4 2b 5a 9f 80

binary:
00011100 11111000 11110100 00101011 01011010
10011111 1000000

binary in groups of 5:
00011 10011 11100 01111 01000 01010 11010 11010
10011 11110 00000

decimal of each group:
3 19 28 15 8 10 26 26 19 30 0
base32 encoding:
D T 4 P I K 2 2 T 6 A

The last step translates each decimal value using table 3 in Base32 [RFC4648] ๐ŸŒธ. So the SASL mechanism name for the SPKM-1 GSSAPI mechanism is "GS2-DT4PIK22T6A". Literally iconic ๐Ÿฆ‹.

Next up is Kerberos V5 [RFC1964]. Its OID is 1.2.840.113554.1.2.2 and its DER encoding is 06 09 2A 86 48 86 F7 12 01 02 02. The SHA-1 hash is 82 d2 73 25 76 6b d6 c8 45 aa 93 25 51 6a fc ff 04 b0 43 60. Same drill, except this time we convert the 7 octets, drop the last bit, regroup in 5s, and convert back to decimal ๐Ÿ”ฅ:

hex:
82 d2 73 25 76 6b d6

binary:
10000010 11010010 01110011 00100101 01110110
01101011 1101011

binary in groups of 5:
10000 01011 01001 00111 00110 01001 01011 10110
01101 01111 01011

decimal of each group:
16 11 9 7 6 9 11 22 13 15 11

base32 encoding:
Q L J H G J L W N P L

Same last step: translate each decimal value using table 3 in Base32 [RFC4648] ๐Ÿ’–. That makes the SASL mechanism name for the Kerberos V5 GSS-API mechanism "GS2-QLJHGJLWNPL", and because this mechanism supports channel binding, "GS2-QLJHGJLWNPL-PLUS" ๐ŸŽ€. Plot twist though: the next section gives Kerberos V5 a name that isn't hash-derived at all ๐Ÿ‘€.

3.4. Grandfathered Mechanism Names ๐Ÿ‘ตโœจ

Some older GSS-API mechanisms never got a SASL GS2 mechanism name, which is giving "vintage but unlisted" energy ๐Ÿงš. Still, a shorter name can be really handy, so we're specifying "GS2-KRB5" and "GS2-KRB5-PLUS" for the Kerberos V5 mechanism. They're meant to be used as if the original specification had documented them, see Section 15 ๐Ÿ’œ.

4. SASL Authentication Exchange Message Format ๐Ÿ’Œ

Alright, this is where the messages actually start flying. During the SASL authentication exchange for GS2, a bunch of messages following the format below get sent between the client and server. On success, the number of messages is the same as the number of context tokens the GSS-API mechanism would normally need to set up a security context. On failures, either party can end the exchange early ๐Ÿ™…โ€โ™€๏ธ.

When you're using a GS2 mechanism, the SASL client is always a GSS-API initiator, and the SASL server is always a GSS-API acceptor. So the client calls GSS_Init_sec_context and the server calls GSS_Accept_sec_context ๐Ÿซถ.

Every SASL authentication message exchanged is exactly the same as the security context tokens of the GSS-API mechanism, with one exception: the initial security context token ๐ŸŒˆ.

The client and server MAY send GSS-API error tokens, which are the tokens output by GSS_Init_sec_context() or GSS_Accept_sec_context() when the major status code is anything other than GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED. Since that signals an error condition, the sending side should fail the authentication right after sending the token ๐Ÿ˜ญ.

Now, the initial security context token gets a little makeover, and it goes like this:

  • The initial context token header (see Section 3.1 of [RFC2743]) MUST be removed if present. If the header is not present, the client MUST send a "gs2-nonstd-flag" flag (see below). On the server side, this header MUST be recomputed and restored prior to passing the token to GSS_Accept_sec_context, except when the "gs2-nonstd-flag" is sent. ๐Ÿช„
  • A GS2 header MUST be prefixed to the resulting initial context token. This header has the form "gs2-header" given below in ABNF [RFC5234] ๐Ÿ“.

The figure below describes the permissible attributes, their use, and the format of their values. All attribute names are single US-ASCII letters and are case sensitive ๐Ÿ”ค.

 UTF8-1-safe    = %x01-2B / %x2D-3C / %x3E-7F
                  ;; As UTF8-1 in RFC 3629 except
                  ;; NUL, "=", and ",".
 UTF8-2         = <as defined in RFC 3629 (STD 63)>
 UTF8-3         = <as defined in RFC 3629 (STD 63)>
 UTF8-4         = <as defined in RFC 3629 (STD 63)>
 UTF8-char-safe = UTF8-1-safe / UTF8-2 / UTF8-3 / UTF8-4

 saslname       = 1*(UTF8-char-safe / "=2C" / "=3D")
 gs2-authzid    = "a=" saslname
                   ;; GS2 has to transport an authzid since
                   ;; the GSS-API has no equivalent
 gs2-nonstd-flag = "F"
                   ;; "F" means the mechanism is not a
                   ;; standard GSS-API mechanism in that the
                   ;; RFC 2743, Section 3.1 header was missing
 cb-name         = 1*(ALPHA / DIGIT / "." / "-")
                   ;; See RFC 5056, Section 7.
 gs2-cb-flag     = ("p=" cb-name) / "n" / "y"
                   ;; GS2 channel binding (CB) flag
                   ;; "p" -> client supports and used CB
                   ;; "n" -> client does not support CB
                   ;; "y" -> client supports CB, thinks the server
                   ;;           does not
 gs2-header = [gs2-nonstd-flag ","] gs2-cb-flag "," [gs2-authzid] ","
                     ;; The GS2 header is gs2-header.

When the "gs2-nonstd-flag" flag is present, that means the client didn't find or remove a token header ([RFC2743], Section 3.1) from the initial token returned by GSS_Init_sec_context. So the server gets the memo that it MUST NOT re-add the data that the client normally removes ๐Ÿ™…โ€โ™€๏ธ๐Ÿ’….

The "gs2-cb-flag" tells everyone which channel binding mode is in play, and it's one of "p", "n", or "y" ๐Ÿ”. A "p" means the client supports and used a channel binding, and the name of the channel binding type is included. An "n" means the client doesn't support channel binding at all. A "y" means the client supports channel binding but thinks the server doesn't, so it didn't use one. We'll get into the details in the next section, so stay tuned ๐Ÿ‘€.

The "gs2-authzid" holds the SASL authorization identity. It's encoded using UTF-8 [RFC3629], with three exceptions ๐ŸŒธ:

  • The NUL character is forbidden, as required by section 3.4.1 of [RFC4422] ๐Ÿšซ.
  • The server MUST replace any "," (comma) in the string with "=2C".
  • The server MUST replace any "=" (equals) in the string with "=3D".

When the server receives this value, it checks that it's correct according to the SASL protocol profile being used. If verification fails, the authentication exchange fails too ๐Ÿ’€.

5. Channel Bindings ๐Ÿ”—

Okay, channel binding is where things get seriously fun ๐Ÿคฉ. GS2 supports channel binding to external secure channels, such as TLS. Clients and servers may or may not support channel binding, so using it is negotiable. However, GS2 doesn't provide security layers, so it's absolutely imperative that GS2 provide integrity protection for the negotiation of channel binding ๐Ÿ›ก๏ธ. No cap, this part matters a lot.

Here's how the negotiation goes down:

  • Servers that support channel binding SHOULD advertise both the non-PLUS and PLUS-variant of each GS2 mechanism name. If the server can't support channel binding, it SHOULD advertise only the non-PLUS-variant. If the server would never succeed at authenticating the non-PLUS-variant due to policy reasons, it MUST advertise only the PLUS-variant ๐Ÿ“ฃ.
  • If the client supports channel binding and the server doesn't appear to (meaning the client did not see the -PLUS name advertised by the server), then the client MUST NOT use an "n" gs2-cb-flag ๐Ÿ™ˆ.
  • Clients that support mechanism negotiation and channel binding MUST use a "p" gs2-cb-flag when the server offers the PLUS-variant of the desired GS2 mechanism ๐ŸŽ€.
  • If the client does not support channel binding, then it MUST use an "n" gs2-cb-flag. Conversely, if the client requires the use of channel binding, then it MUST use a "p" gs2-cb-flag. Clients that do not support mechanism negotiation never use a "y" gs2-cb-flag. They use either "p" or "n", depending on whether they require and support channel binding or don't, respectively ๐Ÿง .
  • The client generates the chan_bindings input parameter for GSS_Init_sec_context as described below ๐Ÿง.
  • When the server gets the initial authentication message, it checks the gs2-cb-flag in the GS2 header and builds a chan_bindings parameter for GSS_Accept_sec_context as described below. If the client channel binding flag was "y" and the server did advertise support for channel bindings (by advertising the PLUS-variant of the mechanism the client chose), then the server MUST fail authentication. If the client channel binding flag was "p" and the server doesn't support the indicated channel binding type, then the server MUST fail authentication ๐Ÿšจ.
  • If the client used an "n" gs2-cb-flag and the server requires the use of channel binding, then the server MUST fail authentication ๐Ÿ™…โ€โ™€๏ธ.

Here's the cheat sheet for all of that, as a table because it's giving organized ๐Ÿ“Š:

  FLAG CLIENT CB SUPPORT   SERVER CB SUPPORT DISPOSITION
  ---- -----------------   ----------------- -----------

  n    no support          N/A               If server disallows
                                             non-channel-bound
                                             authentication, then
                                             fail

  y    Yes, not required   No                Authentication may
                                             succeed; CB not used

  y    Yes, not required   Yes               Authentication must fail

  p    Yes                 Yes               Authentication may
                                             succeed, with CB used

  p    Yes                 No                Authentication will fail

  N/A  Yes, required       No                Client does not even try

If you want more on channel bindings, and on the syntax of the channel binding data for various security protocols, check out [RFC5056] ๐Ÿฆ‹.

5.1. Content of GSS-CHANNEL-BINDINGS Structure ๐Ÿงฉ

Both GSS_Init_sec_context and GSS_Accept_sec_context take a chan_bindings parameter. Its value is a GSS-CHANNEL-BINDINGS structure [RFC5554] ๐Ÿ’ซ.

The initiator-address-type and acceptor-address-type fields of the GSS-CHANNEL-BINDINGS structure MUST be set to 0. The initiator-address and acceptor-address fields MUST be the empty string ๐Ÿซง.

The application-data field MUST be set to the gs2-header, excluding the initial [gs2-nonstd-flag ","] part. When a gs2-cb-flag of "p" is used, it also gets concatenated with the application's channel binding data ๐Ÿ’œ.

5.2. Default Channel Binding โœจ

okay so, if an application protocol doesn't come with its own channel binding type agreement process ๐Ÿซถ, here's the default vibe ๐Ÿ’…

tls-unique is the default channel binding type for any application that doesn't specify one ๐Ÿ’–

Servers MUST implement the "tls-unique" [RFC5929] channel binding type, if they implement any channel binding. Clients SHOULD implement the "tls-unique" channel binding type, if they implement any channel binding. Clients and servers SHOULD choose the highest-layer/innermost end-to-end TLS channel as the channel to which to bind ๐Ÿ”ฅ

Servers MUST choose the channel binding type indicated by the client, or fail authentication if they don't support it ๐Ÿ˜ญ


6. Examples ๐ŸŒˆ

okay these examples are sooo good, let's go ๐Ÿงš

Example #1: a one round-trip GSS-API context token exchange, no channel binding, optional authzid given. ๐Ÿ’œ

C: Request authentication exchange
S: Empty Challenge
C: n,a=someuser,<initial context token with standard
                   header removed>
S: Send reply context token as is
C: Empty message
S: Outcome of authentication exchange

Example #2: a one and one half round-trip GSS-API context token exchange, no channel binding. ๐Ÿฆ‹

C: Request authentication exchange
S: Empty Challenge
C: n,,<initial context token with standard
                   header removed>
S: Send reply context token as is
C: Send reply context token as is
S: Outcome of authentication exchange

Example #3: a two round-trip GSS-API context token exchange, no channel binding, no standard token header. ๐ŸŒธ

C: Request authentication exchange
S: Empty Challenge
C: F,n,,<initial context token without
                    standard header>
S: Send reply context token as is
C: Send reply context token as is
S: Send reply context token as is
C: Empty message
S: Outcome of authentication exchange

Example #4: using channel binding, optional authzid given. ๐ŸŽ€

C: Request authentication exchange
S: Empty Challenge
C: p=tls-unique,a=someuser,<initial context token with standard
                       header removed>
S: Send reply context token as is
...

Example #5: using channel binding. โœจ

C: Request authentication exchange
S: Empty Challenge
C: p=tls-unique,,<initial context token with standard
                       header removed>
S: Send reply context token as is
...

Example #6: using non-standard channel binding (requires out-of-band negotiation). ๐Ÿ™ˆ

C: Request authentication exchange
S: Empty Challenge
C: p=tls-server-end-point,,<initial context token with standard
                       header removed>
S: Send reply context token as is
...

Example #7: client supports channel bindings but server does not, optional authzid given. ๐Ÿ’€

C: Request authentication exchange
S: Empty Challenge
C: y,a=someuser,<initial
                  context token with standard header removed>
S: Send reply context token as is
...

ngl the handshake here is so organised ๐Ÿซถ GSS-API authentication is always started by the client. The SASL framework lets either the client or the server kick things off. In GS2, if the server hasn't received a token from the client yet, it sends an initial empty challenge (a zero-byte string) to get things rolling. See Section 3 of [RFC4422] ๐Ÿ’…


7. Authentication Conditions ๐Ÿšซ

okay the vibe check here is simple: authentication MUST NOT succeed if any of these are true ๐Ÿ™…โ€โ™€๏ธ

  • If GSS_Init/Accept_sec_context returns anything other than GSS_S_CONTINUE_NEEDED or GSS_S_COMPLETE.
  • If the client's initial GS2 header does not match the ABNF.
  • In particular, if the initial character of the client message is anything except "F", "p", "n", or "y".
  • If the client's GS2 channel binding flag was "y" and the server supports channel bindings.
  • If the client's GS2 channel binding flag was "p" and the server does not support the indicated channel binding.
  • If the client requires use of channel binding and the server did not advertise support for channel binding.
  • If authorization of client principal (i.e., src_name in GSS_Accept_sec_context) to requested authzid failed.
  • If the client is not authorized to the requested authzid or an authzid could not be derived from the client's initiator principal name.

8. GSS-API Parameters ๐ŸŽ€

okay so GS2 doesn't use any GSS-API per-message tokens ๐Ÿซถ That means the per-message token ret_flags coming back from GSS_Init_sec_context() and GSS_Accept_sec_context() don't really matter here. Implementations SHOULD NOT set the per-message req_flags ๐Ÿ’…

The mutual_req_flag MUST be set. Clients MUST check that the corresponding ret_flag is set when the context is fully established, else authentication MUST fail ๐Ÿ˜ญ

Whether you use deleg_req_flag and anon_req_flag is an implementation-specific detail ๐ŸŒธ SASL and GS2 implementors are encouraged to offer programming interfaces so clients can choose to delegate credentials, and so servers can receive them. They're also encouraged to offer interfaces that map nicely onto GSS-API naming options โœจ


9. Naming ๐Ÿท๏ธ

there's no requirement that any particular GSS-API name-types be used ๐Ÿ’– That said, SASL servers will typically have host-based acceptor principal names (see [RFC2743], Section 4.1), and clients will typically have username initiator principal names (see [RFC2743], Section 4.2). When a host-based acceptor principal name is used ("service@hostname"), "service" is the service name specified in the protocol's profile, and "hostname" is the fully qualified host name of the server ๐Ÿฆ‹


10. GSS_Inquire_SASLname_for_mech Call ๐Ÿ”

we're adding a brand new GSS-API utility function here so SASL implementations can figure out, super efficiently, which GSS-API mechanism a particular SASL mechanism name refers to ๐Ÿงš

Inputs:

  • desired_mech OBJECT IDENTIFIER

Outputs:

  • major_status INTEGER
  • minor_status INTEGER
  • sasl_mech_name UTF-8 STRING -- SASL name for this mechanism; caller must release with GSS_Release_buffer()
  • mech_name UTF-8 STRING -- name of this mechanism, possibly localized; caller must release with GSS_Release_buffer()
  • mech_description UTF-8 STRING -- possibly localized description of this mechanism; caller must release with GSS_Release_buffer()

Return major_status codes:

  • GSS_S_COMPLETE indicates successful completion, and that output parameters holds correct information.
  • GSS_S_BAD_MECH indicates that a desired_mech was unsupported by the GSS-API implementation.
  • GSS_S_FAILURE indicates that the operation failed for reasons unspecified at the GSS-API level.

So basically, GSS_Inquire_SASLname_for_mech gets you the SASL mechanism name for a GSS-API mechanism ๐Ÿ’… It also hands back a name and description of the mechanism in a user-friendly form โœจ

The sasl_mech_name output holds the IANA registered mechanism name for the GSS-API mechanism. If none is registered, it holds a mechanism name computed from the OID, as described in Section 3.1 of this document ๐ŸŒˆ


10.1. gss_inquire_saslname_for_mech ๐Ÿ’œ

here's the C binding for the GSS_Inquire_SASLname_for_mech call ๐Ÿซถ

As mentioned in [RFC2744], routines may return GSS_S_FAILURE, which means there's an implementation-specific or mechanism-specific error. The details get reported through the minor_status parameter ๐Ÿ˜ญ

OM_uint32 gss_inquire_saslname_for_mech(
  OM_uint32     *minor_status,
  const gss_OID  desired_mech,
  gss_buffer_t   sasl_mech_name,
  gss_buffer_t   mech_name,
  gss_buffer_t   mech_description
);

Purpose: it outputs the SASL mechanism name of a GSS-API mechanism, plus a name and description of that mechanism in a user-friendly form ๐Ÿฆ‹

Parameters:

minor_status      Integer, modify
                  Mechanism-specific status code.

desired_mech      OID, read
                  Identifies the GSS-API mechanism to query.

sasl_mech_name    buffer, character-string, modify, optional
                  Buffer to receive SASL mechanism name.
                  The application must free storage associated
                  with this name after use with a call to
                  gss_release_buffer().

mech_name         buffer, character-string, modify, optional
                  Buffer to receive human-readable mechanism name.
                  The application must free storage associated
                  with this name after use with a call to
                  gss_release_buffer().

mech_description  buffer, character-string, modify, optional
                  Buffer to receive description of mechanism.
                  The application must free storage associated
                  with this name after use with a call to
                  gss_release_buffer().

Function value: GSS status code:

GSS_S_COMPLETE    Successful completion.

GSS_S_BAD_MECH    The desired_mech OID is unsupported.

11. GSS_Inquire_mech_for_SASLname Call ๐ŸŒธ

so this one is the flip side ๐Ÿ™ˆ We're specifying a new GSS-API utility function so SASL clients can efficiently work out which GSS-API mechanism a particular SASL mechanism name refers to โœจ

Inputs:

  • sasl_mech_name UTF-8 STRING -- SASL name of mechanism.

Outputs:

  • major_status INTEGER
  • minor_status INTEGER
  • mech_type OBJECT IDENTIFIER -- must be explicit mechanism, and not "default" specifier. Caller should treat as read-only and should not attempt to release.

Return major_status codes:

  • GSS_S_COMPLETE indicates successful completion, and that output parameters holds correct information.
  • GSS_S_BAD_MECH indicates that no supported GSS-API mechanism had the indicated sasl_mech_name.
  • GSS_S_FAILURE indicates that the operation failed for reasons unspecified at the GSS-API level.

The GSS_Inquire_mech_for_SASLname call is used to get the GSS-API mechanism OID associated with a SASL mechanism name ๐Ÿ’–

11.1. gss_inquire_mech_for_saslname ๐ŸŽ€

okay so this is the C binding for GSS_Inquire_mech_for_SASLname, and it's giving very "look up the mechanism by its SASL name" energy โœจ Quick heads-up: [RFC2744] says routines can return GSS_S_FAILURE for an implementation-specific or mechanism-specific error, and the details come back through minor_status ๐Ÿ’…

OM_uint32 gss_inquire_mech_for_saslname(
  OM_uint32           *minor_status,
  const gss_buffer_t   sasl_mech_name,
  gss_OID             *mech_type
);

Purpose:

Output GSS-API mechanism OID of mechanism associated with given
sasl_mech_name.

Parameters:

minor_status      Integer, modify
                  Mechanism-specific status code.

sasl_mech_name    buffer, character-string, read
                  Buffer with SASL mechanism name.

mech_type         OID, modify, optional
                  Actual mechanism used.  The OID returned via
                  this parameter will be a pointer to static
                  storage that should be treated as read-only.
                  In particular, the application should not attempt
                  to free it.  Specify NULL if not required.

Function value:   GSS status code:

GSS_S_COMPLETE    Successful completion.

GSS_S_BAD_MECH    There is no GSS-API mechanism known
                  as sasl_mech_name.

12. Security Layers ๐Ÿ”ฅ

GS2 does not do SASL security layers, bestie ๐Ÿ™ˆ If your app needs integrity or confidentiality protection, you can either use channel binding to a secure external channel, or pick a different SASL mechanism that actually provides security layers. Choose wisely ๐Ÿ’œ

13. Interoperability with the SASL GSSAPI Mechanism ๐Ÿฆ‹

okay this one is a whole drama. The Kerberos V5 GSS-API mechanism [RFC1964] is already used in SASL under the name GSSAPI (see [RFC4752]). Kerberos V5 can also be used with the GS2 family, and that causes an interoperability problem. Don't worry, we're gonna resolve it below ๐Ÿซถ

13.1. The Interoperability Problem ๐Ÿ’€

The SASL GSSAPI mechanism is not wire compatible with the Kerberos V GSS-API mechanism used as a SASL GS2 mechanism. It's giving two different languages ๐Ÿ˜ญ

If a client (or server) only supports Kerberos V5 under the GSSAPI name, and the server (or client) only supports Kerberos V5 under the GS2 family, then mechanism negotiation will fail. Nobody's getting in ๐Ÿšซ

13.2. Resolving the Problem โœจ

If Kerberos V5 is supported under GS2 in a server, the server SHOULD also support Kerberos V5 through the GSSAPI mechanism, so older clients don't run into interoperability problems ๐ŸŽ€

There can be reasons to break this recommendation, like security considerations about the features the GS2 mechanism is missing. The SASL GSSAPI mechanism doesn't support channel bindings, which means an external secure channel may not be enough protection against active attackers (see [RFC5056] and [MITM]). Yikes ๐Ÿ˜ฌ

13.3. Additional Recommendations ๐ŸŒธ

If the application requires SASL security layers, then it MUST use the SASL GSSAPI mechanism [RFC4752] instead of GS2-KRB5 or GS2-KRB5-PLUS. No exceptions, periodt ๐Ÿ’…

If the application can use channel binding to an external channel, then it is RECOMMENDED that it select Kerberos V5 through the GS2 mechanism rather than the GSSAPI mechanism. That's the move ๐Ÿ‘‘


14. GSS-API Mechanisms That Negotiate Other Mechanisms ๐Ÿงš

okay so a GSS-API mechanism that negotiates other mechanisms is gonna clash with SASL mechanism negotiation, and it's messy ๐Ÿ˜ญ There are two problems here: an interoperability problem and a security concern. We'll go through both and fix them ๐Ÿ’–

14.1. The Interoperability Problem ๐Ÿ™ˆ

If a client implements GSS-API mechanism X, potentially negotiated through a GSS-API mechanism Y, and the server also implements GSS-API mechanism X negotiated through a GSS-API mechanism Z, then the authentication negotiation will fail. Two paths to the same mechanism, and they don't match. Not it ๐Ÿ’€

14.2. Security Problem ๐Ÿ”ฅ

Let's say a client's policy is to prefer GSSAPI mechanism X first, then non-GSSAPI mechanism Y, then GSSAPI mechanism Z. And let's say a server supports mechanisms Y and Z but not X. If the client tries to negotiate mechanism X using a GSS-API mechanism that negotiates other mechanisms (like Simple and Protected GSS-API Negotiation (SPNEGO) [RFC4178]), it may end up using mechanism Z when it ideally should have used mechanism Y. Oof ๐Ÿ˜ญ That's why GSS-API mechanisms that negotiate other mechanisms are disallowed under GS2.

14.3. Resolving the Problems ๐ŸŽ€

GSS-API mechanisms that negotiate other mechanisms MUST NOT be used with the GS2 SASL mechanism. Specifically, SPNEGO [RFC4178] MUST NOT be used as a GS2 mechanism. To make life easier for SASL implementations, we give the SPNEGO GSS-API mechanism a symbolic SASL mechanism name, "SPNEGO". SASL client implementations MUST NOT choose the SPNEGO mechanism under any circumstances. Hard no ๐Ÿšซ

The GSS_C_MA_MECH_NEGO attribute of GSS_Inquire_attrs_for_mech [RFC5587] can be used to identify these mechanisms โœจ


15. IANA Considerations ๐Ÿ“‹

okay so IANA registered a SASL mechanism family under [RFC4422], and here's the whole registration, iykyk ๐Ÿ’…

Subject: Registration of SASL mechanism family GS2-*
SASL mechanism prefix: GS2-
Security considerations: RFC 5801
Published specification: RFC 5801
Person & email address to contact for further information:
  Simon Josefsson <simon@josefsson.org>
Intended usage: COMMON
Owner/Change controller: iesg@ietf.org
Note: Compare with the GSSAPI and GSS-SPNEGO mechanisms.

IANA is advised that SASL mechanism names starting with "GS2-" are reserved for SASL mechanisms that conform to this document. IANA has put a statement to that effect in the SASL Mechanisms registry, so it's official ๐ŸŒˆ

IANA is also advised that GS2 SASL mechanism names MUST NOT end in "-PLUS" except as a version of another mechanism name simply suffixed with "-PLUS". Keep the vibes consistent, bestie ๐Ÿซถ

The SASL names for the Kerberos V5 GSS-API mechanism [RFC4121] [RFC1964] used via GS2 SHALL be GS2-KRB5 and GS2-KRB5-PLUS. Locked in ๐Ÿ”’

The SASL names for the SPNEGO GSS-API mechanism used via GS2 SHALL be SPNEGO and SPNEGO-PLUS. As described in Section 14, the SASL SPNEGO and SPNEGO-PLUS MUST NOT be used. These names are only there as a convenience for SASL library implementors, not for actual use ๐Ÿงš


16. Security Considerations ๐Ÿ›ก๏ธ

Okay, this section is serious, so I'm gonna keep the drama at a respectable level ๐Ÿ’… Security issues are also talked about throughout this memo, so read it all ๐Ÿ‘€

The security a GS2 mechanism provides depends on the security of the GSS-API mechanism underneath it. The GS2 family depends on channel binding support, so GSS-API mechanisms that don't support channel binding can't be successfully used as SASL mechanisms through the GS2 bridge. No channel binding, no GS2, no cap ๐Ÿšซ

Because GS2 doesn't support security layers, it is strongly RECOMMENDED that channel binding to a secure external channel be used. When channel binding succeeds, it eliminates the possibility of man-in-the-middle (MITM) attacks, as long as the external channel, its channel binding data, and the GSS-API mechanism are all secure. If authentication fails because of a channel binding failure, that may mean someone tried a MITM attack. But a real MITM attacker would probably try to close the connection to the client or fake a network partition, so MITM detection is heuristic. Be suspicious, not certain ๐Ÿ”

Channel binding also protects the SASL mechanism negotiation. If there's no MITM, the external secure channel has protected the SASL mechanism negotiation too ๐Ÿฆ‹

The channel binding data MAY be sent (by the actual GSS-API mechanism used) without confidentiality protection, and knowing it is assumed to give a MITM no advantage, since a MITM can compute the channel binding data independently anyway. If the external channel doesn't provide confidentiality protection, and the GSS-API mechanism doesn't provide confidentiality protection for the channel binding data either, then passive attackers (eavesdroppers) can recover the channel binding data (see [RFC5056]). Eavesdroppers, go away ๐Ÿ‘€

When building the input_name_string for GSS_Import_name with the GSS_C_NT_HOSTBASED_SERVICE name type, the client SHOULD NOT canonicalize the server's fully qualified domain name using an insecure or untrusted directory service, such as the Domain Name System [RFC1034] without DNS Security (DNSSEC) [RFC4033]. Don't trust a random directory for your hostnames ๐Ÿ™…โ€โ™€๏ธ

SHA-1 is used to derive SASL mechanism names, but no traditional cryptographic properties are required. The property that matters is that the truncated output for distinct inputs is different for practical input values. GS2 doesn't use any other cryptographic algorithm. So GS2 is "algorithm agile", or as agile as the GSS-API mechanisms available to SASL applications through GS2 ๐Ÿงš

GS2 does not protect against downgrade attacks of channel binding types. Negotiation of channel binding type was intentionally left out of scope for this document ๐Ÿ™ˆ

The security considerations of SASL [RFC4422], the GSS-API [RFC2743], channel binding [RFC5056], any external channels (such as TLS, [RFC5246]), channel binding types (see the IANA channel binding type registry), and GSS-API mechanisms (such as the Kerberos V5 mechanism [RFC4121] [RFC1964]) also apply. So many layers, so much to read ๐Ÿ“š

17. Acknowledgements ๐Ÿซถ

The history of GS2 goes back to the "GSSAPI" mechanism originally specified by RFC 2222. This document was derived from [SASL-GSSAPI], which was prepared by Alexey Melnikov with significant contributions from John G. Myers. Most of this document was rewritten by the current authors though, so it's not just copy-paste ๐Ÿ’–

Thanks so much to the many members of the SASL mailing list who contributed. In particular, ideas and feedback from Pasi Eronen, Sam Hartman, Jeffrey Hutzelman, Alexey Melnikov, and Tom Yu improved the document and the protocol ๐ŸŒธ Other suggestions to the document were made by Spencer Dawkins, Ralph Droms, Adrian Farrel, Robert Sparks, and Glen Zorn. Main-character-level team effort ๐Ÿ‘‘

18. References ๐Ÿ“š

18.1. Normative References ๐Ÿ“š

okay bestie, these are the docs the spec totally leans on, so they're the ones you need to have in your back pocket ๐Ÿ’…

[FIPS.180-1.1995] National Institute of Standards and Technology, "Secure Hash Standard", FIPS PUB 180-1, April 1995, <http://www.itl.nist.gov/fipspubs/fip180-1.htm>.

[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.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.

[RFC4422] Melnikov, A. and K. Zeilenga, "Simple Authentication and Security Layer (SASL)", RFC 4422, June 2006.

[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006.

[RFC5056] Williams, N., "On the Use of Channel Bindings to Secure Channels", RFC 5056, November 2007.

[RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.

[RFC5554] Williams, N., "Clarifications and Extensions to the Generic Security Service Application Program Interface (GSS-API) for the Use of Channel Bindings", RFC 5554, May 2009.

[CCITT.X690.2002] International Telephone and Telegraph Consultative Committee, "ASN.1 encoding rules: Specification of basic encoding Rules (BER), Canonical encoding rules (CER) and Distinguished encoding rules (DER)", CCITT Recommendation X.690, July 2002.

[RFC5929] Altman, J., Williams, N., and L. Zhu, "Channel Bindings for TLS", RFC 5929, July 2010.


18.2. Informative References ๐Ÿงš

these ones are more like background reading. super helpful, not strictly required ๐Ÿซถ

[RFC1034] Mockapetris, P., "Domain names - concepts and facilities", STD 13, RFC 1034, November 1987.

[RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC 1964, June 1996.

[RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", RFC 2025, October 1996.

[RFC2222] Myers, J., "Simple Authentication and Security Layer (SASL)", RFC 2222, October 1997.

[RFC2744] Wray, J., "Generic Security Service API Version 2 : C-bindings", RFC 2744, January 2000.

[RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "DNS Security Introduction and Requirements", RFC 4033, March 2005.

[RFC4121] Zhu, L., Jaganathan, K., and S. Hartman, "The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism: Version 2", RFC 4121, July 2005.

[RFC4178] Zhu, L., Leach, P., Jaganathan, K., and W. Ingersoll, "The Simple and Protected Generic Security Service Application Program Interface (GSS-API) Negotiation Mechanism", RFC 4178, October 2005.

[RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple Authentication and Security Layer (SASL) Mechanism", RFC 4752, November 2006.

[RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, August 2008.

[RFC5587] Williams, N., "Extended Generic Security Service Mechanism Inquiry APIs", RFC 5587, July 2009.

[RFC5802] Menon-Sen, A., Melnikov, A., Newman, C., and N. Williams, "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms", RFC 5802, July 2010.

[MITM] Asokan, N., Niemi, V., and K. Nyberg, "Man-in-the-Middle in Tunnelled Authentication", in 11th Security Protocols Workshop, 2002.

[SASL-GSSAPI] Melnikov, A., "The Kerberos V5 ("GSSAPI") SASL mechanism", Work in Progress, March 2005.


Authors' Addresses ๐ŸŽ€

meet the authors! here's how to reach them ๐Ÿ’Œ

Simon Josefsson
SJD AB
Hagagatan 24
Stockholm  113 47
SE

EMail: simon@josefsson.org
URI:   http://josefsson.org/


Nicolas Williams
Oracle
5300 Riata Trace Ct
Austin, TX  78727
USA

EMail: Nicolas.Williams@oracle.com
๐Ÿ“ฆ where this page comes from