Browse code
Refactor generate_token to use vectors internally
Ed Langley authored on 13/06/2017 20:34:47
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -15,8 +15,12 @@ |
15 | 15 |
#include <openssl/hmac.h> |
16 | 16 |
#include <openssl/evp.h> |
17 | 17 |
|
18 |
+#include "base32.h" |
|
18 | 19 |
namespace |
19 | 20 |
{ |
21 |
+class hmac_failed_exception : public std::exception |
|
22 |
+{}; |
|
23 |
+ |
|
20 | 24 |
int ipow (int base, int exp) |
21 | 25 |
{ |
22 | 26 |
int result = 1; |
... | ... |
@@ -62,7 +66,8 @@ class token_generator_impl : public token_generator_ifc |
62 | 66 |
{ |
63 | 67 |
private: |
64 | 68 |
const sys_time clock; |
65 |
- unsigned int code_digits; |
|
69 |
+ const unsigned int code_digits; |
|
70 |
+ const base32 codec; |
|
66 | 71 |
|
67 | 72 |
private: |
68 | 73 |
std::string zero_fill (unsigned long result, int digits) const |
... | ... |
@@ -82,13 +87,18 @@ private: |
82 | 87 |
return bytesToInt (offsetBytes) & 0x7fffffff; |
83 | 88 |
} |
84 | 89 |
|
85 |
- std::string hotp (const std::string &key, const unsigned char *data, |
|
90 |
+ std::string hotp (const std::vector<uint8_t> &key, |
|
91 |
+ const unsigned char *data, |
|
86 | 92 |
size_t data_size, const int digits=6) const |
87 | 93 |
{ |
88 | 94 |
// TODO: see if I can use sha256/etc. with google auth... |
89 |
- unsigned char *digest = HMAC (EVP_sha1(), key.c_str(), key.size(), data, |
|
95 |
+ unsigned char *digest = HMAC (EVP_sha1(), key.data(), key.size(), data, |
|
90 | 96 |
data_size, NULL, NULL); |
91 | 97 |
|
98 |
+ if (digest == nullptr) { |
|
99 |
+ throw hmac_failed_exception(); |
|
100 |
+ } |
|
101 |
+ |
|
92 | 102 |
std::string digest_s = std::string (reinterpret_cast<const char *> (digest), |
93 | 103 |
20); //TODO: use vectors |
94 | 104 |
|
... | ... |
@@ -103,7 +113,16 @@ public: |
103 | 113 |
clock (clock), code_digits (code_digits) |
104 | 114 |
{} |
105 | 115 |
|
106 |
- std::string generate_token (const std::string &key) const override |
|
116 |
+ std::string generate_token (const std::string &key_string) const override |
|
117 |
+ { |
|
118 |
+ // std::cout << "KEY SIZE: " << key_string.size() << std::endl; |
|
119 |
+ // std::vector<uint8_t> key = codec.decode(key_string); |
|
120 |
+ // std::cout << "LENGTH: " << key.size() << " '" << key_string << "'" << std::endl; |
|
121 |
+ std::vector<uint8_t> key (key_string.begin(), key_string.end()); |
|
122 |
+ return generate_token (key); |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ std::string generate_token (const std::vector<uint8_t> key) const |
|
107 | 126 |
{ |
108 | 127 |
// Assuming time is > 0, integer division produces the result we want. |
109 | 128 |
const time_t &time_chunk = clock.time (nullptr) / 30; |
... | ... |
@@ -123,3 +142,4 @@ totp_generator::totp_generator ( |
123 | 142 |
const int code_digits) : |
124 | 143 |
delegate_ (std::make_shared<token_generator_impl> (clock, code_digits)) |
125 | 144 |
{} |
145 |
+ |
... | ... |
@@ -18,6 +18,7 @@ |
18 | 18 |
#include <iomanip> |
19 | 19 |
#include <cmath> |
20 | 20 |
#include <ctime> |
21 |
+#include <iostream> |
|
21 | 22 |
|
22 | 23 |
#include "sys_stdlib.h" |
23 | 24 |
#include "sys_time.h" |
... | ... |
@@ -33,20 +34,20 @@ public: |
33 | 34 |
|
34 | 35 |
class totp_generator |
35 | 36 |
{ |
36 |
- public: |
|
37 |
+public: |
|
37 | 38 |
using delegate = std::shared_ptr<token_generator_ifc>; |
38 | 39 |
|
39 |
- private: |
|
40 |
+private: |
|
40 | 41 |
delegate delegate_; |
41 | 42 |
|
42 |
- public: |
|
43 |
+public: |
|
43 | 44 |
std::string generate_token (const std::string &key) const |
44 |
- { |
|
45 |
- return delegate_->generate_token(key); |
|
46 |
- } |
|
45 |
+ { |
|
46 |
+ return delegate_->generate_token (key); |
|
47 |
+ } |
|
47 | 48 |
|
48 | 49 |
totp_generator (delegate delegate_) : |
49 |
- delegate_ (delegate_) |
|
50 |
+ delegate_ (delegate_) |
|
50 | 51 |
{} |
51 | 52 |
|
52 | 53 |
totp_generator (const sys_time clock, |
... | ... |
@@ -54,3 +55,4 @@ class totp_generator |
54 | 55 |
}; |
55 | 56 |
|
56 | 57 |
#endif |
58 |
+ |
... | ... |
@@ -81,7 +81,8 @@ int given_digits() |
81 | 81 |
auto generator = totp_generator (stdtime, 6); |
82 | 82 |
|
83 | 83 |
// when |
84 |
- auto actual = generator.generate_token("\x00"); |
|
84 |
+ std::string key { 0 }; |
|
85 |
+ auto actual = generator.generate_token (key); |
|
85 | 86 |
|
86 | 87 |
// then |
87 | 88 |
check (actual.size() == 6, "size is wrong"); |
... | ... |
@@ -101,8 +102,9 @@ int modulated_source_modulates_tokens() |
101 | 102 |
auto generator = totp_generator (stdtime, 6); |
102 | 103 |
|
103 | 104 |
// when |
104 |
- auto actual1 = generator.generate_token("\x00"); |
|
105 |
- auto actual2 = generator.generate_token("\x00"); |
|
105 |
+ std::string key ("\x00", 1); |
|
106 |
+ auto actual1 = generator.generate_token (key); |
|
107 |
+ auto actual2 = generator.generate_token (key); |
|
106 | 108 |
|
107 | 109 |
// then |
108 | 110 |
check (actual1 != actual2, "tokens should be different"); |
... | ... |
@@ -117,9 +119,10 @@ int int_max() |
117 | 119 |
|
118 | 120 |
sys_time stdtime (test_stdtime); |
119 | 121 |
auto generator = totp_generator (stdtime, 6); |
122 |
+ std::string key ("\x00", 1); |
|
120 | 123 |
|
121 | 124 |
// when |
122 |
- auto actual = generator.generate_token("\x00"); |
|
125 |
+ auto actual = generator.generate_token (key); |
|
123 | 126 |
|
124 | 127 |
// then |
125 | 128 |
check (actual.size() == 6, "size is wrong"); |
... | ... |
@@ -134,12 +137,13 @@ int int_min() |
134 | 137 |
// given |
135 | 138 |
std::initializer_list<time_t> samples { INT_MIN }; |
136 | 139 |
auto test_stdtime = std::make_shared<fake_time> (samples); |
140 |
+ std::string key ("\x00", 1); |
|
137 | 141 |
|
138 | 142 |
sys_time stdtime (test_stdtime); |
139 | 143 |
auto generator = totp_generator (stdtime, 6); |
140 | 144 |
|
141 | 145 |
// when |
142 |
- auto actual = generator.generate_token("\x00"); |
|
146 |
+ auto actual = generator.generate_token (key); |
|
143 | 147 |
|
144 | 148 |
// then |
145 | 149 |
check (actual.size() == 6, "size is wrong"); |
... | ... |
@@ -165,7 +169,7 @@ int int_precomputed() |
165 | 169 |
std::string expected = "258675"; |
166 | 170 |
|
167 | 171 |
// when |
168 |
- auto actual = generator.generate_token(key); |
|
172 |
+ auto actual = generator.generate_token (key); |
|
169 | 173 |
|
170 | 174 |
// then |
171 | 175 |
check (actual.size() == 6, "size is wrong"); |
... | ... |
@@ -188,3 +192,4 @@ int main (int argc, char *argv[]) |
188 | 192 |
{ |
189 | 193 |
return !run_tests(); |
190 | 194 |
} |
195 |
+ |