#include "bcrypt.js.h" #include "ow-crypt.h" #include "quickjs.h" #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength); #else #include #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; }