96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
#include <time.h>
|
|
#include <string.h>
|
|
#include <sys/random.h>
|
|
|
|
#include "include/auth.h"
|
|
#include "include/blake2s.h"
|
|
|
|
static const uint8_t dp_secret_charset[] = "abcdefghijklmnopqrstuvwxyz"
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
"0123456789"
|
|
"-_";
|
|
|
|
bool dp_auth_gen_token(uint8_t out[DP_AUTH_TOKEN_SIZE],
|
|
uint64_t timestamp,
|
|
const uint8_t secret_key[DP_AUTH_SECRET_SIZE]) {
|
|
if (!out || timestamp == 0 || !secret_key) {
|
|
return false;
|
|
}
|
|
|
|
dp_Blake2sCtx ctx = {0};
|
|
|
|
if (!dp_Blake2sCtx_init(&ctx, DP_AUTH_TOKEN_SIZE, secret_key,
|
|
DP_AUTH_SECRET_SIZE)) {
|
|
return false;
|
|
}
|
|
|
|
const uint64_t counter = ((uint64_t)time(NULL) - timestamp) / 300;
|
|
|
|
uint8_t counter_always_le[8] = {0};
|
|
for (size_t idx = 0; idx < 8; ++idx) {
|
|
counter_always_le[idx] =
|
|
(uint8_t)((counter >> (8 * idx)) & (uint8_t)0xFF);
|
|
}
|
|
|
|
if (!dp_Blake2sCtx_update(&ctx, counter_always_le, 8)) {
|
|
return false;
|
|
}
|
|
|
|
if (!dp_Blake2sCtx_final(&ctx)) {
|
|
return false;
|
|
}
|
|
|
|
if (!dp_Blake2sCtx_to_digest(&ctx, out)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool dp_auth_gen_secret(uint8_t secret[DP_AUTH_SECRET_SIZE],
|
|
uint8_t key[DP_AUTH_KEY_SIZE],
|
|
uint64_t *timestamp) {
|
|
if (!secret || timestamp == 0) {
|
|
return false;
|
|
}
|
|
|
|
if (getrandom(secret, DP_AUTH_SECRET_SIZE, 0) != DP_AUTH_SECRET_SIZE) {
|
|
return false;
|
|
}
|
|
for (size_t idx = 0; idx < DP_AUTH_SECRET_SIZE; ++idx) {
|
|
secret[idx] = dp_secret_charset[secret[idx] &
|
|
(uint8_t)0x3F]; /* Map to the charset */
|
|
}
|
|
|
|
if (getrandom(key, DP_AUTH_KEY_SIZE, 0) != DP_AUTH_KEY_SIZE) {
|
|
return false;
|
|
}
|
|
for (size_t idx = 0; idx < DP_AUTH_KEY_SIZE; ++idx) {
|
|
key[idx] = dp_secret_charset[key[idx] &
|
|
(uint8_t)0x3F]; /* Map to the charset */
|
|
}
|
|
|
|
*timestamp = (uint64_t)time(NULL);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool dp_auth_verify_token(const uint8_t secret[DP_AUTH_SECRET_SIZE],
|
|
uint64_t timestamp,
|
|
const uint8_t given_token[DP_AUTH_SECRET_SIZE]) {
|
|
if (!secret || !given_token) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t real_token[DP_AUTH_TOKEN_SIZE] = {0};
|
|
|
|
if (!dp_auth_gen_token(real_token, timestamp, secret)) {
|
|
return false;
|
|
}
|
|
|
|
if (memcmp(given_token, real_token, DP_AUTH_TOKEN_SIZE) != 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|