Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-13 Thread Ted Unangst
Michal Mazurek wrote:
> On 15:31:50, 10.06.17, Ted Unangst wrote:
> > > @@ -58,17 +58,29 @@ The provided
> > >  .Fa password
> > >  is randomly salted and hashed and stored in
> > >  .Fa hash .
> > > +.Fa hash
> > > +must already be allocated, and
> > > +.Fa hashsize
> > > +must contain its size, which cannot be less than 61 bytes.
> > 
> > that's an implementation detail. if we're advising a limit, i think we
> > should say 128 or so.
> 
> How come? Tracing the code of crypt_newhash() we end up in
> bcrypt_hashpass(), which has the following check:
> 
> if (encryptedlen < BCRYPT_HASHSPACE)
>   goto inval;
> 
> BCRYPT_HASHSPACE is defined thus:
> libc/crypt/bcrypt.c:#define   BCRYPT_HASHSPACE61

Part of the design criteria for the crypt_newhash function is that it support
other hashes as well. We happen to only support bcrypt (and that's unlikely to
change) but there's no reason to hardcode that assumption into an interface
designed to abstract away such concerns.

PASS_MAX (_PASSWORD_LEN) is 128, though it suffers from nul not included
disease, so I don't know if we want to specify the limit in terms of that
constant. In practice, however, if you look at encrypt/encrypt.c it uses
char buffer[_PASSWORD_LEN];

which is missing the nul, but nevertheless 128. passwd does the same.

so we can use the constant, or just say 128.



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-13 Thread Michal Mazurek
On 15:31:50, 10.06.17, Ted Unangst wrote:
> > @@ -58,17 +58,29 @@ The provided
> >  .Fa password
> >  is randomly salted and hashed and stored in
> >  .Fa hash .
> > +.Fa hash
> > +must already be allocated, and
> > +.Fa hashsize
> > +must contain its size, which cannot be less than 61 bytes.
> 
> that's an implementation detail. if we're advising a limit, i think we
> should say 128 or so.

How come? Tracing the code of crypt_newhash() we end up in
bcrypt_hashpass(), which has the following check:

if (encryptedlen < BCRYPT_HASHSPACE)
goto inval;

BCRYPT_HASHSPACE is defined thus:
libc/crypt/bcrypt.c:#define   BCRYPT_HASHSPACE61

-- 
Michal Mazurek



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-10 Thread Ted Unangst
Michal Mazurek wrote:
> When talking about this with mulander@ it came out that the docs could
> use a touch.
> 
> The commit message for the diff that didn't update the docs was:
> 
> permit "bcrypt" as an alias for "blowfish". this is, after all, what
> 99% of the world calls it.
> allow just "bcrypt" without params to mean auto-tune ("bcrypt,a").
> default remains 8 rounds (for now)
> 
> Comments? OK?
> 
> Index: lib/libc/crypt/crypt_checkpass.3
> ===
> RCS file: /cvs/src/lib/libc/crypt/crypt_checkpass.3,v
> retrieving revision 1.9
> diff -u -p -r1.9 crypt_checkpass.3
> --- lib/libc/crypt/crypt_checkpass.3  23 Jul 2015 22:20:02 -  1.9
> +++ lib/libc/crypt/crypt_checkpass.3  6 Jun 2017 19:06:59 -
> @@ -58,17 +58,29 @@ The provided
>  .Fa password
>  is randomly salted and hashed and stored in
>  .Fa hash .
> +.Fa hash
> +must already be allocated, and
> +.Fa hashsize
> +must contain its size, which cannot be less than 61 bytes.

that's an implementation detail. if we're advising a limit, i think we
should say 128 or so.

i think the rest is fine.



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-10 Thread Michal Mazurek
On 21:16:08,  6.06.17, Michal Mazurek wrote:
> When talking about this with mulander@ it came out that the docs could
> use a touch.
> 
> The commit message for the diff that didn't update the docs was:
> 
> permit "bcrypt" as an alias for "blowfish". this is, after all, what
> 99% of the world calls it.
> allow just "bcrypt" without params to mean auto-tune ("bcrypt,a").
> default remains 8 rounds (for now)
> 
> Comments? OK?

