Subject: sasl-gs2-10 notes

From: Hallvard B Furuseth <[email-masked]>
Date: Tue, 9 Dec 2008 18:14:45 +0100

Some notes about draft-ietf-sasl-gs2-10.txt.
I've only glanced at RFC 2743 (GSS-API), so some notes probably
translate to "please clarify/insert a reference to a GSS-API concept".

> 3.  Mechanism name
> 3.1.  Generating SASL mechanism names from GSS-API OIDs

Please split this up a bit.  At least:

>    The SASL mechanism name for a GSS-API mechanism is

     derived from the GSS-API mechanism's Object Identifier (OID).
     <p>
     It is

>    the concatenation
>    of the string "GS2-" and the Base32 encoding [RFC4648] (with an upper
>    case alphabet) of the first ten bytes of the binary SHA-1 hash
>    [FIPS.180-1.1995] string computed over the ASN.1 DER encoding
>    [ITU.X690.1994], including the tag and length octets, of the GSS-API
>    mechanism's Object Identifier. 

     <p>

>    The Base32 rules on padding
>    characters and characters outside of the base32 alphabet are not
>    relevant to this use of Base32.

Please add a few words with the rationale for GS2 names.  I'm guessing:

     GSS-API represents OIDs in DER format.  The reason it is hashed is
     to make the name short enough for SASL's 20-character name limit.

>    If any padding or non-alphabet
>    characters are encountered, the name is not a GS2 family mechanism
>    name.

nor if the name is not 20 characters long.  Also
s/non-alphabet/non-alphanumeric/.  However I suggest to drop this
sentence since it follows from the definition.

> 3.2.  Computing mechanism names manually
>
>    The SASL mechanism name may be computed manually.

I'd rather not compute SHA-1 manually:-)  You mean it can be precomputed.

>    This is useful
>    when the set of supported GSS-API mechanisms is known in advance.  It
>    also obliterate the need to implement Base32, SHA-1 and DER in the
>    SASL mechanism.  The computed mechanism name can be used directly in
>    the implementation,

Section 3.2 seems to say very little.  How about replacing it with
another paragraph in 3.1:

    "If the gs2 implementation stores a precomputed GSS-API OID -> SASL
    name mapping, it will not need to implement Base32, SHA-1 and DER."

