draft-ietf-sasl-gs2-11.txt   draft-ietf-sasl-gs2-12.txt 
Network Working Group S. Josefsson Network Working Group S. Josefsson
Internet-Draft SJD AB Internet-Draft SJD AB
Intended status: Standards Track N. Williams Intended status: Standards Track N. Williams
Expires: September 24, 2009 Sun Microsystems Expires: October 20, 2009 Sun Microsystems
March 23, 2009 April 18, 2009
Using GSS-API Mechanisms in SASL: The GS2 Mechanism Family Using GSS-API Mechanisms in SASL: The GS2 Mechanism Family
draft-ietf-sasl-gs2-11 draft-ietf-sasl-gs2-12
Status of this Memo Status of this Memo
This Internet-Draft is submitted to IETF in full conformance with the This Internet-Draft is submitted to IETF in full conformance with the
provisions of BCP 78 and BCP 79. This document may contain material provisions of BCP 78 and BCP 79. This document may contain material
from IETF Documents or IETF Contributions published or made publicly from IETF Documents or IETF Contributions published or made publicly
available before November 10, 2008. The person(s) controlling the available before November 10, 2008. The person(s) controlling the
copyright in some of this material may not have granted the IETF copyright in some of this material may not have granted the IETF
Trust the right to allow modifications of such material outside the Trust the right to allow modifications of such material outside the
IETF Standards Process. Without obtaining an adequate license from IETF Standards Process. Without obtaining an adequate license from
skipping to change at page 1, line 43 skipping to change at page 1, line 43
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt. http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html. http://www.ietf.org/shadow.html.
This Internet-Draft will expire on September 24, 2009. This Internet-Draft will expire on October 20, 2009.
Copyright Notice Copyright Notice
Copyright (c) 2009 IETF Trust and the persons identified as the Copyright (c) 2009 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents in effect on the date of Provisions Relating to IETF Documents in effect on the date of
publication of this document (http://trustee.ietf.org/license-info). publication of this document (http://trustee.ietf.org/license-info).
Please review these documents carefully, as they describe your rights Please review these documents carefully, as they describe your rights
skipping to change at page 3, line 11 skipping to change at page 3, line 11
binding are supported. binding are supported.
See <http://josefsson.org/sasl-gs2-*/> for more information. See <http://josefsson.org/sasl-gs2-*/> for more information.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Conventions used in this document . . . . . . . . . . . . . . 5 2. Conventions used in this document . . . . . . . . . . . . . . 5
3. Mechanism name . . . . . . . . . . . . . . . . . . . . . . . . 5 3. Mechanism name . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1. Generating SASL mechanism names from GSS-API OIDs . . . . 5 3.1. Generating SASL mechanism names from GSS-API OIDs . . . . 5
3.2. Computing mechanism names manually . . . . . . . . . . . . 5 3.2. Computing mechanism names manually . . . . . . . . . . . . 6
3.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.4. Grandfathered mechanism names . . . . . . . . . . . . . . 7
4. SASL Authentication Exchange Message Format . . . . . . . . . 7 4. SASL Authentication Exchange Message Format . . . . . . . . . 7
4.1. SASL Messages . . . . . . . . . . . . . . . . . . . . . . 7 4.1. SASL Messages . . . . . . . . . . . . . . . . . . . . . . 7
5. Channel Bindings . . . . . . . . . . . . . . . . . . . . . . . 9 5. Channel Bindings . . . . . . . . . . . . . . . . . . . . . . . 9
6. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
7. Authentication Conditions . . . . . . . . . . . . . . . . . . 11 7. Authentication Conditions . . . . . . . . . . . . . . . . . . 11
8. GSS-API Parameters . . . . . . . . . . . . . . . . . . . . . . 11 8. GSS-API Parameters . . . . . . . . . . . . . . . . . . . . . . 12
9. Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 9. Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
10. GSS_Mechanism_SASLname call . . . . . . . . . . . . . . . . . 11 10. GSS_Inquire_SASLname_for_mech call . . . . . . . . . . . . . . 12
10.1. gss_mechanism_saslname . . . . . . . . . . . . . . . . . . 13 10.1. gss_inquire_saslname_for_mech . . . . . . . . . . . . . . 13
11. GSS_Inquire_mech_for_SASLname call . . . . . . . . . . . . . . 13 11. GSS_Inquire_mech_for_SASLname call . . . . . . . . . . . . . . 13
11.1. gss_inquire_mech_for_saslname . . . . . . . . . . . . . . 15 11.1. gss_inquire_mech_for_saslname . . . . . . . . . . . . . . 15
12. Security Layers . . . . . . . . . . . . . . . . . . . . . . . 15 12. Security Layers . . . . . . . . . . . . . . . . . . . . . . . 15
13. Interoperability with the SASL "GSSAPI" mechanism . . . . . . 16 13. Interoperability with the SASL "GSSAPI" mechanism . . . . . . 16
13.1. The interoperability problem . . . . . . . . . . . . . . . 16 13.1. The interoperability problem . . . . . . . . . . . . . . . 16
13.2. Resolving the problem . . . . . . . . . . . . . . . . . . 16 13.2. Resolving the problem . . . . . . . . . . . . . . . . . . 16
13.3. Additional Recommendations . . . . . . . . . . . . . . . . 16 13.3. Additional Recommendations . . . . . . . . . . . . . . . . 16
14. Mechanisms that negotiate other mechanisms . . . . . . . . . . 17 14. Mechanisms that negotiate other mechanisms . . . . . . . . . . 17
14.1. The interoperability problem . . . . . . . . . . . . . . . 17 14.1. The interoperability problem . . . . . . . . . . . . . . . 17
14.2. Security problem . . . . . . . . . . . . . . . . . . . . . 17 14.2. Security problem . . . . . . . . . . . . . . . . . . . . . 17
skipping to change at page 4, line 25 skipping to change at page 4, line 25
that this is the second GSS-API->SASL mechanism bridge. The original that this is the second GSS-API->SASL mechanism bridge. The original
GSS-API->SASL mechanism bridge was specified by [RFC2222], now GSS-API->SASL mechanism bridge was specified by [RFC2222], now
[RFC4752]; we shall sometimes refer to the original bridge as "GS1" [RFC4752]; we shall sometimes refer to the original bridge as "GS1"
in this document. in this document.
All GSS-API mechanisms are implicitly registered for use within SASL All GSS-API mechanisms are implicitly registered for use within SASL
by this specification. The SASL mechanisms defined in this document by this specification. The SASL mechanisms defined in this document
are known as the "GS2 family of mechanisms". are known as the "GS2 family of mechanisms".
The GS1 bridge failed to gain wide deployment for any GSS-API The GS1 bridge failed to gain wide deployment for any GSS-API
mechanism other than The "Kerberos V GSS-API mechanism" [RFC1964] mechanism other than The "Kerberos V5 GSS-API mechanism" [RFC1964]
[RFC4121], and has a number of problems that lead us to desire a new [RFC4121], and has a number of problems that lead us to desire a new
bridge. Specifically: a) GS1 was not round-trip optimized, b) GS1 bridge. Specifically: a) GS1 was not round-trip optimized, b) GS1
did not support channel binding [RFC5056]. These problems and the did not support channel binding [RFC5056]. These problems and the
opportunity to create the next SASL password-based mechanism, SCRAM opportunity to create the next SASL password-based mechanism, SCRAM
[I-D.newman-auth-scram], as a GSS-API mechanism used by SASL [I-D.newman-auth-scram], as a GSS-API mechanism used by SASL
applications via GS2, provide the motivation for GS2. applications via GS2, provide the motivation for GS2.
In particular, the current consensus of the SASL community appears to In particular, the current consensus of the SASL community appears to
be that SASL "security layers" (i.e., confidentiality and integrity be that SASL "security layers" (i.e., confidentiality and integrity
protection of application data after authentication) are too complex protection of application data after authentication) are too complex
and, since SASL applications tend to have an option to run over a and, since SASL applications tend to have an option to run over a
Transport Layer Security (TLS) [RFC5246] channel, redundant and best Transport Layer Security (TLS) [RFC5246] channel, redundant and best
replaced with channel binding. replaced with channel binding.
GS2 is designed to be as simple as possible. It adds to GSS-API GS2 is designed to be as simple as possible. It adds to GSS-API
security context token exchanges only the bare minimum to support security context token exchanges only the bare minimum to support
SASL semantics and negotiation of use of channel binding. SASL semantics and negotiation of use of channel binding.
Specifically, GS2 adds a small header (2 bytes or 4 bytes plus the Specifically, GS2 adds a small header (2 bytes or 3 bytes plus the
length of the client requested SASL authorization ID (authzid)) to length of the client requested SASL authorization ID (authzid)) to
the initial context token and to the application channel binding the initial context token and to the application channel binding
data, and it uses SASL mechanism negotiation to implement channel data, and it uses SASL mechanism negotiation to implement channel
binding negotiation. All GS2 plaintext is protected via the use of binding negotiation. All GS2 plaintext is protected via the use of
GSS-API channel binding. Additionally, to simplify the GSS-API channel binding. Additionally, to simplify the
implementation of GS2 mechanisms for implementors who will not implementation of GS2 mechanisms for implementors who will not
implement a GSS-API framework, we compress the initial security implement a GSS-API framework, we compress the initial security
context token header required by [RFC2743] (see section 3.1). context token header required by [RFC2743] (see section 3.1).
2. Conventions used in this document 2. Conventions used in this document
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119]. document are to be interpreted as described in [RFC2119].
3. Mechanism name 3. Mechanism name
3.1. Generating SASL mechanism names from GSS-API OIDs
There are two SASL mechanism names for any GSS-API mechanism used There are two SASL mechanism names for any GSS-API mechanism used
through this facility. One denotes that the server supports channel through this facility. One denotes that the server supports channel
binding. The other denotes that it does not. binding. The other denotes that it does not.
The SASL mechanism name for a GSS-API mechanism is that which is The SASL mechanism name for a GSS-API mechanism is that which is
provided by that mechanism when it was specified, if one was provided by that mechanism when it was specified, if one was
specified. This name denotes that the server does not support specified. This name denotes that the server does not support
channel binding. Add the suffix "-PLUS" and the resulting name channel binding. Add the suffix "-PLUS" and the resulting name
denotes that the server does support channel binding. SASL denotes that the server does support channel binding. SASL
implementations can use the GSS_Mechanism_Name call (see below) to implementations can use the GSS_Inquire_SASLname_for_mech call (see
query for the SASL mechanism name of a GSS-API mechanism. 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 need some other mechanism to map mechanism OIDs to
SASL name internally. In this case, the implementation can only
support the mechanisms for which it knows the SASL name. If the
GSS_Inquire_SASLname_for_mech call fails, and the GS2 implementation
cannot map the OID to a SASL mechanism name using some other means,
it cannot use the particular GSS-API mechanism since it does not know
its SASL mechanism name.
If the GSS_Inquire_SASLname_for_mech call is successful, but provides
a zero length string [FIXME: is this a good idea? --simon], it means
the GSS-API mechanism did not have a registered mechanism name. In
this case, the GS2 implementation can derive the SASL mechanism name
from the GSS-API mechanism OID as follows.
3.1. Generating SASL mechanism names from GSS-API OIDs
For GSS-API mechanisms whose SASL names are not defined together with 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 GSS-API mechanism or in this document, the SASL mechanism name is
concatenation of the string "GS2-" and the Base32 encoding [RFC4648] concatenation of the string "GS2-" and the Base32 encoding [RFC4648]
(with an upper case alphabet) of the first 55 bits of the binary (with an upper case alphabet) of the first 55 bits of the binary
SHA-1 hash [FIPS.180-1.1995] string computed over the ASN.1 DER SHA-1 hash [FIPS.180-1.1995] string computed over the ASN.1 DER
encoding [CCITT.X690.2002], including the tag and length octets, of encoding [CCITT.X690.2002], including the tag and length octets, of
the GSS-API mechanism's Object Identifier. The Base32 rules on the GSS-API mechanism's Object Identifier. The Base32 rules on
padding characters and characters outside of the base32 alphabet are padding characters and characters outside of the base32 alphabet are
not relevant to this use of Base32. If any padding or non-alphabet not relevant to this use of Base32. If any padding or non-alphabet
skipping to change at page 6, line 39 skipping to change at page 6, line 51
base32 encoding: base32 encoding:
D T 4 P I K 2 2 T 6 A D T 4 P I K 2 2 T 6 A
The last step translate each decimal value using table 3 in Base32 The last step translate each decimal value using table 3 in Base32
[RFC4648]. Thus the SASL mechanism name for the SPKM-1 GSSAPI [RFC4648]. Thus the SASL mechanism name for the SPKM-1 GSSAPI
mechanism is "GS2-DT4PIK22T6A". mechanism is "GS2-DT4PIK22T6A".
The OID for the Kerberos V5 GSS-API mechanism [RFC1964] is The OID for the Kerberos V5 GSS-API mechanism [RFC1964] is
1.2.840.113554.1.2.2 and its DER encoding is (in hex) 06 09 2A 86 48 1.2.840.113554.1.2.2 and its DER encoding is (in hex) 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 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. Convert the first ten octets to 93 25 51 6a fc ff 04 b0 43 60. Convert the 7 octets to binary, drop
binary, and re-group them in groups of 5, and convert them back to the last bit, and re-group them in groups of 5, and convert them back
decimal, which results in these computations: to decimal, which results in these computations:
hex: hex:
82 d2 73 25 76 6b d6 82 d2 73 25 76 6b d6
binary: binary:
10000010 11010010 01110011 00100101 01110110 10000010 11010010 01110011 00100101 01110110
01101011 1101011 01101011 1101011
binary in groups of 5: binary in groups of 5:
10000 01011 01001 00111 00110 01001 01011 10110 10000 01011 01001 00111 00110 01001 01011 10110
skipping to change at page 7, line 25 skipping to change at page 7, line 27
decimal of each group: decimal of each group:
16 11 9 7 6 9 11 22 13 15 11 16 11 9 7 6 9 11 22 13 15 11
base32 encoding: base32 encoding:
Q L J H G J L W N P L Q L J H G J L W N P L
The last step translate each decimal value using table 3 in Base32 The last step translate each decimal value using table 3 in Base32
[RFC4648]. Thus the SASL mechanism name for the Kerberos V5 GSSAPI [RFC4648]. Thus the SASL mechanism name for the Kerberos V5 GSSAPI
mechanism would be "GS2-QLJHGJLWNPL" and (because this mechanism mechanism would be "GS2-QLJHGJLWNPL" and (because this mechanism
supports channel binding) "GS2-QLJHGJLWNPL-PLUS". But instead, we supports channel binding) "GS2-QLJHGJLWNPL-PLUS". Instead, the next
assign the Kerberos V mechanism a non-hash-derived mechanism name: section assigns the Kerberos V5 mechanism a non-hash-derived
"KerberosV-GS2" and "KerberosV-GS2-PLUS" (see Section 15). mechanism name.
3.4. Grandfathered mechanism names
Some older GSS-API mechanisms were not specified with a SASL GS2
mechanism name. Using a shorter name can be useful nonetheless. We
specify the names "GS2-KRB5" and "GS2-KRB5-PLUS" for the Kerberos V5
mechanism, to be used as if the original specification documented it.
See Section 15.
4. SASL Authentication Exchange Message Format 4. SASL Authentication Exchange Message Format
4.1. SASL Messages 4.1. SASL Messages
During the SASL authentication exchange for GS2, a number of messages During the SASL authentication exchange for GS2, a number of messages
following the following format is sent between the client and server. following the following format is sent between the client and server.
This number is the same as the number of context tokens that the GSS- This number is the same as the number of context tokens that the GSS-
API mechanism would normally require in order to establish a security API mechanism would normally require in order to establish a security
context (or to fail to do so). context (or to fail to do so).
Note that when using a GS2 mechanism the SASL client is always a GSS- Note that when using a GS2 mechanism the SASL client is always a GSS-
API initiator and the SASL server is always a GSS-API acceptor. Thus API initiator and the SASL server is always a GSS-API acceptor. Thus
the SASL client calls GSS_Init_sec_context() and the server calls the SASL client calls GSS_Init_sec_context and the server calls
GSS_Accept_sec_context(). GSS_Accept_sec_context.
All the SASL authentication messages exchanged are exactly the same All the SASL authentication messages exchanged are exactly the same
as the security context tokens of the GSS-API mechanism, except for as the security context tokens of the GSS-API mechanism, except for
the initial security context token. the initial security context token.
Also, the server SHOULD refrain from sending GSS-API error tokens Also, the server SHOULD refrain from sending GSS-API error tokens
(tokens output by GSS_Init_sec_context() or GSS_Accept_sec_context() (tokens output by GSS_Init_sec_context or GSS_Accept_sec_context
along with a major status code other than GSS_S_COMPLETE or along with a major status code other than GSS_S_COMPLETE or
GSS_S_CONTINUE_NEEDED) as SASL applications handle error conditions. GSS_S_CONTINUE_NEEDED) as SASL applications handle error conditions.
The initial security context token is modified as follows: The initial security context token is modified as follows:
o The [RFC2743] section 3.1 initial context token header MUST be o The [RFC2743] section 3.1 initial context token header MUST be
removed if present, and its presence is noted (see below). On the removed if present. If the header is not present, the client MUST
server side this header MUST be recomputed and restored prior to send a "gs2-nonstd-flag" flag (see below). On the server side
passing the token to GSS_Accept_sec_context(). 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.
o A GS2 header MUST be prefixed to the resulting initial context o A GS2 header MUST be prefixed to the resulting initial context
token. This header has the form given below in ABNF [RFC5234]. token. This header has the form "gs2-header" given below in ABNF
[RFC5234].
UTF8-1-safe = %x01-2B / %x2D-3C / %x3E-7F UTF8-1-safe = %x01-2B / %x2D-3C / %x3E-7F
;; As UTF8-1 in RFC 3629 except ;; As UTF8-1 in RFC 3629 except
;; NUL, "=", and ",". ;; NUL, "=", and ",".
UTF8-2 = <as defined in RFC 3629 (STD 63)> UTF8-2 = <as defined in RFC 3629 (STD 63)>
UTF8-3 = <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-4 = <as defined in RFC 3629 (STD 63)>
UTF8-char-safe = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4 UTF8-char-safe = UTF8-1-safe / UTF8-2 / UTF8-3 / UTF8-4
saslname = 1*(UTF8-char-safe / "=2C" / "=3D") saslname = 1*(UTF8-char-safe / "=2C" / "=3D")
gs2-authzid = "a=" saslname gs2-authzid = "a=" saslname
;; GS2 has to transport an authzid since ;; GS2 has to transport an authzid since
;; the GSS-API has no equivalent ;; the GSS-API has no equivalent
gs2-std-mech = "F" gs2-nonstd-flag = "F"
;; "F" means the mechanism is NOT is a ;; "F" means the mechanism is not a
;; standard GSS-API mechanism in that the ;; standard GSS-API mechanism in that the
;; RFC2743 section 3.1 header was missing ;; RFC2743 section 3.1 header was missing
gs2-cb-flag = "n" / "y" / "p" gs2-cb-flag = "p" / "n" / "y"
;; GS2 channel binding (CB) flag ;; GS2 channel binding (CB) flag
;; "p" -> client supports and used CB
;; "n" -> client does not support CB ;; "n" -> client does not support CB
;; "y" -> client supports CB, thinks the server ;; "y" -> client supports CB, thinks the server
;; does not ;; does not
;; "p" -> client supports and used CB gs2-header = [gs2-nonstd-flag] gs2-cb-flag [gs2-authzid] ","
gs2-header = [gs2-std-mech] gs2-cb-flag [gs2-authzid] ","
;; The GS2 header is gs2-header. ;; The GS2 header is gs2-header.
;; gs2-std-mech is present if the GSS-API
;; mechanism's initial context token did not
;; have the standard header defined in
;; [RFC2743] section 3.1.
The GS2 header is also prepended to the application's channel binding When the "gs2-nonstd-flag" flag is present, the client did not find/
data. If the application did not provide channel binding data then remove a [RFC2743] section 3.1 token header from the initial token
the GS2 header is used as though it were application-provided channel returned by GSS_Init_sec_context. This signals to the server that it
binding data. MUST NOT re-add the data that is normally removed by the client.
The "gs2-cb-flag" signals the channel binding mode. One of "p", "n",
or "y" is used. A "p" means the client supports and used a channel
binding. A "n" means that the client does not support channel
binding. A "y" means the client supports channel binding, but
believes the server does not, so it did not use a channel binding.
See the next section for more details.
The "gs2-authzid" holds the SASL authorization identity. It is The "gs2-authzid" holds the SASL authorization identity. It is
encoded using UTF-8 [RFC3629] with three exceptions: encoded using UTF-8 [RFC3629] with three exceptions:
o The NUL characters is forbidden as required by section 3.4.1 of o The NUL characters is forbidden as required by section 3.4.1 of
[RFC4422]. [RFC4422].
o The server MUST replace any "," (comma) in the string with "=2C".
o The server MUST replace any occurance of "," (comma) in the string o The server MUST replace any "=" (equals) in the string with "=3D".
with "=2C".
o The server MUST replace any occurance of "=" (comma) in the string
with "=3D".
If a server sends a string that does not conform to this syntax, the If a server sends a string that does not conform to this syntax, the
client MUST reject authentication. client MUST reject authentication.
5. Channel Bindings 5. Channel Bindings
If the server supports channel binding then it must list both forms If the server supports channel binding then it MUST list both forms
of the SASL mechanism name for each GSS-API mechanism supported via of the SASL mechanism name for each GSS-API mechanism supported via
GS2 (i.e., GSS-API mechanisms that support channel binding). GS2 (i.e., GSS-API mechanisms that support channel binding).
If the client supports channel binding and the server does not (i.e., If the client supports channel binding and the server does not (i.e.,
the server did not advertise the -PLUS names) then the client MUST the server did not advertise the -PLUS names) then the client MUST
either fail authentication or it MUST set the channel binding flag in either fail authentication or it MUST set the channel binding flag in
the GS2 initial security context token to "y" and MUST NOT include the GS2 initial security context token to "y" and MUST NOT include
application channel binding data in the GSS-API channel binding input application channel binding data in the GSS-API channel binding input
to GSS_Init_sec_context(). to GSS_Init_sec_context.
If the client supports channel binding and the server also does then If the client supports channel binding and the server also does then
the client MUST set the channel binding flag in the GS2 initial the client MUST set the channel binding flag in the GS2 initial
security context token to "p" and MUST include application channel security context token to "p" and MUST include application channel
binding data in the GSS-API channel binding input to binding data in the GSS-API channel binding input to
GSS_Init_sec_context(). GSS_Init_sec_context. This is done by pre-pending the gs2-header to
the application's channel binding data. If the application did not
provide channel binding data then the GS2 header is used as though it
were application-provided channel binding data.
If the client does not support channel binding then it MUST set the If the client does not support channel binding then it MUST set the
channel binding flag in the GS2 initial security context token to "n" channel binding flag in the GS2 initial security context token to "n"
and MUST NOT include application channel binding data in the GSS-API and MUST NOT include application channel binding data in the GSS-API
channel binding input to GSS_Init_sec_context(). channel binding input to GSS_Init_sec_context.
Upon receipt of the initial authentication message the server checks Upon receipt of the initial authentication message the server checks
the channel binding flag in the GS2 header and constructs a channel the channel binding flag in the GS2 header and constructs a channel
binding data input for GSS_Accept_sec_context() accordingly. If the binding data input for GSS_Accept_sec_context accordingly. If the
client channel binding flag was "n" then the server MUST NOT include client channel binding flag was "n" then the server MUST NOT include
application channel binding data in the GSS-API channel binding input application channel binding data in the GSS-API channel binding input
to GSS_Accept_sec_context(). If the client channel binding flag was to GSS_Accept_sec_context. If the client channel binding flag was
"y" and the server does support channel binding then the server MUST "y" and the server does support channel binding then the server MUST
fail authentication. If the client channel binding flag was "p" the fail authentication. If the client channel binding flag was "p" the
server MUST include application channel binding data in the GSS-API server MUST include application channel binding data in the GSS-API
channel binding input to GSS_Accept_sec_context(). channel binding input to GSS_Accept_sec_context.
For more discussions of channel bindings, and the syntax of the For more discussions of channel bindings, and the syntax of the
channel binding data for various security protocols, see [RFC5056]. channel binding data for various security protocols, see [RFC5056].
6. Examples 6. Examples
Example #1: a one round-trip GSS-API context token exchange, no Example #1: a one round-trip GSS-API context token exchange, no
channel binding, optional authzid given. channel binding, optional authzid given.
C: Request authentication exchange C: Request authentication exchange
S: Empty Challenge S: Empty Challenge
C: nauthzid=someuser, <initial context token with standard C: na=someuser,<initial context token with standard
header removed> header removed>
S: Send reply context token as is S: Send reply context token as is
C: Empty message C: Empty message
S: Outcome of authentication exchange S: Outcome of authentication exchange
Example #2: a one and one half round-trip GSS-API context token Example #2: a one and one half round-trip GSS-API context token
exchange. exchange.
C: Request authentication exchange C: Request authentication exchange
S: Empty Challenge S: Empty Challenge
C: nauthzid=someuser, <initial context token with standard C: na=someuser,<initial context token with standard
header removed> header removed>
S: Send reply context token as is S: Send reply context token as is
C: Send reply context token as is C: Send reply context token as is
S: Outcome of authentication exchange S: Outcome of authentication exchange
Example #3: a two round-trip GSS-API context token exchange, no
Example #3: a two round-trip GSS-API context token exchange. standard token header.
C: Request authentication exchange C: Request authentication exchange
S: Empty Challenge S: Empty Challenge
C: nauthzid=someuser, <initial context token with standard C: Fna=someuser,<initial context token without
header removed> standard header>
S: Send reply context token as is S: Send reply context token as is
C: Send reply context token as is C: Send reply context token as is
S: Send reply context token as is S: Send reply context token as is
C: Empty message C: Empty message
S: Outcome of authentication exchange S: Outcome of authentication exchange
Example #4: using channel binding. Example #4: using channel binding
C: Request authentication exchange C: Request authentication exchange
S: Empty Challenge S: Empty Challenge
C: yauthzid=someuser, <initial context token with standard C: pa=someuser,<initial context token with standard
header removed> header removed>
S: Send reply context token as is S: Send reply context token as is
... ...
GSS-API authentication is always initiated by the client. The SASL GSS-API authentication is always initiated by the client. The SASL
framework allows either the client and server to initiate framework allows either the client and server to initiate
authentication. In GS2 the server will send an initial empty authentication. In GS2 the server will send an initial empty
challenge (zero byte string) if it has not yet received a token from challenge (zero byte string) if it has not yet received a token from
the client. See section 3 of [RFC4422]. the client. See section 3 of [RFC4422].
7. Authentication Conditions 7. Authentication Conditions
Authentication MUST NOT succeed if any one of the following Authentication MUST NOT succeed if any one of the following
conditions are true: conditions are true:
o GSS_Init/Accept_sec_context() return anything other than o GSS_Init/Accept_sec_context return anything other than
GSS_S_CONTINUE_NEEDED or GSS_S_COMPLETE. GSS_S_CONTINUE_NEEDED or GSS_S_COMPLETE.
o If the client's GS2 channel binding flag was "y" and the server o If the client's GS2 channel binding flag was "y" and the server
supports channel binding. supports channel binding.
o If the client requires use of channel binding and the server did o If the client requires use of channel binding and the server did
not advertise support for channel binding. not advertise support for channel binding.
o Authorization of client principal (i.e., src_name in o Authorization of client principal (i.e., src_name in
GSS_Accept_sec_context()) to requested authzid failed. GSS_Accept_sec_context) to requested authzid failed.
o If the client is not authorized to the requested authzid or an o If the client is not authorized to the requested authzid or an
authzid could not be derived from the client's initiator principal authzid could not be derived from the client's initiator principal
name. name.
8. GSS-API Parameters 8. GSS-API Parameters
GS2 does not use any GSS-API per-message tokens. Therefore the GS2 does not use any GSS-API per-message tokens. Therefore the
setting of req_flags related to per-message tokens is irrelevant. setting of req_flags related to per-message tokens is irrelevant.
9. Naming 9. Naming
There's no requirement that any particular GSS-API name-types be There's no requirement that any particular GSS-API name-types be
used. However, typically SASL servers will have host-based acceptor used. However, typically SASL servers will have host-based acceptor
principal names (see [RFC2743] section 4.1) and clients will principal names (see [RFC2743] section 4.1) and clients will
typically have username initiator principal names (see [RFC2743] typically have username initiator principal names (see [RFC2743]
section 4.2). section 4.2).
10. GSS_Mechanism_SASLname call 10. GSS_Inquire_SASLname_for_mech call
To allow SASL implementations to query for the SASL mechanism name of To allow SASL implementations to query for the SASL mechanism name of
a GSS-API mechanism, we specify a new GSS-API function for this a GSS-API mechanism, we specify a new GSS-API function for this
purpose. purpose.
Inputs: Inputs:
o desired_mech OBJECT IDENTIFIER o desired_mech OBJECT IDENTIFIER
Outputs: Outputs:
o sasl_mech_name OCTET STRING -- SASL name for this mechanism o sasl_mech_name UTF-8 STRING -- SASL name for this mechanism
(really, ASCII)
o mech_name UTF-8 STRING -- name of this mechanism, possibly o mech_name UTF-8 STRING -- name of this mechanism, possibly
localized localized
o mech_description UTF-8 STRING -- possibly localized o mech_description UTF-8 STRING -- possibly localized
description of this mechanism. description of this mechanism.
Return major_status codes: Return major_status codes:
o GSS_S_COMPLETE indicates successful completion, and that output o GSS_S_COMPLETE indicates successful completion, and that output
parameters holds correct information. parameters holds correct information.
o GSS_S_BAD_MECH indicates that a disred_mech was unsupported by o GSS_S_BAD_MECH indicates that a desired_mech was unsupported by
the GSS-API implementation. the GSS-API implementation.
The GSS_Mechanism_SASLname call is used to get the SASL mechanism The GSS_Inquire_SASLname_for_mech call is used to get the SASL
name for a GSS-API mechanism. It also returns a name and mechanism name for a GSS-API mechanism. It also returns a name
description of the mechanism in a human readable form. and description of the mechanism in a human readable form.
10.1. gss_mechanism_saslname 10.1. gss_inquire_saslname_for_mech
The C binding for the GSS_Mechanism_SASLname call is as follows. The C binding for the GSS_Inquire_SASLname_for_mech call is as
follows.
OM_uint32 gss_mechanism_saslname( OM_uint32 gss_inquire_saslname_for_mech(
OM_uint32 *minor_status, OM_uint32 *minor_status,
const gss_OID desired_mech, const gss_OID desired_mech,
gss_buffer_t sasl_mech_name, gss_buffer_t sasl_mech_name,
gss_buffer_t mech_name, gss_buffer_t mech_name,
gss_buffer_t mech_description, gss_buffer_t mech_description,
); );
Purpose: Purpose:
Output the SASL mechanism name of a GSS-API mechanism. Also output Output the SASL mechanism name of a GSS-API mechanism.
a name and description of the mechanism in a human readable form. It also returns a name and description of the mechanism in a
human readable form.
Parameters: Parameters:
minor_status Integer, modify minor_status Integer, modify
Mechanism specific status code. Mechanism specific status code.
Function value: GSS status code Function value: GSS status code
GSS_S_COMPLETE Successful completion GSS_S_COMPLETE Successful completion
GSS_S_BAD_MECH The desired_mech OID is unsupported GSS_S_BAD_MECH The desired_mech OID is unsupported
11. GSS_Inquire_mech_for_SASLname call 11. GSS_Inquire_mech_for_SASLname call
To allow SASL clients to more efficiently identify which GSS-API To allow SASL clients to more efficiently identify which GSS-API
mechanism a particular SASL mechanism name refers to we specify a new mechanism a particular SASL mechanism name refers to we specify a new
GSS-API utility function for this purpose. GSS-API utility function for this purpose.
Inputs: Inputs:
o sasl_mech_name OCTET STRING -- SASL name of mechanism o sasl_mech_name UTF-8 STRING -- SASL name of mechanism
(really, ASCII)
Outputs: Outputs:
o mech_type OBJECT IDENTIFIER -- must be explicit mechanism, o mech_type OBJECT IDENTIFIER -- must be explicit mechanism,
and not "default" specifier and not "default" specifier
Return major_status codes: Return major_status codes:
o GSS_S_COMPLETE indicates successful completion, and that output o GSS_S_COMPLETE indicates successful completion, and that output
parameters holds correct information. parameters holds correct information.
skipping to change at page 15, line 40 skipping to change at page 15, line 40
GSS_S_BAD_MECH The desired_mech OID is unsupported GSS_S_BAD_MECH The desired_mech OID is unsupported
12. Security Layers 12. Security Layers
GS2 does not currently support SASL security layers. Applications GS2 does not currently support SASL security layers. Applications
that need integrity protection or confidentiality and integrity that need integrity protection or confidentiality and integrity
protection MUST use either channel binding to a secure external protection MUST use either channel binding to a secure external
channel or a SASL mechanism that does provide security layers. channel or a SASL mechanism that does provide security layers.
NOTE WELL: the GS2 client's first authentication message MUST always NOTE WELL: the GS2 client's first authentication message MUST always
start with "F", "n", "y" or "p", otherwise the server MUST fail start with "F", "p", "n" or "y", otherwise the server MUST fail
authentication. This will allow us to add support for security authentication. This will allow us to add support for security
layers in the future if it were to become necessary. Note that layers in the future if it were to become necessary. Note that
adding security layer support to GS2 must not break existing SASL/GS2 adding security layer support to GS2 must not break existing SASL/GS2
applications, which can be accomplished by making security layers applications, which can be accomplished by making security layers
optional. optional.
[A sketch of how to add sec layer support... Add a way for the [A sketch of how to add sec layer support... Add a way for the
client to: a) make an offer of sec layers and max buffer, b) make an client to: a) make an offer of sec layers and max buffer, b) make an
opportunistic selection of sec layer and buffer size, both in the opportunistic selection of sec layer and buffer size, both in the
first client authentication message, and starting with a character first client authentication message, and starting with a character
skipping to change at page 16, line 17 skipping to change at page 16, line 17
GSS-API security context token exchange must be abandoned and GSS-API security context token exchange must be abandoned and
recommenced, although this would be a detail of the GS2 bridge not recommenced, although this would be a detail of the GS2 bridge not
exposed to the SASL application. The negotiation would be protected exposed to the SASL application. The negotiation would be protected
via GSS channel binding, as with the rest of GS2.] via GSS channel binding, as with the rest of GS2.]
13. Interoperability with the SASL "GSSAPI" mechanism 13. Interoperability with the SASL "GSSAPI" mechanism
The Kerberos V5 GSS-API [RFC1964] mechanism is currently used in SASL The Kerberos V5 GSS-API [RFC1964] mechanism is currently used in SASL
under the name "GSSAPI", see GSSAPI mechanism [RFC4752]. The under the name "GSSAPI", see GSSAPI mechanism [RFC4752]. The
Kerberos V5 mechanism may also be used with the GS2 family. This Kerberos V5 mechanism may also be used with the GS2 family. This
causes an interopability problem, which is discussed and resolved causes an interoperability problem, which is discussed and resolved
below. below.
13.1. The interoperability problem 13.1. The interoperability problem
The SASL "GSSAPI" mechanism is not wire-compatible with the Kerberos The SASL "GSSAPI" mechanism is not wire-compatible with the Kerberos
V GSS-API mechanism used as a SASL GS2 mechanism. V GSS-API mechanism used as a SASL GS2 mechanism.
If a client (or server) only support Kerberos V5 under the "GSSAPI" If a client (or server) only support Kerberos V5 under the "GSSAPI"
name and the server (or client) only support Kerberos V5 under the name and the server (or client) only support Kerberos V5 under the
GS2 family, the mechanism negotiation will fail. GS2 family, the mechanism negotiation will fail.
skipping to change at page 16, line 44 skipping to change at page 16, line 44
Reasons for violating this recommendation may include security Reasons for violating this recommendation may include security
considerations regarding the absent features in the GS2 mechanism. considerations regarding the absent features in the GS2 mechanism.
The SASL "GSSAPI" mechanism lacks support for channel bindings, which The SASL "GSSAPI" mechanism lacks support for channel bindings, which
means that using an external secure channel may not be sufficient means that using an external secure channel may not be sufficient
protection against active attackers (see [RFC5056], [mitm]). protection against active attackers (see [RFC5056], [mitm]).
13.3. Additional Recommendations 13.3. Additional Recommendations
If the application requires security layers then it MUST prefer the If the application requires security layers then it MUST prefer the
SASL "GSSAPI" mechanism over "KerberosV-GS2". SASL "GSSAPI" mechanism over "GS2-KRB5" or "GS2-KRB5-PLUS".
If the application can use channel binding to an external channel If the application can use channel binding to an external channel
then it is RECOMMENDED that it select Kerberos V5 through the GS2 then it is RECOMMENDED that it select Kerberos V5 through the GS2
mechanism rather than the "GSSAPI" mechanism. mechanism rather than the "GSSAPI" mechanism.
14. Mechanisms that negotiate other mechanisms 14. Mechanisms that negotiate other mechanisms
A GSS-API mechanism that negotiate other mechanisms interact badly A GSS-API mechanism that negotiate other mechanisms interact badly
with the SASL mechanism negotiation. There are two problems. The with the SASL mechanism negotiation. There are two problems. The
first is an interoperability problem and the second is a security first is an interoperability problem and the second is a security
skipping to change at page 17, line 42 skipping to change at page 17, line 42
GSS-API mechanisms that negotiate other mechanisms MUST NOT be used GSS-API mechanisms that negotiate other mechanisms MUST NOT be used
with the GS2 SASL mechanism. Specifically SPNEGO [RFC4178] MUST NOT with the GS2 SASL mechanism. Specifically SPNEGO [RFC4178] MUST NOT
be used as a GS2 mechanism. To make this easier for SASL be used as a GS2 mechanism. To make this easier for SASL
implementations we assign a symbolic SASL mechanism name to the implementations we assign a symbolic SASL mechanism name to the
SPNEGO GSS-API mechanism: "SPNEGO". SASL client implementations MUST SPNEGO GSS-API mechanism: "SPNEGO". SASL client implementations MUST
NOT choose the SPNEGO mechanism under any circumstances. [What about NOT choose the SPNEGO mechanism under any circumstances. [What about
SASL apps that don't do mechanism negotiation? Probably none exist. SASL apps that don't do mechanism negotiation? Probably none exist.
But if any did then presumably it would OK to use the SPNEGO But if any did then presumably it would OK to use the SPNEGO
mechanism, no? -Nico] mechanism, no? -Nico]
The GSS_C_MA_MECH_NEGO attribute of GSS_Inquire_attrs_for_mech() The GSS_C_MA_MECH_NEGO attribute of GSS_Inquire_attrs_for_mech
[I-D.ietf-kitten-extended-mech-inquiry] can be used to identify such [I-D.ietf-kitten-extended-mech-inquiry] can be used to identify such
mechanisms. mechanisms.
15. IANA Considerations 15. IANA Considerations
The SASL names for the Kerberos V GSS-API mechanism [RFC4121] The SASL names for the Kerberos V5 GSS-API mechanism [RFC4121]
[RFC1964] used via GS2 SHALL be "KerberosV-GS2" and "KerberosV-GS2- [RFC1964] used via GS2 SHALL be "GS2-KRB5" and "GS2-KRB5-PLUS".
PLUS".
The SASL names for the SPNEGO GSS-API mechanism used via GS2 SHALL be 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". As described in Section 14 the SASL
"SPNEGO" and "SPNEGO-PLUS" MUST NOT be used. These names are "SPNEGO" and "SPNEGO-PLUS" MUST NOT be used. These names are
provided as a convienience for SASL library implementors. provided as a convenience for SASL library implementors.
The IANA is advised that SASL mechanism names starting with "GS2-" The IANA is advised that SASL mechanism names starting with "GS2-"
are reserved for SASL mechanisms which conform to this document. The are reserved for SASL mechanisms which conform to this document. The
IANA is directed to place a statement to that effect in the sasl- IANA is directed to place a statement to that effect in the sasl-
mechanisms registry. mechanisms registry.
The IANA is further advised that SASL mechanisms MUST NOT end in The IANA is further advised that SASL mechanisms MUST NOT end in
"-PLUS" except as a version of another mechanism name simply suffixed "-PLUS" except as a version of another mechanism name simply suffixed
with "-PLUS". with "-PLUS".
skipping to change at page 19, line 6 skipping to change at page 19, line 5
mechanism used is secure. Authentication failure because of channel mechanism used is secure. Authentication failure because of channel
binding failure may indicate that an MITM attack was attempted, but binding failure may indicate that an MITM attack was attempted, but
note that a real MITM attacker would likely attempt to close the note that a real MITM attacker would likely attempt to close the
connection to the client or simulate network partition , thus MITM connection to the client or simulate network partition , thus MITM
attack detection is heuristic. attack detection is heuristic.
Use of channel binding will also protect the SASL mechanism Use of channel binding will also protect the SASL mechanism
negotiation -- if there is no MITM then the external secure channel negotiation -- if there is no MITM then the external secure channel
will have protected the SASL mechanism negotiation. will have protected the SASL mechanism negotiation.
The channel binding data MAY be sent (byt the actual GSS-API The channel binding data MAY be sent (but the actual GSS-API
mechanism used) without confidentiality protection and knowledge of mechanism used) without confidentiality protection and knowledge of
it is assumed to provide no advantage to an MITM (who can, in any it is assumed to provide no advantage to an MITM (who can, in any
case, compute the channel binding data independently). If the case, compute the channel binding data independently). If the
external channel does not provide confidentiality protection and the external channel does not provide confidentiality protection and the
GSS-API mechanism does not provide confidentiality protection for the GSS-API mechanism does not provide confidentiality protection for the
channel binding data, then passive attackers (eavesdroppers) can channel binding data, then passive attackers (eavesdroppers) can
recover the channel binding data. See [RFC5056]. recover the channel binding data. See [RFC5056].
When constructing the input_name_string for GSS_Import_name() with When constructing the input_name_string for GSS_Import_name with the
the GSS_C_NT_HOSTBASED_SERVICE name type, the client SHOULD NOT GSS_C_NT_HOSTBASED_SERVICE name type, the client SHOULD NOT
canonicalize the server's fully qualified domain name using an canonicalize the server's fully qualified domain name using an
insecure or untrusted directory service, such as the Domain Name insecure or untrusted directory service, such as the Domain Name
System [RFC1034] without DNSSEC [RFC4033]. System [RFC1034] without DNSSEC [RFC4033].
GS2 does not directly use any cryptographic algorithms, therefore it GS2 does not directly use any cryptographic algorithms, therefore it
is automatically "algorithm agile", or, as agile as the GSS-API is automatically "algorithm agile", or, as agile as the GSS-API
mechanisms that are available for use in SASL apoplications via GS2. mechanisms that are available for use in SASL applications via GS2.
The security considerations of SASL [RFC4422], the GSS-API [RFC2743], The security considerations of SASL [RFC4422], the GSS-API [RFC2743],
channel binding [RFC5056], any external channels (such as TLS, channel binding [RFC5056], any external channels (such as TLS,
[RFC5246], channel binding types (see the IANA channel binding type [RFC5246], channel binding types (see the IANA channel binding type
registry), and GSS-API mechanisms (such as the Kerberos V mechanism registry), and GSS-API mechanisms (such as the Kerberos V5 mechanism
[RFC4121] [RFC1964]), may also apply. [RFC4121] [RFC1964]), may also apply.
17. Acknowledgements 17. Acknowledgements
The history of GS2 can be traced to the "GSSAPI" mechanism originally The history of GS2 can be traced to the "GSSAPI" mechanism originally
specified by RFC2222. This document was derived from specified by RFC2222. This document was derived from
draft-ietf-sasl-gssapi-02 which was prepared by Alexey Melnikov with draft-ietf-sasl-gssapi-02 which was prepared by Alexey Melnikov with
significant contributions from John G. Myers, although the majority significant contributions from John G. Myers, although the majority
of this document has been rewritten by the current authors. of this document has been rewritten by the current authors.
skipping to change at page 21, line 23 skipping to change at page 21, line 20
RFC 4178, October 2005. RFC 4178, October 2005.
[RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple [RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple
Authentication and Security Layer (SASL) Mechanism", Authentication and Security Layer (SASL) Mechanism",
RFC 4752, November 2006. RFC 4752, November 2006.
[RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
(TLS) Protocol Version 1.2", RFC 5246, August 2008. (TLS) Protocol Version 1.2", RFC 5246, August 2008.
[I-D.newman-auth-scram] [I-D.newman-auth-scram]
Menon-Sen, A., Melnikov, A., and C. Newman, "Salted Menon-Sen, A., Melnikov, A., Newman, C., and N. Williams,
Challenge Response (SCRAM) SASL Mechanism", "Salted Challenge Response (SCRAM) SASL Mechanism",
draft-newman-auth-scram-10 (work in progress), draft-newman-auth-scram-12 (work in progress), March 2009.
February 2009.
[I-D.ietf-kitten-extended-mech-inquiry] [I-D.ietf-kitten-extended-mech-inquiry]
Williams, N., "Extended Generic Security Service Mechanism Williams, N., "Extended Generic Security Service Mechanism
Inquiry APIs", draft-ietf-kitten-extended-mech-inquiry-04 Inquiry APIs", draft-ietf-kitten-extended-mech-inquiry-06
(work in progress), March 2008. (work in progress), April 2009.
[mitm] Asokan, N., Niemi, V., and K. Nyberg, "Man-in-the-Middle [mitm] Asokan, N., Niemi, V., and K. Nyberg, "Man-in-the-Middle
in Tunneled Authentication", in Tunneled Authentication",
WWW http://www.saunalahti.fi/~asokan/research/mitm.html. WWW http://www.saunalahti.fi/~asokan/research/mitm.html.
Authors' Addresses Authors' Addresses
Simon Josefsson Simon Josefsson
SJD AB SJD AB
Hagagatan 24 Hagagatan 24
 End of changes. 60 change blocks. 
97 lines changed or deleted 125 lines changed or added

This html diff was produced by rfcdiff 1.29, available from http://www.levkowetz.com/ietf/tools/rfcdiff/