Discussion about the defaults aside, any comments on the doc change? OK?

-- 
Michal Mazurek



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-07 Thread Ted Unangst
Michal Mazurek wrote:
> Yes, the function seems a bit inconsistent, in that "bcrypt" means "bcrypt,a"
> but NULL means "bcrypt,8". awolk@ points out that the function is used in
> just a few places - src and some ports patches, so we should be able to
> change it. Judging by the commit message the author was aware of this
> discrepancy though, and marked is as "for now", so let's see what others say.

this was complicated because it's trying to unify several different programs
and everybody has their own idea of what the default should be. so it tries to
squeeze in some useful behaviors without changing everything about how all the
calling programs behave. at least now we're in a situation where we should be
able to discuss changing one program at a time. 



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-07 Thread Adam Wolk
On Tue, Jun 06, 2017 at 08:29:23PM +, Florian Obser wrote:
> On Tue, Jun 06, 2017 at 08:49:32PM +0200, Adam Wolk wrote:
> > On Tue, Jun 06, 2017 at 12:28:59PM -0600, Theo de Raadt wrote:
> > > > The only thing against using automatic rounds would be having them 
> > > > guessed on a
> > > > weaker machine and used on a more powerful server - doubt though that 
> > > > would ever
> > > > pick something below 8 rounds.
> > > 
> > > I don't see the concern.  It has a lower bound.
> > 
> > Attaching the diff with rounds changed to auto, results with 9 rounds on my 
> > server.
> > 
> 
> OK florian@
> 

Committed, thanks!



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Theo de Raadt
> On 20:49:05,  6.06.17, Jason McIntyre wrote:
> > right now this man page suggests that people will use "bcrypt,a"
> > to "automatically suggest rounds based on system performance". is
> > that right? i'd have expected people to just use "bcrypt" (w/o
> > args).

Because you can't change everything in one step.  Seriously, feel free
to pull on this string, and test all the cases.

> > in fact, why have "a" at all? why not just have the default
> > as automatically selecting rounds, but you can optionally specify
> > an amount of rounds?

Waiting for a volunteer who understands the impact.

> > sorry, i know that's not really the main concern of your diff. it just
> > seems a bit weird, and that reflects in the way you're having to word
> > this.
> 
> Yes, the function seems a bit inconsistent, in that "bcrypt" means "bcrypt,a"
> but NULL means "bcrypt,8". awolk@ points out that the function is used in
> just a few places - src and some ports patches, so we should be able to
> change it. Judging by the commit message the author was aware of this
> discrepancy though, and marked is as "for now", so let's see what others say.

Yes, let's change everything at once.

Did you test what you propose?  Your mail seems to be coming in before
you could have changed it, done a full build, and a study.  Am I correct?



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Florian Obser
On Tue, Jun 06, 2017 at 08:49:32PM +0200, Adam Wolk wrote:
> On Tue, Jun 06, 2017 at 12:28:59PM -0600, Theo de Raadt wrote:
> > > The only thing against using automatic rounds would be having them 
> > > guessed on a
> > > weaker machine and used on a more powerful server - doubt though that 
> > > would ever
> > > pick something below 8 rounds.
> > 
> > I don't see the concern.  It has a lower bound.
> 
> Attaching the diff with rounds changed to auto, results with 9 rounds on my 
> server.
> 

OK florian@

> ? htpasswd
> Index: htpasswd.c
> ===
> RCS file: /cvs/src/usr.bin/htpasswd/htpasswd.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 htpasswd.c
> --- htpasswd.c5 Nov 2015 20:07:15 -   1.15
> +++ htpasswd.c6 Jun 2017 18:46:39 -
> @@ -47,7 +47,7 @@ int nagcount;
>  int
>  main(int argc, char** argv)
>  {
> - char salt[_PASSWORD_LEN], tmpl[sizeof("/tmp/htpasswd-XX")];
> + char tmpl[sizeof("/tmp/htpasswd-XX")];
>   char hash[_PASSWORD_LEN], pass[1024], pass2[1024];
>   char *line = NULL, *login = NULL, *tok;
>   int c, fd, loginlen, batch = 0;
> @@ -133,10 +133,8 @@ main(int argc, char** argv)
>   explicit_bzero(pass2, sizeof(pass2));
>   }
>  
> - if (strlcpy(salt, bcrypt_gensalt(8), sizeof(salt)) >= sizeof(salt))
> - errx(1, "salt too long");
> - if (strlcpy(hash, bcrypt(pass, salt), sizeof(hash)) >= sizeof(hash))
> - errx(1, "hash too long");
> + if (crypt_newhash(pass, "bcrypt,a", hash, sizeof(hash)) != 0)
> + err(1, "can't generate hash");
>   explicit_bzero(pass, sizeof(pass));
>  
>   if (file == NULL)


