tildefriends/src/bcrypt.js.c

61 lines
1.9 KiB
C

#include "bcrypt.js.h"
#include "ow-crypt.h"
#include "quickjs.h"
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
#else
#include <sys/random.h>
#endif
JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
JSValue _crypt_gensalt(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
void tf_bcrypt_register(JSContext* context)
{
JSValue global = JS_GetGlobalObject(context);
JSValue bcrypt = JS_NewObject(context);
JS_SetPropertyStr(context, global, "bCrypt", bcrypt);
JS_SetPropertyStr(context, bcrypt, "hashpw", JS_NewCFunction(context, _crypt_hashpw, "hashpw", 2));
JS_SetPropertyStr(context, bcrypt, "gensalt", JS_NewCFunction(context, _crypt_gensalt, "gensalt", 1));
JS_FreeValue(context, global);
}
JSValue _crypt_hashpw(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
const char* key = JS_ToCString(context, argv[0]);
const char* salt = JS_ToCString(context, argv[1]);
char output[7 + 22 + 31 + 1];
char* hash = crypt_rn(key, salt, output, sizeof(output));
JSValue result = JS_NewString(context, hash);
JS_FreeCString(context, key);
JS_FreeCString(context, salt);
return result;
}
JSValue _crypt_gensalt(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
int length = 0;
JS_ToInt32(context, &length, argv[0]);
char buffer[16];
#if defined(_WIN32)
ssize_t bytes = SystemFunction036(buffer, sizeof(buffer)) ? sizeof(buffer) : 0;
#elif defined(__APPLE__)
ssize_t bytes = 0;
if (getentropy(buffer, sizeof(buffer)) == 0)
{
bytes = sizeof(buffer);
}
#else
ssize_t bytes = getrandom(buffer, sizeof(buffer), 0);
#endif
char output[7 + 22 + 1];
char* salt = crypt_gensalt_rn("$2b$", length, buffer, bytes, output, sizeof(output));
JSValue result = JS_NewString(context, salt);
return result;
}