Add password hashing

This commit is contained in:
2025-08-17 10:40:09 +02:00
parent 0e29910197
commit 2196ef06eb
15 changed files with 97 additions and 986 deletions
+45
View File
@@ -0,0 +1,45 @@
#include <stddef.h>
#include <string.h>
#include <crypt_blowfish.h>
#include "bcrypt.h"
int hash_password(char *pass, int passlen, int cost, PasswordHash *hash)
{
char passzt[128];
if (passlen >= (int) sizeof(passzt))
return -1;
memcpy(passzt, pass, passlen);
passzt[passlen] = '\0';
unsigned char random[16] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, // TODO
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
};
char salt[30];
if (_crypt_gensalt_blowfish_rn("$2b$", cost, (char*) random, sizeof(random), salt, sizeof(salt)) == NULL)
return -1;
if (_crypt_blowfish_rn(passzt, salt, hash->data, (int) sizeof(hash->data)) == NULL)
return -1;
return 0;
}
int check_password(char *pass, int passlen, PasswordHash hash)
{
char passzt[128];
if (passlen >= (int) sizeof(passzt))
return -1;
memcpy(passzt, pass, passlen);
passzt[passlen] = '\0';
PasswordHash new_hash;
if (_crypt_blowfish_rn(passzt, hash.data, new_hash.data, sizeof(new_hash.data)) == NULL)
return -1;
if (strcmp(hash.data, new_hash.data)) // TODO: should be constant-time
return 1;
return 0;
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef BCRYPT_INCLUDED
#define BCRYPT_INCLUDED
typedef struct {
char data[61];
} PasswordHash;
int hash_password(char *pass, int passlen, int cost, PasswordHash *hash);
int check_password(char *pass, int passlen, PasswordHash hash);
#endif // BCRYPT_INCLUDED
+34 -5
View File
@@ -4,8 +4,9 @@
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include "sqlite3.h"
#include "chttp.h"
#include "bcrypt.h"
#include "sqlite3.h"
#include "sqlite3utils.h"
#include "template.h"
@@ -45,9 +46,13 @@ int load_file(char *file, char **data, long *size)
int create_user(SQLiteCache *dbcache, HTTP_String name, HTTP_String email, HTTP_String pass)
{
PasswordHash hash;
int ret = hash_password(pass.ptr, pass.len, 12, &hash);
if (ret) return -500;
sqlite3_stmt *stmt;
int ret = sqlite3utils_prepare_and_bind(dbcache, &stmt,
"INSERT INTO Users(username, email, password) VALUES (?, ?, ?)", name, email, pass);
ret = sqlite3utils_prepare_and_bind(dbcache, &stmt,
"INSERT INTO Users(username, email, hash) VALUES (?, ?, ?)", name, email, ((HTTP_String) { hash.data, strlen(hash.data) }));
if (ret != SQLITE_OK)
return -500;
@@ -80,7 +85,7 @@ int user_exists(SQLiteCache *dbcache, HTTP_String name, HTTP_String pass)
{
sqlite3_stmt *stmt;
int ret = sqlite3utils_prepare_and_bind(dbcache, &stmt,
"SELECT id FROM Users WHERE username=? AND password=?", name, pass);
"SELECT id, hash FROM Users WHERE username=?", name);
if (ret != SQLITE_OK)
return -500;
@@ -100,6 +105,30 @@ int user_exists(SQLiteCache *dbcache, HTTP_String name, HTTP_String pass)
return -500;
}
const char *rawhash = (const char*) sqlite3_column_text(stmt, 1);
if (rawhash == NULL) {
sqlite3_reset(stmt);
return -500;
}
int rawhashlen = sqlite3_column_bytes(stmt, 1);
PasswordHash hash;
if (rawhashlen >= sizeof(hash.data)) {
sqlite3_reset(stmt);
return -500;
}
strcpy(hash.data, rawhash);
ret = check_password(pass.ptr, pass.len, hash);
if (ret < 0) {
sqlite3_reset(stmt);
return -500;
}
if (ret > 0) {
sqlite3_reset(stmt);
return -400;
}
ret = sqlite3_reset(stmt);
if (ret != SQLITE_OK)
return -500;
@@ -382,7 +411,7 @@ int main(void)
{
http_global_init();
printf("%s\n", sqlite3_libversion());
printf("%s\n", sqlite3_libversion());
sqlite3 *db;
int ret = sqlite3_open(":memory:", &db);
+2 -2
View File
@@ -83,7 +83,7 @@ static int lookup(SQLiteCache *cache, char *fmt, int fmtlen)
return -1;
}
int sqlite3utils_prepare(SQLiteCache *cache, sqlite3_stmt **pstmt, const char *fmt, int fmtlen)
int sqlite3utils_prepare(SQLiteCache *cache, sqlite3_stmt **pstmt, char *fmt, int fmtlen)
{
if (fmtlen < 0)
fmtlen = strlen(fmt);
@@ -118,7 +118,7 @@ int sqlite3utils_prepare(SQLiteCache *cache, sqlite3_stmt **pstmt, const char *f
}
int sqlite3utils_prepare_and_bind_impl(SQLiteCache *cache,
sqlite3_stmt **pstmt, const char *fmt, VArgs args)
sqlite3_stmt **pstmt, char *fmt, VArgs args)
{
sqlite3_stmt *stmt;
int ret = sqlite3utils_prepare(cache, &stmt, fmt, strlen(fmt));
+2 -2
View File
@@ -13,9 +13,9 @@ void sqlite_cache_free(SQLiteCache *cache);
sqlite3* sqlite_cache_getdb(SQLiteCache *cache);
int sqlite3utils_prepare(SQLiteCache *cache,
sqlite3_stmt **pstmt, const char *fmt, int fmtlen);
sqlite3_stmt **pstmt, char *fmt, int fmtlen);
int sqlite3utils_prepare_and_bind_impl(SQLiteCache *cache,
sqlite3_stmt **pstmt, const char *fmt, VArgs args);
sqlite3_stmt **pstmt, char *fmt, VArgs args);
#endif // SQLITE3UTILS_INCLUDED