Subject: Normalization of passwords in SASL and SSH

From: Sam Hartman <[email-masked]>
Date: Mon, 29 Nov 2004 20:27:45 -0800

Hi.  A discussion in the IETF 61 secsh meeting re-opened the issue of
how to handle password normalization for passwords received by the
server.  The ssh protocol had adopted a significantly different
solution to this problem than the sasl plain mechanism.  This concerns
me; I want to either solve the problem of password normalization in a
consistent manner or to understand why the ssh requirements are
different than the sasl requirements.  

As a result of that discussion I've been talking to several people
about the issue.  Now I think I understand things well enough to
propose a solution to both working groups.

First, I'd like to revisit the motivation behind normalization.  There
are a variety of semantically equivalent sequences of characters that
have multiple representations in Unicode.  The simplest example is
accented characters where one code point represents the accented
character and another series of code points represents the
semantically equivalent character plus a combining accent.  Other
examples exist.  Which sequence of code points gets used tends to
depend on the input method used to enter the characters.  That means
that it tends to depend on the OS, application and version of software
used.  So, telling users to type their password the same way is not a
sufficient answer to guarantee that you end up with the same sequence
of code points; the user may not have a choice of input methods.

The IDN working group developed an architecture called Stringprep
which allows protocol-specific profiles of rules for mapping some
semantically equivalent strings into the same sequences of code
points.  It is not perfect; as with any normalization discussion the
question of where to draw boundaries between equivalence classes is
difficult.  The SASL working group developed a profile of Stringprep
called Saslprep; this profile is targeted at simple usernames and
passwords.  Everyone I talked to over the past two weeks believes that
if you are going to normalize passwords for ssh or the SASL plain
mechanism, Saslprep is a reasonable profile to use.  Saslprep has the
advantage of already being in the rfc editor queue.

We'd like to tell people to normalize passwords all the time.  If they
actually did that then it would improve interoperability and the user
experience.  However most systems we use do not store plaintext
passwords.  Instead, they tend to store some function of the password
or to call out to something like PAM or RADIUS to do password
authentication.  Normalizing a password before you check it but not
when new passwords are stored may be very problematic.  

For example, consider an environment where the input method tends to
produce separate base character and accent code points. Without
normalization, when passwords containing accents are stored, any
computed hash will include both the base character and the accent.
However Saslprep will normalize such a string to use a single code
point when possible.  Thus in such an environment, normalizing only
when checking passwords would decrease interoperability because
accented characters would never work in passwords.

I'm proposing the following approach to address this situation.  For
both ssh and sasl plain, normalization should be done on the server if
at all.  Only the server knows what the password store technology in
use is.  We recommend normalizing when passwords can be normalized
both as they are set and as they are compared.  In environments where
passwords may not be normalized as they are set, implementations may
want to try comparing against both the normalized and supplied form of
the password.  Doing so may improve interoperability because it means
there is a password that if successfully set will work when used with
any input method.  However in many environments such as when a server
calls out to PAM or RADIUS, even the server cannot try multiple
passwords without incrementing failed password counters or having
other similar side effects.  Here are some examples of how I see these
recommendations working.

A sasl plain implementation that manages its own password database
would always normalize when setting a password and when checking
passwords.  

A Windows ssh service  that managed its own authentication database
and provided the only tool for setting passwords  would normalize both
for setting passwords and for comparing them.

An ssh implementation that used a unix password file would not
normalize passwords for comparison.  This is true even if the ssh
implementation sometimes was used to set passwords, because the passwd
command could be used independently of the ssh implementation.

An ssh implementation that called out to PAM or RADIUS would not
normalize passwords.  However some of the modules eventually doing the
password comparison might well do normalization if appropriate for the
password store in question.

Does this seem like a reasonable approach to people?  If so, we can
work on appropriate text.