Subject: [ldapext] draft-stroeder-hashed-userpassword-values-01

From: Michael Ströder <[email-masked]>
Date: Wed, 13 Mar 2013 23:39:28 +0100

Kurt Zeilenga wrote:
> I see this document is marked as being intended to be published as
> Informational, but it reads more like it's trying to be a standard.

I tried to add some wording to avoid that misunderstanding in the next
revision of this draft:

http://www.ietf.org/internet-drafts/draft-stroeder-hashed-userpassword-values-01.txt

> I note that at Isode we have a 2307 style hash scheme that we use to hold
> SCRAM compatible hash.  Aside from being SCRAM compatible, it's designed to
> hinder dictionary and brute force attacks by significant increasing the
> cost of producing the stored value.   It would be good to include this as
> part of the 'current practice'.

I'd like to add that if you provide more detailed information about it.

Ciao, Michael.

---

From: Andrew Findlay <[email-masked]>
Date: Thu, 14 Mar 2013 00:19:01 +0000

> http://www.ietf.org/internet-drafts/draft-stroeder-hashed-userpassword-values-01.txt

Still -01 ?

You are explicitly excluding details of '{crypt}'. I think this is a
mistake, especially in an informational document. {crypt} is
extremely useful in transition scenarios, so people need to know about
it.

What platform-specific variants do you know of?
The really important one is the old Unix-crypt 13-char salted hash.

Could you perhaps say something like:

{crypt} introduces a password-hash string that is generated and
checked by the crypt(3) library. This could be the traditional
13-character 'Unix crypt' or some other variant such as the stronger
'$1$' and $6$' schemes used by recent versions of Linux.

Andrew
-- 
-----------------------------------------------------------------------
|                 From Andrew Findlay, Skills 1st Ltd                 |
| Consultant in large-scale systems, networks, and directory services |
|     http://www.skills-1st.co.uk/                +44 1628 782565     |
-----------------------------------------------------------------------

---

From: Michael Ströder <[email-masked]>
Date: Thu, 14 Mar 2013 02:23:39 +0100

>> http://www.ietf.org/internet-drafts/draft-stroeder-hashed-userpassword-values-01.txt

Not "still" -01. Now -01.

> extremely useful in transition scenarios, so people need to know about

Hmm...I've expected somebody to ask for it. :-/
It makes the spec part more complex.

> What platform-specific variants do you know of?

Well, looking at crypt(3) man page it seems to me that there are many variants
of the library on various Unix platforms. This is what I meant with
"platform-specific".

> '$1$' and $6$' schemes used by recent versions of Linux.

I've added some text hopefully getting {CRYPT} stuff complete. Yuck!

Ciao, Michael.

---

From: Ludovic Poitou <[email-masked]>
Date: Thu, 14 Mar 2013 11:19:20 +0100

Hi Michael,

I'm glad that you've added text to support {CRYPT}. But I'm not sure it is necessary to make the description complete (i.e. refer to all underlying platform specific algorithm).
I think it might be enough to describe the general format of passwords generated by the crypt(3) library, mentions the default unix crypt and one or two other algorithm, but also warn that crypt being extensible and platform specific, it's use might result in interoperability issues.

I would suggest that you add to the list of schemes, PBKDF2 and BCrypt that are 2 mechanisms that are providing much stronger security than the SHA 1 or 2.
I'be happy to provide a description of PBKDF2 if you want, as we've implemented support for it in OpenDJ.

Regards,

Ludo
--  
Ludovic Poitou
http://ludopoitou.wordpress.com

On Thursday, March 14, 2013 at 2:23 , Michael Ströder wrote:

> _______________________________________________
> Ldapext mailing list
> [email-masked] (mailto:[email-masked])
> https://www.ietf.org/mailman/listinfo/ldapext
>  
>  
>  
>  
> Attachments:  
> - smime.p7s
>  
>

---

