From d558941311f1d9b507938f6074502e0937076ccf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 23 Sep 2022 17:30:07 +0200 Subject: [PATCH] Credentials now include a flag to mark whether they are resident or not. It is used by get assertion to attach userId, regardless allowList is present. Signed-off-by: Pol Henarejos --- src/fido/cbor_get_assertion.c | 6 ++++-- src/fido/cbor_make_credential.c | 2 +- src/fido/credential.c | 22 +++++++++++++++++++++- src/fido/credential.h | 3 ++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index f475419..85ff4d0 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -87,6 +87,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { int64_t kty = 2, alg = 0, crv = 0; CborByteString kax = {0}, kay = {0}, salt_enc = {0}, salt_auth = {0}; + DEBUG_DATA(data, len); CBOR_CHECK(cbor_parser_init(data, len, 0, &parser, &map)); uint64_t val_c = 1; CBOR_PARSE_MAP_START(map, 1) { @@ -448,7 +449,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { mbedtls_ecdsa_free(&ekey); uint8_t lfields = 3; - if (resident) + if (selcred->opts.present == true && selcred->opts.rk == ptrue) lfields++; if (numberOfCredentials > 1 && next == false) lfields++; @@ -468,7 +469,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x03)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, sig, olen)); - if (resident) { + if (selcred->opts.present == true && selcred->opts.rk == ptrue) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x04)); CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, 1)); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "id")); @@ -481,6 +482,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + DEBUG_DATA(ctap_resp->init.data + 1,resp_size); err: if (asserted == false) { CBOR_FREE_BYTE_STRING(clientDataHash); diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 4ce3f24..837c052 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -243,7 +243,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { uint8_t cred_id[MAX_CRED_ID_LENGTH]; size_t cred_id_len = 0; - CBOR_CHECK(credential_create(&rp.id, &user.id, &user.parent.name, &user.displayName, &extensions, (!ka || ka->use_sign_count == ptrue), alg, curve, cred_id, &cred_id_len)); + CBOR_CHECK(credential_create(&rp.id, &user.id, &user.parent.name, &user.displayName, &options, &extensions, (!ka || ka->use_sign_count == ptrue), alg, curve, cred_id, &cred_id_len)); mbedtls_ecdsa_context ekey; mbedtls_ecdsa_init(&ekey); diff --git a/src/fido/credential.c b/src/fido/credential.c index 7594267..45fb794 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -41,7 +41,7 @@ int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id return mbedtls_chachapoly_auth_decrypt(&chatx, cred_id_len - (4 + 12 + 16), iv, rp_id_hash, 32, tag, cipher, cipher); } -int credential_create(CborCharString *rpId, CborByteString *userId, CborCharString *userName, CborCharString *userDisplayName, CredExtensions *extensions, bool use_sign_count, int alg, int curve, uint8_t *cred_id, size_t *cred_id_len) { +int credential_create(CborCharString *rpId, CborByteString *userId, CborCharString *userName, CborCharString *userDisplayName, CredOptions *opts, CredExtensions *extensions, bool use_sign_count, int alg, int curve, uint8_t *cred_id, size_t *cred_id_len) { CborEncoder encoder, mapEncoder, mapEncoder2; CborError error = CborNoError; uint8_t rp_id_hash[32]; @@ -74,6 +74,15 @@ int credential_create(CborCharString *rpId, CborByteString *userId, CborCharStri CBOR_APPEND_KEY_UINT_VAL_INT(mapEncoder, 0x09, alg); CBOR_APPEND_KEY_UINT_VAL_INT(mapEncoder, 0x0A, curve); } + if (opts->present == true) { + CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0B)); + CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, CborIndefiniteLength)); + if (opts->rk != NULL) { + CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "rk")); + CBOR_CHECK(cbor_encode_boolean(&mapEncoder2, opts->rk == ptrue)); + } + CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); + } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); size_t rs = cbor_encoder_get_buffer_size(&encoder, cred_id); *cred_id_len = 4 + 12 + rs + 16; @@ -151,6 +160,16 @@ int credential_load(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *r else if (val_u == 0x0A) { CBOR_FIELD_GET_INT(cred->curve, 1); } + else if (val_u == 0x0B) { + cred->opts.present = true; + CBOR_PARSE_MAP_START(_f1, 2) + { + CBOR_FIELD_GET_KEY_TEXT(2); + CBOR_FIELD_KEY_TEXT_VAL_BOOL(2, "rk", cred->opts.rk); + CBOR_ADVANCE(2); + } + CBOR_PARSE_MAP_END(_f1, 2); + } else { CBOR_ADVANCE(1); } @@ -179,6 +198,7 @@ void credential_free(Credential *cred) { CBOR_FREE_BYTE_STRING(cred->id); cred->present = false; cred->extensions.present = false; + cred->opts.present = false; } int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash) { diff --git a/src/fido/credential.h b/src/fido/credential.h index 6e4b4ab..b8ee396 100644 --- a/src/fido/credential.h +++ b/src/fido/credential.h @@ -45,6 +45,7 @@ typedef struct Credential int64_t alg; int64_t curve; CborByteString id; + CredOptions opts; bool present; } Credential; @@ -53,7 +54,7 @@ typedef struct Credential #define CRED_PROT_UV_REQUIRED 0x03 extern int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash); -extern int credential_create(CborCharString *rpId, CborByteString *userId, CborCharString *userName, CborCharString *userDisplayName, CredExtensions *extensions, bool use_sign_count, int alg, int curve, uint8_t *cred_id, size_t *cred_id_len); +extern int credential_create(CborCharString *rpId, CborByteString *userId, CborCharString *userName, CborCharString *userDisplayName, CredOptions *opts, CredExtensions *extensions, bool use_sign_count, int alg, int curve, uint8_t *cred_id, size_t *cred_id_len); extern void credential_free(Credential *cred); extern int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash); extern int credential_load(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash, Credential *cred);