Skip to content

Commit

Permalink
Fixed pin and unlock unit tests for UI
Browse files Browse the repository at this point in the history
  • Loading branch information
italo-sampaio committed Nov 18, 2022
1 parent bedd820 commit ea3abd3
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Ledger UI's tests
working-directory: ledger/src/ui/test/
run: |
for d in communication onboard; do
for d in communication onboard pin unlock; do
(cd "$d" && make clean test)
done
Expand Down
166 changes: 137 additions & 29 deletions ledger/src/ui/test/pin/test_pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,79 +27,187 @@
#include <assert.h>
#include <string.h>

#include "apdu.h"
#include "os.h"
#include "pin.h"

#define IS_VALID true
#define IS_NOT_VALID false

void set_payload(pin_t *pin_ctx, unsigned char *payload, size_t n) {
memcpy(GET_PIN(pin_ctx), payload, n);
}

void assert_pin(char *pin, bool expected) {
unsigned char pin_length = (char)strlen(pin);
unsigned char *pin_buffer = malloc(pin_length + 2);
unsigned char pin_buffer[16];
memset(pin_buffer, 0, sizeof(pin_buffer));
pin_buffer[0] = pin_length;
strcpy((char *)pin_buffer + 1, pin);

pin_t pin_ctx;
init_pin_ctx(&pin_ctx, pin_buffer);
assert(is_pin_valid(&pin_ctx) == expected);
free(pin_buffer);
// Mock RSK_PIN_CMD
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

assert(is_pin_valid() == expected);
}

void test_update_pin_buffer() {
printf("Test update pin buffer...\n");

unsigned char pin_buffer[] = "X1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}
}

void test_set_pin() {
printf("Test set pin ok...\n");

unsigned char pin_buffer[] = "X1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
assert(3 == set_pin());
assert(get_mock_func_call(0) == MOCK_FUNC_OS_PERSO_SET_PIN);
assert(get_mock_func_call(1) == MOCK_FUNC_OS_GLOBAL_PIN_INVALIDATE);
assert(get_mock_func_call(2) == MOCK_FUNC_OS_GLOBAL_PIN_CHECK);
assert(get_mock_func_call_count() == 3);
}

