commit 829e07c7a24fed5657bad3c8e68b92ddd06264e5
parent 7bdd269314659865bd53083666c6c20f18b6d5b1
Author: Michael Savage <mikejsavage@gmail.com>
Date: Tue, 25 Feb 2014 14:20:57 +0000
Check crypt_rn/crypt_gensalt_rn errors and improve interface
bcrypt.* calls will now error appropriately if their receive bad inputs.
bcrypt.digest can now be used with a rounds parameter instead of a salt.
Diffstat:
README.md | | | 13 | +++++++++++-- |
src/main.c | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
2 files changed, 64 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
@@ -11,8 +11,17 @@ Usage
-----
local bcrypt = require( "bcrypt" )
+ local rounds = 5 -- tune this as appropriate
+
+ local digest = bcrypt.digest( "password", rounds )
+ assert( bcrypt.verify( "password", digest ) )
- local salt = bcrypt.salt( 5 )
- local digest = bcrypt.digest( "password", salt )
+You can also explicitly pass a salt to `bcrypt.digest`:
+ local bcrypt = require( "bcrypt" )
+ local rounds = 5 -- tune this as appropriate
+
+ local salt = bcrypt.salt( rounds )
+ local digest = bcrypt.digest( "password", salt )
+
assert( bcrypt.verify( "password", digest ) )
diff --git a/src/main.c b/src/main.c
@@ -10,8 +10,8 @@
#include "ow-crypt.h"
-#define HASH_SIZE 184
-#define SALT_SIZE 128
+#define CRYPT_OUTPUT_SIZE ( 7 + 22 + 31 + 1 )
+#define CRYPT_GENSALT_OUTPUT_SIZE ( 7 + 22 + 1 )
#define ENTROPY_SIZE 32
#if LUA_VERSION_NUM < 502
@@ -20,38 +20,75 @@
static int urandom;
-// bcrypt.digest( key, salt )
+static int makesalt( char * const salt, const size_t size, const int rounds ) {
+ char entropy[ ENTROPY_SIZE ];
+ const ssize_t bytes = read( urandom, entropy, sizeof( entropy ) );
+
+ if( bytes != sizeof( entropy ) ) {
+ return 1;
+ }
+
+ const char * const ok = crypt_gensalt_rn( "$2y$", rounds, entropy, sizeof( entropy ), salt, size );
+
+ if( ok == NULL ) {
+ return 1;
+ }
+
+ return 0;
+}
+
+// bcrypt.digest( key, [salt/rounds] )
static int luabcrypt_digest( lua_State * const L ) {
const char * const key = luaL_checkstring( L, 1 );
- const char * const salt = luaL_checkstring( L, 2 );
+ const long rounds = lua_tointeger( L, 2 );
- char hash[ HASH_SIZE ];
+ char hash[ CRYPT_OUTPUT_SIZE ];
memset( hash, 0, sizeof( hash ) );
- crypt_rn( key, salt, hash, sizeof( hash ) );
+ char newsalt[ CRYPT_GENSALT_OUTPUT_SIZE ];
+ const char * salt = NULL;
+
+ if( rounds != 0 ) {
+ int rv_salt = makesalt( newsalt, sizeof( newsalt ), rounds );
+
+ if( rv_salt != 0 ) {
+ lua_pushstring( L, strerror( errno ) );
+
+ return lua_error( L );
+ }
+
+ salt = newsalt;
+ }
+ else {
+ salt = luaL_checkstring( L, 2 );
+ }
+
+ const char * const rv_crypt = crypt_rn( key, salt, hash, sizeof( hash ) );
+
+ if( rv_crypt == NULL ) {
+ lua_pushstring( L, strerror( errno ) );
+
+ return lua_error( L );
+ }
lua_pushstring( L, hash );
return 1;
}
-// bcrypt.salt( logRounds )
+// bcrypt.salt( rounds )
static int luabcrypt_salt( lua_State * const L ) {
- const unsigned long logRounds = luaL_checkinteger( L, 1 );
+ const unsigned long rounds = luaL_checkinteger( L, 1 );
- char entropy[ ENTROPY_SIZE ];
- char salt[ SALT_SIZE ];
+ char salt[ CRYPT_GENSALT_OUTPUT_SIZE ];
+ int rv = makesalt( salt, sizeof( salt ), rounds );
- const ssize_t bytes = read( urandom, entropy, sizeof( entropy ) );
-
- if( bytes != sizeof( entropy ) ) {
+ if( rv != 0 ) {
lua_pushstring( L, strerror( errno ) );
return lua_error( L );
}
- crypt_gensalt_rn( "$2y$", logRounds, entropy, sizeof( entropy ), salt, sizeof( salt ) );
-
lua_pushstring( L, salt );
return 1;
@@ -62,7 +99,7 @@ static int luabcrypt_verify( lua_State * const L ) {
const char * const key = luaL_checkstring( L, 1 );
const char * const digest = luaL_checkstring( L, 2 );
- char hash[ HASH_SIZE ];
+ char hash[ CRYPT_OUTPUT_SIZE ];
memset( hash, 0, sizeof( hash ) );
crypt_rn( key, digest, hash, sizeof( hash ) );