(Update the exact text to match the outcome of the "GSS init tok header
compression" discussion, which I'm not quite following yet.)

Though is "...and DER" true, or will the GSS-API implementation include
that anyway?

>    and the implementation need not concern itself
>    with that the mechanism is part of a mechanism family.

I dropped this from my suggested text since it's implicit in SASL:
A mechanism family is just a collection of names with a common prefix.
It has no other semantics to be concerned with.

> 3.3.  Examples

This is very verbose.  With so much text, there should be room for a
step-by-step description so one doesn't need to refer to the DER and
Base32 documents.  Delete example #1 instead, since that is least
complex.  (It doesn't include OID components >= 128.)

Suggestion:

3.2.  Algorithm to compute SASL name from GSS-API OID

Here is a step-by-step guide to compute the SASL mechanism name as
defined above.

Take the OID (Object Identifier) of the GSS-API mechanism.

DER-encode [ITU.X690.1994] the OID if you have it in textual form
(e.g. "1.2.3456.789.0") instead of binary DER form:
* Replace the two first OID components with (40*1st component + 2nd
  component).
* Convert each resulting OID component to base 128 (digits %x00-%x7F),
  but add 128 to all but the last base-128 digit of each component.
* Concatenate the results, one byte per base-128 digit.
* Prepend a byte with the length of the above encoding if smaller than
  128.  Otherwise prepend 128 + number of length bytes, followed by
  the minimum possible number of base-256 length bytes, big-endian.
* Prepend %x06.  (DER tag for ASN.1's OBJECT IDENTIFIER type).

SHA-1 hash [FIPS.180-1.1995] the DER encoding.

Base32-encode [RFC4648] the SHA-1 hash's first 10 bytes:
* Consider them a stream of 80 bits.  (10 bytes*8 bits/byte.)
* Group these as 16 5-bit numbers.
* Output as base-32 numbers using ASCII digits uppercase
  "A"-"Z", "2"-"7" (0-25, 26-31).

Finally, prepend uppercase "GS2-".

3.3.  Example

The OID for the Kerberos V5 GSS-API mechanism [RFC1964] is
1.2.840.113554.1.2.2.  To derive the SASL mechanism name as in Section
3.2:

GSS-API mech OID:  1.2.840.113554.1.2.2
40*1st + 2nd:      42, 840,      113554,           1, 2, 2
Base 128:          42, 6+128 72, 6+128 119+128 18, 1, 2, 2
Tag,length: 06 09  2A  86    48  86    F7      12  01 02 02 (hex)
SHA-1:      82 D2 73 25 76 6B D6 C8 45 AA ... (first 10 bytes hex)
SHA-1 in binary:  10000010 11010010 01110011 00100101 01110110
                  01101011 11010110 11001000 01000101 10101010
As 5-bit numbers: 10000 01011 01001 00111 00110 01001 01011 10110
                  01101 01111 01011 01100 10000 10001 01101 01010
In decimal:       16 11 9 7 6 9 11 22 13 15 11 12 16 17 13 10
In base-32:       Q  L  J H G J L  W  N  P  L  M  Q  R  N  K
SASL mechanism name: "GS2-QLJHGJLWNPLMQRNK"

> 4.1.  SASL Messages
>    Messages shorter than or equal to 8 octets are invalid.  (The only
>    exception is the initial empty challenge sent by the server which may
>    be 0 octets.)

Remove the parenthesis since the information in them cannot be omitted.

> 4.2.2.  Server side
>    (**) - Use of server's principal names having
>    GSS_C_NT_HOSTBASED_SERVICE name type and "service@hostname" format,
>    where "service" is the service name specified in the protocol's
>    profile, and "hostname" is the fully qualified host name of the
>    server, is RECOMMENDED.

Please move the verb near the beginning of the sentence, so one can find
out earlier what's going on.  Something like this, though I should have
read GSS-API before suggesting a text.  Should it be e.g. "... to use
one of the server's ..."?

     It is RECOMMENDED to use server's principal names having
     GSS_C_NT_HOSTBASED_SERVICE name type and "service@hostname" format.
     "service" is the service name specified in the protocol's
     profile, and "hostname" is the fully qualified host name of the
     server.

>    Upon successful establishment of the security context (i.e.
>    GSS_Accept_sec_context returns GSS_S_COMPLETE) the server SHOULD
>    verify that the negotiated GSS-API mechanism is indeed the registered
>    one.  This is done by examining the value of the mech_type parameter
>    returned from the GSS_Accept_sec_context call.  If the value differ,
>    the SASL authentication MUST be aborted.

Make up your mind - SHOULD or MUST auth be aborted if values differ?
The current text implies that the server MUST NOT verify the mechanism
ID (e.g. to log any differences) unless it also aborts if they differ.

There is a similar MUST-MUST-MAY here:

> 4.3.2.  Client first GS2_Wrap input
>    The "client_maxbuf" field indicate the maximum protected buffer size
>    the client can receive in network byte order.  It MUST be 0 if the
>    client doesn't advertise support for any security layer, the server
>    MUST verify this.  Small values can make it impossible for the server
>    to send any protected message to the client, due to the overhead
>    added by GSS_Wrap, and the server MAY reject the authentication if it
>    detects this situation.

Since it MUST verify this, what MUST it do with a verification failure
if it does not follow the MAY and reject the authentication?

Also the "server_maxbuf" field in 4.3.3 (Server last GS2_Wrap input).

However, which security layer and advertised how?  I see no reference to
that in RFC 2743 (GSS-API) or this draft.  SASL has no feature to
advertise its security layers, though it says protocols should advertise
mechanisms.  Or are we talking about another security layer, like TLS?
Is this related to Section 9, Security Layer Bits?

> 4.3.2.  Client first GS2_Wrap input
>    The
>    authorization identity is not terminated with the NUL (U+0000)
>    character.

Why would it be?  If this is a reference to strings in the C language,
drop it.  These data are binary anyway, not text strings.

> 6.  Protocol Overview
>          S: After PROT_READY is set,
>             send [GSS_Accept_sec_context,
>                   GS2_Wrap(server_qops | server_maxbuf]

Missing ")".

> 7.  Authentication Conditions
>
>    Authentication MUST NOT succeed if any one of the following
>    conditions are true:

Please indicate which conditions are introduced in this section, and
which ones are duplicates of conditions elsewhere (and where they are
introduced).

Finally, the draft refers to the "protocol('s) profile".  Should that be
"SASL protocol requirements" referring to [SASL] Section 4?  That was
called "protocol profile" in the [SASL] drafts I remember, don't know
when it was changed.

-- 
Hallvard

---

From: Hallvard B Furuseth <[email-masked]>
Date: Tue, 9 Dec 2008 19:44:36 +0100

I wrote:
> (...)

That was confusing.  Trying again:
  * Output as base-32 numbers using digits A-Z 2-7 (%x41-%x5A %x32-%x37)
    for values 0-25 26-31.

-- 
Hallvard

---

From: Hallvard B Furuseth <[email-masked]>
Date: Wed, 10 Dec 2008 07:16:20 +0100

>     name mapping, it will not need to implement Base32, SHA-1 and DER."

No, if it "stores a mapping {GSS-API OID => precomputed SASL name}".

> SHA-1 in binary:  10000010 11010010 01110011 00100101 01110110

That left column reads as "the whole SHA-1 hash".  Make that

  SHA-1[0:10]: 82 D2 73 25 76 6B D6 C8 45 AA ... (first 10 bytes hex)
  In binary:        10000010 11010010 01110011 00100101 01110110
                    01101011 11010110 11001000 01000101 10101010

(Doesn't matter what "substring" syntax is used since the text describes
it anyway, just as long as it indicates to people who start at the
example that they need to look closer.)

-- 
Hallvard