From: Michael Ströder <[email-masked]>
Date: Thu, 14 Mar 2013 15:31:28 +0100

Ludovic Poitou wrote:
> I'm glad that you've added text to support {CRYPT}. But I'm not sure it is
> necessary to make the description complete (i.e. refer to all underlying
> platform specific algorithm).
> I think it might be enough to describe the general format of passwords
> generated by the crypt(3) library, mentions the default unix crypt and one or
> two other algorithm, but also warn that crypt being extensible and platform
> specific, it's use might result in interoperability issues.

That's exactly what I did even without describing any of the algorithms.

> I would suggest that you add to the list of schemes, PBKDF2 and BCrypt that
> are 2 mechanisms that are providing much stronger security than the SHA 1 or 2.

I'm glad to see PBKDF2 appearing in LDAP server implementations.
Yes, please provide text to be added.

Ciao, Michael.

---

From: Howard Chu <[email-masked]>
Date: Thu, 14 Mar 2013 09:05:52 -0700

> extremely useful in transition scenarios, so people need to know about

Who benefits from this document? What interoperability problems does it solve? 
Hashed userPassword values are strictly a server-internal implementation 
detail, clients never need to know about them.

The syntax specification is defective in at least 2 ways:
   1) it only allows a form "hashandsalt" which actually precludes any 
unsalted hash mechanisms.
   2) it only allows "b64-hashandsalt" which precludes any mechanisms that 
don't use base64 format for their values. E.g. Unix crypt and Windows LANMAN 
hash formats use their own binary-to-printable encoding, not base64.

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

---

From: Kurt Zeilenga <[email-masked]>
Date: Thu, 14 Mar 2013 10:34:28 -0700

SCRAM is
	"{" scram-mech"}"  scram-authInfo "$" scram-authValue

where the scram-* productions are defined in RFC 5803.  Example:

    {SCRAM-SHA-1}4096:oX1HwnNpqWsmV5xrv5m1YQ==$PcqaaIoiFSOA9/txc4QaNa1jWxA=:4m6FNpHpuxJK63WRpXTAinev7zM=

-- Kurt

---

From: Michael Ströder <[email-masked]>
Date: Thu, 14 Mar 2013 19:29:48 +0100

> Who benefits from this document? What interoperability problems does it solve?

Anybody who has to generate or compare such userPassword values.

> detail, clients never need to know about them.

Not true.

1. E.g. think of bulk sync processes where it's quite usual that you convert
password hashes within the LDAP client - in some cases even salted.

2. Furthermore if a server does not support RFC 3062 and/or server-side
hashing but supports this hashed values when performing password checking you
also have to do client-side generation. This gets rare with recent server
releases of various vendors but it's not something to completely ignore.

3. In some cases it's more appropriate that a LDAP client writes several
attributes in a *single* LDAP write operation instead of using a add/modify
with a subsequent Password Modify ext. op. E.g. when subschema has 'MUST
userPassword' for an object class used.

>   1) it only allows a form "hashandsalt" which actually precludes any unsalted
> hash mechanisms.

Not true. The unsalted variant has simply a zero-length salt. For -02 I've
added some text to clarify this.

> hash formats use their own binary-to-printable encoding, not base64.

Well, at first I simply wanted to ignore this completely.
But after Andrews request I've already changed it for upcoming -02 like this:

    userpasswordvalue  = cleartext-password / prefix hashed-password

    prefix       = "{" scheme "}"
    scheme = %x30-39 / %x41-5A / %x61-7a / %x2D-2F / %x5F
         ;0-9, A-Z, a-z, "-", ".", "/", or "_"

    hashed-password = b64-hashandsalt / crypt3-result

    b64-hashandsalt = <base64 of hashandsalt>

    hashandsalt = password-hash salt

    password-hash = <digest of cleartext-password salt>

    cleartext-password = %x00-FF

    salt = %x00-FF

    crypt3-result = <generated by Unix function crypt(3)>

