Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getters for OTP and PWS properties #198

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions NK_C_API.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,38 @@ extern "C" {
});
}

NK_C_API uint8_t NK_get_pws_slot_count() {
szszszsz marked this conversation as resolved.
Show resolved Hide resolved
return NitrokeyManager::instance()->get_pws_slot_count();
}

NK_C_API size_t NK_get_pws_name_length() {
return NitrokeyManager::instance()->get_pws_name_length();
}

NK_C_API size_t NK_get_pws_login_length() {
return NitrokeyManager::instance()->get_pws_login_length();
}

NK_C_API size_t NK_get_pws_password_length() {
return NitrokeyManager::instance()->get_pws_password_length();
}

NK_C_API uint8_t NK_get_totp_slot_count() {
return NitrokeyManager::instance()->get_totp_slot_count();
}

NK_C_API uint8_t NK_get_hotp_slot_count() {
return NitrokeyManager::instance()->get_hotp_slot_count();
}

NK_C_API size_t NK_get_otp_name_length() {
return NitrokeyManager::instance()->get_otp_name_length();
}

NK_C_API size_t NK_get_otp_secret_length() {
return NitrokeyManager::instance()->get_otp_secret_length();
}

NK_C_API char * NK_get_hotp_code(uint8_t slot_number) {
return NK_get_hotp_code_PIN(slot_number, "");
}
Expand Down
51 changes: 51 additions & 0 deletions NK_C_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define LIBNITROKEY_NK_C_API_H

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "deprecated.h"
Expand Down Expand Up @@ -527,6 +528,56 @@ extern "C" {
*/
NK_C_API int NK_read_config_struct(struct NK_config* out);

// OTP and PWS properties

/**
* Returns the number of PWS slots provided by the connected device or
* zero if no device is connected.
*/
NK_C_API uint8_t NK_get_pws_slot_count();

/**
* Returns the maximum length of a PWS slot name in bytes for the
* connected device or zero if no device is connected.
*/
NK_C_API size_t NK_get_pws_name_length();

/**
* Returns the maximum length of a PWS login in bytes for the connected
* device or zero if no device is connected.
*/
NK_C_API size_t NK_get_pws_login_length();

/**
* Returns the maximum length of a PWS password in bytes for the
* connected device or zero if no device is connected.
*/
NK_C_API size_t NK_get_pws_password_length();

/**
* Returns the number of TOTP slots provided by the connected device or
* zero if no device is connected.
*/
NK_C_API uint8_t NK_get_totp_slot_count();

/**
* Returns the number of HOTP slots provided by the connected device or
* zero if no device is connected.
*/
NK_C_API uint8_t NK_get_hotp_slot_count();

/**
* Returns the maximum length of an OTP slot name in bytes for the
* connected device or zero if no device is connected.
*/
NK_C_API size_t NK_get_otp_name_length();

/**
* Returns the maximum length of an OTP secret in bytes for the
* connected device or zero if no device is connected.
*/
NK_C_API size_t NK_get_otp_secret_length();

//OTP

/**
Expand Down
72 changes: 67 additions & 5 deletions NitrokeyManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,69 @@ using nitrokey::misc::strcpyT;
}
}

uint8_t NitrokeyManager::get_pws_slot_count() {
if (device == nullptr) {
return 0;
} else {
return PWS_SLOT_COUNT;
}
}

size_t NitrokeyManager::get_pws_name_length() {
if (device == nullptr) {
return 0;
} else {
return PWS_SLOTNAME_LENGTH;
}
}

size_t NitrokeyManager::get_pws_login_length() {
if (device == nullptr) {
return 0;
} else {
return PWS_LOGINNAME_LENGTH;
}
}

size_t NitrokeyManager::get_pws_password_length() {
if (device == nullptr) {
return 0;
} else {
return PWS_PASSWORD_LENGTH;
}
}

uint8_t NitrokeyManager::get_totp_slot_count() {
if (device == nullptr) {
return 0;
} else {
return TOTP_SLOT_COUNT;
}
}

uint8_t NitrokeyManager::get_hotp_slot_count() {
if (device == nullptr) {
return 0;
} else {
return HOTP_SLOT_COUNT;
}
}

size_t NitrokeyManager::get_otp_name_length() {
if (device == nullptr) {
return 0;
} else {
return OTP_SLOTNAME_LENGTH;
}
}

size_t NitrokeyManager::get_otp_secret_length() {
if (device == nullptr) {
return 0;
} else {
return OTP_SECRET_LENGTH;
}
}

string NitrokeyManager::get_serial_number() {
try {
Expand Down Expand Up @@ -470,8 +533,8 @@ using nitrokey::misc::strcpyT;
}

bool NitrokeyManager::is_internal_hotp_slot_number(uint8_t slot_number) const { return slot_number < 0x20; }
bool NitrokeyManager::is_valid_hotp_slot_number(uint8_t slot_number) const { return slot_number < 3; }
bool NitrokeyManager::is_valid_totp_slot_number(uint8_t slot_number) const { return slot_number < 0x10-1; } //15
bool NitrokeyManager::is_valid_hotp_slot_number(uint8_t slot_number) const { return slot_number < HOTP_SLOT_COUNT; }
bool NitrokeyManager::is_valid_totp_slot_number(uint8_t slot_number) const { return slot_number < TOTP_SLOT_COUNT; }
uint8_t NitrokeyManager::get_internal_slot_number_for_totp(uint8_t slot_number) const { return (uint8_t) (0x20 + slot_number); }
uint8_t NitrokeyManager::get_internal_slot_number_for_hotp(uint8_t slot_number) const { return (uint8_t) (0x10 + slot_number); }

Expand Down Expand Up @@ -636,9 +699,8 @@ using nitrokey::misc::strcpyT;
payload2.id = 0;
auto secret_bin = misc::hex_string_to_byte(secret);
auto remaining_secret_length = secret_bin.size();
const auto maximum_OTP_secret_size = 40;
if(remaining_secret_length > maximum_OTP_secret_size){
throw TargetBufferSmallerThanSource(remaining_secret_length, maximum_OTP_secret_size);
if(remaining_secret_length > OTP_SECRET_LENGTH){
throw TargetBufferSmallerThanSource(remaining_secret_length, OTP_SECRET_LENGTH);
}

while (remaining_secret_length>0){
Expand Down
49 changes: 49 additions & 0 deletions libnitrokey/NitrokeyManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "stick10_commands.h"
#include "stick10_commands_0.8.h"
#include "stick20_commands.h"
#include <cstddef>
#include <vector>
#include <memory>
#include <unordered_map>
Expand Down Expand Up @@ -64,6 +65,54 @@ char * strndup(const char* str, size_t maxlen);
stick10::ReadSlot::ResponsePayload get_TOTP_slot_data(const uint8_t slot_number);
stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number);

/**
* Returns the number of PWS slots provided by the connected device or
* zero if no device is connected.
*/
uint8_t get_pws_slot_count();

/**
* Returns the maximum length of a PWS slot name in bytes for the
* connected device or zero if no device is connected.
*/
size_t get_pws_name_length();

/**
* Returns the maximum length of a PWS login in bytes for the connected
* device or zero if no device is connected.
*/
size_t get_pws_login_length();

/**
* Returns the maximum length of a PWS password in bytes for the
* connected device or zero if no device is connected.
*/
size_t get_pws_password_length();

/**
* Returns the number of TOTP slots provided by the connected device or
* zero if no device is connected.
*/
uint8_t get_totp_slot_count();

/**
* Returns the number of HOTP slots provided by the connected device or
* zero if no device is connected.
*/
uint8_t get_hotp_slot_count();

/**
* Returns the maximum length of an OTP slot name in bytes for the
* connected device or zero if no device is connected.
*/
size_t get_otp_name_length();

/**
* Returns the maximum length of an OTP secret in bytes for the
* connected device or zero if no device is connected.
*/
size_t get_otp_secret_length();

bool set_time(uint64_t time);
/**
* Set the device time used for TOTP to the given time. Contrary to
Expand Down
5 changes: 5 additions & 0 deletions libnitrokey/device_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
#define PWS_SEND_TAB 2
#define PWS_SEND_CR 3

#define HOTP_SLOT_COUNT 3
#define TOTP_SLOT_COUNT 15
#define OTP_SLOTNAME_LENGTH 15
#define OTP_SECRET_LENGTH 40

#include <mutex>
#include "DeviceCommunicationExceptions.h"
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
Expand Down
12 changes: 11 additions & 1 deletion unittest/test_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ def test_offline(C_offline):

# v3.4.1-29-g1f3d
search = re.search(b'v\d\.\d(\.\d)?', libnk_version)
assert search is not None
assert search is not None

assert C_offline.NK_get_pws_slot_count() == 0
assert C_offline.NK_get_pws_name_length() == 0
assert C_offline.NK_get_pws_login_length() == 0
assert C_offline.NK_get_pws_password_length() == 0

assert C_offline.NK_get_hotp_slot_count() == 0
assert C_offline.NK_get_totp_slot_count() == 0
assert C_offline.NK_get_otp_name_length() == 0
assert C_offline.NK_get_otp_secret_length() == 0
16 changes: 16 additions & 0 deletions unittest/test_pro.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ def test_password_safe_slot_status(C):
assert is_slot_programmed[1] == 1


@pytest.mark.PWS
def test_password_safe_properties(C):
assert C.NK_get_pws_slot_count() == 16
assert C.NK_get_pws_name_length() == 11
assert C.NK_get_pws_login_length() == 32
assert C.NK_get_pws_password_length() == 20


@pytest.mark.aes
def test_issue_device_locks_on_second_key_generation_in_sequence(C):
# if is_pro_rtm_07(C) or is_pro_rtm_08(C):
Expand Down Expand Up @@ -1070,3 +1078,11 @@ def test_OTP_all_rw(C):
all_codes.append(this_loop_codes)
from pprint import pprint
pprint(all_codes)


@pytest.mark.otp
def test_otp_properties(C):
assert C.NK_get_hotp_slot_count() == 3
assert C.NK_get_totp_slot_count() == 15
assert C.NK_get_otp_name_length() == 15
assert C.NK_get_otp_secret_length() == 40