-- 
I'm not entirely sure you are real.



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Michal Mazurek
On 20:49:05,  6.06.17, Jason McIntyre wrote:
> right now this man page suggests that people will use "bcrypt,a"
> to "automatically suggest rounds based on system performance". is
> that right? i'd have expected people to just use "bcrypt" (w/o
> args). in fact, why have "a" at all? why not just have the default
> as automatically selecting rounds, but you can optionally specify
> an amount of rounds?
> 
> sorry, i know that's not really the main concern of your diff. it just
> seems a bit weird, and that reflects in the way you're having to word
> this.

Yes, the function seems a bit inconsistent, in that "bcrypt" means "bcrypt,a"
but NULL means "bcrypt,8". awolk@ points out that the function is used in
just a few places - src and some ports patches, so we should be able to
change it. Judging by the commit message the author was aware of this
discrepancy though, and marked is as "for now", so let's see what others say.

-- 
Michal Mazurek



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Jason McIntyre
On Tue, Jun 06, 2017 at 09:16:08PM +0200, Michal Mazurek wrote:
> When talking about this with mulander@ it came out that the docs could
> use a touch.
> 
> The commit message for the diff that didn't update the docs was:
> 
> permit "bcrypt" as an alias for "blowfish". this is, after all, what
> 99% of the world calls it.
> allow just "bcrypt" without params to mean auto-tune ("bcrypt,a").
> default remains 8 rounds (for now)
> 
> Comments? OK?
> 

the diff itself reads fine. one question:

> Index: lib/libc/crypt/crypt_checkpass.3
> ===
> RCS file: /cvs/src/lib/libc/crypt/crypt_checkpass.3,v
> retrieving revision 1.9
> diff -u -p -r1.9 crypt_checkpass.3
> --- lib/libc/crypt/crypt_checkpass.3  23 Jul 2015 22:20:02 -  1.9
> +++ lib/libc/crypt/crypt_checkpass.3  6 Jun 2017 19:06:59 -
> @@ -58,17 +58,29 @@ The provided
>  .Fa password
>  is randomly salted and hashed and stored in
>  .Fa hash .
> +.Fa hash
> +must already be allocated, and
> +.Fa hashsize
> +must contain its size, which cannot be less than 61 bytes.
>  The
>  .Fa pref
>  argument identifies the preferred hashing algorithm and parameters.
> +If set to
> +.Dv NULL
> +it defaults to 
> +.Dq bcrypt,8 .
>  Possible values are:
>  .Bl -tag -width Ds
> -.It Dq bcrypt,
> +.It Dq bcrypt[,]
>  The bcrypt algorithm, where the value of rounds can be between 4 and 31 and
>  specifies the base 2 logarithm of the number of rounds.
>  The special rounds value
>  .Sq a
>  automatically selects rounds based on system performance.
> +This is the default if rounds is omitted.

right now this man page suggests that people will use "bcrypt,a"
to "automatically suggest rounds based on system performance". is
that right? i'd have expected people to just use "bcrypt" (w/o
args). in fact, why have "a" at all? why not just have the default
as automatically selecting rounds, but you can optionally specify
an amount of rounds?

sorry, i know that's not really the main concern of your diff. it just
seems a bit weird, and that reflects in the way you're having to word
this.

jmc

