Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<meta charset="utf-8">
<title>Digital Credential API: org-iso-mdoc response handling</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body></body>
<script type="module">
import { makeGetOptions } from "../support/helper.js";
// Tests for org-iso-mdoc response handling.
// Uses the WebDriver BiDi virtual wallet to inject mock responses.
//
// Key architectural fact: the browser does NOT validate the Annex C
// EncryptedResponse CBOR. It passes the response object through to
// the site as credential.data. The site (as the verifier) is responsible
// for base64url decoding, CBOR parsing, and HPKE decryption.
//
// These tests verify:
// 1. The browser correctly passes through response data
// 2. The credential.protocol is set correctly
// 3. The response shape matches what the site expects
async function setMockResponse(t, responseObj) {
await test_driver.set_virtual_wallet_behavior("respond", "org-iso-mdoc", responseObj);
t.add_cleanup(() => test_driver.set_virtual_wallet_behavior("clear"));
}
// --- Response passthrough tests ---
promise_test(async (t) => {
// ISO 18013-7 Annex C.3: { "response": Base64EncryptedResponse }
const responseData = { response: "gmVkY2FwaaJjZW5jWEEEAAAAAAAA" };
await setMockResponse(t, responseData);
await test_driver.bless("user activation");
const options = makeGetOptions({ protocol: "org-iso-mdoc" });
const result = await navigator.credentials.get(options);
assert_equals(result.protocol, "org-iso-mdoc");
assert_equals(result.data.response, "gmVkY2FwaaJjZW5jWEEEAAAAAAAA");
}, "org-iso-mdoc response is passed through with correct protocol and data.");
promise_test(async (t) => {
// Response with the full Annex C structure as the site would receive it
const responseData = { response: "gmVkY2FwaaJjZW5jWCEEq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6tqY2lwaGVyVGV4dFhAq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urqw" };
await setMockResponse(t, responseData);
await test_driver.bless("user activation");
const options = makeGetOptions({ protocol: "org-iso-mdoc" });
const result = await navigator.credentials.get(options);
assert_equals(result.protocol, "org-iso-mdoc");
assert_true("response" in result.data, "Response object has 'response' field");
assert_equals(typeof result.data.response, "string", "Response field is a string");
}, "org-iso-mdoc response with Annex C shaped data preserves the response string.");
promise_test(async (t) => {
// Verify the browser doesn't modify the response data
const originalResponse = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
const responseData = { response: originalResponse };
await setMockResponse(t, responseData);
await test_driver.bless("user activation");
const options = makeGetOptions({ protocol: "org-iso-mdoc" });
const result = await navigator.credentials.get(options);
assert_equals(result.data.response, originalResponse,
"Browser must not modify the response string (no re-encoding, no validation)");
}, "Response data is passed through byte-for-byte without modification.");
promise_test(async (t) => {
// Empty response string (site would fail to decode, but browser should pass through)
const responseData = { response: "" };
await setMockResponse(t, responseData);
await test_driver.bless("user activation");
const options = makeGetOptions({ protocol: "org-iso-mdoc" });
const result = await navigator.credentials.get(options);
assert_equals(result.protocol, "org-iso-mdoc");
assert_equals(result.data.response, "");
}, "Empty response string is passed through (validation is the site's responsibility).");
promise_test(async (t) => {
// Extra fields beyond 'response' (future extensibility)
const responseData = { response: "gmVkY2FwaQ", extra: "field", version: 2 };
await setMockResponse(t, responseData);
await test_driver.bless("user activation");
const options = makeGetOptions({ protocol: "org-iso-mdoc" });
const result = await navigator.credentials.get(options);
assert_equals(result.protocol, "org-iso-mdoc");
assert_equals(result.data.response, "gmVkY2FwaQ");
assert_equals(result.data.extra, "field");
assert_equals(result.data.version, 2);
}, "Additional fields in the response object are preserved.");
</script>