Merge branch 'jc-thread-safe-bcrypt'
diff --git a/c_src/bcrypt.c b/c_src/bcrypt.c
index 13635d0..dbc9571 100644
--- a/c_src/bcrypt.c
+++ b/c_src/bcrypt.c
@@ -63,14 +63,13 @@
#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
-char *bcrypt(const char *, const char *);
+int bcrypt(char *, const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
-static char encrypted[_PASSWORD_LEN];
-static char error[] = ":";
+#define ERROR -1
const static u_int8_t Base64Code[] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -143,8 +142,8 @@
/* We handle $Vers$log2(NumRounds)$salt+passwd$
i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
-char *
-bcrypt(const char *key, const char *salt)
+int
+bcrypt(char * encrypted, const char *key, const char *salt)
{
blf_ctx state;
u_int32_t rounds, i, k;
@@ -160,7 +159,7 @@
if (*salt > BCRYPT_VERSION) {
/* How do I handle errors ? Return ':' */
- return error;
+ return ERROR;
}
/* Check for minor versions */
@@ -172,7 +171,7 @@
salt++;
break;
default:
- return error;
+ return ERROR;
}
} else
minor = 0;
@@ -182,21 +181,21 @@
if (salt[2] != '$')
/* Out of sync with passwd entry */
- return error;
+ return ERROR;
/* Computer power doesn't increase linear, 2^x should be fine */
n = atoi(salt);
if (n > 31 || n < 0)
- return error;
+ return ERROR;
logr = (u_int8_t)n;
if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS)
- return error;
+ return ERROR;
/* Discard num rounds + "$" identifier */
salt += 3;
if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
- return error;
+ return ERROR;
/* We dont want the base64 salt but the raw data */
decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
@@ -248,7 +247,7 @@
memset(ciphertext, 0, sizeof(ciphertext));
memset(csalt, 0, sizeof(csalt));
memset(cdata, 0, sizeof(cdata));
- return encrypted;
+ return 0;
}
static void
diff --git a/c_src/bcrypt_nif.c b/c_src/bcrypt_nif.c
index b9e636d..b2f8adc 100644
--- a/c_src/bcrypt_nif.c
+++ b/c_src/bcrypt_nif.c
@@ -75,7 +75,7 @@
{
char password[1024] = { 0 };
char salt[1024] = { 0 };
- char *ret = NULL;
+ char encrypted[1024] = { 0 };
size_t password_sz = 1024;
if (password_sz > task->data.hash.password.size)
@@ -87,7 +87,7 @@
salt_sz = task->data.hash.salt.size;
(void)memcpy(&salt, task->data.hash.salt.data, salt_sz);
- if (NULL == (ret = bcrypt(password, salt)) || 0 == strcmp(ret, ":")) {
+ if (bcrypt(encrypted, password, salt)) {
return enif_make_tuple3(
task->env,
enif_make_atom(task->env, "error"),
@@ -99,7 +99,7 @@
task->env,
enif_make_atom(task->env, "ok"),
task->ref,
- enif_make_string(task->env, ret, ERL_NIF_LATIN1));
+ enif_make_string(task->env, encrypted, ERL_NIF_LATIN1));
}
void* async_worker(void* arg)
diff --git a/c_src/bcrypt_nif.h b/c_src/bcrypt_nif.h
index 5d513cb..7326cb5 100644
--- a/c_src/bcrypt_nif.h
+++ b/c_src/bcrypt_nif.h
@@ -5,7 +5,7 @@
typedef unsigned char byte;
-char *bcrypt(const char *, const char *);
+int bcrypt(char *, const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
typedef struct {
diff --git a/c_src/bcrypt_port.c b/c_src/bcrypt_port.c
index 9abc013..d2f7421 100644
--- a/c_src/bcrypt_port.c
+++ b/c_src/bcrypt_port.c
@@ -35,7 +35,7 @@
typedef unsigned char byte;
-char *bcrypt(const char *, const char *);
+char *bcrypt(char *, const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
/* These methods came from the Erlang port command tutorial:
@@ -72,7 +72,7 @@
static int
write_buf(int fd, byte *buf, int len)
{
- int i, done = 0;
+ int i, done = 0;
do {
if ((i = write(fd, buf+done, len-done)) < 0) {
if (errno != EINTR)
@@ -150,7 +150,7 @@
ETERM *pattern, *pwd, *slt, *pwd_bin, *slt_bin;
char password[1024];
char salt[1024];
- char *ret = NULL;
+ char encrypted[1024] = { 0 };
(void)memset(&password, '\0', sizeof(password));
(void)memset(&salt, '\0', sizeof(salt));
@@ -168,11 +168,10 @@
} else {
memcpy(password, ERL_BIN_PTR(pwd_bin), ERL_BIN_SIZE(pwd_bin));
memcpy(salt, ERL_BIN_PTR(slt_bin), ERL_BIN_SIZE(slt_bin));
- if (NULL == (ret = bcrypt(password, salt)) ||
- 0 == strcmp(ret, ":")) {
+ if (bcrypt(encrypted, password, salt)) {
retval = process_reply(pid, CMD_HASHPW, "Invalid salt");
} else {
- retval = process_reply(pid, CMD_HASHPW, ret);
+ retval = process_reply(pid, CMD_HASHPW, encrypted);
}
}
erl_free_term(pwd);