|
|
@ -1080,7 +1080,7 @@ static JSValue _authenticate_jwt(JSContext* context, const char* jwt)
|
|
|
|
tf_task_t* task = tf_task_get(context);
|
|
|
|
tf_task_t* task = tf_task_get(context);
|
|
|
|
tf_ssb_t* ssb = tf_task_get_ssb(task);
|
|
|
|
tf_ssb_t* ssb = tf_task_get_ssb(task);
|
|
|
|
char public_key_b64[k_id_base64_len] = { 0 };
|
|
|
|
char public_key_b64[k_id_base64_len] = { 0 };
|
|
|
|
tf_ssb_db_identity_visit(ssb, ":auth", _public_key_visit, public_key_b64);
|
|
|
|
tf_ssb_db_identity_visit(ssb, ":admin", _public_key_visit, public_key_b64);
|
|
|
|
|
|
|
|
|
|
|
|
const char* payload = jwt + dot[0] + 1;
|
|
|
|
const char* payload = jwt + dot[0] + 1;
|
|
|
|
size_t payload_length = dot[1] - dot[0] - 1;
|
|
|
|
size_t payload_length = dot[1] - dot[0] - 1;
|
|
|
@ -1150,15 +1150,12 @@ static void _visit_auth_identity(const char* identity, void* user_data)
|
|
|
|
static bool _get_auth_private_key(tf_ssb_t* ssb, uint8_t* out_private_key)
|
|
|
|
static bool _get_auth_private_key(tf_ssb_t* ssb, uint8_t* out_private_key)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char id[k_id_base64_len] = { 0 };
|
|
|
|
char id[k_id_base64_len] = { 0 };
|
|
|
|
tf_ssb_db_identity_visit(ssb, ":auth", _visit_auth_identity, id);
|
|
|
|
tf_ssb_db_identity_visit(ssb, ":admin", _visit_auth_identity, id);
|
|
|
|
if (*id)
|
|
|
|
if (*id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return tf_ssb_db_identity_get_private_key(ssb, ":auth", id, out_private_key, crypto_sign_SECRETKEYBYTES);
|
|
|
|
return tf_ssb_db_identity_get_private_key(ssb, ":admin", id, out_private_key, crypto_sign_SECRETKEYBYTES);
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return tf_ssb_db_identity_create(ssb, ":auth", out_private_key + crypto_sign_PUBLICKEYBYTES, out_private_key);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|
|
|
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|
|
@ -1167,21 +1164,15 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
|
|
|
|
|
|
|
|
if (!_get_auth_private_key(ssb, private_key))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uv_timespec64_t now = { 0 };
|
|
|
|
uv_timespec64_t now = { 0 };
|
|
|
|
uv_clock_gettime(UV_CLOCK_REALTIME, &now);
|
|
|
|
uv_clock_gettime(UV_CLOCK_REALTIME, &now);
|
|
|
|
|
|
|
|
|
|
|
|
JSContext* context = tf_ssb_get_context(ssb);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* header_json = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
|
|
|
|
const char* header_json = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
|
|
|
|
char header_base64[256];
|
|
|
|
char header_base64[256];
|
|
|
|
sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
|
|
|
sodium_bin2base64(header_base64, sizeof(header_base64), (uint8_t*)header_json, strlen(header_json), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JSContext* context = tf_ssb_get_context(ssb);
|
|
|
|
JSValue payload = JS_NewObject(context);
|
|
|
|
JSValue payload = JS_NewObject(context);
|
|
|
|
JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name));
|
|
|
|
JS_SetPropertyStr(context, payload, "name", JS_NewString(context, name));
|
|
|
|
JS_SetPropertyStr(context, payload, "exp", JS_NewInt64(context, now.tv_sec * 1000 + now.tv_nsec / 1000000LL + k_refresh_interval));
|
|
|
|
JS_SetPropertyStr(context, payload, "exp", JS_NewInt64(context, now.tv_sec * 1000 + now.tv_nsec / 1000000LL + k_refresh_interval));
|
|
|
@ -1196,6 +1187,9 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|
|
|
unsigned long long signature_length = 0;
|
|
|
|
unsigned long long signature_length = 0;
|
|
|
|
char signature_base64[256] = { 0 };
|
|
|
|
char signature_base64[256] = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
|
|
|
|
|
|
|
|
if (_get_auth_private_key(ssb, private_key))
|
|
|
|
|
|
|
|
{
|
|
|
|
if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0)
|
|
|
|
if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
|
|
|
sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
|
|
@ -1203,6 +1197,8 @@ static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name)
|
|
|
|
result = tf_malloc(size);
|
|
|
|
result = tf_malloc(size);
|
|
|
|
snprintf(result, size, "%s.%s.%s", header_base64, payload_base64, signature_base64);
|
|
|
|
snprintf(result, size, "%s.%s.%s", header_base64, payload_base64, signature_base64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sodium_memzero(private_key, sizeof(private_key));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
JS_FreeCString(context, payload_string);
|
|
|
|
JS_FreeCString(context, payload_string);
|
|
|
|
JS_FreeValue(context, payload_json);
|
|
|
|
JS_FreeValue(context, payload_json);
|
|
|
|