|
| 1 | +# OpenID4VP Matcher: Comprehensive Code Index |
| 2 | + |
| 3 | +## 1. Registry Binary Format |
| 4 | +The registry blob is a custom binary format: |
| 5 | +- **Header**: 4 bytes (Little-endian `int`) representing the offset from the start of the blob to the beginning of the JSON metadata. |
| 6 | +- **Icon Section**: Raw PNG bytes located between the header and the JSON metadata. |
| 7 | +- **Metadata Section**: UTF-8 encoded JSON string starting at the specified offset. |
| 8 | + |
| 9 | +## 2. Registry JSON Schema |
| 10 | +Root structure: `{"credentials": { ... }}` |
| 11 | + |
| 12 | +### 2.1 mso_mdoc (credentials.mso_mdoc) |
| 13 | +- **Key**: Document Type (e.g., "org.iso.18013.5.1.mDL") |
| 14 | +- **Value**: Array of Credential Objects: |
| 15 | + - `id`: String. |
| 16 | + - `display`: |
| 17 | + - `verification`: |
| 18 | + - `title`: String. |
| 19 | + - `subtitle`: String (optional). |
| 20 | + - `explainer`: String (optional). |
| 21 | + - `warning`: String (optional). |
| 22 | + - `metadata_display_text`: String (optional). |
| 23 | + - `icon`: `{"start": <int>, "length": <int>}`. |
| 24 | + - `paths`: Map of Namespace -> Map of ClaimName -> Claim object: |
| 25 | + - `value`: Any (raw value). |
| 26 | + - `display`: |
| 27 | + - `verification`: |
| 28 | + - `display`: String (localized name). |
| 29 | + - `display_value`: String (optional localized value). |
| 30 | + |
| 31 | +### 2.2 dc+sd-jwt (credentials.dc+sd-jwt) |
| 32 | +- **Key**: Verifiable Credential Type (VCT) string. |
| 33 | +- **Value**: Array of Credential Objects. |
| 34 | +- **Paths Construction**: The Kotlin `SdJwtEntry.claims` (a list) is flattened into a nested `paths` object. Each `SdJwtClaim.path` (an array of strings) defines the nesting. |
| 35 | +- **Example**: A claim with `path = ["user", "name", "first"]` becomes: |
| 36 | + ```json |
| 37 | + "paths": { |
| 38 | + "user": { |
| 39 | + "name": { |
| 40 | + "first": { |
| 41 | + "value": "John", |
| 42 | + "display": { "verification": { "display": "First Name", ... } } |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | + ``` |
| 48 | +- **Structure**: |
| 49 | + - `id`: String. |
| 50 | + - `display`: (same as mso_mdoc). |
| 51 | + - `paths`: Recursive nested object. Leaf nodes are Claim objects (same structure as mso_mdoc). |
| 52 | + |
| 53 | +### 2.3 Issuance (credentials.issuance) |
| 54 | +- **mso_mdoc**: Array of MdocInlineIssuanceEntry objects: |
| 55 | + - `id`: String. |
| 56 | + - `subtitle`: String (optional). |
| 57 | + - `title`: String (optional hint). |
| 58 | + - `icon`: `{"start": <int>, "length": <int>}` (optional). |
| 59 | + - `supported`: Array of DocType Strings. |
| 60 | +- **dc+sd-jwt**: Array of SdJwtInlineIssuanceEntry objects: |
| 61 | + - `id`: String. |
| 62 | + - `subtitle`: String (optional). |
| 63 | + - `title`: String (optional hint). |
| 64 | + - `icon`: `{"start": <int>, "length": <int>}` (optional). |
| 65 | + - `supported`: Array of VCT Strings. |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## 3. C Function Index |
| 70 | + |
| 71 | +### base64.c / base64.h |
| 72 | +- `static int B64Lookup(char x)`: Helper function that maps Base64-URL characters to their corresponding 6-bit integer values. |
| 73 | +- `int B64DecodeURL(char* input, char** output)`: Takes a Base64-URL encoded string and decodes it. It allocates a new buffer for the output using `malloc` and returns the decoded length. It correctly handles base64url specific characters ('-' and '_') as well as standard padding ('='). |
| 74 | + |
| 75 | +### credentialmanager.c / credentialmanager.h |
| 76 | +- Provides ACM (Android Credential Manager) environment bindings to interface with the Android OS. |
| 77 | +- `void* GetRequest()`: Fetches the buffer containing the ACM request JSON. |
| 78 | +- `void* GetCredentials()`: Fetches the buffer containing the Registry binary blob. |
| 79 | +- Also exposes WASM imports for ACM reporting: `AddEntrySet`, `AddEntryToSet`, `AddFieldToEntrySet`, `AddPaymentEntryToSetV2`, `GetWasmVersion`, `AddInlineIssuanceEntry`, etc. |
| 80 | + |
| 81 | +### dcql.c / dcql.h |
| 82 | +- `int AddAllClaims(cJSON* matched_claim_names, cJSON* candidate_paths)`: Recursively traverses a JSON object representing candidate claim paths. For every object containing a "display" key, it adds that "display" object to the `matched_claim_names` array. This is used when a request doesn't specify specific claims, so the matcher must collect all available claims from the credential to show to the user. |
| 83 | +- `cJSON* MatchCredential(cJSON* credential, cJSON* credential_store)`: Evaluates a single DCQL `credential` requirement against the registry `credential_store`. |
| 84 | + - Determines if the requested format is `mso_mdoc` or `dc+sd-jwt`. |
| 85 | + - Checks if the credential candidate matches the `meta` criteria (e.g., matching `doctype_value` for `mso_mdoc`, or `vct_values` for `dc+sd-jwt`). |
| 86 | + - Iterates over candidates that matched the `meta` criteria. |
| 87 | + - If specific `claims` are requested, it traverses the `paths` of the candidate using the requested JSON paths array. It matches claim values if `values` are specified in the request. |
| 88 | + - If `claim_sets` are specified, it verifies that at least one logical group of claims is fully satisfied by the matched claims. |
| 89 | + - Identifies matching inline issuance options by comparing `supported` DocTypes or VCTs against the `meta` requirements. |
| 90 | + - Returns a JSON object with `matched_creds` (list of matched credentials containing `id`, `display`, `matched_claim_names`, and `matched_claim_metadata`) and an `inline_issuance` entry if applicable. |
| 91 | +- `cJSON* dcql_query(cJSON* query, cJSON* credential_store)`: High-level function that orchestrates DCQL evaluation. |
| 92 | + - Iterates over all `credentials` in the DCQL query and calls `MatchCredential` for each. |
| 93 | + - If `credential_sets` are defined in the query, it iterates over these sets and their options to find valid combinations of matched credentials that satisfy the query logic (handling `required` flags). |
| 94 | + - If no `credential_sets` are defined, it requires all requested credentials to match. |
| 95 | + - Returns a final `match_result` JSON containing `matched_credential_sets` (valid combinations of credentials) and `matched_credentials` (the actual credential details). |
| 96 | + |
| 97 | +### openid4vp1_0.c |
| 98 | +- `void report_credential_set_length(...)`: Recursively calculates the total number of credentials across all options in a matched credential set and reports this total length to the ACM using `AddEntrySet`. |
| 99 | +- `void report_matched_credential(...)`: Reports a specific matched credential to the ACM. |
| 100 | + - Constructs a JSON metadata string containing the matched claims, request index, and DCQL IDs. |
| 101 | + - Checks if the credential is a payment transaction (if `transaction_credential_ids` match). If so, it reports it as a payment entry via `AddPaymentEntryToSetV2` or `AddPaymentEntryToSet` (depending on the WASM version). |
| 102 | + - Otherwise, it reports it as a standard entry via `AddEntryToSet`, providing title, subtitle, explainer, and icon offsets. |
| 103 | + - Iterates through `matched_claim_names` to report each individual matched claim via `AddFieldToEntrySet`. |
| 104 | + - Reports `metadata_display_text` via `AddMetadataDisplayTextToEntrySet` if present. |
| 105 | +- `void report_matched_credential_set(...)`: Recursively iterates through the complex `matched_credential_sets` structure returned by `dcql_query` and calls `report_matched_credential` for each valid credential in each option. |
| 106 | +- `int main()`: The global entry point for the WASM module. |
| 107 | + - Fetches the credentials binary blob and finds the JSON metadata offset. |
| 108 | + - Parses the registry JSON and the DCQL request JSON. |
| 109 | + - Determines if the request is OpenID4VP (signed or unsigned) and decodes the payload via `B64DecodeURL` if it's signed (JWS). |
| 110 | + - Handles transaction data extraction for payments (merchant name, amount, additional info). |
| 111 | + - Calls `dcql_query` to perform the actual matching. |
| 112 | + - Extracts the matched results and uses the `report_*` functions to format and send the results back to the Android OS via the ACM API. |
| 113 | + - Handles inline issuance fallback by calling `AddInlineIssuanceEntry` if no regular credentials match but inline issuance is supported. |
| 114 | + |
| 115 | +### testharness.c |
| 116 | +- Provides mock implementations for ACM APIs (`GetRequestSize`, `GetRequestBuffer`, `GetCredentialsSize`, `ReadCredentialsBuffer`, etc.) to allow for local execution of the `main()` function. |
| 117 | +- Reads test inputs from local files like `request.json` and `testcreds.json`. |
0 commit comments