pos/database/salt_store.cpp

64 lines
1.5 KiB
C++

#include "salt_store.h"
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <stdint.h>
#include <ctime>
SaltStore::SaltStore(uint64_t key_lifetime, size_t salt_size, std::string secret) {
this->key_lifetime = key_lifetime;
this->salt_size = salt_size;
this->secret = secret;
}
std::string SaltStore::getSalt() {
expireKeys();
unsigned char bfr[salt_size];
FILE * rand_in = fopen("/dev/urandom", "r");
if(!rand_in) {
fprintf(stderr, "Could not open /dev/urandom!\n");
return "";
}
if(salt_size != fread(bfr, sizeof(char), salt_size, rand_in)) {
fclose(rand_in);
fprintf(stderr, "Could not read from /dev/urandom!\n");
return "";
}
fclose(rand_in);
// everything sucks
for(unsigned int i=0;i<salt_size;++i) {
bfr[i] = (bfr[i] % 78) + 48;
}
bfr[salt_size-1] = 0;
std::string salt((char*)bfr);
valid_keys.push_back(std::pair<uint64_t, SHA1Hash>((uint64_t)time(NULL), SHA1Hash(salt + secret)));
return salt;
}
bool SaltStore::consumeKey(std::string key) {
expireKeys();
SHA1Hash h;
h.fromHex(key);
std::list<std::pair<uint64_t, SHA1Hash> >::iterator p;
for(p = valid_keys.begin();p != valid_keys.end(); ++p) {
if(p->second == h) {
valid_keys.erase(p);
return true;
}
}
return false;
}
void SaltStore::expireKeys() {
std::list<std::pair<uint64_t, SHA1Hash> >::iterator p;
uint64_t cur_t = (uint64_t)time(NULL);
for(p = valid_keys.begin();p != valid_keys.end();++p) {
if((cur_t - p->first) > key_lifetime)
p = valid_keys.erase(p);
}
}