diff options
| author | Szczepan Zalega <szczepan@nitrokey.com> | 2019-06-22 17:31:45 +0200 | 
|---|---|---|
| committer | Szczepan Zalega <szczepan@nitrokey.com> | 2019-06-22 17:31:45 +0200 | 
| commit | 3ede630625cdc83cde2753897bee260595a5137a (patch) | |
| tree | 578e349f9e5b44acabf106e3f8f8f2073a80ad02 /unittest | |
| parent | 3fc4193776b4ea29354838df024a72d7c8349ea9 (diff) | |
| parent | 1fed3fd903da061a58d846f92161b60b711d8df5 (diff) | |
| download | libnitrokey-3ede630625cdc83cde2753897bee260595a5137a.tar.gz libnitrokey-3ede630625cdc83cde2753897bee260595a5137a.tar.bz2 | |
Merge branch 'otp_tests'
Add OTP tests:
- complete writing and reading codes
- test edge slots of TOTP and HOTP
Diffstat (limited to 'unittest')
| -rw-r--r-- | unittest/constants.py | 3 | ||||
| -rw-r--r-- | unittest/test_pro.py | 91 | 
2 files changed, 92 insertions, 2 deletions
| diff --git a/unittest/constants.py b/unittest/constants.py index 714c8c6..645ef6a 100644 --- a/unittest/constants.py +++ b/unittest/constants.py @@ -57,3 +57,6 @@ class LibraryErrors:      INVALID_HEX_STRING = 202      TARGET_BUFFER_SIZE_SMALLER_THAN_SOURCE = 203 + +HOTP_slot_count = 3 +TOTP_slot_count = 15
\ No newline at end of file diff --git a/unittest/test_pro.py b/unittest/test_pro.py index b8ae290..29eabff 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -22,9 +22,10 @@ SPDX-License-Identifier: LGPL-3.0  import pytest  from conftest import skip_if_device_version_lower_than -from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, bb, bbRFC_SECRET, LibraryErrors +from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, bb, bbRFC_SECRET, LibraryErrors, HOTP_slot_count, \ +    TOTP_slot_count  from misc import ffi, gs, wait, cast_pointer_to_tuple, has_binary_counter -from misc import is_pro_rtm_07, is_pro_rtm_08, is_storage +from misc import is_storage  @pytest.mark.lock_device  @pytest.mark.PWS @@ -431,6 +432,10 @@ def test_HOTP_64bit_counter(C):          lib_res += (t, lib_at(t))      assert dev_res == lib_res +def helper_set_HOTP_test_slot(C, slot_number): +    assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +    assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, 0, False, False, True, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +  def helper_set_TOTP_test_slot(C, slot_number):      PIN_protection = False @@ -593,6 +598,20 @@ def test_get_code_user_authorize(C):      assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK +def helper_get_TOTP_code(C,i): +    code = gs(C.NK_get_totp_code(i, 0, 0, 30)) +    assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK +    assert code != b'' +    return code + + +def helper_get_HOTP_code(C,i): +    code = gs(C.NK_get_hotp_code(i)) +    assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK +    assert code != b'' +    return code + +  @pytest.mark.otp  def test_authorize_issue_admin(C):      skip_if_device_version_lower_than({'S': 43, 'P': 9}) @@ -1003,3 +1022,71 @@ def test_HOTP_counter_getter(C, counter_mid: int):          assert read_slot_st.slot_counter == counter +def test_edge_OTP_slots(C): +    # -> shows TOTP15 is not written +    # -> assuming HOTP1 is written +    # (optional) Write slot HOTP1 +    # Write slot TOTP15 +    # Wait +    # Read slot TOTP15 details +    # Read HOTP1 details +    # returns SLOT_NOT_PROGRAMMED +    # (next nkapp execution) +    # -> shows HOTP1 is not written +    # briefly writing TOTP15 clears HOTP1, and vice versa + +    read_slot_st = ffi.new('struct ReadSlot_t *') +    if not read_slot_st: +        raise Exception("Could not allocate status") +    use_pin_protection = False +    use_8_digits = False +    assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +    assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, +                             DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +    counter = 0 +    HOTP_slot_number = 1 -1 +    TOTP_slot_number = 15 -1  # 0 based +    assert C.NK_write_totp_slot(TOTP_slot_number, b'python_test', bbRFC_SECRET, 30, False, False, False, b'', +                                DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +    assert C.NK_write_hotp_slot(HOTP_slot_number, b'python_test', bbRFC_SECRET, counter, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK +    for i in range(5): +        code_hotp = gs(C.NK_get_hotp_code(HOTP_slot_number)) +        assert code_hotp +        assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK +        assert C.NK_read_HOTP_slot(HOTP_slot_number, read_slot_st) == DeviceErrorCode.STATUS_OK +        assert read_slot_st.slot_counter == (i+1) +        helper_set_time_on_device(C, 1) +        code_totp = gs((C.NK_get_totp_code(TOTP_slot_number, 0, 0, 30))) +        assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK + + +def test_OTP_all_rw(C): +    """ +    Write all OTP slots and read codes from them two times. +    All generated codes should be the same, which is checked as well. +    """ +    for i in range(TOTP_slot_count): +        helper_set_TOTP_test_slot(C, i) +    for i in range(HOTP_slot_count): +        helper_set_HOTP_test_slot(C, i) +    all_codes = [] +    for i in range(5): +        this_loop_codes = [] +        code_old = b'' +        helper_set_time_on_device(C, 30*i) +        for i in range(TOTP_slot_count): +            code = helper_get_TOTP_code(C, i) +            if code_old: +                assert code == code_old +            code_old = code +            this_loop_codes.append(('T', i, code)) +        code_old = b'' +        for i in range(HOTP_slot_count): +            code = helper_get_HOTP_code(C, i) +            if code_old: +                assert code == code_old +            code_old = code +            this_loop_codes.append(('H', i, code)) +        all_codes.append(this_loop_codes) +    from pprint import pprint +    pprint(all_codes)
\ No newline at end of file | 
