git.fiddlerwoaroof.com
Browse code

CJPM-5223: Refactor totp generator to use vectors

Ed Langley authored on 14/06/2017 18:51:08
Showing 1 changed files
... ...
@@ -18,6 +18,8 @@
18 18
 #include "base32.h"
19 19
 namespace
20 20
 {
21
+using octet_vector = std::vector<uint8_t>;
22
+
21 23
 class hmac_failed_exception : public std::exception
22 24
 {};
23 25
 
... ...
@@ -49,7 +51,8 @@ unsigned char *timeToBytes (unsigned long long time, unsigned char *data,
49 51
     return data;
50 52
 }
51 53
 
52
-unsigned long bytesToInt (const std::string &bytes)
54
+template <typename S>
55
+unsigned long bytesToInt (const S &bytes)
53 56
 {
54 57
     unsigned long result = 0;
55 58
     auto          byteCount = bytes.size() - 1;
... ...
@@ -77,12 +80,14 @@ private:
77 80
         return result_stream.str();
78 81
     }
79 82
 
80
-    unsigned long truncate (const std::string &mac) const
83
+    unsigned long truncate (const octet_vector &mac) const
81 84
     {
82 85
         uint8_t offset = static_cast<uint8_t > (mac[19]) & static_cast<uint8_t>
83 86
                          (0x0f);
84 87
 
85
-        std::string  offsetBytes = mac.substr (offset, 4);
88
+        auto mac_begin = mac.begin();
89
+        auto subseq_begin = mac_begin + offset;
90
+        octet_vector  offsetBytes (subseq_begin, subseq_begin + 4);
86 91
 
87 92
         return bytesToInt (offsetBytes) & 0x7fffffff;
88 93
     }
... ...
@@ -92,15 +97,16 @@ private:
92 97
                       size_t data_size, const int digits=6) const
93 98
     {
94 99
         // TODO: see if I can use sha256/etc. with google auth...
95
-        unsigned char *digest = HMAC (EVP_sha1(), key.data(), key.size(), data,
100
+        const unsigned char *digest = HMAC (EVP_sha1(), key.data(), key.size(), data,
96 101
                                       data_size, NULL, NULL);
97 102
 
98 103
         if (digest == nullptr) {
99 104
             throw hmac_failed_exception();
100 105
         }
101 106
 
102
-        std::string digest_s = std::string (reinterpret_cast<const char *> (digest),
103
-                                            20); //TODO: use vectors
107
+        size_t sha1_output_size = 20;
108
+        // const_cast should be safe here because we generated the pointer
109
+        octet_vector digest_s = octet_vector (digest, digest+sha1_output_size);
104 110
 
105 111
         unsigned long result = truncate (digest_s) % ipow (10,digits);
106 112
 
... ...
@@ -142,4 +148,3 @@ totp_generator::totp_generator (
142 148
     const int code_digits) :
143 149
     delegate_ (std::make_shared<token_generator_impl> (clock, code_digits))
144 150
 {}
145
-