mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-28 08:44:06 +02:00
hash passwords
This commit is contained in:
parent
355c907135
commit
d537e0a709
1
slige/runtime/.gitignore
vendored
1
slige/runtime/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
build/
|
build/
|
||||||
|
database.db
|
||||||
|
@ -14,7 +14,8 @@ C_FLAGS = \
|
|||||||
-Wall -Wextra -Wpedantic -Wconversion \
|
-Wall -Wextra -Wpedantic -Wconversion \
|
||||||
-pedantic -pedantic-errors \
|
-pedantic -pedantic-errors \
|
||||||
|
|
||||||
L_FLAGS = -lm -pthread
|
L_FLAGS = -lm -pthread $(shell pkg-config sqlite3 openssl --libs)
|
||||||
|
C_FLAGS = $(shell pkg-config sqlite3 openssl --cflags)
|
||||||
|
|
||||||
F_FLAGS =
|
F_FLAGS =
|
||||||
OPTIMIZATION =
|
OPTIMIZATION =
|
||||||
|
35
slige/runtime/prepare.sql
Normal file
35
slige/runtime/prepare.sql
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
email TEXT NOT NULL,
|
||||||
|
password_hash TEXT NOT NULL,
|
||||||
|
balanceInDkkCent INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS products (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
priceInDkkCent INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS product_prices (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
product INTEGER NOT NULL,
|
||||||
|
priceInDkkCent INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(product) REFERENCES products(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS carts (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
user INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(user) REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS cart_items (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
cart INTEGER NOT NULL,
|
||||||
|
amount INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(cart) REFERENCES carts(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
@ -322,6 +322,7 @@ static inline void worker_handle_request(Worker* worker, Client* client)
|
|||||||
l1_return:
|
l1_return:
|
||||||
header_vec_destroy(&handler_ctx.res_headers);
|
header_vec_destroy(&handler_ctx.res_headers);
|
||||||
req_destroy(&req);
|
req_destroy(&req);
|
||||||
|
if (body)
|
||||||
free(body);
|
free(body);
|
||||||
l0_return:
|
l0_return:
|
||||||
close(client->file);
|
close(client->file);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "http_server.h"
|
#include "http_server.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
#include "str_util.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -47,18 +49,61 @@ void route_post_set_number(HttpCtx* ctx)
|
|||||||
JsonValue* body = json_parser_parse(&parser);
|
JsonValue* body = json_parser_parse(&parser);
|
||||||
json_parser_destroy(&parser);
|
json_parser_destroy(&parser);
|
||||||
|
|
||||||
|
if (!json_object_has(body, "value")) {
|
||||||
|
RESPOND_JSON(
|
||||||
|
ctx, 200, "{\"ok\": false, \"msg\": \"no 'value' key\"}\r\n");
|
||||||
|
goto l0_return;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t value = json_int(json_object_get(body, "value"));
|
int64_t value = json_int(json_object_get(body, "value"));
|
||||||
cx->number = (int)value;
|
cx->number = (int)value;
|
||||||
|
|
||||||
json_value_free(body);
|
|
||||||
|
|
||||||
RESPOND_JSON(ctx, 200, "{\"ok\": true}\r\n");
|
RESPOND_JSON(ctx, 200, "{\"ok\": true}\r\n");
|
||||||
|
|
||||||
|
l0_return:
|
||||||
|
json_value_free(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServer* server;
|
HttpServer* server;
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
char password[] = "Merc1234";
|
||||||
|
|
||||||
|
const char* other_password = "Merc1234";
|
||||||
|
|
||||||
|
{
|
||||||
|
StrHash password_hash = str_hash(password);
|
||||||
|
char* password_hash_str = str_hash_to_string(password_hash);
|
||||||
|
printf("'%s'\n", password_hash_str);
|
||||||
|
|
||||||
|
bool other_is_equal = str_hash_is_equal(password_hash, other_password);
|
||||||
|
printf("is_equal = %s\n", other_is_equal ? "true" : "false");
|
||||||
|
|
||||||
|
free(password_hash_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StrHash password_hash = str_hash(password);
|
||||||
|
char* password_hash_str = str_hash_to_string(password_hash);
|
||||||
|
printf("'%s'\n", password_hash_str);
|
||||||
|
|
||||||
|
bool other_is_equal = str_hash_is_equal(password_hash, other_password);
|
||||||
|
printf("is_equal = %s\n", other_is_equal ? "true" : "false");
|
||||||
|
|
||||||
|
free(password_hash_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sqlite3* db;
|
||||||
|
int res = sqlite3_open("database.db", &db);
|
||||||
|
if (res != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "error: could not open sqlite 'database.db'\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Cx cx = { .number = 1 };
|
Cx cx = { .number = 1 };
|
||||||
|
|
||||||
server = http_server_new((HttpServerOpts) {
|
server = http_server_new((HttpServerOpts) {
|
||||||
@ -77,4 +122,5 @@ int main(void)
|
|||||||
http_server_listen(server);
|
http_server_listen(server);
|
||||||
|
|
||||||
http_server_free(server);
|
http_server_free(server);
|
||||||
|
sqlite3_close(db);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#include "str_util.h"
|
#include "str_util.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
StrSplitter str_split(const char* text, size_t text_len, const char* split)
|
StrSplitter str_split(const char* text, size_t text_len, const char* split)
|
||||||
@ -44,3 +48,72 @@ char* string_copy(const String* string)
|
|||||||
copy[string->size] = '\0';
|
copy[string->size] = '\0';
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
static inline StrHash str_hash_with_salt(const char* str, const uint8_t* salt)
|
||||||
|
{
|
||||||
|
if (strlen(str) >= MAX_HASH_INPUT_LEN - 1) {
|
||||||
|
fprintf(stderr, "error: tried to hash too long input\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
StrHash hash;
|
||||||
|
memcpy(hash.salt, salt, STR_HASH_SALT_SIZE);
|
||||||
|
|
||||||
|
uint8_t input[MAX_HASH_INPUT_LEN + STR_HASH_SALT_SIZE] = { 0 };
|
||||||
|
memcpy(input, hash.salt, STR_HASH_SALT_SIZE);
|
||||||
|
memcpy(&input[STR_HASH_SALT_SIZE], str, strlen(str));
|
||||||
|
|
||||||
|
SHA256(input, strlen((char*)input), hash.hash);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrHash str_hash(const char* str)
|
||||||
|
{
|
||||||
|
uint8_t salt[STR_HASH_SALT_SIZE];
|
||||||
|
RAND_bytes(salt, STR_HASH_SALT_SIZE);
|
||||||
|
return str_hash_with_salt(str, salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool str_hash_is_equal(StrHash hash, const char* str)
|
||||||
|
{
|
||||||
|
StrHash other = str_hash_with_salt(str, hash.salt);
|
||||||
|
return memcmp(hash.hash, other.hash, STR_HASH_HASH_SIZE) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* str_hash_to_string(StrHash hash)
|
||||||
|
{
|
||||||
|
char* result = calloc(STR_HASH_STR_LEN + 1, sizeof(char));
|
||||||
|
for (size_t i = 0; i < STR_HASH_SALT_SIZE; ++i) {
|
||||||
|
char bytestr[3] = { 0 };
|
||||||
|
snprintf(bytestr, 3, "%02x", hash.salt[i]);
|
||||||
|
result[i * 2] = bytestr[0];
|
||||||
|
result[i * 2 + 1] = bytestr[1];
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < STR_HASH_HASH_SIZE; ++i) {
|
||||||
|
char bytestr[3] = { 0 };
|
||||||
|
snprintf(bytestr, 3, "%02x", hash.salt[i]);
|
||||||
|
result[(STR_HASH_SALT_SIZE + i) * 2] = bytestr[0];
|
||||||
|
result[(STR_HASH_SALT_SIZE + i) * 2 + 1] = bytestr[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrHash str_hash_from_string(const char* str)
|
||||||
|
{
|
||||||
|
uint8_t result[64] = { 0 };
|
||||||
|
size_t result_i = 0;
|
||||||
|
for (size_t i = 0; i < strlen(str) && result_i < 64; i += 2) {
|
||||||
|
char bytestr[3] = { 0 };
|
||||||
|
strncpy(bytestr, &str[i], 2);
|
||||||
|
uint64_t byte = strtoul(bytestr, NULL, 16);
|
||||||
|
result[result_i] = (uint8_t)byte;
|
||||||
|
result_i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrHash hash;
|
||||||
|
// memcpy((uint8_t*)&hash, result, sizeof(result));
|
||||||
|
for (size_t i = 0; i < 32; ++i) {
|
||||||
|
hash.salt[i] = result[i];
|
||||||
|
hash.hash[i] = result[32 + i];
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "collection.h"
|
#include "collection.h"
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* ptr;
|
const char* ptr;
|
||||||
@ -25,3 +27,19 @@ void string_push_str(String* string, const char* str);
|
|||||||
char* string_copy(const String* string);
|
char* string_copy(const String* string);
|
||||||
|
|
||||||
DEFINE_VEC(char*, RawStrVec, rawstr_vec, 8)
|
DEFINE_VEC(char*, RawStrVec, rawstr_vec, 8)
|
||||||
|
|
||||||
|
#define MAX_HASH_INPUT_LEN 256
|
||||||
|
|
||||||
|
#define STR_HASH_SALT_SIZE 32
|
||||||
|
#define STR_HASH_HASH_SIZE 32
|
||||||
|
#define STR_HASH_STR_LEN 128
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t salt[STR_HASH_SALT_SIZE];
|
||||||
|
uint8_t hash[STR_HASH_HASH_SIZE];
|
||||||
|
} StrHash;
|
||||||
|
|
||||||
|
StrHash str_hash(const char* str);
|
||||||
|
bool str_hash_is_equal(StrHash hash, const char* str);
|
||||||
|
char* str_hash_to_string(StrHash hash);
|
||||||
|
StrHash str_hash_from_string(const char* str);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user