> +.Dq blowfish
> +can be used as an alias for
> +.Dq bcrypt .
>  .El
>  .Sh RETURN VALUES
>  .Rv -std crypt_checkpass crypt_newhash
> @@ -89,7 +101,9 @@ to
>  .Er EINVAL
>  if
>  .Fa pref
> -is unsupported.
> +is unsupported, or the value of 
> +.Fa hashsize
> +is insufficient.
>  .Sh SEE ALSO
>  .Xr crypt 3 ,
>  .Xr login.conf 5 ,
> 
> -- 
> Michal Mazurek
> 



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Michal Mazurek
When talking about this with mulander@ it came out that the docs could
use a touch.

The commit message for the diff that didn't update the docs was:

permit "bcrypt" as an alias for "blowfish". this is, after all, what
99% of the world calls it.
allow just "bcrypt" without params to mean auto-tune ("bcrypt,a").
default remains 8 rounds (for now)

Comments? OK?

Index: lib/libc/crypt/crypt_checkpass.3
===
RCS file: /cvs/src/lib/libc/crypt/crypt_checkpass.3,v
retrieving revision 1.9
diff -u -p -r1.9 crypt_checkpass.3
--- lib/libc/crypt/crypt_checkpass.323 Jul 2015 22:20:02 -  1.9
+++ lib/libc/crypt/crypt_checkpass.36 Jun 2017 19:06:59 -
@@ -58,17 +58,29 @@ The provided
 .Fa password
 is randomly salted and hashed and stored in
 .Fa hash .
+.Fa hash
+must already be allocated, and
+.Fa hashsize
+must contain its size, which cannot be less than 61 bytes.
 The
 .Fa pref
 argument identifies the preferred hashing algorithm and parameters.
+If set to
+.Dv NULL
+it defaults to 
+.Dq bcrypt,8 .
 Possible values are:
 .Bl -tag -width Ds
-.It Dq bcrypt,
+.It Dq bcrypt[,]
 The bcrypt algorithm, where the value of rounds can be between 4 and 31 and
 specifies the base 2 logarithm of the number of rounds.
 The special rounds value
 .Sq a
 automatically selects rounds based on system performance.
+This is the default if rounds is omitted.
+.Dq blowfish
+can be used as an alias for
+.Dq bcrypt .
 .El
 .Sh RETURN VALUES
 .Rv -std crypt_checkpass crypt_newhash
@@ -89,7 +101,9 @@ to
 .Er EINVAL
 if
 .Fa pref
-is unsupported.
+is unsupported, or the value of 
+.Fa hashsize
+is insufficient.
 .Sh SEE ALSO
 .Xr crypt 3 ,
 .Xr login.conf 5 ,

-- 
Michal Mazurek



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Adam Wolk
On Tue, Jun 06, 2017 at 12:28:59PM -0600, Theo de Raadt wrote:
> > The only thing against using automatic rounds would be having them guessed 
> > on a
> > weaker machine and used on a more powerful server - doubt though that would 
> > ever
> > pick something below 8 rounds.
> 
> I don't see the concern.  It has a lower bound.

Attaching the diff with rounds changed to auto, results with 9 rounds on my 
server.

? htpasswd
Index: htpasswd.c
===
RCS file: /cvs/src/usr.bin/htpasswd/htpasswd.c,v
retrieving revision 1.15
diff -u -p -r1.15 htpasswd.c
--- htpasswd.c  5 Nov 2015 20:07:15 -   1.15
+++ htpasswd.c  6 Jun 2017 18:46:39 -
@@ -47,7 +47,7 @@ int nagcount;
 int
 main(int argc, char** argv)
 {
-   char salt[_PASSWORD_LEN], tmpl[sizeof("/tmp/htpasswd-XX")];
+   char tmpl[sizeof("/tmp/htpasswd-XX")];
char hash[_PASSWORD_LEN], pass[1024], pass2[1024];
char *line = NULL, *login = NULL, *tok;
int c, fd, loginlen, batch = 0;
@@ -133,10 +133,8 @@ main(int argc, char** argv)
explicit_bzero(pass2, sizeof(pass2));
}
 
