mirror of
https://github.com/polhenarejos/pico-fido
synced 2026-06-11 21:08:16 +02:00
Compare commits
13 Commits
dc6007d1b4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be6bda1baa | ||
|
|
ac2d839c15 | ||
|
|
0982522447 | ||
|
|
f7edfc916a | ||
|
|
0fd81c47d6 | ||
|
|
9ffcfb4beb | ||
|
|
3ccd6e827f | ||
|
|
a2044d697d | ||
|
|
659c04c837 | ||
|
|
a0437dbfb2 | ||
|
|
604e7868e2 | ||
|
|
0e3d0d9a7d | ||
|
|
1f4be2a051 |
Submodule pico-keys-sdk updated: c4bffd5433...f94c74a74c
@@ -34,9 +34,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next);
|
|||||||
|
|
||||||
const uint8_t aaguid[16] = { 0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45 }; // First 16 bytes of SHA256("Pico FIDO2")
|
const uint8_t aaguid[16] = { 0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45 }; // First 16 bytes of SHA256("Pico FIDO2")
|
||||||
|
|
||||||
const uint8_t *cbor_data = NULL;
|
static const uint8_t *volatile cbor_data = NULL;
|
||||||
size_t cbor_len = 0;
|
static volatile size_t cbor_len = 0;
|
||||||
uint8_t cbor_cmd = 0;
|
static volatile uint8_t cbor_cmd = 0;
|
||||||
|
|
||||||
int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
|
int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
|
||||||
if (len == 0 && cmd == CTAPHID_CBOR) {
|
if (len == 0 && cmd == CTAPHID_CBOR) {
|
||||||
@@ -108,7 +108,10 @@ void *cbor_thread(void *arg) {
|
|||||||
if (m == EV_EXIT) {
|
if (m == EV_EXIT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
apdu.sw = (uint16_t)cbor_parse(cbor_cmd, cbor_data, cbor_len);
|
const uint8_t *data = (const uint8_t *)cbor_data;
|
||||||
|
size_t len = cbor_len;
|
||||||
|
uint8_t cmd = cbor_cmd;
|
||||||
|
apdu.sw = (uint16_t)cbor_parse(cmd, data, len);
|
||||||
if (apdu.sw == 0) {
|
if (apdu.sw == 0) {
|
||||||
DEBUG_DATA(res_APDU, res_APDU_size);
|
DEBUG_DATA(res_APDU, res_APDU_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "mbedtls/ecdh.h"
|
#include "mbedtls/ecdh.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#include "mbedtls/hkdf.h"
|
#include "mbedtls/hkdf.h"
|
||||||
|
#include "mbedtls/constant_time.h"
|
||||||
#include "cbor.h"
|
#include "cbor.h"
|
||||||
#include "ctap.h"
|
#include "ctap.h"
|
||||||
#include "ctap2_cbor.h"
|
#include "ctap2_cbor.h"
|
||||||
@@ -221,10 +222,10 @@ int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t l
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (protocol == 1) {
|
if (protocol == 1) {
|
||||||
return ct_memcmp(sign, hmac, 16);
|
return mbedtls_ct_memcmp(sign, hmac, 16);
|
||||||
}
|
}
|
||||||
else if (protocol == 2) {
|
else if (protocol == 2) {
|
||||||
return ct_memcmp(sign, hmac, 32);
|
return mbedtls_ct_memcmp(sign, hmac, 32);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -491,7 +492,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
pin_derive_verifier(paddedNewPin, 16, dhash);
|
pin_derive_verifier(paddedNewPin, 16, dhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
|
if (mbedtls_ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
|
||||||
regenerate();
|
regenerate();
|
||||||
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
|
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
|
||||||
if (retries == 0) {
|
if (retries == 0) {
|
||||||
@@ -569,7 +570,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
pin_data[2] = 1; // New format indicator
|
pin_data[2] = 1; // New format indicator
|
||||||
pin_derive_verifier(dhash, 16, pin_data + 3);
|
pin_derive_verifier(dhash, 16, pin_data + 3);
|
||||||
|
|
||||||
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1 && ct_memcmp(pin_data + 3, file_get_data(ef_pin) + 3, 32) == 0) {
|
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1 && mbedtls_ct_memcmp(pin_data + 3, file_get_data(ef_pin) + 3, 32) == 0) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
|
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
|
||||||
}
|
}
|
||||||
file_put_data(ef_pin, pin_data, sizeof(pin_data));
|
file_put_data(ef_pin, pin_data, sizeof(pin_data));
|
||||||
@@ -652,7 +653,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
else {
|
else {
|
||||||
pin_derive_verifier(paddedNewPin, 16, dhash);
|
pin_derive_verifier(paddedNewPin, 16, dhash);
|
||||||
}
|
}
|
||||||
if (ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
|
if (mbedtls_ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
|
||||||
regenerate();
|
regenerate();
|
||||||
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
|
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
|
||||||
mbedtls_platform_zeroize(dhash, sizeof(dhash));
|
mbedtls_platform_zeroize(dhash, sizeof(dhash));
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
int cbor_get_assertion(const uint8_t *data, size_t len, bool next);
|
int cbor_get_assertion(const uint8_t *data, size_t len, bool next);
|
||||||
|
extern char *rp_id, *user_name, *display_name;
|
||||||
|
|
||||||
bool residentx = false;
|
bool residentx = false;
|
||||||
Credential credsx[MAX_CREDENTIAL_COUNT_IN_LIST] = { 0 };
|
Credential credsx[MAX_CREDENTIAL_COUNT_IN_LIST] = { 0 };
|
||||||
@@ -205,6 +206,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
|
|||||||
if (rpId.present == false || clientDataHash.present == false) {
|
if (rpId.present == false || clientDataHash.present == false) {
|
||||||
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
||||||
}
|
}
|
||||||
|
rp_id = rpId.data;
|
||||||
|
user_name = NULL;
|
||||||
|
display_name = NULL;
|
||||||
|
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
uint8_t rp_id_hash[32] = {0};
|
uint8_t rp_id_hash[32] = {0};
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "crypto_utils.h"
|
#include "crypto_utils.h"
|
||||||
|
|
||||||
|
char *rp_id = NULL, *user_name = NULL, *display_name = NULL;
|
||||||
|
|
||||||
int cbor_make_credential(const uint8_t *data, size_t len) {
|
int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||||
CborParser parser;
|
CborParser parser;
|
||||||
CborValue map;
|
CborValue map;
|
||||||
@@ -192,6 +194,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CBOR_PARSE_MAP_END(map, 1);
|
CBOR_PARSE_MAP_END(map, 1);
|
||||||
|
rp_id = rp.id.data;
|
||||||
|
user_name = user.parent.name.data;
|
||||||
|
display_name = user.displayName.data;
|
||||||
|
|
||||||
uint8_t flags = FIDO2_AUT_FLAG_AT;
|
uint8_t flags = FIDO2_AUT_FLAG_AT;
|
||||||
uint8_t rp_id_hash[32] = {0};
|
uint8_t rp_id_hash[32] = {0};
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ int cbor_reset(void) {
|
|||||||
return CTAP2_ERR_NOT_ALLOWED;
|
return CTAP2_ERR_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (wait_button_pressed() == true) {
|
if (wait_button_pressed() > 0) {
|
||||||
return CTAP2_ERR_USER_ACTION_TIMEOUT;
|
return CTAP2_ERR_USER_ACTION_TIMEOUT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,9 +20,16 @@
|
|||||||
#include "ctap2_cbor.h"
|
#include "ctap2_cbor.h"
|
||||||
#include "ctap.h"
|
#include "ctap.h"
|
||||||
|
|
||||||
|
extern char *rp_id, *user_name, *display_name;
|
||||||
|
|
||||||
int cbor_selection(void) {
|
int cbor_selection(void) {
|
||||||
if (wait_button_pressed() == true) {
|
rp_id = user_name = display_name = NULL;
|
||||||
|
int ret = wait_button_pressed() ;
|
||||||
|
if (ret == 1) {
|
||||||
return CTAP2_ERR_USER_ACTION_TIMEOUT;
|
return CTAP2_ERR_USER_ACTION_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
else if (ret == 2) {
|
||||||
|
return CTAP2_ERR_OPERATION_DENIED;
|
||||||
|
}
|
||||||
return CTAP2_OK;
|
return CTAP2_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int cmd_authenticate(void) {
|
|||||||
if (req->keyHandleLen < KEY_HANDLE_LEN) {
|
if (req->keyHandleLen < KEY_HANDLE_LEN) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (P1(apdu) == CTAP_AUTH_ENFORCE && wait_button_pressed() == true) {
|
if (P1(apdu) == CTAP_AUTH_ENFORCE && wait_button_pressed() > 0) {
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ int cmd_register(void) {
|
|||||||
if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE) {
|
if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE) {
|
||||||
return SW_WRONG_LENGTH();
|
return SW_WRONG_LENGTH();
|
||||||
}
|
}
|
||||||
if (wait_button_pressed() == true) {
|
if (wait_button_pressed() > 0) {
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
if (memcmp(req->appId, bogus_firefox,
|
if (memcmp(req->appId, bogus_firefox,
|
||||||
|
|||||||
@@ -498,22 +498,28 @@ void init_fido(void) {
|
|||||||
needs_power_cycle = false;
|
needs_power_cycle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wait_button_pressed(void) {
|
int wait_button_pressed(void) {
|
||||||
uint32_t val = EV_PRESS_BUTTON;
|
uint32_t val = EV_PRESS_BUTTON;
|
||||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||||
queue_try_add(&card_to_usb_q, &val);
|
queue_try_add(&card_to_usb_q, &val);
|
||||||
do {
|
do {
|
||||||
queue_remove_blocking(&usb_to_card_q, &val);
|
queue_remove_blocking(&usb_to_card_q, &val);
|
||||||
} while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
} while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT && val != EV_BUTTON_CANCELLED);
|
||||||
#endif
|
#endif
|
||||||
return val == EV_BUTTON_TIMEOUT;
|
if (val == EV_BUTTON_TIMEOUT) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (val == EV_BUTTON_CANCELLED) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_present_time_limit = 0;
|
uint32_t user_present_time_limit = 0;
|
||||||
|
|
||||||
bool check_user_presence(void) {
|
bool check_user_presence(void) {
|
||||||
if (user_present_time_limit == 0 || user_present_time_limit + TRANSPORT_TIME_LIMIT < board_millis()) {
|
if (user_present_time_limit == 0 || user_present_time_limit + TRANSPORT_TIME_LIMIT < board_millis()) {
|
||||||
if (wait_button_pressed() == true) { //timeout
|
if (wait_button_pressed() > 0) { //timeout
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//user_present_time_limit = board_millis();
|
//user_present_time_limit = board_millis();
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ extern int derive_key(const uint8_t *app_id,
|
|||||||
int,
|
int,
|
||||||
mbedtls_ecp_keypair *key);
|
mbedtls_ecp_keypair *key);
|
||||||
extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecp_keypair *);
|
extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecp_keypair *);
|
||||||
extern bool wait_button_pressed(void);
|
extern int wait_button_pressed(void);
|
||||||
extern void init_fido(void);
|
extern void init_fido(void);
|
||||||
extern void init_otp(void);
|
extern void init_otp(void);
|
||||||
extern void scan_all(void);
|
extern void scan_all(void);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "asn1.h"
|
#include "tlv.h"
|
||||||
#include "management.h"
|
#include "management.h"
|
||||||
|
|
||||||
bool is_gpg = true;
|
bool is_gpg = true;
|
||||||
@@ -64,9 +64,9 @@ bool cap_supported(uint16_t cap) {
|
|||||||
uint16_t tag = 0x0;
|
uint16_t tag = 0x0;
|
||||||
uint8_t *tag_data = NULL, *p = NULL;
|
uint8_t *tag_data = NULL, *p = NULL;
|
||||||
uint16_t tag_len = 0;
|
uint16_t tag_len = 0;
|
||||||
asn1_ctx_t ctxi;
|
tlv_ctx_t ctxi;
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
while (tlv_walk(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||||
if (tag == TAG_USB_ENABLED) {
|
if (tag == TAG_USB_ENABLED) {
|
||||||
uint16_t ecaps = tag_data[0];
|
uint16_t ecaps = tag_data[0];
|
||||||
if (tag_len == 2) {
|
if (tag_len == 2) {
|
||||||
|
|||||||
158
src/fido/oath.c
158
src/fido/oath.c
@@ -22,7 +22,7 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "asn1.h"
|
#include "tlv.h"
|
||||||
#include "crypto_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "management.h"
|
#include "management.h"
|
||||||
|
|
||||||
@@ -128,9 +128,9 @@ static int oath_unload(void) {
|
|||||||
static file_t *find_oath_cred(const uint8_t *name, size_t name_len) {
|
static file_t *find_oath_cred(const uint8_t *name, size_t name_len) {
|
||||||
for (int i = 0; i < MAX_OATH_CRED; i++) {
|
for (int i = 0; i < MAX_OATH_CRED; i++) {
|
||||||
file_t *ef = file_search((uint16_t)(EF_OATH_CRED + i));
|
file_t *ef = file_search((uint16_t)(EF_OATH_CRED + i));
|
||||||
asn1_ctx_t ctxi, ef_tag = { 0 };
|
tlv_ctx_t ctxi, ef_tag = { 0 };
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||||
if (file_has_data(ef) && asn1_find_tag(&ctxi, TAG_NAME, &ef_tag) == true && ef_tag.len == name_len && memcmp(ef_tag.data, name, name_len) == 0) {
|
if (file_has_data(ef) && tlv_find_tag(&ctxi, TAG_NAME, &ef_tag) == true && ef_tag.len == name_len && memcmp(ef_tag.data, name, name_len) == 0) {
|
||||||
return ef;
|
return ef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,16 +141,16 @@ static int cmd_put(void) {
|
|||||||
if (validated == false) {
|
if (validated == false) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, key = { 0 }, name = { 0 }, imf = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, name = { 0 }, imf = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) {
|
if (tlv_find_tag(&ctxi, TAG_KEY, &key) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
|
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
|
||||||
if (asn1_find_tag(&ctxi, TAG_IMF, &imf) == false) {
|
if (tlv_find_tag(&ctxi, TAG_IMF, &imf) == false) {
|
||||||
memcpy(apdu.data + apdu.nc, "\x7a\x08\x00\x00\x00\x00\x00\x00\x00\x00", 10);
|
memcpy(apdu.data + apdu.nc, "\x7a\x08\x00\x00\x00\x00\x00\x00\x00\x00", 10);
|
||||||
apdu.nc += 10;
|
apdu.nc += 10;
|
||||||
}
|
}
|
||||||
@@ -189,9 +189,9 @@ static int cmd_delete(void) {
|
|||||||
if (validated == false) {
|
if (validated == false) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, ctxo = { 0 };
|
tlv_ctx_t ctxi, ctxo = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &ctxo) == true) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &ctxo) == true) {
|
||||||
file_t *ef = find_oath_cred(ctxo.data, ctxo.len);
|
file_t *ef = find_oath_cred(ctxo.data, ctxo.len);
|
||||||
if (ef) {
|
if (ef) {
|
||||||
file_delete(ef);
|
file_delete(ef);
|
||||||
@@ -224,9 +224,9 @@ static int cmd_set_code(void) {
|
|||||||
validated = true;
|
validated = true;
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) {
|
if (tlv_find_tag(&ctxi, TAG_KEY, &key) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (key.len == 0) {
|
if (key.len == 0) {
|
||||||
@@ -234,10 +234,10 @@ static int cmd_set_code(void) {
|
|||||||
validated = true;
|
validated = true;
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
if (tlv_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) {
|
if (tlv_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,19 +286,19 @@ static int cmd_list(void) {
|
|||||||
for (int i = 0; i < MAX_OATH_CRED; i++) {
|
for (int i = 0; i < MAX_OATH_CRED; i++) {
|
||||||
file_t *ef = file_search((uint16_t)(EF_OATH_CRED + i));
|
file_t *ef = file_search((uint16_t)(EF_OATH_CRED + i));
|
||||||
if (file_has_data(ef)) {
|
if (file_has_data(ef)) {
|
||||||
asn1_ctx_t ctxi, key = { 0 }, name = { 0 }, pws = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, name = { 0 }, pws = { 0 };
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == true && asn1_find_tag(&ctxi, TAG_KEY, &key) == true) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == true && tlv_find_tag(&ctxi, TAG_KEY, &key) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_NAME_LIST;
|
res_APDU[res_APDU_size++] = TAG_NAME_LIST;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(name.len + 1 + (ext ? 1 : 0));
|
res_APDU[res_APDU_size++] = (uint8_t)(name.len + 1 + (ext ? 1 : 0));
|
||||||
res_APDU[res_APDU_size++] = key.data[0];
|
res_APDU[res_APDU_size++] = key.data[0];
|
||||||
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
|
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
|
||||||
if (ext) {
|
if (ext) {
|
||||||
uint8_t props = 0x0;
|
uint8_t props = 0x0;
|
||||||
if (asn1_find_tag(&ctxi, TAG_PWS_LOGIN, &pws) == true || asn1_find_tag(&ctxi, TAG_PWS_PASSWORD, &pws) == true || asn1_find_tag(&ctxi, TAG_PWS_METADATA, &pws) == true) {
|
if (tlv_find_tag(&ctxi, TAG_PWS_LOGIN, &pws) == true || tlv_find_tag(&ctxi, TAG_PWS_PASSWORD, &pws) == true || tlv_find_tag(&ctxi, TAG_PWS_METADATA, &pws) == true) {
|
||||||
props |= 0x4;
|
props |= 0x4;
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_PROPERTY, &pws) == true && (pws.data[0] & PROP_TOUCH)) {
|
if (tlv_find_tag(&ctxi, TAG_PROPERTY, &pws) == true && (pws.data[0] & PROP_TOUCH)) {
|
||||||
props |= 0x1;
|
props |= 0x1;
|
||||||
}
|
}
|
||||||
res_APDU[res_APDU_size++] = props;
|
res_APDU[res_APDU_size++] = props;
|
||||||
@@ -311,12 +311,12 @@ static int cmd_list(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_validate(void) {
|
static int cmd_validate(void) {
|
||||||
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
if (tlv_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) {
|
if (tlv_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
file_t *ef = file_search(EF_OATH_CODE);
|
file_t *ef = file_search(EF_OATH_CODE);
|
||||||
@@ -387,26 +387,26 @@ static int cmd_calculate(void) {
|
|||||||
if (validated == false) {
|
if (validated == false) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
if (tlv_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
file_t *ef = find_oath_cred(name.data, name.len);
|
file_t *ef = find_oath_cred(name.data, name.len);
|
||||||
if (file_has_data(ef) == false) {
|
if (file_has_data(ef) == false) {
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxe;
|
tlv_ctx_t ctxe;
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe);
|
||||||
if (asn1_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
if (tlv_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
|
if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) {
|
||||||
if (asn1_find_tag(&ctxe, TAG_IMF, &chal) == false) {
|
if (tlv_find_tag(&ctxe, TAG_IMF, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,9 +423,9 @@ static int cmd_calculate(void) {
|
|||||||
v++;
|
v++;
|
||||||
uint8_t *tmp = (uint8_t *) calloc(1, ef_size);
|
uint8_t *tmp = (uint8_t *) calloc(1, ef_size);
|
||||||
memcpy(tmp, file_get_data(ef), ef_size);
|
memcpy(tmp, file_get_data(ef), ef_size);
|
||||||
asn1_ctx_t ctxt;
|
tlv_ctx_t ctxt;
|
||||||
asn1_ctx_init(tmp, (uint16_t)ef_size, &ctxt);
|
tlv_ctx_init(tmp, (uint16_t)ef_size, &ctxt);
|
||||||
asn1_find_tag(&ctxt, TAG_IMF, &chal);
|
tlv_find_tag(&ctxt, TAG_IMF, &chal);
|
||||||
put_uint64_be(v, chal.data);
|
put_uint64_be(v, chal.data);
|
||||||
file_put_data(ef, tmp, (uint16_t)ef_size);
|
file_put_data(ef, tmp, (uint16_t)ef_size);
|
||||||
flash_commit();
|
flash_commit();
|
||||||
@@ -436,15 +436,15 @@ static int cmd_calculate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_calculate_all(void) {
|
static int cmd_calculate_all(void) {
|
||||||
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, prop = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, prop = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (P2(apdu) != 0x0 && P2(apdu) != 0x1) {
|
if (P2(apdu) != 0x0 && P2(apdu) != 0x1) {
|
||||||
return SW_INCORRECT_P1P2();
|
return SW_INCORRECT_P1P2();
|
||||||
}
|
}
|
||||||
if (validated == false) {
|
if (validated == false) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
if (tlv_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
res_APDU_size = 0;
|
res_APDU_size = 0;
|
||||||
@@ -453,9 +453,9 @@ static int cmd_calculate_all(void) {
|
|||||||
if (file_has_data(ef)) {
|
if (file_has_data(ef)) {
|
||||||
const uint8_t *ef_data = file_get_data(ef);
|
const uint8_t *ef_data = file_get_data(ef);
|
||||||
size_t ef_len = file_get_size(ef);
|
size_t ef_len = file_get_size(ef);
|
||||||
asn1_ctx_t ctxe;
|
tlv_ctx_t ctxe;
|
||||||
asn1_ctx_init((uint8_t *)ef_data, (uint16_t)ef_len, &ctxe);
|
tlv_ctx_init((uint8_t *)ef_data, (uint16_t)ef_len, &ctxe);
|
||||||
if (asn1_find_tag(&ctxe, TAG_NAME, &name) == false || asn1_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
if (tlv_find_tag(&ctxe, TAG_NAME, &name) == false || tlv_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
res_APDU[res_APDU_size++] = TAG_NAME;
|
res_APDU[res_APDU_size++] = TAG_NAME;
|
||||||
@@ -466,7 +466,7 @@ static int cmd_calculate_all(void) {
|
|||||||
res_APDU[res_APDU_size++] = 1;
|
res_APDU[res_APDU_size++] = 1;
|
||||||
res_APDU[res_APDU_size++] = key.data[1];
|
res_APDU[res_APDU_size++] = key.data[1];
|
||||||
}
|
}
|
||||||
else if (asn1_find_tag(&ctxe, TAG_PROPERTY, &prop) == true && (prop.data[0] & PROP_TOUCH)) {
|
else if (tlv_find_tag(&ctxe, TAG_PROPERTY, &prop) == true && (prop.data[0] & PROP_TOUCH)) {
|
||||||
res_APDU[res_APDU_size++] = TAG_TOUCH_RESPONSE;
|
res_APDU[res_APDU_size++] = TAG_TOUCH_RESPONSE;
|
||||||
res_APDU[res_APDU_size++] = 1;
|
res_APDU[res_APDU_size++] = 1;
|
||||||
res_APDU[res_APDU_size++] = key.data[1];
|
res_APDU[res_APDU_size++] = key.data[1];
|
||||||
@@ -495,9 +495,9 @@ static int cmd_set_otp_pin(void) {
|
|||||||
if (file_has_data(ef_otp_pin)) {
|
if (file_has_data(ef_otp_pin)) {
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, pw = { 0 };
|
tlv_ctx_t ctxi, pw = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
if (tlv_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
hsh[0] = MAX_OTP_COUNTER;
|
hsh[0] = MAX_OTP_COUNTER;
|
||||||
@@ -513,16 +513,16 @@ static int cmd_change_otp_pin(void) {
|
|||||||
if (!file_has_data(ef_otp_pin)) {
|
if (!file_has_data(ef_otp_pin)) {
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, pw = { 0 }, new_pw = { 0 };
|
tlv_ctx_t ctxi, pw = { 0 }, new_pw = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
if (tlv_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
double_hash_pin(pw.data, pw.len, hsh + 1);
|
double_hash_pin(pw.data, pw.len, hsh + 1);
|
||||||
if (memcmp(file_get_data(ef_otp_pin) + 1, hsh + 1, 32) != 0) {
|
if (memcmp(file_get_data(ef_otp_pin) + 1, hsh + 1, 32) != 0) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_NEW_PASSWORD, &new_pw) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NEW_PASSWORD, &new_pw) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
hsh[0] = MAX_OTP_COUNTER;
|
hsh[0] = MAX_OTP_COUNTER;
|
||||||
@@ -538,9 +538,9 @@ static int cmd_verify_otp_pin(void) {
|
|||||||
if (!file_has_data(ef_otp_pin)) {
|
if (!file_has_data(ef_otp_pin)) {
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxi, pw = { 0 };
|
tlv_ctx_t ctxi, pw = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
if (tlv_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
double_hash_pin(pw.data, pw.len, hsh + 1);
|
double_hash_pin(pw.data, pw.len, hsh + 1);
|
||||||
@@ -562,29 +562,29 @@ static int cmd_verify_otp_pin(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_verify_hotp(void) {
|
static int cmd_verify_hotp(void) {
|
||||||
asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, code = { 0 };
|
tlv_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, code = { 0 };
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
uint32_t code_int = 0;
|
uint32_t code_int = 0;
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
file_t *ef = file_search_by_fid(EF_OATH_CRED, NULL, SPECIFY_EF);
|
file_t *ef = file_search_by_fid(EF_OATH_CRED, NULL, SPECIFY_EF);
|
||||||
if (file_has_data(ef) == false) {
|
if (file_has_data(ef) == false) {
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
}
|
}
|
||||||
asn1_ctx_t ctxe;
|
tlv_ctx_t ctxe;
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe);
|
||||||
if (asn1_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
if (tlv_find_tag(&ctxe, TAG_KEY, &key) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((key.data[0] & OATH_TYPE_MASK) != OATH_TYPE_HOTP) {
|
if ((key.data[0] & OATH_TYPE_MASK) != OATH_TYPE_HOTP) {
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxe, TAG_IMF, &chal) == false) {
|
if (tlv_find_tag(&ctxe, TAG_IMF, &chal) == false) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_RESPONSE, &code) == true) {
|
if (tlv_find_tag(&ctxi, TAG_RESPONSE, &code) == true) {
|
||||||
code_int = get_uint32_be(code.data);
|
code_int = get_uint32_be(code.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +608,7 @@ static int cmd_verify_hotp(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_rename(void) {
|
static int cmd_rename(void) {
|
||||||
asn1_ctx_t ctxi, name = { 0 }, new_name = { 0 };
|
tlv_ctx_t ctxi, name = { 0 }, new_name = { 0 };
|
||||||
|
|
||||||
if (validated == false) {
|
if (validated == false) {
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
@@ -616,13 +616,13 @@ static int cmd_rename(void) {
|
|||||||
if (apdu.data[0] != TAG_NAME) {
|
if (apdu.data[0] != TAG_NAME) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
|
|
||||||
asn1_ctx_init(name.data + name.len, (uint16_t)(apdu.nc - (name.data + name.len - apdu.data)), &ctxi);
|
tlv_ctx_init(name.data + name.len, (uint16_t)(apdu.nc - (name.data + name.len - apdu.data)), &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &new_name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &new_name) == false) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
if (name.len == new_name.len && memcmp(name.data, new_name.data, name.len) == 0) {
|
if (name.len == new_name.len && memcmp(name.data, new_name.data, name.len) == 0) {
|
||||||
@@ -634,8 +634,8 @@ static int cmd_rename(void) {
|
|||||||
}
|
}
|
||||||
uint8_t *fdata = file_get_data(ef);
|
uint8_t *fdata = file_get_data(ef);
|
||||||
uint16_t fsize = file_get_size(ef);
|
uint16_t fsize = file_get_size(ef);
|
||||||
asn1_ctx_init(fdata, fsize, &ctxi);
|
tlv_ctx_init(fdata, fsize, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
uint8_t *new_data = (uint8_t *) calloc(fsize + new_name.len - name.len, sizeof(uint8_t));
|
uint8_t *new_data = (uint8_t *) calloc(fsize + new_name.len - name.len, sizeof(uint8_t));
|
||||||
@@ -650,44 +650,44 @@ static int cmd_rename(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_get_credential(void) {
|
static int cmd_get_credential(void) {
|
||||||
asn1_ctx_t ctxi, name = { 0 };
|
tlv_ctx_t ctxi, name = { 0 };
|
||||||
if (apdu.nc < 3) {
|
if (apdu.nc < 3) {
|
||||||
return SW_INCORRECT_PARAMS();
|
return SW_INCORRECT_PARAMS();
|
||||||
}
|
}
|
||||||
if (apdu.data[0] != TAG_NAME) {
|
if (apdu.data[0] != TAG_NAME) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
tlv_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == false) {
|
||||||
return SW_WRONG_DATA();
|
return SW_WRONG_DATA();
|
||||||
}
|
}
|
||||||
file_t *ef = find_oath_cred(name.data, name.len);
|
file_t *ef = find_oath_cred(name.data, name.len);
|
||||||
if (file_has_data(ef) == false) {
|
if (file_has_data(ef) == false) {
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
}
|
}
|
||||||
asn1_ctx_t login = { 0 }, pw = { 0 }, meta = { 0 }, prop = { 0 };
|
tlv_ctx_t login = { 0 }, pw = { 0 }, meta = { 0 }, prop = { 0 };
|
||||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
tlv_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||||
if (asn1_find_tag(&ctxi, TAG_NAME, &name) == true) {
|
if (tlv_find_tag(&ctxi, TAG_NAME, &name) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_NAME;
|
res_APDU[res_APDU_size++] = TAG_NAME;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(name.len);
|
res_APDU[res_APDU_size++] = (uint8_t)(name.len);
|
||||||
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
|
memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len;
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_PWS_LOGIN, &login) == true) {
|
if (tlv_find_tag(&ctxi, TAG_PWS_LOGIN, &login) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_PWS_LOGIN;
|
res_APDU[res_APDU_size++] = TAG_PWS_LOGIN;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(login.len);
|
res_APDU[res_APDU_size++] = (uint8_t)(login.len);
|
||||||
memcpy(res_APDU + res_APDU_size, login.data, login.len); res_APDU_size += login.len;
|
memcpy(res_APDU + res_APDU_size, login.data, login.len); res_APDU_size += login.len;
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_PWS_PASSWORD, &pw) == true) {
|
if (tlv_find_tag(&ctxi, TAG_PWS_PASSWORD, &pw) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_PWS_PASSWORD;
|
res_APDU[res_APDU_size++] = TAG_PWS_PASSWORD;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(pw.len);
|
res_APDU[res_APDU_size++] = (uint8_t)(pw.len);
|
||||||
memcpy(res_APDU + res_APDU_size, pw.data, pw.len); res_APDU_size += pw.len;
|
memcpy(res_APDU + res_APDU_size, pw.data, pw.len); res_APDU_size += pw.len;
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_PWS_METADATA, &meta) == true) {
|
if (tlv_find_tag(&ctxi, TAG_PWS_METADATA, &meta) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_PWS_METADATA;
|
res_APDU[res_APDU_size++] = TAG_PWS_METADATA;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(meta.len);
|
res_APDU[res_APDU_size++] = (uint8_t)(meta.len);
|
||||||
memcpy(res_APDU + res_APDU_size, meta.data, meta.len); res_APDU_size += meta.len;
|
memcpy(res_APDU + res_APDU_size, meta.data, meta.len); res_APDU_size += meta.len;
|
||||||
}
|
}
|
||||||
if (asn1_find_tag(&ctxi, TAG_PROPERTY, &prop) == true) {
|
if (tlv_find_tag(&ctxi, TAG_PROPERTY, &prop) == true) {
|
||||||
res_APDU[res_APDU_size++] = TAG_PROPERTY;
|
res_APDU[res_APDU_size++] = TAG_PROPERTY;
|
||||||
res_APDU[res_APDU_size++] = (uint8_t)(prop.len);
|
res_APDU[res_APDU_size++] = (uint8_t)(prop.len);
|
||||||
memcpy(res_APDU + res_APDU_size, prop.data, prop.len); res_APDU_size += prop.len;
|
memcpy(res_APDU + res_APDU_size, prop.data, prop.len); res_APDU_size += prop.len;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "asn1.h"
|
|
||||||
#include "hid/ctap_hid.h"
|
#include "hid/ctap_hid.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#if defined(PICO_PLATFORM)
|
#if defined(PICO_PLATFORM)
|
||||||
@@ -148,8 +147,7 @@ static int otp_select(app_t *a, uint8_t force) {
|
|||||||
if (cap_supported(CAP_OTP)) {
|
if (cap_supported(CAP_OTP)) {
|
||||||
a->process_apdu = otp_process_apdu;
|
a->process_apdu = otp_process_apdu;
|
||||||
a->unload = otp_unload;
|
a->unload = otp_unload;
|
||||||
if (file_has_data(file_search(EF_OTP_SLOT1)) ||
|
if (file_has_data(file_search(EF_OTP_SLOT1)) || file_has_data(file_search(EF_OTP_SLOT2))) {
|
||||||
file_has_data(file_search(EF_OTP_SLOT2))) {
|
|
||||||
config_seq = 1;
|
config_seq = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ RUN apt install -y libccid \
|
|||||||
cmake \
|
cmake \
|
||||||
libfuse-dev \
|
libfuse-dev \
|
||||||
python3-pyscard \
|
python3-pyscard \
|
||||||
|
libtss2-dev \
|
||||||
|
tpm2-tools \
|
||||||
|
swtpm \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
RUN pip3 install pytest pycvc cryptography inputimeout fido2==2.0.0 --break-system-packages
|
RUN pip3 install pytest pycvc cryptography inputimeout fido2==2.0.0 --break-system-packages
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ cd build
|
|||||||
esptool.py --chip ESP32-S2 merge_bin -o ../release/pico_fido_esp32-s2.bin @flash_args
|
esptool.py --chip ESP32-S2 merge_bin -o ../release/pico_fido_esp32-s2.bin @flash_args
|
||||||
cd ..
|
cd ..
|
||||||
else
|
else
|
||||||
|
sudo apt install -y libtss2-dev tpm2-tools swtpm cmake
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DENABLE_EMULATION=1 ..
|
cmake -DENABLE_EMULATION=1 ..
|
||||||
|
|||||||
Reference in New Issue
Block a user