Skip to content

Commit b8e5e48

Browse files
committed
Fix credential id import to different boards
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
1 parent 6453971 commit b8e5e48

1 file changed

Lines changed: 22 additions & 14 deletions

File tree

src/fido/credential.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -438,10 +438,7 @@ int credential_create(CborCharString *rpId, CborByteString *userId, CborCharStri
438438
mbedtls_chachapoly_context chatx;
439439
mbedtls_chachapoly_init(&chatx);
440440
mbedtls_chachapoly_setkey(&chatx, key);
441-
int ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, rs, iv, rp_id_hash, RP_ID_HASH_LEN,
442-
cred_id + CRED_PROTO_LEN + CRED_IV_LEN,
443-
cred_id + CRED_PROTO_LEN + CRED_IV_LEN,
444-
cred_id + CRED_PROTO_LEN + CRED_IV_LEN + rs);
441+
int ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, rs, iv, rp_id_hash, RP_ID_HASH_LEN, cred_id + CRED_PROTO_LEN + CRED_IV_LEN, cred_id + CRED_PROTO_LEN + CRED_IV_LEN, cred_id + CRED_PROTO_LEN + CRED_IV_LEN + rs);
445442
mbedtls_chachapoly_free(&chatx);
446443
if (ret != 0) {
447444
CBOR_ERROR(CTAP1_ERR_OTHER);
@@ -639,7 +636,7 @@ static int credential_parse_metadata(const uint8_t *data, size_t data_len, Crede
639636
CBOR_PARSE_MAP_END(_f1, 2);
640637
}
641638
else if (val_u == 0x0C) { CBOR_FIELD_GET_UINT(cred->rtc_creation, 1); }
642-
else if (val_u == 0x0D) { CBOR_ADVANCE(1); }
639+
else if (val_u == 0x0D) { CBOR_FIELD_GET_BYTES(cred->residentId, 1); }
643640
else { CBOR_ADVANCE(1); }
644641
}
645642
CBOR_PARSE_MAP_END(map, 1);
@@ -784,10 +781,16 @@ int credential_import(const credential_import_record_t *record) {
784781
}
785782
Credential parsed = {0};
786783
int ret = credential_parse_metadata(record->metadata, record->metadata_len, &parsed);
784+
const uint8_t *resident_id = parsed.residentId.data;
785+
size_t resident_id_len = parsed.residentId.len;
786+
if (!parsed.residentId.present && credential_is_resident(record->requested_id, record->requested_id_len)) {
787+
resident_id = record->requested_id;
788+
resident_id_len = record->requested_id_len;
789+
}
787790
mbedtls_ecp_group_id curve = fido_curve_to_mbedtls((int)parsed.curve);
788791
uint8_t rp_id_hash[RP_ID_HASH_LEN] = {0};
789792
uint8_t credential_hash[RP_ID_HASH_LEN] = {0};
790-
if (ret != PICOKEYS_OK || !parsed.rpId.present || !parsed.rpIdHash.present || parsed.rpIdHash.len != RP_ID_HASH_LEN || parsed.rpId.len != record->rp_id_len || mbedtls_ct_memcmp(parsed.rpId.data, record->rp_id, record->rp_id_len) != 0 || !credential_algorithm_matches_curve(parsed.alg, parsed.curve) || curve == MBEDTLS_ECP_DP_NONE) {
793+
if (ret != PICOKEYS_OK || !parsed.rpId.present || !parsed.rpIdHash.present || parsed.rpIdHash.len != RP_ID_HASH_LEN || parsed.rpId.len != record->rp_id_len || mbedtls_ct_memcmp(parsed.rpId.data, record->rp_id, record->rp_id_len) != 0 || !credential_algorithm_matches_curve(parsed.alg, parsed.curve) || curve == MBEDTLS_ECP_DP_NONE || !resident_id || resident_id_len != CRED_RESIDENT_LEN || !credential_is_resident(resident_id, resident_id_len)) {
791794
log_errstr("credential import: metadata validation failed parse_ret=%d rp_id=\"%.*s\" rp_id_present=%d rp_id_len=%zu expected_len=%zu algorithm=%d curve=%d", ret, parsed.rpId.present ? (int)(parsed.rpId.len > 32u ? 32u : parsed.rpId.len) : 0, parsed.rpId.present ? parsed.rpId.data : "", parsed.rpId.present, parsed.rpId.len, record->rp_id_len, parsed.alg, parsed.curve);
792795
credential_free(&parsed);
793796
return PICOKEYS_WRONG_DATA;
@@ -818,10 +821,7 @@ int credential_import(const credential_import_record_t *record) {
818821
}
819822
uint8_t client_id[CRED_RESIDENT_LEN] = {0};
820823
if (ret == 0 && error == CborNoError) {
821-
ret = credential_derive_resident(record->credential_id, record->credential_id_len, client_id);
822-
if (ret != PICOKEYS_OK) {
823-
log_errstr("credential import: resident ID derivation failed ret=%d credential_id_len=%zu", ret, record->credential_id_len);
824-
}
824+
memcpy(client_id, resident_id, sizeof(client_id));
825825
}
826826
int slot = -1;
827827
if (ret == 0) {
@@ -1096,17 +1096,25 @@ int credential_load_resident(const file_t *ef, const uint8_t *rp_id_hash, Creden
10961096
if (ret == PICOKEYS_OK && (resident_metadata.properties & FIDO_RESIDENT_PROPERTY_IMPORTED) != 0) {
10971097
cred->imported = true;
10981098
ret = credential_resident_container_read_alloc(ef, FIDO_RESIDENT_OBJECT_METADATA, &metadata, &metadata_len);
1099-
if (ret == PICOKEYS_OK) ret = credential_resident_container_read_alloc(ef, FIDO_RESIDENT_OBJECT_PRIVATE_KEY, &private_key, &private_key_len);
1100-
if (ret == PICOKEYS_OK) ret = credential_parse_metadata(metadata, metadata_len, cred);
1099+
if (ret == PICOKEYS_OK) {
1100+
ret = credential_resident_container_read_alloc(ef, FIDO_RESIDENT_OBJECT_PRIVATE_KEY, &private_key, &private_key_len);
1101+
}
1102+
if (ret == PICOKEYS_OK) {
1103+
ret = credential_parse_metadata(metadata, metadata_len, cred);
1104+
}
11011105
if (ret == PICOKEYS_OK) {
11021106
cred->id.data = (uint8_t *)calloc(1, credential_len);
1103-
if (!cred->id.data) ret = PICOKEYS_ERR_NO_MEMORY;
1107+
if (!cred->id.data) {
1108+
ret = PICOKEYS_ERR_NO_MEMORY;
1109+
}
11041110
else {
11051111
memcpy(cred->id.data, credential, credential_len);
11061112
cred->id.len = credential_len;
11071113
cred->id.present = true;
11081114
cred->privateKey.data = (uint8_t *)calloc(1, private_key_len);
1109-
if (!cred->privateKey.data) ret = PICOKEYS_ERR_NO_MEMORY;
1115+
if (!cred->privateKey.data) {
1116+
ret = PICOKEYS_ERR_NO_MEMORY;
1117+
}
11101118
else {
11111119
memcpy(cred->privateKey.data, private_key, private_key_len);
11121120
cred->privateKey.len = private_key_len;

0 commit comments

Comments
 (0)