<!DOCTYPE html>
<title>Web Authentication API: PublicKeyCredential's [[create]] success cases with a mock local authenticator.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/util.js"></script>
<script src="./resources/cbor.js"></script>
<script>
    // Default mock configuration. Tests need to override if they need different configuration.
    if (window.testRunner)
        testRunner.setWebAuthenticationMockConfiguration({
            local: {
                acceptAuthentication: true,
                acceptAttestation: true,
                privateKeyBase64: testES256PrivateKeyBase64,
                userCertificateBase64: testAttestationCertificateBase64,
                intermediateCACertificateBase64: testAttestationIssuingCACertificateBase64
            }
        });

    function checkResult(credential)
    {
        // Check keychain
        if (window.testRunner) {
            assert_true(testRunner.keyExistsInKeychain(testRpId, testUserhandleBase64));
            testRunner.cleanUpKeychain(testRpId);
        }

        // Check respond
        assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testCredentialIdBase64));
        assert_equals(credential.type, 'public-key');
        assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testCredentialIdBase64));
        assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');
        assert_not_exists(credential.getClientExtensionResults(), "appid");

        // Check attestation
        const attestationObject = CBOR.decode(credential.response.attestationObject);
        assert_equals(attestationObject.fmt, "Apple");
        // Check authData
        const authData = decodeAuthData(attestationObject.authData);
        assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");
        assert_equals(authData.flags, 69);
        assert_equals(authData.counter, 0);
        assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000");
        assert_array_equals(authData.credentialID, Base64URL.parse(testCredentialIdBase64));
        // Check self attestation
        assert_equals(attestationObject.attStmt.alg, -7);
        assert_true(checkPublicKey(authData.publicKey));
        assert_equals(attestationObject.attStmt.x5c.length, 2);
        assert_array_equals(attestationObject.attStmt.x5c[0], Base64URL.parse(testAttestationCertificateBase64));
        assert_array_equals(attestationObject.attStmt.x5c[1], Base64URL.parse(testAttestationIssuingCACertificateBase64));

        // Check signature
        let publicKeyData = new Uint8Array(65);
        publicKeyData[0] = 0x04;
        publicKeyData.set(authData.publicKey['-2'], 1);
        publicKeyData.set(authData.publicKey['-3'], 33);
        return crypto.subtle.importKey("raw", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => {
            return crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, publicKey, extractRawSignature(attestationObject.attStmt.sig), attestationObject.authData).then( verified => {
                assert_true(verified);
            });
        });
    }

    promise_test(t => {
        const options = {
            publicKey: {
                rp: {
                    name: "localhost",
                },
                user: {
                    name: "John Appleseed",
                    id: Base64URL.parse(testUserhandleBase64),
                    displayName: "Appleseed",
                },
                challenge: Base64URL.parse("MTIzNDU2"),
                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
            }
        };

        return navigator.credentials.create(options).then(credential => {
            checkResult(credential);
        });
    }, "PublicKeyCredential's [[create]] with minimum options in a mock local authenticator.");

    promise_test(t => {
        const options = {
            publicKey: {
                rp: {
                    name: "localhost",
                },
                user: {
                    name: "John Appleseed",
                    id: Base64URL.parse(testUserhandleBase64),
                    displayName: "Appleseed",
                },
                challenge: Base64URL.parse("MTIzNDU2"),
                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
                authenticatorSelection: { authenticatorAttachment: "platform" }
            }
        };

        return navigator.credentials.create(options).then(credential => {
            checkResult(credential);
        });
    }, "PublicKeyCredential's [[create]] with authenticatorSelection { 'platform' } in a mock local authenticator.");

    promise_test(t => {
        const options = {
            publicKey: {
                rp: {
                    name: "example.com"
                },
                user: {
                    name: "John Appleseed",
                    id: Base64URL.parse(testUserhandleBase64),
                    displayName: "John",
                },
                challenge: asciiToUint8Array("123456"),
                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
                excludeCredentials: [
                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }
                ]
            }
        };
        if (window.testRunner)
            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);

        return navigator.credentials.create(options).then(credential => {
            checkResult(credential);
        });
    }, "PublicKeyCredential's [[create]] with matched exclude credential ids but not transports in a mock local authenticator.");
</script>
