git.fiddlerwoaroof.com
generator_test.cc
7d075ab4
 /* Copyright (C) CJ Affiliate
  *
  * You may use, distribute and modify this code under  the
  * terms of the  GNU General Public License  version 2  or
  * later.
  *
  * You should have received a copy of the license with this
  * file. If not, you will find a copy in the "LICENSE" file
  * at https://github.com/cjdev/dual-control.
  */
46cb80e7
 #include <memory>
55563eab
 #include <algorithm>
46cb80e7
 #include <initializer_list>
 #include <vector>
cff139be
 #include <climits>
9b03a29b
 #include <ctime>
 #include <iostream>
cff139be
 
55563eab
 #include "generator.h"
46cb80e7
 #include "sys_stdlib.h"
9b03a29b
 #include "sys_time.h"
55563eab
 #include "test_util.h"
c1e18905
 #include "typealiases.h"
55563eab
 
23c0bd4d
 class fake_stdlib : public stdlib_ifc
 {
 
 private:
     std::vector<int> samples_;
     mutable std::vector<int>::iterator current_;
 public:
     fake_stdlib ( const std::initializer_list<int> &samples)
         : samples_ (samples.begin(), samples.end()),
           current_ (samples_.begin()) {}
     int rand() const override
     {
         if (current_ != samples_.end()) {
             auto rval = *current_;
             current_ += 1;
             return rval;
         }
 
         return 0;
46cb80e7
     }
 };
 
9b03a29b
 class fake_time : public sys_time_ifc
 {
 
 private:
     std::vector<time_t> samples_;
     mutable std::vector<time_t>::iterator current_;
 public:
     fake_time ( const std::initializer_list<time_t> &samples)
         : samples_ (samples.begin(), samples.end()),
           current_ (samples_.begin()) {}
     time_t time (time_t *time_ptr) const override
     {
         if (current_ != samples_.end()) {
             auto rval = *current_;
 
             if (time_ptr != nullptr) {
                 *time_ptr = rval;
             }
 
             current_ += 1;
             return rval;
         }
 
         return 0;
     }
 };
 
47f1fe7f
 int given_digits()
7d075ab4
 {
     // given
9b03a29b
     std::initializer_list<time_t> samples { 1 };
     auto test_stdtime = std::make_shared<fake_time> (samples);
 
     sys_time stdtime (test_stdtime);
     // Fake the Key
e57144d3
     auto generator = totp_generator (stdtime, 6);
55563eab
 
7d075ab4
     // when
40fd6c82
     octet_vector key { 0 };
c1080d50
     auto actual = generator.generate_token (key);
55563eab
 
7d075ab4
     // then
     check (actual.size() == 6, "size is wrong");
     check (std::all_of (actual.begin(), actual.end(), [] (char c) {
         return c >= '0' && c <= '9';
     }), "not just digits");
     succeed();
55563eab
 }
 
23c0bd4d
 int modulated_source_modulates_tokens()
 {
46cb80e7
     // given
9b03a29b
     std::initializer_list<time_t> samples { 1, 31 };
     auto test_stdtime = std::make_shared<fake_time> (samples);
 
     sys_time stdtime (test_stdtime);
e57144d3
     auto generator = totp_generator (stdtime, 6);
46cb80e7
 
     // when
40fd6c82
     octet_vector key { 0 };
c1080d50
     auto actual1 = generator.generate_token (key);
     auto actual2 = generator.generate_token (key);
46cb80e7
 
     // then
9b03a29b
     check (actual1 != actual2, "tokens should be different");
46cb80e7
     succeed();
 }
 
cff139be
 int int_max()
 {
     // given
9b03a29b
     std::initializer_list<time_t> samples { INT_MAX };
     auto test_stdtime = std::make_shared<fake_time> (samples);
 
     sys_time stdtime (test_stdtime);
e57144d3
     auto generator = totp_generator (stdtime, 6);
40fd6c82
     octet_vector key { 0 };
cff139be
 
     // when
c1080d50
     auto actual = generator.generate_token (key);
cff139be
 
     // then
     check (actual.size() == 6, "size is wrong");
     check (std::all_of (actual.begin(), actual.end(), [] (char c) {
         return c >= '0' && c <= '9';
     }), "not just digits");
     succeed();
 }
 
 int int_min()
 {
     // given
9b03a29b
     std::initializer_list<time_t> samples { INT_MIN };
     auto test_stdtime = std::make_shared<fake_time> (samples);
40fd6c82
     octet_vector key { 0 };
9b03a29b
 
     sys_time stdtime (test_stdtime);
e57144d3
     auto generator = totp_generator (stdtime, 6);
cff139be
 
     // when
c1080d50
     auto actual = generator.generate_token (key);
cff139be
 
     // then
     check (actual.size() == 6, "size is wrong");
     check (std::all_of (actual.begin(), actual.end(), [] (char c) {
         return c >= '0' && c <= '9';
     }), "not just digits");
     succeed();
 }
 
9b03a29b
 // totp test
 int int_precomputed()
 {
     // given
     // The token for key 76I6WTYEUTNCJUREMGKVM45PMA and time '2017/01/01 00:00:00' is 258675
     time_t theTime = 1483257600;
     std::initializer_list<time_t> samples { theTime }; //
     auto test_stdtime = std::make_shared<fake_time> (samples);
 
     sys_time stdtime (test_stdtime);
     // Fake the Key
40fd6c82
     octet_vector key {255, 145, 235, 79, 4, 164, 218, 36, 210, 36, 97, 149, 86, 115, 175, 96};
e57144d3
     auto generator = totp_generator (stdtime, 6);
9b03a29b
     std::string expected = "258675";
 
     // when
c1080d50
     auto actual = generator.generate_token (key);
9b03a29b
 
     // then
     check (actual.size() == 6, "size is wrong");
8adb1737
     check (actual == expected, "precomputed value failed to match");
9b03a29b
     succeed();
 }
 
7d075ab4
 int run_tests()
 {
47f1fe7f
     test (given_digits);
46cb80e7
     test (modulated_source_modulates_tokens);
cff139be
     test (int_max);
     test (int_min);
9b03a29b
     test (int_precomputed);
55563eab
     succeed();
 }
 
7d075ab4
 int main (int argc, char *argv[])
 {
55563eab
     return !run_tests();
 }
0d8b9a17