Subject: [Isms] A hopefully useful SASL tutorial

From: Ken Hornstein <[email-masked]>
Date: Fri, 15 Oct 2004 16:00:24 -0400

Dave Perkins had asked me privately for a good tutorial on SASL.  I
cruised around the web a bit, and I couldn't find one.  So I decided to
write this to hopefully explain a bit about SASL, so everyone is
(hopefully) on the same page.  I hope that people who know more about
SASL than I do will understand that I've simplified a number of things
here in the interests of space.

SASL is unfortunately a bit difficult to grasp at first, since it's
a sort of protocol "middleware"; it doesn't define a network protocol,
but a framework that application protocols can use to perform
authentication.

First, some definitions.  Within SASL are these items called "mechanisms".
These are different types of authentication that SASL can perform.
Each of these mechanisms have different capabilities and requires.  Some
examples of SASL mechanisms are:

- CRAM-MD5 - A shared secret is known on each side, and the client sends
  back the MD5 hash of the shared secret and a server-supplied nonce.
  This is an update of the POP "APOP" mechanism.

- LOGIN/PLAIN - Two different variants of the same thing: a plaintext password
  sent unencrypted (as far as SASL knows, at least).

- DIGEST-MD5 - An improved version of CRAM-MD5 (read RFC2222 if you want
  more details).

- GSSAPI - Kerberos 5 authentication

Now, one thing that not everyone appreciates is that SASL contains
within it the framework to do encryption and integrity protection.  I
believe the reason that not everyone understands this is partially
because the SASL RFC calls this "security layers", for reasons which I
have never fully understood.  In SASL, however, the confidentiality and
integrity are done by each mechanism, and not every mechanism supports
confidentiality and integrity protection (e.g., CRAM-MD5 does not, but
DIGEST-MD5 and GSSAPI do).  Exactly what encryption is used is
dependant on the particular mechanism.  DIGEST-MD5 sends a list of
cipher suites it supports as part of it's negotiation; for GSSAPI, the
encryption used is dictated by the session key chosen by the underlying
Kerberos protocol.  So when you're discussing the security of SASL, you
have to also include the particular mechanisms you're talking about.

How SASL messages get exchanged is specific to each protocol, and
is part of a protocol's "SASL profile".  The SASL profile includes
how a protocol can indicate which SASL mechanisms it supports, how
to start authentication, and how authentication messages are transmitted
across that protocol.

Let's take an example: SMTP.  To understand this completely, you'd
have to read RFC 2222 (the SASL base spec), RFC 2554 (The SMTP AUTH
RFC, which defines the SMTP SASL profile), and the documents for
the mechanisms that you were interested in (some of which are still
in draft form right now).  The way that SMTP indicates which mechanisms
it supports is by including an extra line in the EHLO response, e.g.:

EHLO some.mail.client
250-some.mail.server Hello some.mail.client [1.2.3.4], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 209715200
250-DSN
250-ETRN
250-AUTH GSSAPI DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP

The key item here is the "AUTH" line.  This lists the mechanisms that the
server supports.  What happens next is that the client picks one (which
is usually based on what it supports and the ones that the server prefers),
issues an "AUTH mechanism-name", and then the client and server exchange
base64-encoded SASL blobs until either the authentication completes, or
one side has decided that the authentication has failed.

Now note that many of these features (the AUTH command, the text list of
mechanisms, the base64 encoding) are purely features of the SMTP SASL
profile.  An application protocol can choose whatever is appropriate
to transmit the list of supported mechanisms and SASL messages (for
example, LDAP does this very differently).

In terms of implementation (which I feel is important to at least touch
on a bit), the library I am most familiar with is the Cyrus-SASL
library.  With that library, the details of each mechanism are hidden
from you; you call a generic set of functions to extract out a list of
mechanisms, select a mechanism, generate and process the SASL mechanism
messages, and perform encryption.  The encryption functions, however,
are basically "here's some data, encrypt/decrypt it for me".  You don't
really have an idea what the mechanism is doing underneath the hood
(you can tell if encryption has been negotiated or not, though), and
you don't get access to any of the keying material.

If you're careful, you can truely write code that is
mechanism-agnostic.  You can also set criteria for which mechanisms you
want to support.  For example, if you want to select mechanisms that
aren't vulnerable to network sniffing, you can do that and your SASL
library won't offer the PLAIN mechanism.  You can also require that
your mechanisms support mutual authentication, encryption, etc etc ...
a whole bunch of options.

I hope this makes the SASL murkiness a bit clearer.  If you have
further questions, please feel free to ask them on the list, because
likely you're not the only one I have confused.

--Ken

_______________________________________________
Isms mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/isms