From c51e0a58f4a100e43c737c9fb070ff24a7e0d187 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 27 Nov 2018 19:33:51 +0200 Subject: [PATCH] added allowList to authenticatorGetAssertion command --- client/cmdhffido.c | 8 ++-- client/fido/fido2.json | 2 +- client/fido/fidocore.c | 102 ++++++++++++++++++++++++++--------------- client/fido/fidocore.h | 2 +- 4 files changed, 72 insertions(+), 42 deletions(-) diff --git a/client/cmdhffido.c b/client/cmdhffido.c index 57f8e5f2b..273982bed 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -783,13 +783,14 @@ int CmdHFFido2GetAssertion(const char *cmd) { CLIParserInit("hf fido assert", "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file `fido2.json`. File can be placed in proxmark directory or in `proxmark/fido` directory.", "Usage:\n\thf fido assert -> execute command default parameters file `fido2.json`\n" - "\thf fido assert test.json -> execute command with parameters file `text.json`"); + "\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId"); void* argtable[] = { arg_param_begin, arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_lit0("cC", "cbor", "show CBOR decoded data"), + arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator don't store credential to its memory)"), arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; @@ -799,11 +800,12 @@ int CmdHFFido2GetAssertion(const char *cmd) { bool verbose = arg_get_lit(2); bool verbose2 = arg_get_lit(2) > 1; bool showCBOR = arg_get_lit(3); + bool createAllowList = arg_get_lit(4); uint8_t jsonname[250] ={0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - CLIGetStrWithReturn(4, jsonname, &jsonnamelen); + CLIGetStrWithReturn(5, jsonname, &jsonnamelen); if (!jsonnamelen) { strcat(cjsonname, "fido2"); @@ -847,7 +849,7 @@ int CmdHFFido2GetAssertion(const char *cmd) { return 2; } - res = FIDO2CreateGetAssertionReq(root, data, sizeof(data), &datalen); + res = FIDO2CreateGetAssertionReq(root, data, sizeof(data), &datalen, createAllowList); if (res) return res; diff --git a/client/fido/fido2.json b/client/fido/fido2.json index 8ecd04103..abbfae5dc 100644 --- a/client/fido/fido2.json +++ b/client/fido/fido2.json @@ -24,7 +24,7 @@ ], "MakeCredentialOptions": { "uv": false, - "rk": false + "rk": true }, "GetAssertionOptions": { "up": true, diff --git a/client/fido/fidocore.c b/client/fido/fidocore.c index 1792550a4..39c2052f9 100644 --- a/client/fido/fidocore.c +++ b/client/fido/fidocore.c @@ -564,7 +564,7 @@ int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, b return 0; } -int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen) { +int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen, bool createAllowList) { if (datalen) *datalen = 0; if (!root || !data || !maxdatalen) @@ -572,19 +572,18 @@ int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, s int res; CborEncoder encoder; - CborEncoder map; + CborEncoder map, array, mapint; cbor_encoder_init(&encoder, data, maxdatalen, 0); // create main map - res = cbor_encoder_create_map(&encoder, &map, 3); + res = cbor_encoder_create_map(&encoder, &map, createAllowList ? 4 : 3); fido_check_if(res) { // rpId res = cbor_encode_uint(&map, 1); fido_check_if(res) { - - res = CBOREncodeElm(root, "$.RelyingPartyEntity.id", &map); - fido_check(res); + res = CBOREncodeElm(root, "$.RelyingPartyEntity.id", &map); + fido_check(res); } // clientDataHash @@ -594,6 +593,34 @@ int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, s fido_check(res); } + // allowList + if (createAllowList) { + res = cbor_encode_uint(&map, 3); + fido_check_if(res) { + res = cbor_encoder_create_array(&map, &array, 1); + fido_check_if(res) { + res = cbor_encoder_create_map(&array, &mapint, 2); + fido_check_if(res) { + res = cbor_encode_text_stringz(&mapint, "type"); + fido_check(res); + + res = cbor_encode_text_stringz(&mapint, "public-key"); + fido_check(res); + + res = cbor_encode_text_stringz(&mapint, "id"); + fido_check(res); + + res = CBOREncodeElm(root, "$.AppData.CredentialId", &mapint); + fido_check(res); + } + res = cbor_encoder_close_container(&array, &mapint); + fido_check(res); + } + res = cbor_encoder_close_container(&map, &array); + fido_check(res); + } + } + // options res = cbor_encode_uint(&map, 5); fido_check_if(res) { @@ -695,45 +722,46 @@ int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool // publicKeyCredentialUserEntity res = CborMapGetKeyById(&parser, &map, data, dataLen, 4); - if (res) - return res; - - res = cbor_value_enter_container(&map, &mapint); - cbor_check(res); - - while (!cbor_value_at_end(&mapint)) { - char key[100] = {0}; - res = CborGetStringValue(&mapint, key, sizeof(key), &n); + if (res) { + PrintAndLog("UserEntity n/a"); + } else { + res = cbor_value_enter_container(&map, &mapint); cbor_check(res); - - if (!strcmp(key, "name") || !strcmp(key, "displayName")) { - char cname[200] = {0}; - res = CborGetStringValue(&mapint, cname, sizeof(cname), &n); + + while (!cbor_value_at_end(&mapint)) { + char key[100] = {0}; + res = CborGetStringValue(&mapint, key, sizeof(key), &n); cbor_check(res); - PrintAndLog("UserEntity %s: %s", key, cname); - } - if (!strcmp(key, "id")) { - uint8_t cid[200] = {0}; - res = CborGetBinStringValue(&mapint, cid, sizeof(cid), &n); - cbor_check(res); - PrintAndLog("UserEntity id [%d]: %s", n, sprint_hex(cid, n)); - - // check - uint8_t idbuf[100] = {0}; - size_t idbuflen; + if (!strcmp(key, "name") || !strcmp(key, "displayName")) { + char cname[200] = {0}; + res = CborGetStringValue(&mapint, cname, sizeof(cname), &n); + cbor_check(res); + PrintAndLog("UserEntity %s: %s", key, cname); + } - JsonLoadBufAsHex(root, "$.UserEntity.id", idbuf, sizeof(idbuf), &idbuflen); + if (!strcmp(key, "id")) { + uint8_t cid[200] = {0}; + res = CborGetBinStringValue(&mapint, cid, sizeof(cid), &n); + cbor_check(res); + PrintAndLog("UserEntity id [%d]: %s", n, sprint_hex(cid, n)); + + // check + uint8_t idbuf[100] = {0}; + size_t idbuflen; - if (idbuflen == n && !memcmp(idbuf, cid, idbuflen)) { - PrintAndLog("UserEntity id OK."); - } else { - PrintAndLog("ERROR: Wrong UserEntity id (from json: %s)", sprint_hex(idbuf, idbuflen)); + JsonLoadBufAsHex(root, "$.UserEntity.id", idbuf, sizeof(idbuf), &idbuflen); + + if (idbuflen == n && !memcmp(idbuf, cid, idbuflen)) { + PrintAndLog("UserEntity id OK."); + } else { + PrintAndLog("ERROR: Wrong UserEntity id (from json: %s)", sprint_hex(idbuf, idbuflen)); + } } } + res = cbor_value_leave_container(&map, &mapint); + cbor_check(res); } - res = cbor_value_leave_container(&map, &mapint); - cbor_check(res); // signature diff --git a/client/fido/fidocore.h b/client/fido/fidocore.h index 092261104..b0b50e2ac 100644 --- a/client/fido/fidocore.h +++ b/client/fido/fidocore.h @@ -51,7 +51,7 @@ extern char *fido2GetCmdErrorDescription(uint8_t errorCode); extern bool CheckrpIdHash(json_t *json, uint8_t *hash); extern int FIDO2CreateMakeCredentionalReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen); extern int FIDO2MakeCredentionalParseRes(json_t *root, uint8_t *data, size_t dataLen, bool verbose, bool verbose2, bool showCBOR, bool showDERTLV); -extern int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen); +extern int FIDO2CreateGetAssertionReq(json_t *root, uint8_t *data, size_t maxdatalen, size_t *datalen, bool createAllowList); extern int FIDO2GetAssertionParseRes(json_t *root, uint8_t *data, size_t dataLen, bool verbose, bool verbose2, bool showCBOR); #endif /* __FIDOCORE_H__ */