From 56d5c61044358c33bdd596f54923f31cc3861a02 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 6 Sep 2025 19:14:27 +0200 Subject: [PATCH] Add compatibility of old resident key system with the new one. Related to #184. Signed-off-by: Pol Henarejos --- src/fido/cbor_cred_mgmt.c | 4 ++-- src/fido/cbor_get_assertion.c | 4 ++-- src/fido/cbor_make_credential.c | 2 +- src/fido/credential.c | 7 +++++++ src/fido/credential.h | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index fe5c95a..901ec00 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -259,7 +259,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { } Credential cred = { 0 }; - if (credential_load(file_get_data(cred_ef) + 32 + CRED_RESIDENT_LEN, file_get_size(cred_ef) - 32 - CRED_RESIDENT_LEN, rpIdHash.data, &cred) != 0) { + if (credential_load_resident(cred_ef, rpIdHash.data, &cred) != 0) { CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); } @@ -419,7 +419,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { if (file_has_data(ef) && memcmp(file_get_data(ef) + 32, credentialId.id.data, CRED_RESIDENT_LEN) == 0) { Credential cred = { 0 }; uint8_t *rp_id_hash = file_get_data(ef); - if (credential_load(rp_id_hash + 32 + CRED_RESIDENT_LEN, file_get_size(ef) - 32 - CRED_RESIDENT_LEN, rp_id_hash, &cred) != 0) { + if (credential_load_resident(ef, rp_id_hash, &cred) != 0) { CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); } if (memcmp(user.id.data, cred.userId.data, MIN(user.id.len, cred.userId.len)) != 0) { diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index 743e70f..e2cbaab 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -302,7 +302,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { continue; } if (memcmp(file_get_data(ef) + 32, allowList[e].id.data, CRED_RESIDENT_LEN) == 0) { - if (credential_load(file_get_data(ef) + 32 + CRED_RESIDENT_LEN, file_get_size(ef) - 32 - CRED_RESIDENT_LEN, rp_id_hash, &creds[creds_len]) != 0) { + if (credential_load_resident(ef, rp_id_hash, &creds[creds_len]) != 0) { // Should never happen credential_free(&creds[creds_len]); continue; @@ -347,7 +347,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { if (!file_has_data(ef) || memcmp(file_get_data(ef), rp_id_hash, 32) != 0) { continue; } - int ret = credential_load(file_get_data(ef) + 32 + CRED_RESIDENT_LEN, file_get_size(ef) - 32 - CRED_RESIDENT_LEN, rp_id_hash, &creds[creds_len]); + int ret = credential_load_resident(ef, rp_id_hash, &creds[creds_len]); if (ret != 0) { credential_free(&creds[creds_len]); } diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 75d87f6..08ef580 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -355,7 +355,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } uint8_t *cred_idr = file_get_data(ef_cred) + 32; if (memcmp(cred_idr, excludeList[e].id.data, CRED_RESIDENT_LEN) == 0) { - if (credential_load(file_get_data(ef_cred) + 32 + CRED_RESIDENT_LEN, file_get_size(ef_cred) - 32 - CRED_RESIDENT_LEN, rp_id_hash, &ecred) == 0 && (ecred.extensions.credProtect != CRED_PROT_UV_REQUIRED || (flags & FIDO2_AUT_FLAG_UV))) { + if (credential_load_resident(ef_cred, rp_id_hash, &ecred) == 0 && (ecred.extensions.credProtect != CRED_PROT_UV_REQUIRED || (flags & FIDO2_AUT_FLAG_UV))) { credential_free(&ecred); CBOR_ERROR(CTAP2_ERR_CREDENTIAL_EXCLUDED); } diff --git a/src/fido/credential.c b/src/fido/credential.c index e7c2ecd..3ba18f6 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -440,3 +440,10 @@ int credential_derive_resident(const uint8_t *cred_id, size_t cred_id_len, uint8 bool credential_is_resident(const uint8_t *cred_id, size_t cred_id_len) { return memcmp(cred_id, CRED_PROTO_RESIDENT, CRED_PROTO_RESIDENT_LEN) == 0; } + +int credential_load_resident(const file_t *ef, const uint8_t *rp_id_hash, Credential *cred) { + if (credential_is_resident(file_get_data(ef) + 32, file_get_size(ef) - 32)) { + return credential_load(file_get_data(ef) + 32 + CRED_RESIDENT_LEN, file_get_size(ef) - 32 - CRED_RESIDENT_LEN, rp_id_hash, cred); + } + return credential_load(file_get_data(ef) + 32, file_get_size(ef) - 32, rp_id_hash, cred); +} diff --git a/src/fido/credential.h b/src/fido/credential.h index e7a2792..3b3bbab 100644 --- a/src/fido/credential.h +++ b/src/fido/credential.h @@ -19,6 +19,7 @@ #define _CREDENTIAL_H_ #include "ctap2_cbor.h" +#include "file.h" typedef struct CredOptions { const bool *rk; @@ -102,5 +103,6 @@ extern int credential_derive_large_blob_key(const uint8_t *cred_id, uint8_t *outk); extern int credential_derive_resident(const uint8_t *cred_id, size_t cred_id_len, uint8_t *outk); extern bool credential_is_resident(const uint8_t *cred_id, size_t cred_id_len); +extern int credential_load_resident(const file_t *ef, const uint8_t *rp_id_hash, Credential *cred); #endif // _CREDENTIAL_H_