Fix credential and container for imported credentials.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-08-09 01:32:01 +02:00
parent 7015976439
commit b4cb9a0cb4
3 changed files with 32 additions and 1 deletions
+2
View File
@@ -990,6 +990,7 @@ int credential_load_resident(const file_t *ef, const uint8_t *rp_id_hash, Creden
if (!file_has_data(ef) || !rp_id_hash || !cred) {
return CTAP1_ERR_INVALID_PARAMETER;
}
cred->imported = false;
if (resident_container_is_marker(ef)) {
if (!credential_resident_usable(ef)) {
return CTAP2_ERR_NO_CREDENTIALS;
@@ -1017,6 +1018,7 @@ int credential_load_resident(const file_t *ef, const uint8_t *rp_id_hash, Creden
fido_resident_metadata_t resident_metadata;
ret = resident_container_read_metadata((uint8_t)ef->fid, &resident_metadata);
if (ret == PICOKEYS_OK && resident_metadata.properties == FIDO_RESIDENT_PROPERTY_IMPORTED) {
cred->imported = true;
ret = credential_resident_container_read_alloc(ef, FIDO_RESIDENT_OBJECT_METADATA, &metadata, &metadata_len);
if (ret == PICOKEYS_OK) ret = credential_resident_container_read_alloc(ef, FIDO_RESIDENT_OBJECT_PRIVATE_KEY, &private_key, &private_key_len);
if (ret == PICOKEYS_OK) ret = credential_parse_metadata(metadata, metadata_len, cred);
+1
View File
@@ -54,6 +54,7 @@ typedef struct Credential {
CborByteString residentId;
CborByteString privateKey;
CredOptions opts;
bool imported;
bool present;
uint64_t rtc_creation;
} Credential;
+29 -1
View File
@@ -26,6 +26,10 @@
#define FIDO_RESIDENT_MANIFEST_SLOT_1_PREFIX 0xd2u
#define FIDO_RESIDENT_RECORD_SLOT_0_PREFIX 0xd3u
#define FIDO_RESIDENT_RECORD_SLOT_1_PREFIX 0xd7u
#define FIDO_RESIDENT_RECORD_PRIVATE_SLOT_0_PREFIX 0xe0u
#define FIDO_RESIDENT_RECORD_PRIVATE_SLOT_1_PREFIX 0xe1u
#define FIDO_RESIDENT_RECORD_STATE_SLOT_0_PREFIX 0xe2u
#define FIDO_RESIDENT_RECORD_STATE_SLOT_1_PREFIX 0xe3u
#define FIDO_RESIDENT_CONTAINER_MARKER_SIZE 8u
#define FIDO_RESIDENT_CONTAINER_MARKER_VERSION_OFFSET 4u
#define FIDO_RESIDENT_CONTAINER_MARKER_SLOT_OFFSET 5u
@@ -53,12 +57,30 @@ static uint16_t resident_record_fid(uint8_t slot, uint8_t manifest_slot, uint16_
prefix = manifest_slot == 0 ? 0xdbu : 0xdcu;
return (uint16_t)((prefix << 8) | slot);
}
else if (object_type == FIDO_RESIDENT_OBJECT_PRIVATE_KEY) {
prefix = manifest_slot == 0 ? FIDO_RESIDENT_RECORD_PRIVATE_SLOT_0_PREFIX : FIDO_RESIDENT_RECORD_PRIVATE_SLOT_1_PREFIX;
return (uint16_t)((prefix << 8) | slot);
}
else if (object_type == FIDO_RESIDENT_OBJECT_STATE) {
prefix = manifest_slot == 0 ? FIDO_RESIDENT_RECORD_STATE_SLOT_0_PREFIX : FIDO_RESIDENT_RECORD_STATE_SLOT_1_PREFIX;
return (uint16_t)((prefix << 8) | slot);
}
else {
prefix = manifest_slot == 0 ? FIDO_RESIDENT_RECORD_SLOT_0_PREFIX : FIDO_RESIDENT_RECORD_SLOT_1_PREFIX;
}
return (uint16_t)(((prefix + object_type - 1u) << 8) | slot);
}
static uint16_t resident_record_fid_legacy(uint8_t slot, uint8_t manifest_slot, uint16_t object_type) {
uint8_t prefix;
if (object_type == FIDO_RESIDENT_OBJECT_METADATA) {
prefix = manifest_slot == 0 ? 0xdbu : 0xdcu;
return (uint16_t)((prefix << 8) | slot);
}
prefix = manifest_slot == 0 ? FIDO_RESIDENT_RECORD_SLOT_0_PREFIX : FIDO_RESIDENT_RECORD_SLOT_1_PREFIX;
return (uint16_t)(((prefix + object_type - 1u) << 8) | slot);
}
static bool resident_object_type_valid(uint16_t object_type) {
return object_type >= FIDO_RESIDENT_OBJECT_RP_ID_HASH && object_type <= FIDO_RESIDENT_OBJECT_STATE;
}
@@ -68,7 +90,13 @@ static bool resident_record_id_valid(uint8_t slot, const file_object_descriptor_
return false;
}
uint16_t record_fid = (uint16_t)object->record_id;
return record_fid == resident_record_fid(slot, 0, object->object_type) || record_fid == resident_record_fid(slot, 1, object->object_type);
if (record_fid == resident_record_fid(slot, 0, object->object_type) || record_fid == resident_record_fid(slot, 1, object->object_type)) {
return true;
}
if (object->object_type == FIDO_RESIDENT_OBJECT_PRIVATE_KEY || object->object_type == FIDO_RESIDENT_OBJECT_STATE) {
return record_fid == resident_record_fid_legacy(slot, 0, object->object_type) || record_fid == resident_record_fid_legacy(slot, 1, object->object_type);
}
return false;
}
static int resident_replace_file(uint16_t fid, const uint8_t *data, uint32_t data_size) {