diff --git a/src/lib/libc/crypt/crypt.3 b/src/lib/libc/crypt/crypt.3 index 95eb8c15..a1912f8a 100644 --- a/src/lib/libc/crypt/crypt.3 +++ b/src/lib/libc/crypt/crypt.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: crypt.3,v 1.38 2014/05/16 22:11:00 jmc Exp $ +.\" $OpenBSD: crypt.3,v 1.39 2014/11/17 16:47:28 tedu Exp $ .\" .\" FreeSec: libcrypt .\" @@ -31,7 +31,7 @@ .\" .\" Manual page, using -mandoc macros .\" -.Dd $Mdocdate: May 16 2014 $ +.Dd $Mdocdate: November 17 2014 $ .Dt CRYPT 3 .Os .Sh NAME @@ -55,6 +55,8 @@ .Ft int .Fn crypt_checkpass "const char *password" "const char *hash" .Ft int +.Fn crypt_newhash "const char *password" "login_cap_t *lc" "char *hash" "size_t hashsize" +.Ft int .Fn encrypt "char *block" "int flag" .Ft int .Fn des_setkey "const char *key" @@ -102,6 +104,19 @@ If the hash is NULL, authentication will always fail, but a default amount of work is performed to simulate the hashing operation. A successful match will return 0. A failure will return \-1 and set errno. +.Pp +The +.Fn crypt_newhash +function is provided to simplify the creation of new password hashes. +The provided +.Fa password +is randomly salted and hashed and stored in +.Fa hash . +The login class argument +.Fa lc +is used to identify the preferred hashing algorithm and parameters. +Refer to +.Xr login.conf 5 . .Ss Extended crypt The .Ar key diff --git a/src/lib/libc/crypt/cryptutil.c b/src/lib/libc/crypt/cryptutil.c index 36deda77..4a8c46be 100644 --- a/src/lib/libc/crypt/cryptutil.c +++ b/src/lib/libc/crypt/cryptutil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptutil.c,v 1.1 2014/05/12 19:13:14 tedu Exp $ */ +/* $OpenBSD: cryptutil.c,v 1.2 2014/11/17 16:47:28 tedu Exp $ */ /* * Copyright (c) 2014 Ted Unangst * @@ -18,6 +18,7 @@ #include #include #include +#include #include int @@ -52,3 +53,30 @@ fail: errno = EACCES; return -1; } + +int +crypt_newhash(const char *pass, login_cap_t *lc, char *hash, size_t hashlen) +{ + int rv = -1; + char *pref; + char *defaultpref = "blowfish,8"; + const char *errstr; + int rounds; + + if (lc == NULL || + (pref = login_getcapstr(lc, "localcipher", NULL, NULL)) == NULL) + pref = defaultpref; + if (strncmp(pref, "blowfish,", 9) != 0) { + errno = EINVAL; + goto err; + } + rounds = strtonum(pref + 9, 4, 31, &errstr); + if (errstr) + goto err; + rv = bcrypt_newhash(pass, rounds, hash, hashlen); + +err: + if (pref != defaultpref) + free(pref); + return rv; +}