void test_ok() {
printf("Test OK...\n");
void test_set_pin_invalid() {
printf("Test set pin invalid...\n");

unsigned char pin_buffer[] = "X12345678";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
assert(0x69A0 == set_pin()); // ERR_INVALID_PIN
assert(get_mock_func_call_count() == 0);
}

void test_validate_ok() {
printf("Test validate pin OK...\n");

assert_pin("abcdefgh", IS_VALID);
assert_pin("8b23ef1s", IS_VALID);
assert_pin("MN22P3S9", IS_VALID);
assert_pin("MN22p3s9", IS_VALID);
}

void test_numeric_pin() {
printf("Test pin with only numbers...\n");
void test_validate_numeric_pin() {
printf("Test validate pin with only numbers...\n");

assert_pin("1234", IS_NOT_VALID);
assert_pin("123456", IS_NOT_VALID);
assert_pin("12345678", IS_NOT_VALID);
assert_pin("1234567890", IS_NOT_VALID);
}

void test_pin_too_long() {
printf("Test pin buffer too long...\n");
void test_validate_pin_too_long() {
printf("Test validate pin buffer too long...\n");

assert_pin("abcdefghi", IS_NOT_VALID);
assert_pin("8b23ef1s85", IS_NOT_VALID);
assert_pin("MN22P3S9P20", IS_NOT_VALID);
assert_pin("MNOPQRSTQDAS", IS_NOT_VALID);
// Long pins are accepted, but internally capped to PIN_LENGTH
assert_pin("abcdefghi", IS_VALID);
assert_pin("8b23ef1s85", IS_VALID);
assert_pin("MN22P3S9P20", IS_VALID);
assert_pin("MNOPQRSTQDAS", IS_VALID);
}

void test_pin_too_short() {
printf("Test pin buffer too short...\n");
void test_validate_pin_too_short() {
printf("Test validate pin buffer too short...\n");

assert_pin("abcdefg", IS_NOT_VALID);
assert_pin("8b23ef", IS_NOT_VALID);
assert_pin("MN22P", IS_NOT_VALID);
assert_pin("MNOP", IS_NOT_VALID);
}

void test_pin_non_alpha() {
printf("Test pin non alpha chars...\n");
void test_validate_pin_non_alpha() {
printf("Test validate pin non alpha chars...\n");

assert_pin("a1-@.;", IS_NOT_VALID);
assert_pin("!@#$^&*", IS_NOT_VALID);
assert_pin("(),./;']", IS_NOT_VALID);
assert_pin("abcdefg", IS_NOT_VALID);
}

int main() {
test_ok();
void test_unlock_with_pin() {
printf("Test unlock with pin...\n");

unsigned char pin_buffer[] = "1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
assert(1 == unlock_with_pin(false));
assert(get_mock_func_call(0) == MOCK_FUNC_OS_GLOBAL_PIN_CHECK);
assert(get_mock_func_call_count() == 1);
}

test_numeric_pin();
test_pin_too_long();
test_pin_too_short();
test_pin_non_alpha();
void test_unlock_with_pin_prepended_length() {
printf("Test unlock with pin (prepended length)...\n");

unsigned char pin_buffer[] = "X1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
assert(1 == unlock_with_pin(true));
assert(get_mock_func_call(0) == MOCK_FUNC_OS_GLOBAL_PIN_CHECK);
assert(get_mock_func_call_count() == 1);
}

void test_set_device_pin() {
printf("Test set device pin...\n");

unsigned char pin_buffer[] = "X1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
set_device_pin();
assert(get_mock_func_call(0) == MOCK_FUNC_OS_PERSO_SET_PIN);
assert(get_mock_func_call_count() == 1);
}

int main() {
test_update_pin_buffer();
test_set_pin();
test_set_pin_invalid();
test_validate_ok();
test_validate_numeric_pin();
test_validate_pin_too_long();
test_validate_pin_too_short();
test_validate_pin_non_alpha();
test_unlock_with_pin();
test_unlock_with_pin_prepended_length();
test_set_device_pin();

return 0;
}
41 changes: 16 additions & 25 deletions ledger/src/ui/test/unlock/test_unlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,25 @@
#include "os.h"
#include "unlock.h"

void test_ok() {
printf("Test OK...\n");

pin_t pin_ctx;
init_pin_ctx(&pin_ctx, (unsigned char *)"1234567a\0\0");

unsigned int tx = unlock(&pin_ctx);
assert(tx == 3);
assert(APDU_OP() == 1);
}

void test_wrong_pin() {
printf("Test wrong pin...\n");

pin_t pin_ctx;
init_pin_ctx(&pin_ctx, (unsigned char *)"wrong-pin\0");

unsigned int tx = unlock(&pin_ctx);
assert(tx == 3);
assert(APDU_OP() == 0);
void test_unlock() {
printf("Test unlock...\n");

unsigned char pin_buffer[] = "1234567a";
unsigned int rx = 4;
for (int i = 0; i < strlen((const char *)pin_buffer); i++) {
SET_APDU_AT(2, i);
SET_APDU_AT(3, pin_buffer[i]);
assert(3 == update_pin_buffer(rx));
}

reset_mock_func_call_list();
assert(3 == unlock());
assert(get_mock_func_call(0) == MOCK_FUNC_OS_GLOBAL_PIN_CHECK);
assert(get_mock_func_call_count() == 1);
}

int main() {
// Set device pin
mock_set_pin((unsigned char *)"1234567a", strlen("1234567a"));

test_ok();
test_wrong_pin();
test_unlock();

return 0;
}

0 comments on commit ea3abd3

Please sign in to comment.