Remove the :auth key. We can sign JWTs with :admin, and it's one less magic key.

This commit is contained in:
Cory McWilliams 2024-05-11 09:50:00 -04:00
parent 7d9b1b508b
commit 52962f3a5e
2 changed files with 16 additions and 20 deletions

View File

@ -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,12 +1187,17 @@ 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 };
if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0) uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
if (_get_auth_private_key(ssb, private_key))
{ {
sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING); if (crypto_sign_detached(signature, &signature_length, (const uint8_t*)payload_base64, strlen(payload_base64), private_key) == 0)
size_t size = strlen(header_base64) + 1 + strlen(payload_base64) + 1 + strlen(signature_base64) + 1; {
result = tf_malloc(size); sodium_bin2base64(signature_base64, sizeof(signature_base64), signature, sizeof(signature), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
snprintf(result, size, "%s.%s.%s", header_base64, payload_base64, signature_base64); size_t size = strlen(header_base64) + 1 + strlen(payload_base64) + 1 + strlen(signature_base64) + 1;
result = tf_malloc(size);
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);

View File

@ -163,6 +163,7 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
" private_key TEXT UNIQUE" " private_key TEXT UNIQUE"
")"); ")");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS identities_user ON identities (user, public_key)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS identities_user ON identities (user, public_key)");
_tf_ssb_db_exec(db, "DELETE FROM identities WHERE user = ':auth'");
bool populate_fts = false; bool populate_fts = false;
if (!_tf_ssb_db_has_rows(db, "PRAGMA table_list('messages_fts')")) if (!_tf_ssb_db_has_rows(db, "PRAGMA table_list('messages_fts')"))
@ -1623,7 +1624,6 @@ bool tf_ssb_db_set_account_password(tf_ssb_t* ssb, const char* name, const char*
if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, user_string, user_length, NULL) == SQLITE_OK) if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, user_string, user_length, NULL) == SQLITE_OK)
{ {
result = sqlite3_step(statement) == SQLITE_DONE; result = sqlite3_step(statement) == SQLITE_DONE;
tf_printf("set account password = %d\n", result);
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);
} }