refactor credMgmt to parse as subCommandParams, and get ready for delete command
This commit is contained in:
parent
a28a05673f
commit
682a443f4e
52
fido2/ctap.c
52
fido2/ctap.c
@ -382,6 +382,19 @@ static void ctap_increment_rk_store()
|
|||||||
STATE.rk_stored++;
|
STATE.rk_stored++;
|
||||||
ctap_flush_state();
|
ctap_flush_state();
|
||||||
}
|
}
|
||||||
|
static void ctap_decrement_rk_store()
|
||||||
|
{
|
||||||
|
STATE.rk_stored--;
|
||||||
|
ctap_flush_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return 1 if rk is valid, 0 if not.
|
||||||
|
static int ctap_rk_is_valid(CTAP_residentKey * rk)
|
||||||
|
{
|
||||||
|
return (rk->id.count > 0 && rk->id.count != 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int is_matching_rk(CTAP_residentKey * rk, CTAP_residentKey * rk2)
|
static int is_matching_rk(CTAP_residentKey * rk, CTAP_residentKey * rk2)
|
||||||
{
|
{
|
||||||
@ -1121,9 +1134,13 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
|
|||||||
crypto_sha256_final(rpIdHash);
|
crypto_sha256_final(rpIdHash);
|
||||||
|
|
||||||
printf1(TAG_GREEN, "true rpIdHash: "); dump_hex1(TAG_GREEN, rpIdHash, 32);
|
printf1(TAG_GREEN, "true rpIdHash: "); dump_hex1(TAG_GREEN, rpIdHash, 32);
|
||||||
for(i = 0; i < STATE.rk_stored; i++)
|
for(i = 0; i < ctap_rk_size(); i++)
|
||||||
{
|
{
|
||||||
ctap_load_rk(i, &rk);
|
ctap_load_rk(i, &rk);
|
||||||
|
if (! ctap_rk_is_valid(&rk)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
printf1(TAG_GREEN, "rpIdHash%d: ", i); dump_hex1(TAG_GREEN, rk.id.rpIdHash, 32);
|
printf1(TAG_GREEN, "rpIdHash%d: ", i); dump_hex1(TAG_GREEN, rk.id.rpIdHash, 32);
|
||||||
|
|
||||||
int protection_status =
|
int protection_status =
|
||||||
@ -1454,31 +1471,17 @@ uint8_t ctap_cred_rk(CborEncoder * encoder, int rk_ind, int rk_count)
|
|||||||
|
|
||||||
uint8_t ctap_cred_mgmt_pinauth(CTAP_credMgmt *CM)
|
uint8_t ctap_cred_mgmt_pinauth(CTAP_credMgmt *CM)
|
||||||
{
|
{
|
||||||
uint8_t ret = 0;
|
if (CM->cmd != CM_cmdMetadata &&
|
||||||
if (CM->cmd != CM_cmdMetadata && CM->cmd != CM_cmdRPBegin && CM->cmd != CM_cmdRKBegin)
|
CM->cmd != CM_cmdRPBegin &&
|
||||||
|
CM->cmd != CM_cmdRKBegin &&
|
||||||
|
CM->cmd != CM_cmdRKDelete)
|
||||||
{
|
{
|
||||||
// pinAuth is not required for other commands
|
// pinAuth is not required for other commands
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (CM->pinProtocol != 1)
|
|
||||||
{
|
int8_t ret = verify_pin_auth_ex(CM->pinAuth, (uint8_t*)&CM->hashed, CM->subCommandParamsCborSize + 1);
|
||||||
return CTAP1_ERR_OTHER;
|
|
||||||
}
|
|
||||||
if (CM->cmd == CM_cmdMetadata || CM->cmd == CM_cmdRPBegin)
|
|
||||||
{
|
|
||||||
uint8_t cmd = (uint8_t) CM->cmd;
|
|
||||||
ret = verify_pin_auth_ex(CM->pinAuth, &cmd, 1);
|
|
||||||
}
|
|
||||||
else if (CM->cmd == CM_cmdRKBegin)
|
|
||||||
{
|
|
||||||
uint8_t params[5 + sizeof(CM->rpIdHash)] = {CM->cmd, 0xa1, 0x01, 0x58, 0x20};
|
|
||||||
if (CM->pinProtocol != 1)
|
|
||||||
{
|
|
||||||
return CTAP1_ERR_OTHER;
|
|
||||||
}
|
|
||||||
memcpy(¶ms[5], CM->rpIdHash, sizeof(CM->rpIdHash));
|
|
||||||
ret = verify_pin_auth_ex(CM->pinAuth, params, sizeof(params));
|
|
||||||
}
|
|
||||||
if (ret == CTAP2_ERR_PIN_AUTH_INVALID)
|
if (ret == CTAP2_ERR_PIN_AUTH_INVALID)
|
||||||
{
|
{
|
||||||
ctap_decrement_pin_attempts();
|
ctap_decrement_pin_attempts();
|
||||||
@ -1492,6 +1495,7 @@ uint8_t ctap_cred_mgmt_pinauth(CTAP_credMgmt *CM)
|
|||||||
{
|
{
|
||||||
ctap_reset_pin_attempts();
|
ctap_reset_pin_attempts();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,7 +1543,7 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
rk_auth = true;
|
rk_auth = true;
|
||||||
rp_auth = false;
|
rp_auth = false;
|
||||||
// store the specified hash, we will need it for CM_cmdRKNext
|
// store the specified hash, we will need it for CM_cmdRKNext
|
||||||
memcpy(rpIdHash, CM.rpIdHash, 32);
|
memcpy(rpIdHash, CM.subCommandParams.rpIdHash, 32);
|
||||||
// count how many RKs have this hash
|
// count how many RKs have this hash
|
||||||
for (i = 0; i < STATE.rk_stored; i++)
|
for (i = 0; i < STATE.rk_stored; i++)
|
||||||
{
|
{
|
||||||
@ -1601,6 +1605,8 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
curr_rk_ind++;
|
curr_rk_ind++;
|
||||||
break;
|
break;
|
||||||
|
case CM_cmdRKDelete:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf2(TAG_ERR, "error, invalid credMgmt cmd: 0x%02x\n", CM.cmd);
|
printf2(TAG_ERR, "error, invalid credMgmt cmd: 0x%02x\n", CM.cmd);
|
||||||
return CTAP1_ERR_INVALID_COMMAND;
|
return CTAP1_ERR_INVALID_COMMAND;
|
||||||
|
15
fido2/ctap.h
15
fido2/ctap.h
@ -44,7 +44,10 @@
|
|||||||
#define CM_cmdRPNext 0x03
|
#define CM_cmdRPNext 0x03
|
||||||
#define CM_cmdRKBegin 0x04
|
#define CM_cmdRKBegin 0x04
|
||||||
#define CM_cmdRKNext 0x05
|
#define CM_cmdRKNext 0x05
|
||||||
#define CM_rpIdHash 0x02
|
#define CM_cmdRKDelete 0x06
|
||||||
|
#define CM_subCommandParams 0x02
|
||||||
|
#define CM_subCommandRpId 0x01
|
||||||
|
#define CM_subCommandCred 0x02
|
||||||
#define CM_pinProtocol 0x03
|
#define CM_pinProtocol 0x03
|
||||||
#define CM_pinAuth 0x04
|
#define CM_pinAuth 0x04
|
||||||
|
|
||||||
@ -311,7 +314,17 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int cmd;
|
int cmd;
|
||||||
|
struct {
|
||||||
uint8_t rpIdHash[32];
|
uint8_t rpIdHash[32];
|
||||||
|
CTAP_credentialDescriptor credentialDescriptor;
|
||||||
|
} subCommandParams;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t subCommandParamsCborCopy[sizeof(CTAP_credentialDescriptor) + 16];
|
||||||
|
} hashed;
|
||||||
|
uint32_t subCommandParamsCborSize;
|
||||||
|
|
||||||
uint8_t pinAuth[16];
|
uint8_t pinAuth[16];
|
||||||
uint8_t pinAuthPresent;
|
uint8_t pinAuthPresent;
|
||||||
int pinProtocol;
|
int pinProtocol;
|
||||||
|
@ -1007,7 +1007,7 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t parse_rpid_hash(CborValue * val, CTAP_credMgmt * CM)
|
static uint8_t parse_cred_mgmt_subcommandparams(CborValue * val, CTAP_credMgmt * CM)
|
||||||
{
|
{
|
||||||
size_t map_length;
|
size_t map_length;
|
||||||
int key;
|
int key;
|
||||||
@ -1022,8 +1022,12 @@ static uint8_t parse_rpid_hash(CborValue * val, CTAP_credMgmt * CM)
|
|||||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = cbor_value_enter_container(val,&map);
|
ret = cbor_value_enter_container(val,&map);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
|
|
||||||
|
const uint8_t * start_byte = cbor_value_get_next_byte(&map) - 1;
|
||||||
|
|
||||||
ret = cbor_value_get_map_length(val, &map_length);
|
ret = cbor_value_get_map_length(val, &map_length);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
|
|
||||||
@ -1040,8 +1044,8 @@ static uint8_t parse_rpid_hash(CborValue * val, CTAP_credMgmt * CM)
|
|||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case 1:
|
case CM_subCommandRpId:
|
||||||
ret = cbor_value_copy_byte_string(&map, CM->rpIdHash, &sz, NULL);
|
ret = cbor_value_copy_byte_string(&map, CM->subCommandParams.rpIdHash, &sz, NULL);
|
||||||
if (ret == CborErrorOutOfMemory)
|
if (ret == CborErrorOutOfMemory)
|
||||||
{
|
{
|
||||||
printf2(TAG_ERR,"Error, map key is too large\n");
|
printf2(TAG_ERR,"Error, map key is too large\n");
|
||||||
@ -1049,10 +1053,26 @@ static uint8_t parse_rpid_hash(CborValue * val, CTAP_credMgmt * CM)
|
|||||||
}
|
}
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
break;
|
break;
|
||||||
|
case CM_subCommandCred:
|
||||||
|
ret = parse_credential_descriptor(&map, &CM->subCommandParams.credentialDescriptor);
|
||||||
|
check_ret(ret);;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ret = cbor_value_advance(&map);
|
ret = cbor_value_advance(&map);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t * end_byte = cbor_value_get_next_byte(&map);
|
||||||
|
|
||||||
|
uint32_t length = (uint32_t)end_byte - (uint32_t)start_byte;
|
||||||
|
if (length > sizeof(CM->hashed.subCommandParamsCborCopy))
|
||||||
|
{
|
||||||
|
return CTAP2_ERR_LIMIT_EXCEEDED;
|
||||||
|
}
|
||||||
|
// Copy the details that were hashed so they can be verified later.
|
||||||
|
memmove(CM->hashed.subCommandParamsCborCopy, start_byte, length);
|
||||||
|
CM->subCommandParamsCborSize = length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1076,6 +1096,7 @@ uint8_t ctap_parse_cred_mgmt(CTAP_credMgmt * CM, uint8_t * request, int length)
|
|||||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = cbor_value_enter_container(&it,&map);
|
ret = cbor_value_enter_container(&it,&map);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
|
|
||||||
@ -1106,17 +1127,17 @@ uint8_t ctap_parse_cred_mgmt(CTAP_credMgmt * CM, uint8_t * request, int length)
|
|||||||
{
|
{
|
||||||
ret = cbor_value_get_int_checked(&map, &CM->cmd);
|
ret = cbor_value_get_int_checked(&map, &CM->cmd);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
|
CM->hashed.cmd = CM->cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CM_rpIdHash:
|
case CM_subCommandParams:
|
||||||
printf1(TAG_CM, "CM_rpIdHash\n");
|
printf1(TAG_CM, "CM_subCommandParams\n");
|
||||||
ret = parse_rpid_hash(&map, CM);
|
ret = parse_cred_mgmt_subcommandparams(&map, CM);
|
||||||
check_ret(ret);
|
check_ret(ret);
|
||||||
dump_hex1(TAG_CM, CM->rpIdHash, 32);
|
|
||||||
break;
|
break;
|
||||||
case CM_pinProtocol:
|
case CM_pinProtocol:
|
||||||
printf1(TAG_CM, "CM_pinProtocol\n");
|
printf1(TAG_CM, "CM_pinProtocol\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user