breaking out the salt storing functionality so i can reuse it
authorOwen Smith <owen@omsmith.ca>
Tue, 20 Nov 2012 03:38:56 +0000 (22:38 -0500)
committerOwen Smith <owen@omsmith.ca>
Tue, 20 Nov 2012 03:38:56 +0000 (22:38 -0500)
database/salt_store.cpp [new file with mode: 0644]
database/salt_store.h [new file with mode: 0644]

diff --git a/database/salt_store.cpp b/database/salt_store.cpp
new file mode 100644 (file)
index 0000000..e9ca878
--- /dev/null
@@ -0,0 +1,63 @@
+#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();
+       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);
+
+       // zero-terminated strings suck
+       for(unsigned int i=0;i<salt_size;++i)
+               if(bfr[i] == 0)
+                       bfr[i] = 1;
+       bfr[salt_size-1] = 0;
+
+       std::string salt(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);
+       }
+}
+
diff --git a/database/salt_store.h b/database/salt_store.h
new file mode 100644 (file)
index 0000000..ea34d15
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _SALT_STORE_H_
+#define _SALT_STORE_H_
+#include "sha1.h"
+#include <string>
+#include <list>
+
+class SaltStore {
+
+public:
+       SaltStore(uint64_t key_lifetime, size_t salt_size, std::string secret);
+       ~SaltStore();
+       std::string getSalt();
+       bool consumeKey(std::string key);
+
+private:
+       void expireKeys();
+       std::list<std::pair<uint64_t, SHA1Hash> > valid_keys;
+       uint64_t key_lifetime;
+       size_t salt_size;
+       std::string secret;
+
+};
+
+#endif
+