Please review this. Comments about clarity welcome.

Ciao, Michael.

---

From: Howard Chu <[email-masked]>
Date: Thu, 14 Mar 2013 12:02:33 -0700

> password hashes within the LDAP client - in some cases even salted.

If you can convert from one hash to another, the hash is broken.

> releases of various vendors but it's not something to completely ignore.

A server that can effectively read/use values but cannot write/create them in 
the first place has to be considered defective. Fine, don't ignore it, but 
footnote it. It doesn't deserve to be treated as in any way normal.

> userPassword' for an object class used.

Perhaps so. But this requires the client (or admin running the client) to 
already know what schemes the target server supports. So again, it's 
server-specific knowledge and isn't required for interoperability between 
heterogeneous implementations. Taking the opposite approach - there is no way 
for a server to advertise what mechanisms it supports, so an uninformed 
client/admin cannot possibly do this correctly anyway.

And on that note - no, I don't believe the server should advertise what its 
supported mechanisms are. Again, it's purely an internal matter, and there's 
no reason to give an arbitrary 3rd party a head start on cracking attempts.

Without advance knowledge, obtained out of band, none of these scenarios are 
feasible. The advance knowledge is always specific to a particular server 
deployment.

Finally, an objectclass that defines "MUST userPassword" also has to be 
considered broken. (Reminds me of groupOfNames / MUST member.)

>      userpasswordvalue  = cleartext-password / prefix hashed-password

I think you should replace "hashed-password" with "scheme-specific data" and 
stop there. Provide examples for MD5/SHA/SHA-2 if you like, but emphasize that 
these are just informal examples. There's no reason someone can't come along 
and use an unconstrained octet string after the scheme, if they really want to.

---

From: Michael Ströder <[email-masked]>
Date: Thu, 14 Mar 2013 20:19:12 +0100

> If you can convert from one hash to another, the hash is broken.

Conversion in this context means converting string representations of (salted)
hashes. Obviously the algorithm and order of password and salt has to be the same.

> already know what schemes the target server supports.

We all know that clients have to use some a priori knowledge - most times
called protocol. ;-)

Another use-cases is dealing with data migration to server product of another
vendor.

=> So I consider this draft to be useful.

> considered broken. (Reminds me of groupOfNames / MUST member.)

That's simply your personal opinion not a strong objecting argument.

> stop there.

That's a conclusion of your opinion. But I want to describe the *order* of
password and salt used by any server I saw using the scheme.

> Provide examples for MD5/SHA/SHA-2 if you like, but emphasize that
> these are just informal examples.

The whole I-D has target "informational".

> There's no reason someone can't come along

Yes. But this would just be another scheme to be defined somewhere else.
This draft does not claim to cover everything you could ever stuff into
'userPassword'.

Ciao, Michael.

---

From: Howard Chu <[email-masked]>
Date: Thu, 14 Mar 2013 12:35:00 -0700

> But after Andrews request I've already changed it for upcoming -02 like this:

I think you need to re-read RFC5234.

>           ;0-9, A-Z, a-z, "-", ".", "/", or "_"

Should be something like
	schemechar = %x30-39 / %x41-5A / %x61-7a / %x2D-2F / %x5F
	scheme = 1*schemechar

>      cleartext-password = %x00-FF

Should be something like
	octet = %x00-FF

	cleartext-password = 1*octet
	salt = 0*octet

