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 |
|