mirror of
https://github.com/polhenarejos/pico-fido.git
synced 2025-12-18 09:30:04 +08:00
Added support for enterprise attestation.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -59,7 +59,7 @@ void clearUserVerifiedFlag() {
|
||||
|
||||
void clearPinUvAuthTokenPermissionsExceptLbw() {
|
||||
if (paut.in_use == true)
|
||||
paut.permissions = FIDO2_PERMISSION_LBW;
|
||||
paut.permissions = CTAP_PERMISSION_LBW;
|
||||
}
|
||||
|
||||
void stopUsingPinUvAuthToken() {
|
||||
|
||||
@@ -188,6 +188,10 @@ int cbor_config(const uint8_t *data, size_t len) {
|
||||
low_flash_available();
|
||||
goto err; //No return
|
||||
}
|
||||
else if (subcommand == 0x01) {
|
||||
set_opts(get_opts() | FIDO2_OPT_EA);
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
||||
CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder));
|
||||
|
||||
@@ -46,7 +46,9 @@ int cbor_get_info() {
|
||||
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, aaguid, sizeof(aaguid)));
|
||||
|
||||
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x04));
|
||||
CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &arrayEncoder, 6));
|
||||
CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &arrayEncoder, 7));
|
||||
CBOR_CHECK(cbor_encode_text_stringz(&arrayEncoder, "ep"));
|
||||
CBOR_CHECK(cbor_encode_boolean(&arrayEncoder, get_opts() & FIDO2_OPT_EA));
|
||||
CBOR_CHECK(cbor_encode_text_stringz(&arrayEncoder, "rk"));
|
||||
CBOR_CHECK(cbor_encode_boolean(&arrayEncoder, true));
|
||||
CBOR_CHECK(cbor_encode_text_stringz(&arrayEncoder, "credMgmt"));
|
||||
|
||||
@@ -207,6 +207,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
CBOR_ERROR(CTAP2_ERR_PUAT_REQUIRED);
|
||||
}
|
||||
if (enterpriseAttestation > 0) {
|
||||
if (!(get_opts() & FIDO2_OPT_EA)) {
|
||||
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
||||
}
|
||||
if (enterpriseAttestation != 1 && enterpriseAttestation != 2) { //9.2.1
|
||||
CBOR_ERROR(CTAP2_ERR_INVALID_OPTION);
|
||||
}
|
||||
@@ -259,14 +262,6 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
|
||||
CBOR_CHECK(credential_create(&rp.id, &user.id, &user.parent.name, &user.displayName, &options, &extensions, (!ka || ka->use_sign_count == ptrue), alg, curve, cred_id, &cred_id_len));
|
||||
|
||||
mbedtls_ecdsa_context ekey;
|
||||
mbedtls_ecdsa_init(&ekey);
|
||||
int ret = fido_load_key(curve, cred_id, &ekey);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
CBOR_ERROR(CTAP1_ERR_OTHER);
|
||||
}
|
||||
|
||||
if (getUserVerifiedFlagValue())
|
||||
flags |= FIDO2_AUT_FLAG_UV;
|
||||
size_t ext_len = 0;
|
||||
@@ -315,9 +310,18 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
flags |= FIDO2_AUT_FLAG_ED;
|
||||
}
|
||||
uint8_t pkey[66];
|
||||
const mbedtls_ecp_curve_info *cinfo = mbedtls_ecp_curve_info_from_grp_id(ekey.grp.id);
|
||||
if (cinfo == NULL)
|
||||
mbedtls_ecdsa_context ekey;
|
||||
mbedtls_ecdsa_init(&ekey);
|
||||
int ret = fido_load_key(curve, cred_id, &ekey);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
CBOR_ERROR(CTAP1_ERR_OTHER);
|
||||
}
|
||||
const mbedtls_ecp_curve_info *cinfo = mbedtls_ecp_curve_info_from_grp_id(ekey.grp.id);
|
||||
if (cinfo == NULL) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
CBOR_ERROR(CTAP1_ERR_OTHER);
|
||||
}
|
||||
size_t olen = 0;
|
||||
uint32_t ctr = get_sign_counter();
|
||||
uint8_t cbor_buf[1024];
|
||||
@@ -354,15 +358,17 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
memcpy(pa, cred_id, cred_id_len); pa += cred_id_len;
|
||||
memcpy(pa, cbor_buf, rs); pa += rs;
|
||||
memcpy(pa, ext, ext_len); pa += ext_len;
|
||||
if (pa-aut_data != aut_data_len)
|
||||
if (pa-aut_data != aut_data_len) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
CBOR_ERROR(CTAP1_ERR_OTHER);
|
||||
}
|
||||
|
||||
memcpy(pa, clientDataHash.data, clientDataHash.len);
|
||||
uint8_t hash[32], sig[MBEDTLS_ECDSA_MAX_LEN];
|
||||
ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), aut_data, aut_data_len+clientDataHash.len, hash);
|
||||
|
||||
bool self_attestation = true;
|
||||
if (ka && ka->use_self_attestation == pfalse) {
|
||||
if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
mbedtls_ecdsa_init(&ekey);
|
||||
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), 32);
|
||||
@@ -372,7 +378,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
mbedtls_ecdsa_free(&ekey);
|
||||
|
||||
cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0);
|
||||
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 3));
|
||||
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 4));
|
||||
|
||||
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01));
|
||||
CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder, "packed"));
|
||||
@@ -394,6 +400,8 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
}
|
||||
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2));
|
||||
|
||||
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x04));
|
||||
CBOR_CHECK(cbor_encode_boolean(&mapEncoder, enterpriseAttestation == 2));
|
||||
CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder));
|
||||
resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1);
|
||||
|
||||
|
||||
@@ -325,6 +325,19 @@ uint32_t get_sign_counter() {
|
||||
return (*caddr) | (*(caddr + 1) << 8) | (*(caddr + 2) << 16) | (*(caddr + 3) << 24);
|
||||
}
|
||||
|
||||
uint8_t get_opts() {
|
||||
file_t *ef = search_by_fid(EF_OPTS, NULL, SPECIFY_EF);
|
||||
if (file_has_data(ef))
|
||||
return *file_get_data(ef);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_opts(uint8_t opts) {
|
||||
file_t *ef = search_by_fid(EF_OPTS, NULL, SPECIFY_EF);
|
||||
flash_write_data_to_file(ef, &opts, sizeof(uint8_t));
|
||||
low_flash_available();
|
||||
}
|
||||
|
||||
typedef struct cmd
|
||||
{
|
||||
uint8_t ins;
|
||||
|
||||
@@ -63,12 +63,7 @@ extern int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSec
|
||||
#define FIDO2_AUT_FLAG_AT 0x40
|
||||
#define FIDO2_AUT_FLAG_ED 0x80
|
||||
|
||||
#define FIDO2_PERMISSION_MC 0x1
|
||||
#define FIDO2_PERMISSION_GA 0x2
|
||||
#define FIDO2_PERMISSION_CM 0x4
|
||||
#define FIDO2_PERMISSION_BE 0x8
|
||||
#define FIDO2_PERMISSION_LBW 0x10
|
||||
#define FIDO2_PERMISSION_ACFG 0x20
|
||||
#define FIDO2_OPT_EA 0x01 // Enterprise Attestation
|
||||
|
||||
#define MAX_PIN_RETRIES 8
|
||||
extern bool getUserPresentFlagValue();
|
||||
@@ -78,6 +73,8 @@ extern void clearUserVerifiedFlag();
|
||||
extern void clearPinUvAuthTokenPermissionsExceptLbw();
|
||||
extern void send_keepalive();
|
||||
extern uint32_t get_sign_counter();
|
||||
extern uint8_t get_opts();
|
||||
extern void set_opts(uint8_t);
|
||||
#define MAX_CREDENTIAL_COUNT_IN_LIST 16
|
||||
#define MAX_CRED_ID_LENGTH 1024
|
||||
#define MAX_RESIDENT_CREDENTIALS 256
|
||||
|
||||
@@ -27,6 +27,7 @@ file_t file_entries[] = {
|
||||
{.fid = EF_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // PIN
|
||||
{.fid = EF_AUTHTOKEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // AUTH TOKEN
|
||||
{.fid = EF_MINPINLEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // MIN PIN LENGTH
|
||||
{.fid = EF_OPTS, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // Global options
|
||||
{ .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define EF_KEY_DEV_ENC 0xCC01
|
||||
#define EF_EE_DEV 0xCE00
|
||||
#define EF_COUNTER 0xC000
|
||||
#define EF_OPTS 0xC001
|
||||
#define EF_PIN 0x1080
|
||||
#define EF_AUTHTOKEN 0x1090
|
||||
#define EF_MINPINLEN 0x1100
|
||||
|
||||
Reference in New Issue
Block a user