From 4f63622bbfa6ea9186b692a0e59c00b5b4fe5caa Mon Sep 17 00:00:00 2001 From: Brian Lee Date: Thu, 9 Jul 2026 13:29:57 -0400 Subject: [PATCH 1/2] Refactor OpenID4VP Wasm matcher main loop into process_request helper Extract the single-request evaluation logic inside main() / openid4vp_main() into a standalone process_request(...) helper function without altering existing sequential matching behavior. --- matcher/openid4vp1_0.c | 383 +++++++++++++++++++++-------------------- 1 file changed, 200 insertions(+), 183 deletions(-) diff --git a/matcher/openid4vp1_0.c b/matcher/openid4vp1_0.c index dc8ed8d..f14891f 100644 --- a/matcher/openid4vp1_0.c +++ b/matcher/openid4vp1_0.c @@ -195,7 +195,206 @@ void report_matched_credential_set(char* set_id, int curr_set_idx, cJSON *matche } } +static int process_request( + cJSON *request, + int request_id, + cJSON *credential_store, + uint32_t wasm_version, + char *creds_blob, + cJSON_bool is_modern_request +) +{ + int should_offer_issuance = 0; + char *merchant_name = NULL; + char *transaction_amount = NULL; + char *additional_info = NULL; + + char *protocol = cJSON_GetStringValue(cJSON_GetObjectItem(request, "protocol")); + if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_UNSIGNED) == 0 || strcmp(protocol, PROTOCOL_OPENID4VP_1_0_SIGNED) == 0 || strcmp(protocol, PROTOCOL_OPENID4VP_1_0_MULTISIGNED) == 0) + { + // We have an OpenID4VP request + cJSON *data_json; + if (is_modern_request) + { + data_json = cJSON_GetObjectItem(request, "data"); + if (cJSON_IsString(data_json)) + { // Legacy spec + char *data_json_string = cJSON_GetStringValue(data_json); + data_json = cJSON_Parse(data_json_string); + } + } + else + { // Legacy spec + cJSON *data = cJSON_GetObjectItem(request, "request"); + char *data_json_string = cJSON_GetStringValue(data); + data_json = cJSON_Parse(data_json_string); + } + + if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_SIGNED) == 0) + { + cJSON *signed_request = cJSON_GetObjectItem(data_json, "request"); + char *signed_request_string = cJSON_GetStringValue(signed_request); + int delimiter = '.'; + char *payload_start = strchr(signed_request_string, delimiter); + payload_start++; + char *payload_end = strchr(payload_start, delimiter); + *payload_end = '\0'; + char *decoded_request_json; + int decoded_request_json_len = B64DecodeURL(payload_start, &decoded_request_json); + data_json = cJSON_Parse(decoded_request_json); + } + else if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_MULTISIGNED) == 0) + { + cJSON *multisigned_request = cJSON_GetObjectItem(data_json, "request"); + cJSON *jws_json = multisigned_request; + cJSON *payload_obj = cJSON_GetObjectItem(jws_json, "payload"); + if (payload_obj != NULL && cJSON_IsString(payload_obj)) + { + char *payload_string = cJSON_GetStringValue(payload_obj); + char *decoded_request_json; + int decoded_request_json_len = B64DecodeURL(payload_string, &decoded_request_json); + data_json = cJSON_Parse(decoded_request_json); + } + } + cJSON *query = cJSON_GetObjectItem(data_json, "dcql_query"); + if (cJSON_HasObjectItem(data_json, "offer")) + { + should_offer_issuance = 1; + } + + // For now we only support one transaction data item + + cJSON *transaction_data_list = cJSON_GetObjectItem(data_json, "transaction_data"); + + cJSON *transaction_data = NULL; + cJSON *transaction_credential_ids = NULL; + if (transaction_data_list != NULL) + { + if (cJSON_GetArraySize(transaction_data_list) == 1) + { + cJSON *transaction_data_encoded = cJSON_GetArrayItem(transaction_data_list, 0); + char *transaction_data_encoded_str = cJSON_GetStringValue(transaction_data_encoded); + char *transaction_data_json; + int transaction_data_json_len = B64DecodeURL(transaction_data_encoded_str, &transaction_data_json); + printf("transaction data %s\n", transaction_data_json); + transaction_data = cJSON_Parse(transaction_data_json); + transaction_credential_ids = cJSON_GetObjectItem(transaction_data, "credential_ids"); + char *transaction_data_type = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "type")); + if (transaction_data_type != NULL && strcmp(transaction_data_type, "urn:eudi:sca:payment:1") == 0) { + cJSON *payload = cJSON_GetObjectItem(transaction_data, "payload"); + merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(cJSON_GetObjectItem(payload, "payee"), "name")); + + transaction_amount = cJSON_GetStringValue(cJSON_GetObjectItem(payload, "amount_display")); + + if (transaction_amount == NULL) { + double amount = cJSON_GetNumberValue(cJSON_GetObjectItem(payload, "amount")); + int length_for_amount = log10(amount); + char *currency = cJSON_GetStringValue(cJSON_GetObjectItem(payload, "currency")); + int total_length = length_for_amount + 4 + strlen(currency) + 2; + transaction_amount = malloc(length_for_amount + 4 + strlen(currency) + 2); + sprintf(transaction_amount, "%s %f", currency, amount); + transaction_amount[total_length - 1] = '\0'; + } + printf("transaction amount %s\n", transaction_amount); + + additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); + } else if (transaction_data_type != NULL && strcmp(transaction_data_type, "payment_details") == 0) { + merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payee_name")); + + char *amount = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payment_amount")); + char *currency = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payment_currency")); + transaction_amount = malloc(strlen(amount) + strlen(currency) + 2); + sprintf(transaction_amount, "%s %s", currency, amount); + printf("transaction amount %s\n", transaction_amount); + + additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); + } else { + merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "merchant_name")); + transaction_amount = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "amount")); + additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); + } + } + } + + cJSON *matched_result = dcql_query(query, credential_store); + // printf("matched_creds %d\n", cJSON_GetArraySize(matched_creds)); + printf("match result %s\n", cJSON_Print(matched_result)); + cJSON *matched_credential_sets = cJSON_GetObjectItemCaseSensitive(matched_result, "matched_credential_sets"); + cJSON *matched_docs = cJSON_GetObjectItemCaseSensitive(matched_result, "matched_credentials"); + + int matched_credential_sets_size = cJSON_GetArraySize(matched_credential_sets); + if (matched_credential_sets_size > 0) { // Some credential(s) matched + cJSON *first_matched_credential_set = cJSON_GetArrayItem(matched_credential_sets, 0); + cJSON *matched_option; + cJSON_ArrayForEach(matched_option, first_matched_credential_set) { + cJSON *matched_credential_ids = cJSON_GetObjectItemCaseSensitive(matched_option, "matched_credential_ids"); + int credential_set_size = cJSON_GetArraySize(matched_credential_ids); + char set_id_buffer[64]; + + if (cJSON_HasObjectItem(matched_option, "set_id")) { + char *set_idx = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(matched_option, "set_id")); + char *option_idx = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(matched_option, "option_id")); + int chars_written = sprintf(set_id_buffer, "req:%d;set:%s;option:%s", request_id, set_idx, option_idx); + if (wasm_version > 1) { // Report set length + report_credential_set_length(set_id_buffer, credential_set_size, 1, matched_credential_sets, matched_credential_sets_size); + } + + cJSON *matched_doc; + cJSON *matched_credential_id; + int doc_idx = 0; + cJSON_ArrayForEach(matched_credential_id, matched_credential_ids) + { + printf("matched_credential_id %s\n", cJSON_GetStringValue(matched_credential_id)); + matched_doc = cJSON_GetObjectItemCaseSensitive(matched_docs, cJSON_GetStringValue(matched_credential_id)); + report_matched_credential(wasm_version, matched_doc, matched_credential_id, doc_idx, request_id, set_id_buffer, set_idx, option_idx, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); + ++doc_idx; + } + report_matched_credential_set(set_id_buffer, 1, matched_credential_sets, doc_idx, matched_credential_sets_size, wasm_version, matched_docs, request_id, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); + } else { // No credential_sets present in dcql + int chars_written = sprintf(set_id_buffer, "req:%d;null", request_id); + if (wasm_version > 1) { // Report set length + AddEntrySet(set_id_buffer, credential_set_size); + } + + cJSON *matched_doc; + cJSON *matched_credential_id; + int doc_idx = 0; + cJSON_ArrayForEach(matched_credential_id, matched_credential_ids) + { + printf("matched_credential_id %s\n", cJSON_GetStringValue(matched_credential_id)); + matched_doc = cJSON_GetObjectItemCaseSensitive(matched_docs, cJSON_GetStringValue(matched_credential_id)); + report_matched_credential(wasm_version, matched_doc, matched_credential_id, doc_idx, request_id, set_id_buffer, NULL, NULL, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); + ++doc_idx; + } + } + } + } + + cJSON *inline_issuance = cJSON_GetObjectItemCaseSensitive(matched_result, "inline_issuance"); + if (inline_issuance != NULL) { + char *cred_id = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "id")); + char *title = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "title")); + char *subtitle = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "subtitle")); + cJSON *icon = cJSON_GetObjectItem(inline_issuance, "icon"); + if (icon == NULL) { + AddInlineIssuanceEntry(cred_id, 0, 0, title, subtitle); + } else { + double icon_start = cJSON_GetNumberValue(cJSON_GetObjectItem(icon, "start")); + int icon_start_int = icon_start; + int icon_len = (int)(cJSON_GetNumberValue(cJSON_GetObjectItem(icon, "length"))); + AddInlineIssuanceEntry(cred_id, creds_blob + icon_start_int, icon_len, title, subtitle); + } + } + } + + return 0; +} + +#if defined(__wasm__) int main() +#else +int openid4vp_main() +#endif { uint32_t credentials_size; GetCredentialsSize(&credentials_size); @@ -230,193 +429,11 @@ int main() } int requests_size = cJSON_GetArraySize(requests); - int matched = 0; - int should_offer_issuance = 0; - char *merchant_name = NULL; - char *transaction_amount = NULL; - char *additional_info = NULL; for (int i = 0; i < requests_size; i++) { cJSON *request = cJSON_GetArrayItem(requests, i); // printf("Request %s\n", cJSON_Print(request)); - - char *protocol = cJSON_GetStringValue(cJSON_GetObjectItem(request, "protocol")); - if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_UNSIGNED) == 0 || strcmp(protocol, PROTOCOL_OPENID4VP_1_0_SIGNED) == 0 || strcmp(protocol, PROTOCOL_OPENID4VP_1_0_MULTISIGNED) == 0) - { - // We have an OpenID4VP request - cJSON *data_json; - if (is_modern_request) - { - data_json = cJSON_GetObjectItem(request, "data"); - if (cJSON_IsString(data_json)) - { // Legacy spec - char *data_json_string = cJSON_GetStringValue(data_json); - data_json = cJSON_Parse(data_json_string); - } - } - else - { // Legacy spec - cJSON *data = cJSON_GetObjectItem(request, "request"); - char *data_json_string = cJSON_GetStringValue(data); - data_json = cJSON_Parse(data_json_string); - } - - if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_SIGNED) == 0) - { - cJSON *signed_request = cJSON_GetObjectItem(data_json, "request"); - char *signed_request_string = cJSON_GetStringValue(signed_request); - int delimiter = '.'; - char *payload_start = strchr(signed_request_string, delimiter); - payload_start++; - char *payload_end = strchr(payload_start, delimiter); - *payload_end = '\0'; - char *decoded_request_json; - int decoded_request_json_len = B64DecodeURL(payload_start, &decoded_request_json); - data_json = cJSON_Parse(decoded_request_json); - } - else if (strcmp(protocol, PROTOCOL_OPENID4VP_1_0_MULTISIGNED) == 0) - { - cJSON *multisigned_request = cJSON_GetObjectItem(data_json, "request"); - cJSON *jws_json = multisigned_request; - cJSON *payload_obj = cJSON_GetObjectItem(jws_json, "payload"); - if (payload_obj != NULL && cJSON_IsString(payload_obj)) - { - char *payload_string = cJSON_GetStringValue(payload_obj); - char *decoded_request_json; - int decoded_request_json_len = B64DecodeURL(payload_string, &decoded_request_json); - data_json = cJSON_Parse(decoded_request_json); - } - } - cJSON *query = cJSON_GetObjectItem(data_json, "dcql_query"); - if (cJSON_HasObjectItem(data_json, "offer")) - { - should_offer_issuance = 1; - } - - // For now we only support one transaction data item - - cJSON *transaction_data_list = cJSON_GetObjectItem(data_json, "transaction_data"); - - cJSON *transaction_data = NULL; - cJSON *transaction_credential_ids = NULL; - if (transaction_data_list != NULL) - { - if (cJSON_GetArraySize(transaction_data_list) == 1) - { - cJSON *transaction_data_encoded = cJSON_GetArrayItem(transaction_data_list, 0); - char *transaction_data_encoded_str = cJSON_GetStringValue(transaction_data_encoded); - char *transaction_data_json; - int transaction_data_json_len = B64DecodeURL(transaction_data_encoded_str, &transaction_data_json); - printf("transaction data %s\n", transaction_data_json); - transaction_data = cJSON_Parse(transaction_data_json); - transaction_credential_ids = cJSON_GetObjectItem(transaction_data, "credential_ids"); - char *transaction_data_type = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "type")); - if (transaction_data_type != NULL && strcmp(transaction_data_type, "urn:eudi:sca:payment:1") == 0) { - cJSON *payload = cJSON_GetObjectItem(transaction_data, "payload"); - merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(cJSON_GetObjectItem(payload, "payee"), "name")); - - transaction_amount = cJSON_GetStringValue(cJSON_GetObjectItem(payload, "amount_display")); - - if (transaction_amount == NULL) { - double amount = cJSON_GetNumberValue(cJSON_GetObjectItem(payload, "amount")); - int length_for_amount = log10(amount); - char *currency = cJSON_GetStringValue(cJSON_GetObjectItem(payload, "currency")); - int total_length = length_for_amount + 4 + strlen(currency) + 2; - transaction_amount = malloc(length_for_amount + 4 + strlen(currency) + 2); - sprintf(transaction_amount, "%s %f", currency, amount); - transaction_amount[total_length - 1] = '\0'; - } - printf("transaction amount %s\n", transaction_amount); - - additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); - } else if (transaction_data_type != NULL && strcmp(transaction_data_type, "payment_details") == 0) { - merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payee_name")); - - char *amount = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payment_amount")); - char *currency = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "payment_currency")); - transaction_amount = malloc(strlen(amount) + strlen(currency) + 2); - sprintf(transaction_amount, "%s %s", currency, amount); - printf("transaction amount %s\n", transaction_amount); - - additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); - } else { - merchant_name = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "merchant_name")); - transaction_amount = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "amount")); - additional_info = cJSON_GetStringValue(cJSON_GetObjectItem(transaction_data, "additional_info")); - } - } - } - - cJSON *matched_result = dcql_query(query, credential_store); - // printf("matched_creds %d\n", cJSON_GetArraySize(matched_creds)); - printf("match result %s\n", cJSON_Print(matched_result)); - cJSON *matched_credential_sets = cJSON_GetObjectItemCaseSensitive(matched_result, "matched_credential_sets"); - cJSON *matched_docs = cJSON_GetObjectItemCaseSensitive(matched_result, "matched_credentials"); - - int matched_credential_sets_size = cJSON_GetArraySize(matched_credential_sets); - if (matched_credential_sets_size > 0) { // Some credential(s) matched - cJSON *first_matched_credential_set = cJSON_GetArrayItem(matched_credential_sets, 0); - cJSON *matched_option; - cJSON_ArrayForEach(matched_option, first_matched_credential_set) { - cJSON *matched_credential_ids = cJSON_GetObjectItemCaseSensitive(matched_option, "matched_credential_ids"); - int credential_set_size = cJSON_GetArraySize(matched_credential_ids); - char set_id_buffer[64]; - - if (cJSON_HasObjectItem(matched_option, "set_id")) { - char *set_idx = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(matched_option, "set_id")); - char *option_idx = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(matched_option, "option_id")); - int chars_written = sprintf(set_id_buffer, "req:%d;set:%s;option:%s", i, set_idx, option_idx); - if (wasm_version > 1) { // Report set length - report_credential_set_length(set_id_buffer, credential_set_size, 1, matched_credential_sets, matched_credential_sets_size); - } - - cJSON *matched_doc; - cJSON *matched_credential_id; - int doc_idx = 0; - cJSON_ArrayForEach(matched_credential_id, matched_credential_ids) - { - printf("matched_credential_id %s\n", cJSON_GetStringValue(matched_credential_id)); - matched_doc = cJSON_GetObjectItemCaseSensitive(matched_docs, cJSON_GetStringValue(matched_credential_id)); - report_matched_credential(wasm_version, matched_doc, matched_credential_id, doc_idx, i, set_id_buffer, set_idx, option_idx, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); - ++doc_idx; - } - report_matched_credential_set(set_id_buffer, 1, matched_credential_sets, doc_idx, matched_credential_sets_size, wasm_version, matched_docs, i, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); - } else { // No credential_sets present in dcql - int chars_written = sprintf(set_id_buffer, "req:%d;null", i); - if (wasm_version > 1) { // Report set length - AddEntrySet(set_id_buffer, credential_set_size); - } - - cJSON *matched_doc; - cJSON *matched_credential_id; - int doc_idx = 0; - cJSON_ArrayForEach(matched_credential_id, matched_credential_ids) - { - printf("matched_credential_id %s\n", cJSON_GetStringValue(matched_credential_id)); - matched_doc = cJSON_GetObjectItemCaseSensitive(matched_docs, cJSON_GetStringValue(matched_credential_id)); - report_matched_credential(wasm_version, matched_doc, matched_credential_id, doc_idx, i, set_id_buffer, NULL, NULL, creds_blob, transaction_credential_ids, merchant_name, transaction_amount, additional_info); - ++doc_idx; - } - } - } - } - - cJSON *inline_issuance = cJSON_GetObjectItemCaseSensitive(matched_result, "inline_issuance"); - if (inline_issuance != NULL) { - char *cred_id = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "id")); - char *title = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "title")); - char *subtitle = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "subtitle")); - cJSON *icon = cJSON_GetObjectItem(inline_issuance, "icon"); - if (icon == NULL) { - AddInlineIssuanceEntry(cred_id, 0, 0, title, subtitle); - } else { - double icon_start = cJSON_GetNumberValue(cJSON_GetObjectItem(icon, "start")); - int icon_start_int = icon_start; - int icon_len = (int)(cJSON_GetNumberValue(cJSON_GetObjectItem(icon, "length"))); - AddInlineIssuanceEntry(cred_id, creds_blob + icon_start_int, icon_len, title, subtitle); - } - } - } + (void)process_request(request, i, credential_store, wasm_version, creds_blob, is_modern_request); } return 0; From 9b05fc44f8337fde0ac5cc7d2c8e4d1e448256ef Mon Sep 17 00:00:00 2001 From: Brian Lee Date: Thu, 9 Jul 2026 18:46:08 -0400 Subject: [PATCH 2/2] Add OpenID4VP preference-ordered protocol matching to Wasm matcher Support preference-ordered protocol selection via supported_protocols array in GetDigitalCredentialOption requests, short-circuiting on first match. Fallback to sequential evaluation when supported_protocols is omitted or empty. --- app/src/main/assets/openid4vp1_0.wasm | Bin 69424 -> 69779 bytes matcher/openid4vp1_0.c | 38 ++++- matcher/test_runner.cc | 12 ++ ...edSupportedProtocolAvailable_expected.json | 139 ++++++++++++++++++ ...redSupportedProtocolAvailable_request.json | 40 +++++ ...equestsForSupportedProtocols_expected.json | 4 + ...RequestsForSupportedProtocols_request.json | 20 +++ matcher/testdata/registry.json | 5 + 8 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_expected.json create mode 100644 matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_request.json create mode 100644 matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_expected.json create mode 100644 matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_request.json diff --git a/app/src/main/assets/openid4vp1_0.wasm b/app/src/main/assets/openid4vp1_0.wasm index b1c5152943233631e21ecbb21427742f9b475d86..f80fc949f2e27950f212fdc20bc8c99c6cabd8fc 100755 GIT binary patch delta 11303 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 0) { // Some credential(s) matched + matched = 1; cJSON *first_matched_credential_set = cJSON_GetArrayItem(matched_credential_sets, 0); cJSON *matched_option; cJSON_ArrayForEach(matched_option, first_matched_credential_set) { @@ -372,6 +378,7 @@ static int process_request( cJSON *inline_issuance = cJSON_GetObjectItemCaseSensitive(matched_result, "inline_issuance"); if (inline_issuance != NULL) { + matched = 1; char *cred_id = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "id")); char *title = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "title")); char *subtitle = cJSON_GetStringValue(cJSON_GetObjectItem(inline_issuance, "subtitle")); @@ -385,6 +392,7 @@ static int process_request( AddInlineIssuanceEntry(cred_id, creds_blob + icon_start_int, icon_len, title, subtitle); } } + return matched; } return 0; @@ -429,11 +437,33 @@ int openid4vp_main() } int requests_size = cJSON_GetArraySize(requests); - for (int i = 0; i < requests_size; i++) + cJSON *supported_protocols = cJSON_GetObjectItem(creds, "supported_protocols"); + int supported_protocols_size = (supported_protocols != NULL && cJSON_IsArray(supported_protocols)) + ? cJSON_GetArraySize(supported_protocols) : 0; + printf("supported_protocols size: %d\n", supported_protocols_size); + for (int p = 0; p < supported_protocols_size; p++) { - cJSON *request = cJSON_GetArrayItem(requests, i); - // printf("Request %s\n", cJSON_Print(request)); - (void)process_request(request, i, credential_store, wasm_version, creds_blob, is_modern_request); + cJSON *item = cJSON_GetArrayItem(supported_protocols, p); + char *target_protocol = cJSON_GetStringValue(item); + if (target_protocol == NULL) + { + continue; + } + + for (int i = 0; i < requests_size; i++) + { + cJSON *request = cJSON_GetArrayItem(requests, i); + char *protocol = cJSON_GetStringValue(cJSON_GetObjectItem(request, "protocol")); + if (protocol != NULL && strcmp(protocol, target_protocol) == 0) + { + if (process_request(request, i, credential_store, wasm_version, creds_blob, is_modern_request) == 1) + { + // If there are multiple requests of the same preferred protocol, + // we only process the first request that yields a match. + return 0; + } + } + } } return 0; diff --git a/matcher/test_runner.cc b/matcher/test_runner.cc index 1811827..6ec189b 100644 --- a/matcher/test_runner.cc +++ b/matcher/test_runner.cc @@ -435,4 +435,16 @@ TEST_CASE("TC37_WasmMetadataText") { } RunTest("TC37_WasmMetadataText", registry_with_meta); +} + +TEST_CASE("TC39_MatchMostPreferredSupportedProtocolAvailable") { + json reg = json::parse(ReadFileToString("testdata/registry.json")); + reg["supported_protocols"] = {"openid4vp-v1-signed", "openid4vp-v1-unsigned"}; + RunTest("TC39_MatchMostPreferredSupportedProtocolAvailable", reg.dump()); +} + +TEST_CASE("TC40_NoMatchIfNoRequestsForSupportedProtocols") { + json reg = json::parse(ReadFileToString("testdata/registry.json")); + reg["supported_protocols"] = {"openid4vp-v1-signed"}; + RunTest("TC40_NoMatchIfNoRequestsForSupportedProtocols", reg.dump()); } \ No newline at end of file diff --git a/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_expected.json b/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_expected.json new file mode 100644 index 0000000..988dccb --- /dev/null +++ b/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_expected.json @@ -0,0 +1,139 @@ +{ + "entrySets": { + "req:1;null": { + "entries": { + "0": { + "mdoc_cred_1": { + "additional_info": "", + "credId": "mdoc_cred_1", + "disclaimer": "", + "fields": [ + [ + "Age", + "" + ], + [ + "Over 21", + "Yes" + ], + [ + "Family Name", + "Doe" + ], + [ + "Given Name", + "John" + ] + ], + "merchant_name": "", + "metadata_display_text": "", + "subtitle": "", + "title": "John's Driving License", + "transaction_amount": "", + "type": "Verification", + "warning": "" + }, + "mdoc_cred_3": { + "additional_info": "", + "credId": "mdoc_cred_3", + "disclaimer": "", + "fields": [ + [ + "Age", + "" + ], + [ + "Over 21", + "" + ], + [ + "Family Name", + "" + ], + [ + "Given Name", + "" + ] + ], + "merchant_name": "", + "metadata_display_text": "", + "subtitle": "", + "title": "Alice's Driving License", + "transaction_amount": "", + "type": "Verification", + "warning": "" + }, + "mdoc_cred_4": { + "additional_info": "", + "credId": "mdoc_cred_4", + "disclaimer": "", + "fields": [ + [ + "Age", + "" + ], + [ + "Over 21", + "" + ], + [ + "Family Name", + "" + ], + [ + "Given Name", + "" + ] + ], + "merchant_name": "", + "metadata_display_text": "", + "subtitle": "", + "title": "Jane's Driving License", + "transaction_amount": "", + "type": "Verification", + "warning": "" + }, + "mdoc_cred_underage": { + "additional_info": "", + "credId": "mdoc_cred_underage", + "disclaimer": "", + "fields": [ + [ + "Age", + "" + ], + [ + "Over 21", + "Yes" + ] + ], + "merchant_name": "", + "metadata_display_text": "", + "subtitle": "", + "title": "Underage License", + "transaction_amount": "", + "type": "Verification", + "warning": "" + } + } + }, + "setId": "req:1;null", + "setLength": 1 + } + }, + "standaloneEntries": [ + { + "additional_info": "", + "credId": "issuance_mdl_1", + "disclaimer": "", + "fields": [], + "merchant_name": "", + "metadata_display_text": "", + "subtitle": "From your local DMV", + "title": "Get a New mDL", + "transaction_amount": "", + "type": "InlineIssuance", + "warning": "" + } + ] +} \ No newline at end of file diff --git a/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_request.json b/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_request.json new file mode 100644 index 0000000..50ba9d1 --- /dev/null +++ b/matcher/testdata/TC39_MatchMostPreferredSupportedProtocolAvailable_request.json @@ -0,0 +1,40 @@ +{ + "requests": [ + { + "data": { + "dcql_query": { + "credentials": [ + { + "format": "mso_mdoc", + "id": "mdl", + "meta": { + "doctype_value": "org.iso.18013.5.1.mDL" + } + } + ] + } + }, + "protocol": "openid4vp-v1-unsigned" + }, + { + "data": { + "request": "header.eyJkY3FsX3F1ZXJ5Ijp7ImNyZWRlbnRpYWxzIjpbeyJmb3JtYXQiOiJtc29fbWRvYyIsImlkIjoibWRsIiwibWV0YSI6eyJkb2N0eXBlX3ZhbHVlIjoib3JnLmlzby4xODAxMy41LjEubURMIn19XX19.signature" + }, + "protocol": "openid4vp-v1-signed" + }, + { + "data": { + "request": "header.eyJkY3FsX3F1ZXJ5Ijp7ImNyZWRlbnRpYWxzIjpbeyJmb3JtYXQiOiJtc29fbWRvYyIsImlkIjoibWRsIiwibWV0YSI6eyJkb2N0eXBlX3ZhbHVlIjoib3JnLmlzby4xODAxMy41LjEubURMIn19XX19.signature" + }, + "protocol": "openid4vp-v1-signed" + }, + { + "data": { + "request": { + "payload": "eyJkY3FsX3F1ZXJ5Ijp7ImNyZWRlbnRpYWxzIjpbeyJmb3JtYXQiOiJtc29fbWRvYyIsImlkIjoibWRsIiwibWV0YSI6eyJkb2N0eXBlX3ZhbHVlIjoib3JnLmlzby4xODAxMy41LjEubURMIn19XX19" + } + }, + "protocol": "openid4vp-v1-multisigned" + } + ] +} diff --git a/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_expected.json b/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_expected.json new file mode 100644 index 0000000..4a37a2a --- /dev/null +++ b/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_expected.json @@ -0,0 +1,4 @@ +{ + "entrySets": {}, + "standaloneEntries": [] +} diff --git a/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_request.json b/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_request.json new file mode 100644 index 0000000..ed8afd9 --- /dev/null +++ b/matcher/testdata/TC40_NoMatchIfNoRequestsForSupportedProtocols_request.json @@ -0,0 +1,20 @@ +{ + "requests": [ + { + "data": { + "dcql_query": { + "credentials": [ + { + "format": "mso_mdoc", + "id": "mdl", + "meta": { + "doctype_value": "org.iso.18013.5.1.mDL" + } + } + ] + } + }, + "protocol": "openid4vp-v1-unsigned" + } + ] +} diff --git a/matcher/testdata/registry.json b/matcher/testdata/registry.json index c219cc9..9034bbd 100644 --- a/matcher/testdata/registry.json +++ b/matcher/testdata/registry.json @@ -1,4 +1,9 @@ { + "supported_protocols": [ + "openid4vp-v1-signed", + "openid4vp-v1-unsigned", + "openid4vp-v1-multisigned" + ], "credentials": { "mso_mdoc": { "org.iso.18013.5.1.mDL": [