(Or perhaps you allow zero-length passwords? Don't care much either way.)

	md5-hash = 16octet
	sha1-hash = 20octet
  	...

---

From: Michael Ströder <[email-masked]>
Date: Thu, 14 Mar 2013 23:51:50 +0100

> I think you need to re-read RFC5234.

I did and followed some more of the recommendations found therein.
Thanks for your feedback regarding the ABNF definition. Most of your
modifications will appear in -02.

Not sure about whether it's really needed to have something like this:

    md5-hash = 16octet
    sha1-hash = 20octet

I'd like to avoid having to specify a rule for each algorithm. But maybe it
should be made more clear how the table listing the algorithms should be
interpreted.

Ciao, Michael.

---

From: Andrew Findlay <[email-masked]>
Date: Fri, 15 Mar 2013 10:18:40 +0000

> password and salt used by any server I saw using the scheme.

Why not separate the description of the data from the overall syntax?
It will be easier to read that way, and much more obvious that the whole
thing is extensible and a bit informal.

userPassword has Octet String syntax, so in principle the value is
<scheme name in curly brackets> <arbitrary data>

A separate section of the doc could then describe (or refer to) the formats
of all the commonly-used storage schemes. I was about to call them 'hash
schemes' but that is wrong, as some servers support reversible encryption
schemes as well as hashes.

On a slight tangent, a rough guide to the current strength of various hash
schemes can be found on hashcat's front page:

	http://hashcat.net/oclhashcat-plus/

The table at the bottom gives the brute-force attack rate in crypts/sec
using a single PC with a good (mid-range gaming) graphics engine.
Numbers range from about 4k c/s for bcrypt up to 7500M c/2 for NTLM.
It does not explicitly list figures for SSHA and SMD5 but I suspect the
'sha512crypt $6$' figure is indicative at 12k c/s.

Andrew

---

From: Kurt Zeilenga <[email-masked]>
Date: Fri, 15 Mar 2013 04:07:29 -0700

> 'sha512crypt $6$' figure is indicative at 12k c/s.

The difference per check of SSHA and SHA is one SHAUpdate call, even if this call account for 100% of the work, then SSHA should be no more than twice as expensive SHA.  Likewise for other simple salted hash methods.

-- Kurt

> [email-masked]

---

From: Andrew Findlay <[email-masked]>
Date: Fri, 15 Mar 2013 12:36:10 +0000

> The difference per check of SSHA and SHA is one SHAUpdate call, even if this call account for 100% of the work, then SSHA should be no more than twice as expensive SHA.  Likewise for other simple s…

Good point. Salt protects against pre-computed lookup tables but
on its own has minimal effect on this style of brute-force attack,
as the salt is known by the attacker.

The big difference with sha512crypt is the number of rounds. This defaults
to 5000, which should make it 5000 times slower than SHA512. The Hashcat
numbers are roughly consistent with that.

This suggests that implementers should be encouraged to future-proof their
products:

	Make it easy to add new password-storage schemes - preferably
		without recompiling the server or client code
	Provide schemes with multiple rounds in the standard distribution
	Make it easy to configure the number of rounds
	Ensure that passwords stored with different schemes and number of
		rounds can still be used even if the server config is changed
	Provide a way to disable passwords stored with particular
		configs in the past that are now considered insecure

The document under discussion would be a good place to put that advice.

Andrew

---

From: Andrew Findlay <[email-masked]>
Date: Fri, 15 Mar 2013 12:53:26 +0000

> http://www.ietf.org/internet-drafts/draft-stroeder-hashed-userpassword-values-01.txt

In section 3 Implementation Issues, the 4th paragraph talks
about checking the syntax of the storage scheme. This
certainly has to be done, but I am a bit worried by the last
sentence:

	Any value which do not adhere to this syntax MAY be treated as
	clear-text password by the DSA when processing a LDAP simple
	bind request or LDAP compare request.

This is probably what most servers actually do, but it does
mean that any unrecognised schemes or badly-formatted values
effectively become clear-text passwords. Not a good failure
mode...

This is another case where the use of standard-setting words
like MAY and SHOULD sits uneasily with the informational
status of the document. From a security perspective I would
prefer something like this:

	Any value which does not have correct syntax SHOULD be
	treated as a value that can never match any password
	asserted by a user.

On the other hand, as a description of current practice it may
be better to say:

	The treatment of values with incorrect syntax is
	defined by the server implementation. Administrators
	should be aware that servers may treat such values as
	clear-text passwords, thus removing the benefit of
	hashing entirely. Values using storage schemes not
	known to the server may have the same effect.

Andrew

---

From: Howard Chu <[email-masked]>
Date: Fri, 15 Mar 2013 06:18:05 -0700

> Another use-cases is dealing with data migration to server product of another

In which case the Admin must look up the documentation of the other vendor's 
product. It is not the IETF's job to serve as a clearinghouse for all 
vendor-specific implementation details, nor is it practical in the long run.

> That's simply your personal opinion not a strong objecting argument.

You're obviously missing the bigger picture then. I shouldn't need to remind 
you of all the trouble that "MUST member" has caused. In this case, deleting a 
userPassword is a straightforward way of disabling authentication for an 
account. If your schema prevents this mechanism your schema is broken. That's 
not an opinion, that's fact.

> password and salt used by any server I saw using the scheme.

You can describe those things separately, but this is as far as you should go 
with a formal syntax. Otherwise you will get sucked into the rathole of 
defining special cases for every currently known encoding, and you've already 
stated that you want to avoid that. So no, it's a logical conclusion from 
*your* opinion, not mine.

> This draft does not claim to cover everything you could ever stuff into

But defining a formal syntax as you're doing *does* exactly that. Which is why 
I'm telling you you're making a mistake.

---

From: Michael Ströder <[email-masked]>
Date: Fri, 15 Mar 2013 23:08:15 +0100

> effectively become clear-text passwords. Not a good failure

I know that this sounds kinda problematic but what is the actual risk?
The risk depends on how predictable the incorrect value is.

It would be good to know how the various server implementors handle this.

Also see this in the context with the paragraph following the above citation:

   Servers MAY provide local configuration items to limit the set of
   hash schemes to be processed and for completely disabling use of
   clear-text passwords in attribute 'userPassword'.

The "MAY provide" here sounds too weak from a security perspective but using
SHOULD would be too strong. Maybe it could be replaced by a lower-cased
"should consider to provide".

> status of the document.

Agreed.

> From a security perspective I would

The condition "does not have correct syntax" cannot be resolved because the
syntax definition starts with:

   userpasswordvalue = cleartext-password / ( prefix hashed-password )

> 	known to the server may have the same effect.

That's better.
But I'm not sure whether administrator is a usual term in this type of documents.

Ciao, Michael.

---

From: Michael Ströder <[email-masked]>
Date: Fri, 15 Mar 2013 23:44:37 +0100

Howard Chu wrote:
> product.

Yes. But it's so much easier to ask a vendor whether the userPassword syntax
adheres to some of the variants described in this document. Actually according
to your statement above it's a pretty good example why such a document is needed.

> You're obviously missing the bigger picture then.

I don't. But this document is not about schema design anyway.

> I shouldn't need to remind
> you of all the trouble that "MUST member" has caused.

Ok, let's go for this example...

I remember Kurt pointing out one use-case for "MUST member" during discussion
about draft-findlay-ldap-groupofentries:
You can check whether 'member' is empty or whether access was prohibited by ACLs.

Not that I'm *personally* in favour of such a use-case (up to now). But
another deployer could have good reasons to want that and it was good to read
Kurt's hint about something I personally did not think about before. Or maybe
even I personally might have such a use-case in the future.

So stating that "MUST userPassword" is broken in any case for every deployment
is pretty presumptuous.

> In this case, deleting a userPassword is a straightforward way of disabling
> authentication for an account.

It's one possibility to do it.
It's not the variant I prefer though.

And also normal user accounts for humans are not the only user accounts to
consider.

> If your schema prevents this mechanism your schema is broken. That's

I strongly disagree for various reasons we should discuss in another thread if
you really want.

> I'm telling you you're making a mistake.

This draft does not claim that the formal syntax specified therein is the only
possible syntax for 'userPassword' ever used.

If you suggest wording to make that more clear I'd of course consider it to be
added.

Ciao, Michael.

---

From: Hallvard Breien Furuseth <[email-masked]>
Date: Sat, 16 Mar 2013 04:54:22 +0100

I'm not convinced that this much detail is useful, but anyway:

You can document existing practice and recommend what implementations'
practice ought to be, but should say that the implementation's doc is
authoritative.  What implementations have you surveyed for that
existing practice?

If we generate 'userPassword's which this document says is OK but the
implementation does not support, then Bind can break in interesting
ways.  So users MUST NOT trust this document if the implementation
differs, which they must read the implementation doc to discover.

E.g. some implementation might have a scheme {SSHA} with a different
syntax like <hash "$" salt>.  Or:

>   Implementations MUST be prepared of handling field salt of arbitrary
>   length.

Who wants megabyte-sized salts?  It seems reasonable for the
implementation to set some arbitrary limit.  Both for convenience
and because you could do a DoS attack by setting a huge salt and
repeatedly Bind, forcing the server to hash a large value often.

================

Unix crypt(3):

This is a function, not a library.  Drop the 3 since non-Unix people
will wonder why we're passing 3 to the function.

The definition should boil down to "whatever crypt() returns on this
host", which is no more yucky than the notes above other schemes:-)
Perhaps less so since there's no point in giving a syntax, crypt()
should be used to both generate the hash and verify a password.

Please and add a reference to the quite general definition in the
Single Unix Specification at <http://www.unix.org/online.html>
functions/crypt.html.  It's free, but you must register to read it.

================

An EXAMPLES section with the same value and hash in different schemes
would be useful - including Linux {crypt}$1$ (salted MD5) and {SMD5}.

================

>>    clear-text password (...)
>

Umm... The reason we use hashes at all is that if someone knows the
attribute value, he can't just type it in and Bind with it.

Please add the {CLEARTEXT} scheme from OpenLDAP for this purpose.
RECOMMEND that servers are configured to not recognize userPassword
values without a scheme.  And maybe that this config is the default.

================

>> There's no reason someone can't come along and use an unconstrained
>> octet string after the scheme, if they really want to.
>
> Yes. But this would just be another scheme to be defined somewhere
> else.  This draft does not claim to cover everything you could ever
> stuff into 'userPassword'.

Yes it does.  The sentence
   "userPassword values MUST be represented by following syntax:"
claims to cover everything you could ever stuff into 'userPassword',
and thus that anything using different userPassword syntax is invalid.
That is wrong for schemes like {CRYPT} with different syntax, and
for servers which treat "{scheme}foo" as a cleartext password.

Instead you can say:
- Generally, syntax "{" scheme "}" scheme-parameters / cleartext pw
  like someone said.  Leave scheme-parameters unspecified.
- [The following listed schemes] share [the following more specific
  scheme-parameters definition].

Note that scheme-parameters need not involve a hashing or a password.
In OpenLDAP, {CLEARTEXT} does not hash.  I think {SASL} need not
encode the password either, just tell SASL where to find auth info.

================

The draft can RECOMMEND that clients avoid needing to know anything
about password formats by using the Password Modify operation (RFC
3062) when feasible.

Provided the server will then hash the password if it is stored in
userPassword, anyway.  Which it hopefully will.  But RFC 3062 says
nothing about hashing in that case.  Should it be updated to do so?

Use cases at our site for generating {scheme}hash:
- Importing user info including userPassword from the SQL user
  database - which does not keep the cleartext passwords.
- Multiple passwords in one entry, typically during the transition
  when changing the password for an LDAP service DN.

MUST userPassword in an object class may be broken, but RFC 1274
defines simpleSecurityObject (AUXILIARY MUST userPassword) anyway.
For use with classes like 'account' which lack userPassword.  Might
be about time to define simpleSecurityObject2 using 'MAY' instead.

-- 
Hallvard