diff options
Diffstat (limited to 'dom/webauthn/tests/test_webauthn_attestation_conveyance.html')
-rw-r--r-- | dom/webauthn/tests/test_webauthn_attestation_conveyance.html | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/dom/webauthn/tests/test_webauthn_attestation_conveyance.html b/dom/webauthn/tests/test_webauthn_attestation_conveyance.html new file mode 100644 index 0000000000..f4a3c39349 --- /dev/null +++ b/dom/webauthn/tests/test_webauthn_attestation_conveyance.html @@ -0,0 +1,123 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<head> + <title>W3C Web Authentication - Attestation Conveyance</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="u2futil.js"></script> + <script type="text/javascript" src="pkijs/common.js"></script> + <script type="text/javascript" src="pkijs/asn1.js"></script> + <script type="text/javascript" src="pkijs/x509_schema.js"></script> + <script type="text/javascript" src="pkijs/x509_simpl.js"></script> + <script type="text/javascript" src="cbor.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + + <h1>W3C Web Authentication - Attestation Conveyance</h1> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1428916">Mozilla Bug 1428916</a> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1416056">Mozilla Bug 1416056</a> + + <script class="testbody" type="text/javascript"> + "use strict"; + + add_task(() => { + return SpecialPowers.pushPrefEnv({"set": [ + ["security.webauth.webauthn_testing_allow_direct_attestation", true], + ]}); + }); + + function getAttestationCertFromAttestationBuffer(aAttestationBuffer) { + return webAuthnDecodeCBORAttestation(aAttestationBuffer) + .then((aAttestationObj) => { + is(aAttestationObj.fmt, "fido-u2f", "Is a FIDO U2F Attestation"); + let attestationCertDER = aAttestationObj.attStmt.x5c[0]; + let certDERBuffer = attestationCertDER.slice(0, attestationCertDER.byteLength).buffer; + let certAsn1 = org.pkijs.fromBER(certDERBuffer); + return new org.pkijs.simpl.CERT({ schema: certAsn1.result }); + }); + } + + function verifyAnonymizedCertificate(aResult) { + return webAuthnDecodeCBORAttestation(aResult.response.attestationObject) + .then(({fmt, attStmt}) => { + is(fmt, "none", "Is a None Attestation"); + is(typeof(attStmt), "object", "attStmt is a map"); + is(Object.keys(attStmt).length, 0, "attStmt is empty"); + }); + } + + function verifyDirectCertificate(aResult) { + return getAttestationCertFromAttestationBuffer(aResult.response.attestationObject) + .then((attestationCert) => { + let subject = attestationCert.subject.types_and_values[0].value.value_block.value; + is(subject, "Firefox U2F Soft Token", "Subject name matches the direct Soft Token") + }); + } + + function arrivingHereIsBad(aResult) { + ok(false, "Bad result! Received a: " + aResult); + } + + function expectTypeError(aResult) { + ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError, got " + aResult); + } + + // Start a new MakeCredential() request. + function requestMakeCredential(attestation) { + let publicKey = { + rp: {id: document.domain, name: "none", icon: "none"}, + user: {id: new Uint8Array(), name: "none", icon: "none", displayName: "none"}, + challenge: crypto.getRandomValues(new Uint8Array(16)), + timeout: 5000, // the minimum timeout is actually 15 seconds + pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}], + attestation, + }; + + return navigator.credentials.create({publicKey}); + } + + // Test success cases for make credential. + add_task(async function test_make_credential_success () { + // No selection criteria should be equal to none, which means anonymized + await requestMakeCredential() + .then(verifyAnonymizedCertificate) + .catch(arrivingHereIsBad); + + // Request an unknown attestation type. This should be treated as "none". + await requestMakeCredential("unknown") + .then(verifyAnonymizedCertificate) + .catch(arrivingHereIsBad); + + // Request no attestation. + await requestMakeCredential("none") + .then(verifyAnonymizedCertificate) + .catch(arrivingHereIsBad); + + // Request indirect attestation, which is the same as direct. + await requestMakeCredential("indirect") + .then((x) => { + if (AppConstants.platform === "android") { + // If this is Android, the result will be anonymized (Bug 1551229) + return verifyAnonymizedCertificate(x); + } else { + return verifyDirectCertificate(x); + } + }) + .catch(arrivingHereIsBad); + + // Request direct attestation, which will prompt for user intervention. + await requestMakeCredential("direct") + .then((x) => { + if (AppConstants.platform === "android") { + // If this is Android, the result will be anonymized (Bug 1551229) + return verifyAnonymizedCertificate(x); + } else { + return verifyDirectCertificate(x); + } + }) + .catch(arrivingHereIsBad); + }); + </script> + +</body> +</html> |