mirror of
https://github.com/polhenarejos/pico-fido.git
synced 2024-09-20 03:10:10 +00:00
Added support for management via Yubikey Manager to enable/disable specific interfaces individually.
All interfaces are enabled by default. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
a79842b33f
commit
2b1227b105
@ -22,6 +22,7 @@
|
||||
#include "random.h"
|
||||
#include "files.h"
|
||||
#include "hid/ctap_hid.h"
|
||||
#include "management.h"
|
||||
|
||||
const uint8_t u2f_aid[] = {
|
||||
7,
|
||||
@ -32,7 +33,7 @@ int u2f_unload();
|
||||
int u2f_process_apdu();
|
||||
|
||||
app_t *u2f_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, u2f_aid + 1, MIN(aid_len, u2f_aid[0]))) {
|
||||
if (!memcmp(aid, u2f_aid + 1, MIN(aid_len, u2f_aid[0])) && cap_supported(CAP_U2F)) {
|
||||
a->aid = u2f_aid;
|
||||
a->process_apdu = u2f_process_apdu;
|
||||
a->unload = u2f_unload;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "bsp/board.h"
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include "management.h"
|
||||
|
||||
int fido_process_apdu();
|
||||
int fido_unload();
|
||||
@ -52,7 +53,7 @@ const uint8_t atr_fido[] = {
|
||||
};
|
||||
|
||||
app_t *fido_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, fido_aid + 1, MIN(aid_len, fido_aid[0]))) {
|
||||
if (!memcmp(aid, fido_aid + 1, MIN(aid_len, fido_aid[0])) && cap_supported(CAP_FIDO2)) {
|
||||
a->aid = fido_aid;
|
||||
a->process_apdu = fido_process_apdu;
|
||||
a->unload = fido_unload;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define EF_PIN 0x1080
|
||||
#define EF_AUTHTOKEN 0x1090
|
||||
#define EF_MINPINLEN 0x1100
|
||||
#define EF_DEV_CONF 0x1122
|
||||
#define EF_CRED 0xCF00 // Creds at 0xCF00 - 0xCFFF
|
||||
#define EF_RP 0xD000 // RPs at 0xD000 - 0xD0FF
|
||||
#define EF_LARGEBLOB 0x1101 // Large Blob Array
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include "hsm.h"
|
||||
#include "apdu.h"
|
||||
#include "version.h"
|
||||
#include "files.h"
|
||||
#include "asn1.h"
|
||||
#include "management.h"
|
||||
|
||||
int man_process_apdu();
|
||||
int man_unload();
|
||||
@ -27,7 +30,7 @@ const uint8_t man_aid[] = {
|
||||
8,
|
||||
0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17
|
||||
};
|
||||
|
||||
extern void scan_all();
|
||||
app_t *man_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, man_aid + 1, MIN(aid_len, man_aid[0]))) {
|
||||
a->aid = man_aid;
|
||||
@ -36,6 +39,7 @@ app_t *man_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
sprintf((char *)res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR);
|
||||
res_APDU_size = strlen((char *)res_APDU);
|
||||
apdu.ne = res_APDU_size;
|
||||
scan_all();
|
||||
return a;
|
||||
}
|
||||
return NULL;
|
||||
@ -49,43 +53,69 @@ int man_unload() {
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
bool cap_supported(uint16_t cap) {
|
||||
file_t *ef = search_dynamic_file(EF_DEV_CONF);
|
||||
if (file_has_data(ef)) {
|
||||
uint16_t tag = 0x0, data_len = file_get_size(ef);
|
||||
uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
|
||||
size_t tag_len = 0;
|
||||
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag == TAG_USB_ENABLED) {
|
||||
uint16_t ecaps = tag_data[0];
|
||||
if (tag_len == 2) {
|
||||
ecaps = (tag_data[1] << 8) | tag_data[0];
|
||||
}
|
||||
return (ecaps & cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int man_get_config() {
|
||||
file_t *ef = search_dynamic_file(EF_DEV_CONF);
|
||||
res_APDU_size = 0;
|
||||
res_APDU[res_APDU_size++] = 0; // Overall length. Filled later
|
||||
res_APDU[res_APDU_size++] = 0x01;
|
||||
res_APDU[res_APDU_size++] = TAG_USB_SUPPORTED;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = 0x02;
|
||||
res_APDU[res_APDU_size++] = 0x01 | 0x02 | 0x20;
|
||||
res_APDU[res_APDU_size++] = 0x02;
|
||||
res_APDU[res_APDU_size++] = CAP_FIDO2 >> 8;
|
||||
res_APDU[res_APDU_size++] = CAP_OTP | CAP_U2F | CAP_OATH;
|
||||
res_APDU[res_APDU_size++] = TAG_SERIAL;
|
||||
res_APDU[res_APDU_size++] = 4;
|
||||
#ifndef ENABLE_EMULATION
|
||||
pico_get_unique_board_id_string((char *) res_APDU + res_APDU_size, 4);
|
||||
#endif
|
||||
res_APDU_size += 4;
|
||||
res_APDU[res_APDU_size++] = 0x03;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = 0x02;
|
||||
res_APDU[res_APDU_size++] = 0x01 | 0x02 | 0x20;
|
||||
res_APDU[res_APDU_size++] = 0x04;
|
||||
res_APDU[res_APDU_size++] = TAG_FORM_FACTOR;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x01;
|
||||
res_APDU[res_APDU_size++] = 0x05;
|
||||
res_APDU[res_APDU_size++] = TAG_VERSION;
|
||||
res_APDU[res_APDU_size++] = 3;
|
||||
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR;
|
||||
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR;
|
||||
res_APDU[res_APDU_size++] = 0;
|
||||
res_APDU[res_APDU_size++] = 0x08;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x80;
|
||||
res_APDU[res_APDU_size++] = 0x0A;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x00;
|
||||
res_APDU[res_APDU_size++] = 0x0D;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x00;
|
||||
res_APDU[res_APDU_size++] = 0x0E;
|
||||
res_APDU[res_APDU_size++] = TAG_NFC_SUPPORTED;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x00;
|
||||
if (!file_has_data(ef)) {
|
||||
res_APDU[res_APDU_size++] = TAG_USB_ENABLED;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = CAP_FIDO2 >> 8;
|
||||
res_APDU[res_APDU_size++] = CAP_OTP | CAP_U2F | CAP_OATH;
|
||||
res_APDU[res_APDU_size++] = TAG_DEVICE_FLAGS;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = FLAG_EJECT;
|
||||
res_APDU[res_APDU_size++] = TAG_CONFIG_LOCK;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x00;
|
||||
res_APDU[res_APDU_size++] = TAG_NFC_ENABLED;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = 0x00;
|
||||
}
|
||||
else {
|
||||
memcpy(res_APDU + res_APDU_size, file_get_data(ef), file_get_size(ef));
|
||||
res_APDU_size += file_get_size(ef);
|
||||
}
|
||||
res_APDU[0] = res_APDU_size - 1;
|
||||
return 0;
|
||||
}
|
||||
@ -95,10 +125,22 @@ int cmd_read_config() {
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
int cmd_write_config() {
|
||||
if (apdu.data[0] != apdu.nc - 1) {
|
||||
return SW_WRONG_DATA();
|
||||
}
|
||||
file_t *ef = file_new(EF_DEV_CONF);
|
||||
flash_write_data_to_file(ef, apdu.data + 1, apdu.nc - 1);
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
#define INS_READ_CONFIG 0x1D
|
||||
#define INS_WRITE_CONFIG 0x1C
|
||||
|
||||
static const cmd_t cmds[] = {
|
||||
{ INS_READ_CONFIG, cmd_read_config },
|
||||
{ INS_WRITE_CONFIG, cmd_write_config },
|
||||
{ 0x00, 0x0 }
|
||||
};
|
||||
|
||||
|
55
src/fido/management.h
Normal file
55
src/fido/management.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the Pico FIDO distribution (https://github.com/polhenarejos/pico-fido).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _MANAGEMENT_H_
|
||||
#define _MANAGEMENT_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifndef ENABLE_EMULATION
|
||||
#include "pico/stdlib.h"
|
||||
#endif
|
||||
|
||||
#define TAG_USB_SUPPORTED 0x01
|
||||
#define TAG_SERIAL 0x02
|
||||
#define TAG_USB_ENABLED 0x03
|
||||
#define TAG_FORM_FACTOR 0x04
|
||||
#define TAG_VERSION 0x05
|
||||
#define TAG_AUTO_EJECT_TIMEOUT 0x06
|
||||
#define TAG_CHALRESP_TIMEOUT 0x07
|
||||
#define TAG_DEVICE_FLAGS 0x08
|
||||
#define TAG_APP_VERSIONS 0x09
|
||||
#define TAG_CONFIG_LOCK 0x0A
|
||||
#define TAG_UNLOCK 0x0B
|
||||
#define TAG_REBOOT 0x0C
|
||||
#define TAG_NFC_SUPPORTED 0x0D
|
||||
#define TAG_NFC_ENABLED 0x0E
|
||||
|
||||
#define CAP_OTP 0x01
|
||||
#define CAP_U2F 0x02
|
||||
#define CAP_FIDO2 0x200
|
||||
#define CAP_OATH 0x20
|
||||
#define CAP_PIV 0x10
|
||||
#define CAP_OPENPGP 0x08
|
||||
#define CAP_HSMAUTH 0x100
|
||||
|
||||
#define FLAG_REMOTE_WAKEUP 0x40
|
||||
#define FLAG_EJECT 0x80
|
||||
|
||||
extern bool cap_supported(uint16_t cap);
|
||||
extern int man_get_config();
|
||||
|
||||
#endif //_MANAGEMENT_H
|
@ -23,6 +23,7 @@
|
||||
#include "version.h"
|
||||
#include "asn1.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "management.h"
|
||||
|
||||
#define MAX_OATH_CRED 255
|
||||
#define CHALLENGE_LEN 8
|
||||
@ -36,7 +37,7 @@
|
||||
#define TAG_T_RESPONSE 0x76
|
||||
#define TAG_NO_RESPONSE 0x77
|
||||
#define TAG_PROPERTY 0x78
|
||||
#define TAG_VERSION 0x79
|
||||
#define TAG_T_VERSION 0x79
|
||||
#define TAG_IMF 0x7a
|
||||
#define TAG_ALGO 0x7b
|
||||
#define TAG_TOUCH_RESPONSE 0x7c
|
||||
@ -68,12 +69,12 @@ const uint8_t oath_aid[] = {
|
||||
};
|
||||
|
||||
app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, oath_aid + 1, MIN(aid_len, oath_aid[0]))) {
|
||||
if (!memcmp(aid, oath_aid + 1, MIN(aid_len, oath_aid[0])) && cap_supported(CAP_OATH)) {
|
||||
a->aid = oath_aid;
|
||||
a->process_apdu = oath_process_apdu;
|
||||
a->unload = oath_unload;
|
||||
res_APDU_size = 0;
|
||||
res_APDU[res_APDU_size++] = TAG_VERSION;
|
||||
res_APDU[res_APDU_size++] = TAG_T_VERSION;
|
||||
res_APDU[res_APDU_size++] = 3;
|
||||
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR;
|
||||
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "bsp/board.h"
|
||||
#endif
|
||||
#include "mbedtls/aes.h"
|
||||
#include "management.h"
|
||||
|
||||
#define FIXED_SIZE 16
|
||||
#define KEY_SIZE 16
|
||||
@ -114,7 +115,7 @@ const uint8_t otp_aid[] = {
|
||||
};
|
||||
|
||||
app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, otp_aid + 1, MIN(aid_len, otp_aid[0]))) {
|
||||
if (!memcmp(aid, otp_aid + 1, MIN(aid_len, otp_aid[0]) && cap_supported(CAP_OTP))) {
|
||||
a->aid = otp_aid;
|
||||
a->process_apdu = otp_process_apdu;
|
||||
a->unload = otp_unload;
|
||||
@ -175,6 +176,9 @@ extern int calculate_oath(uint8_t truncate,
|
||||
static uint8_t session_counter[2] = {0};
|
||||
#endif
|
||||
int otp_button_pressed(uint8_t slot) {
|
||||
if (!cap_supported(CAP_OTP)) {
|
||||
return 3;
|
||||
}
|
||||
init_otp();
|
||||
#ifndef ENABLE_EMULATION
|
||||
file_t *ef = search_dynamic_file(slot == 1 ? EF_OTP_SLOT1 : EF_OTP_SLOT2);
|
||||
@ -328,8 +332,6 @@ bool check_crc(const otp_config_t *data) {
|
||||
return crc == 0xF0B8;
|
||||
}
|
||||
|
||||
extern int man_get_config();
|
||||
|
||||
int cmd_otp() {
|
||||
uint8_t p1 = P1(apdu), p2 = P2(apdu);
|
||||
if (p2 != 0x00) {
|
||||
|
Loading…
Reference in New Issue
Block a user