Compare commits
9 Commits
rgerganov-
...
reset-time
Author | SHA1 | Date | |
---|---|---|---|
c555e4ce46 | |||
299e91b91b | |||
cbf40f4ec7 | |||
8d93f88631 | |||
5f8a9a44fc | |||
8aa1f4ad01 | |||
04cffb6509 | |||
f002d08071 | |||
e53b83257d |
@ -1 +1 @@
|
|||||||
3.2.0
|
4.0.0
|
||||||
|
102
fido2/ctap.c
102
fido2/ctap.c
@ -31,6 +31,7 @@ uint8_t PIN_TOKEN[PIN_TOKEN_SIZE];
|
|||||||
uint8_t KEY_AGREEMENT_PUB[64];
|
uint8_t KEY_AGREEMENT_PUB[64];
|
||||||
static uint8_t KEY_AGREEMENT_PRIV[32];
|
static uint8_t KEY_AGREEMENT_PRIV[32];
|
||||||
static int8_t PIN_BOOT_ATTEMPTS_LEFT = PIN_BOOT_ATTEMPTS;
|
static int8_t PIN_BOOT_ATTEMPTS_LEFT = PIN_BOOT_ATTEMPTS;
|
||||||
|
static uint32_t BOOT_TIME = 0;
|
||||||
|
|
||||||
AuthenticatorState STATE;
|
AuthenticatorState STATE;
|
||||||
|
|
||||||
@ -461,6 +462,7 @@ static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf
|
|||||||
// Generate credRandom
|
// Generate credRandom
|
||||||
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
||||||
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
|
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
|
||||||
|
crypto_sha256_update(&getAssertionState.user_verified, 1);
|
||||||
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
||||||
|
|
||||||
// Decrypt saltEnc
|
// Decrypt saltEnc
|
||||||
@ -1524,46 +1526,6 @@ static int credentialId_to_rk_index(CredentialId * credId){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 1 if Left(rpIdHash, 16) has been counted in rpHashes.
|
|
||||||
static int8_t _rk_counted(uint8_t rpHashes [50][16], uint8_t * hash, int unique_count)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for (; i < unique_count; i++)
|
|
||||||
{
|
|
||||||
if (memcmp(rpHashes[i], hash, 16) == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t count_unique_rks()
|
|
||||||
{
|
|
||||||
CTAP_residentKey rk;
|
|
||||||
unsigned int unique_count = 0;
|
|
||||||
unsigned int i;
|
|
||||||
uint8_t rpHashes [50][16];
|
|
||||||
memset(rpHashes, 0, sizeof(rpHashes));
|
|
||||||
|
|
||||||
for(i = 0; i < ctap_rk_size(); i++)
|
|
||||||
{
|
|
||||||
ctap_load_rk(i, &rk);
|
|
||||||
if ( ctap_rk_is_valid(&rk) )
|
|
||||||
{
|
|
||||||
if (! _rk_counted(rpHashes, rk.id.rpIdHash, unique_count))
|
|
||||||
{
|
|
||||||
memmove(rpHashes[unique_count], rk.id.rpIdHash, 16);
|
|
||||||
unique_count += 1;
|
|
||||||
if (unique_count >= ctap_rk_size())
|
|
||||||
{
|
|
||||||
return unique_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return unique_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the next valid resident key of a different rpIdHash
|
// Load the next valid resident key of a different rpIdHash
|
||||||
static int scan_for_next_rp(int index){
|
static int scan_for_next_rp(int index){
|
||||||
CTAP_residentKey rk;
|
CTAP_residentKey rk;
|
||||||
@ -1626,18 +1588,15 @@ static int scan_for_next_rk(int index, uint8_t * initialRpIdHash){
|
|||||||
|
|
||||||
if (initialRpIdHash != NULL) {
|
if (initialRpIdHash != NULL) {
|
||||||
memmove(lastRpIdHash, initialRpIdHash, 32);
|
memmove(lastRpIdHash, initialRpIdHash, 32);
|
||||||
index = 0;
|
index = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctap_load_rk(index, &rk);
|
ctap_load_rk(index, &rk);
|
||||||
memmove(lastRpIdHash, rk.id.rpIdHash, 32);
|
memmove(lastRpIdHash, rk.id.rpIdHash, 32);
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctap_load_rk(index, &rk);
|
do
|
||||||
|
|
||||||
while ( memcmp( rk.id.rpIdHash, lastRpIdHash, 32 ) != 0 )
|
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
if ((unsigned int)index >= ctap_rk_size())
|
if ((unsigned int)index >= ctap_rk_size())
|
||||||
@ -1646,6 +1605,7 @@ static int scan_for_next_rk(int index, uint8_t * initialRpIdHash){
|
|||||||
}
|
}
|
||||||
ctap_load_rk(index, &rk);
|
ctap_load_rk(index, &rk);
|
||||||
}
|
}
|
||||||
|
while ( memcmp( rk.id.rpIdHash, lastRpIdHash, 32 ) != 0 );
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@ -1661,13 +1621,11 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
static int curr_rp_ind = 0;
|
static int curr_rp_ind = 0;
|
||||||
static int curr_rk_ind = 0;
|
static int curr_rk_ind = 0;
|
||||||
|
|
||||||
// flag that authenticated RPBegin was received
|
// flags that authenticate whether *Begin was before *Next
|
||||||
static bool rp_auth = false;
|
static bool rp_auth = false;
|
||||||
// flag that authenticated RKBegin was received
|
|
||||||
static bool rk_auth = false;
|
static bool rk_auth = false;
|
||||||
// number of stored RPs
|
|
||||||
int rp_count = 0;
|
int rp_count = 0;
|
||||||
// number of RKs with the specified rpIdHash
|
|
||||||
int rk_count = 0;
|
int rk_count = 0;
|
||||||
|
|
||||||
int ret = ctap_parse_cred_mgmt(&CM, request, length);
|
int ret = ctap_parse_cred_mgmt(&CM, request, length);
|
||||||
@ -1686,10 +1644,20 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
if (CM.cmd == CM_cmdRPBegin)
|
if (CM.cmd == CM_cmdRPBegin)
|
||||||
{
|
{
|
||||||
curr_rk_ind = -1;
|
curr_rk_ind = -1;
|
||||||
curr_rp_ind = scan_for_next_rp(-1);
|
|
||||||
rp_count = count_unique_rks();
|
|
||||||
rp_auth = true;
|
rp_auth = true;
|
||||||
rk_auth = false;
|
rk_auth = false;
|
||||||
|
curr_rp_ind = scan_for_next_rp(-1);
|
||||||
|
|
||||||
|
// Count total unique RP's
|
||||||
|
while (curr_rp_ind >= 0)
|
||||||
|
{
|
||||||
|
curr_rp_ind = scan_for_next_rp(curr_rp_ind);
|
||||||
|
rp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset scan
|
||||||
|
curr_rp_ind = scan_for_next_rp(-1);
|
||||||
|
|
||||||
printf1(TAG_MC, "RP Begin @%d. %d total.\n", curr_rp_ind, rp_count);
|
printf1(TAG_MC, "RP Begin @%d. %d total.\n", curr_rp_ind, rp_count);
|
||||||
}
|
}
|
||||||
else if (CM.cmd == CM_cmdRKBegin)
|
else if (CM.cmd == CM_cmdRKBegin)
|
||||||
@ -1716,17 +1684,6 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
curr_rp_ind = -1;
|
curr_rp_ind = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CM.cmd == CM_cmdRPNext && !rp_auth)
|
|
||||||
{
|
|
||||||
printf2(TAG_ERR, "RPNext without RPBegin\n");
|
|
||||||
return CTAP2_ERR_NO_CREDENTIALS;
|
|
||||||
}
|
|
||||||
if (CM.cmd == CM_cmdRKNext && !rk_auth)
|
|
||||||
{
|
|
||||||
printf2(TAG_ERR, "RKNext without RKBegin\n");
|
|
||||||
return CTAP2_ERR_NO_CREDENTIALS;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (CM.cmd)
|
switch (CM.cmd)
|
||||||
{
|
{
|
||||||
case CM_cmdMetadata:
|
case CM_cmdMetadata:
|
||||||
@ -1737,7 +1694,7 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
case CM_cmdRPBegin:
|
case CM_cmdRPBegin:
|
||||||
case CM_cmdRPNext:
|
case CM_cmdRPNext:
|
||||||
printf1(TAG_CM, "Get RP %d\n", curr_rp_ind);
|
printf1(TAG_CM, "Get RP %d\n", curr_rp_ind);
|
||||||
if (curr_rp_ind < 0) {
|
if (curr_rp_ind < 0 || !rp_auth) {
|
||||||
rp_auth = false;
|
rp_auth = false;
|
||||||
rk_auth = false;
|
rk_auth = false;
|
||||||
return CTAP2_ERR_NO_CREDENTIALS;
|
return CTAP2_ERR_NO_CREDENTIALS;
|
||||||
@ -1751,7 +1708,7 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
case CM_cmdRKBegin:
|
case CM_cmdRKBegin:
|
||||||
case CM_cmdRKNext:
|
case CM_cmdRKNext:
|
||||||
printf1(TAG_CM, "Get Cred %d\n", curr_rk_ind);
|
printf1(TAG_CM, "Get Cred %d\n", curr_rk_ind);
|
||||||
if (curr_rk_ind < 0) {
|
if (curr_rk_ind < 0 || !rk_auth) {
|
||||||
rp_auth = false;
|
rp_auth = false;
|
||||||
rk_auth = false;
|
rk_auth = false;
|
||||||
return CTAP2_ERR_NO_CREDENTIALS;
|
return CTAP2_ERR_NO_CREDENTIALS;
|
||||||
@ -1764,9 +1721,6 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case CM_cmdRKDelete:
|
case CM_cmdRKDelete:
|
||||||
rp_auth = false;
|
|
||||||
rk_auth = false;
|
|
||||||
|
|
||||||
printf1(TAG_CM, "CM_cmdRKDelete\n");
|
printf1(TAG_CM, "CM_cmdRKDelete\n");
|
||||||
i = credentialId_to_rk_index(&CM.subCommandParams.credentialDescriptor.credential.id);
|
i = credentialId_to_rk_index(&CM.subCommandParams.credentialDescriptor.credential.id);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
@ -2332,10 +2286,17 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
|||||||
break;
|
break;
|
||||||
case CTAP_RESET:
|
case CTAP_RESET:
|
||||||
printf1(TAG_CTAP,"CTAP_RESET\n");
|
printf1(TAG_CTAP,"CTAP_RESET\n");
|
||||||
status = ctap2_user_presence_test();
|
if ((millis() - BOOT_TIME) > 10 * 1000)
|
||||||
if (status == CTAP1_ERR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
ctap_reset();
|
status = CTAP2_ERR_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = ctap2_user_presence_test();
|
||||||
|
if (status == CTAP1_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
ctap_reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GET_NEXT_ASSERTION:
|
case GET_NEXT_ASSERTION:
|
||||||
@ -2429,6 +2390,7 @@ void ctap_init()
|
|||||||
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved,
|
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved,
|
||||||
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved
|
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved
|
||||||
);
|
);
|
||||||
|
BOOT_TIME = millis();
|
||||||
crypto_ecc256_init();
|
crypto_ecc256_init();
|
||||||
|
|
||||||
int is_init = authenticator_read_state(&STATE);
|
int is_init = authenticator_read_state(&STATE);
|
||||||
|
Reference in New Issue
Block a user