-   if (strlcpy(salt, bcrypt_gensalt(8), sizeof(salt)) >= sizeof(salt))
-   errx(1, "salt too long");
-   if (strlcpy(hash, bcrypt(pass, salt), sizeof(hash)) >= sizeof(hash))
-   errx(1, "hash too long");
+   if (crypt_newhash(pass, "bcrypt,a", hash, sizeof(hash)) != 0)
+   err(1, "can't generate hash");
explicit_bzero(pass, sizeof(pass));
 
if (file == NULL)


Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Theo de Raadt
> The only thing against using automatic rounds would be having them guessed on 
> a
> weaker machine and used on a more powerful server - doubt though that would 
> ever
> pick something below 8 rounds.

I don't see the concern.  It has a lower bound.



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Adam Wolk
On Tue, Jun 06, 2017 at 02:20:38PM -0400, Bryan Steele wrote:
> >  
> > -   if (strlcpy(salt, bcrypt_gensalt(8), sizeof(salt)) >= sizeof(salt))
> > -   errx(1, "salt too long");
> > -   if (strlcpy(hash, bcrypt(pass, salt), sizeof(hash)) >= sizeof(hash))
> > -   errx(1, "hash too long");
> > +   if (crypt_newhash(pass, "bcrypt,8", hash, sizeof(hash)) != 0)
> > +   err(1, "can't generate hash");
> > explicit_bzero(pass, sizeof(pass));
> >  
> > if (file == NULL)
> 
> It should be possible to use the automatic rouds, i.e: "bcrypt,a" instead
> of just hardcoding 8.
> 

I wasn't sure about introducing that change, went the minimal changes from
existing behavior.

The only thing against using automatic rounds would be having them guessed on a
weaker machine and used on a more powerful server - doubt though that would ever
pick something below 8 rounds.

Roughly, if the general consensus is to move to automatic rounds then I'm all
for it.

Side note, does anyone know why crypt_newhash defaults to blowfish? The
docs don't mention it.



Re: htpasswd: use crypt_newhash instead of bcrypt API

2017-06-06 Thread Bryan Steele
On Tue, Jun 06, 2017 at 07:43:02PM +0200, Adam Wolk wrote:
> Hi tech@
> 
> While reading htpasswd and htpasswd handling in httpd I noticed that both use
> different APIs to handle encrypting/decrypting the passwords.
> 
> - htpasswd uses the bcrypt API
> - httpd uses the new crypt API
> 
> The documentation for bcrypt states:
>  These functions are deprecated in favor of crypt_checkpass(3) and
>  crypt_newhash(3).
> 
> I'm attaching a diff moving htpasswd to the new API. Tested with httpd from
> 6.1 with a htpasswd generated with the diff applied on current.
> 
> Feedback? OK's?
> 
> Regards,
> Adam

> ? htpasswd
> Index: htpasswd.c
> ===
> RCS file: /cvs/src/usr.bin/htpasswd/htpasswd.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 htpasswd.c
> --- htpasswd.c5 Nov 2015 20:07:15 -   1.15
> +++ htpasswd.c6 Jun 2017 17:26:31 -
> @@ -47,7 +47,7 @@ int nagcount;
>  int
>  main(int argc, char** argv)
>  {
> - char salt[_PASSWORD_LEN], tmpl[sizeof("/tmp/htpasswd-XX")];
> + char tmpl[sizeof("/tmp/htpasswd-XX")];
>   char hash[_PASSWORD_LEN], pass[1024], pass2[1024];
>   char *line = NULL, *login = NULL, *tok;
>   int c, fd, loginlen, batch = 0;
> @@ -133,10 +133,8 @@ main(int argc, char** argv)
>   explicit_bzero(pass2, sizeof(pass2));
>   }
>  
> - if (strlcpy(salt, bcrypt_gensalt(8), sizeof(salt)) >= sizeof(salt))
> - errx(1, "salt too long");
> - if (strlcpy(hash, bcrypt(pass, salt), sizeof(hash)) >= sizeof(hash))
> - errx(1, "hash too long");
> + if (crypt_newhash(pass, "bcrypt,8", hash, sizeof(hash)) != 0)
> + err(1, "can't generate hash");
>   explicit_bzero(pass, sizeof(pass));
>  
>   if (file == NULL)

It should be possible to use the automatic rouds, i.e: "bcrypt,a" instead
of just hardcoding 8.