Diff
Modified: trunk/LayoutTests/ChangeLog (227381 => 227382)
--- trunk/LayoutTests/ChangeLog 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/LayoutTests/ChangeLog 2018-01-23 03:00:59 UTC (rev 227382)
@@ -1,3 +1,33 @@
+2018-01-22 Jiewen Tan <jiewen_...@apple.com>
+
+ [WebAuthN] Implement PublicKeyCredential's [[Create]] with a dummy authenticator
+ https://bugs.webkit.org/show_bug.cgi?id=181928
+ <rdar://problem/36459893>
+
+ Reviewed by Brent Fulgham.
+
+ Test cases are divided into two different folders. One follows wpt style. The other contains tests
+ that I don't know how to write them in wpt style.
+
+ * http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https-expected.txt: Added.
+ * http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https.html: Added.
+ * http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt: Added.
+ * http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https.html: Added.
+ * http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt: Added.
+ * http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https.html: Added.
+ * http/tests/webauthn/resources/last-layer-frame.https.html: Added.
+ * http/tests/webauthn/resources/second-layer-frame.https.html: Added.
+ * http/tests/webauthn/resources/util.js: Added.
+ It will be good to convert them into wpt style.
+ * http/wpt/webauthn/WebAuthN.idl: Added.
+ * http/wpt/webauthn/idl.https-expected.txt: Added.
+ * http/wpt/webauthn/idl.https.html: Added.
+ * http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt: Added.
+ * http/wpt/webauthn/public-key-credential-create-failure.https.html: Added.
+ * http/wpt/webauthn/public-key-credential-create-success.https-expected.txt: Added.
+ * http/wpt/webauthn/public-key-credential-create-success.https.html: Added.
+ * http/wpt/webauthn/resources/util.js: Added.
+
2018-01-22 Ryan Haddad <ryanhad...@apple.com>
Skip http/tests/ssl/applepay/ApplePayRequestShippingContact.https.html on Sierra.
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,64 @@
+Tests that PublicKeyCredential's [[create]] throws TypeError when invalid options are passed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialCreationOptions.rp is required and must be an instance of PublicKeyCredentialRpEntity.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialCreationOptions.user is required and must be an instance of PublicKeyCredentialUserEntity.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialCreationOptions.challenge is required and must be an instance of (ArrayBufferView or ArrayBuffer).
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialCreationOptions.pubKeyCredParams is required and must be an instance of sequence.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialRpEntity.name is required and must be an instance of DOMString.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialUserEntity.name is required and must be an instance of DOMString.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialUserEntity.id is required and must be an instance of (ArrayBufferView or ArrayBuffer).
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialUserEntity.displayName is required and must be an instance of DOMString.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialParameters.type is required and must be an instance of PublicKeyCredentialType.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialParameters.alg is required and must be an instance of long.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialDescriptor.type is required and must be an instance of PublicKeyCredentialType.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Member PublicKeyCredentialDescriptor.id is required and must be an instance of (ArrayBufferView or ArrayBuffer).
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a number.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a number.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Cannot convert a symbol to a string.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS navigator.credentials.create(invalidOptions) rejected promise with TypeError: Type error.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https.html (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+ description("Tests that PublicKeyCredential's [[create]] throws TypeError when invalid options are passed.");
+
+ jsTestIsAsync = true;
+
+ const rp = {
+ name: "example.com"
+ };
+ const user = {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "Appleseed"
+ };
+ const challenge = asciiToUint8Array("123456");
+ const pubKeyCredParam = { type: "public-key", alg: -7 };
+ const excludeCredentials = { type: "public-key", id: asciiToUint8Array("123456") };
+
+ const missingAttributeVector = [
+ // missing top level attribute
+ [undefined, user, challenge, [pubKeyCredParam]],
+ [rp, undefined, challenge, [pubKeyCredParam]],
+ [rp, user, undefined, [pubKeyCredParam]],
+ [rp, user, challenge, undefined],
+ // missing rp attribute
+ [{ name: undefined }, user, challenge, [pubKeyCredParam]],
+ // missing user attribute
+ [rp, { name: undefined, id: user.id, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: undefined, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: user.id, displayName: undefined}, challenge, [pubKeyCredParam]],
+ // missing pubKeyCredParams attribute
+ [rp, user, challenge, [{ type: undefined, alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: pubKeyCredParam.type, alg: undefined }]],
+ // missing excludeCredentials attribute
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: undefined, id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: undefined }]]
+ ];
+
+ const wrongTypeAttributeVector = [
+ // wrong rp attribute type
+ [{ name: Symbol() }, user, challenge, [pubKeyCredParam]],
+ [{ name: rp.name, icon: Symbol() }, user, challenge, [pubKeyCredParam]],
+ [{ name: rp.name, id: Symbol() }, user, challenge, [pubKeyCredParam]],
+ // wrong user attribute type
+ [rp, { name: Symbol(), id: user.id, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: 1, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: true, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: null, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: Symbol(), displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: { }, displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: "foo", displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: [ ], displayName: user.displayName}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: user.id, displayName: Symbol()}, challenge, [pubKeyCredParam]],
+ [rp, { name: user.name, id: user.id, displayName: user.displayName, icon: Symbol()}, challenge, [pubKeyCredParam]],
+ // wrong challenge type
+ [rp, user, 1, [pubKeyCredParam]],
+ [rp, user, true, [pubKeyCredParam]],
+ [rp, user, null, [pubKeyCredParam]],
+ [rp, user, Symbol(), [pubKeyCredParam]],
+ [rp, user, "foo", [pubKeyCredParam]],
+ [rp, user, [ ], [pubKeyCredParam]],
+ [rp, user, { }, [pubKeyCredParam]],
+ // wrong pubKeyCredParam type
+ [rp, user, challenge, [{ type: 1, alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: true, alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: null, alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: Symbol(), alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: "foo", alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: [ ], alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: { }, alg: pubKeyCredParam.alg }]],
+ [rp, user, challenge, [{ type: pubKeyCredParam.type, alg: Symbol() }]],
+ // wrong timeout type
+ [rp, user, challenge, [pubKeyCredParam], Symbol(), undefined],
+ // wrong excludeCredentials
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: 1, id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: true, id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: null, id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: Symbol(), id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: "foo", id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: [ ], id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: { }, id: excludeCredentials.id }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: 1 }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: true }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: null }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: Symbol() }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: "foo" }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: [ ] }]],
+ [rp, user, challenge, [pubKeyCredParam], undefined, [{ type: excludeCredentials.type, id: { } }]]
+ ]
+
+ function makeOptions(attributes)
+ {
+ if (attributes.length == 4)
+ return { publicKey: { rp: attributes[0], user: attributes[1], challenge: attributes[2], pubKeyCredParams: attributes[3] } };
+ return { publicKey: { rp: attributes[0], user: attributes[1], challenge: attributes[2], pubKeyCredParams: attributes[3], timeout: attributes[4], excludeCredentials: attributes[5]} };
+ }
+
+ function runTest(attributesVectors) {
+ attributesVectors.forEach(function(attributesVector) {
+ attributesVector.forEach(async function(attributes) {
+ invalidOptions = makeOptions(attributes);
+ await shouldReject('navigator.credentials.create(invalidOptions)');
+ });
+ });
+
+ finishJSTest();
+ }
+
+ const vectors = [];
+ vectors.push(missingAttributeVector);
+ vectors.push(wrongTypeAttributeVector);
+ runTest(vectors);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,10 @@
+Tests that a frame that doesn't share the same origin with all its ancestors could not access the API.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Throw NotAllowedError.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https.html (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+ <script>
+ description("Tests that a frame that doesn't share the same origin with all its ancestors could not access the API.");
+ jsTestIsAsync = true;
+
+ window.addEventListener("message", receiveMessage, false);
+ </script>
+</head>
+<body>
+ <iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,10 @@
+Tests that a frame that doesn't share the same origin with all its ancestors could not access the API.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Throw NotAllowedError.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https.html (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+ <script>
+ description("Tests that a frame that doesn't share the same origin with all its ancestors could not access the API.");
+ jsTestIsAsync = true;
+
+ window.addEventListener("message", receiveMessage, false);
+ </script>
+</head>
+<body>
+ <iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/webauthn/resources/last-layer-frame.https.html (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/resources/last-layer-frame.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/resources/last-layer-frame.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,37 @@
+<html>
+<head>
+ <script src=""
+ <script src=""
+ <script>
+ function messageToTop(messagePrefix) {
+ top.postMessage(messagePrefix, "https://127.0.0.1:8443");
+ }
+
+ const options = {
+ publicKey: {
+ rp: {
+ name: "example.com"
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "John",
+ },
+ challenge: asciiToUint8Array("123456"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }]
+ }
+ };
+ navigator.credentials.create(options).then(
+ function(value) {
+ messageToTop("Access granted. " + value);
+ },
+ function(exception) {
+ if (exception.name == "NotAllowedError")
+ messageToTop("PASS Throw NotAllowedError.");
+ else
+ messageToTop("Throw " + exception.name + ".");
+ }
+ );
+ </script>
+</head>
+</html>
Added: trunk/LayoutTests/http/tests/webauthn/resources/second-layer-frame.https.html (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/resources/second-layer-frame.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/resources/second-layer-frame.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+ <iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/webauthn/resources/util.js (0 => 227382)
--- trunk/LayoutTests/http/tests/webauthn/resources/util.js (rev 0)
+++ trunk/LayoutTests/http/tests/webauthn/resources/util.js 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,18 @@
+function receiveMessage(event) {
+ if (event.origin === "https://localhost:8443") {
+ if (event.data.indexOf("PASS ") !== -1)
+ testPassed(event.data.replace("PASS ", ""));
+ else
+ testFailed(event.data);
+ } else
+ testFailed("Received a message from an unexpected origin: " + event.origin);
+ finishJSTest();
+}
+
+function asciiToUint8Array(str)
+{
+ const chars = [];
+ for (var i = 0; i < str.length; ++i)
+ chars.push(str.charCodeAt(i));
+ return new Uint8Array(chars);
+}
Added: trunk/LayoutTests/http/wpt/webauthn/WebAuthN.idl (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/WebAuthN.idl (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/WebAuthN.idl 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,135 @@
+// Copied from https://www.w3.org/TR/webauthn/#idl-index as of 5 December 2017
+[SecureContext, Exposed=Window]
+interface PublicKeyCredential : Credential {
+ [SameObject] readonly attribute ArrayBuffer rawId;
+ [SameObject] readonly attribute AuthenticatorResponse response;
+ AuthenticationExtensions getClientExtensionResults();
+};
+
+partial dictionary CredentialCreationOptions {
+ MakePublicKeyCredentialOptions publicKey;
+};
+
+partial dictionary CredentialRequestOptions {
+ PublicKeyCredentialRequestOptions publicKey;
+};
+
+partial interface PublicKeyCredential {
+ static Promise < boolean > isUserVerifyingPlatformAuthenticatorAvailable();
+};
+
+[SecureContext, Exposed=Window]
+interface AuthenticatorResponse {
+ [SameObject] readonly attribute ArrayBuffer clientDataJSON;
+};
+
+[SecureContext, Exposed=Window]
+interface AuthenticatorAttestationResponse : AuthenticatorResponse {
+ [SameObject] readonly attribute ArrayBuffer attestationObject;
+};
+
+[SecureContext, Exposed=Window]
+interface AuthenticatorAssertionResponse : AuthenticatorResponse {
+ [SameObject] readonly attribute ArrayBuffer authenticatorData;
+ [SameObject] readonly attribute ArrayBuffer signature;
+ [SameObject] readonly attribute ArrayBuffer userHandle;
+};
+
+dictionary PublicKeyCredentialParameters {
+ required PublicKeyCredentialType type;
+ required COSEAlgorithmIdentifier alg;
+};
+
+dictionary MakePublicKeyCredentialOptions {
+ required PublicKeyCredentialRpEntity rp;
+ required PublicKeyCredentialUserEntity user;
+
+ required BufferSource challenge;
+ required sequence<PublicKeyCredentialParameters> pubKeyCredParams;
+
+ unsigned long timeout;
+ sequence<PublicKeyCredentialDescriptor> excludeCredentials = [];
+ AuthenticatorSelectionCriteria authenticatorSelection;
+ AttestationConveyancePreference attestation = "none";
+ AuthenticationExtensions extensions;
+};
+
+dictionary PublicKeyCredentialEntity {
+ required DOMString name;
+ USVString icon;
+};
+
+dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
+ DOMString id;
+};
+
+dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
+ required BufferSource id;
+ required DOMString displayName;
+};
+
+dictionary AuthenticatorSelectionCriteria {
+ AuthenticatorAttachment authenticatorAttachment;
+ boolean requireResidentKey = false;
+ UserVerificationRequirement userVerification = "preferred";
+};
+
+enum AuthenticatorAttachment {
+ "platform", // Platform attachment
+ "cross-platform" // Cross-platform attachment
+};
+
+enum AttestationConveyancePreference {
+ "none",
+ "indirect",
+ "direct"
+};
+
+dictionary PublicKeyCredentialRequestOptions {
+ required BufferSource challenge;
+ unsigned long timeout;
+ USVString rpId;
+ sequence<PublicKeyCredentialDescriptor> allowCredentials = [];
+ UserVerificationRequirement userVerification = "preferred";
+ AuthenticationExtensions extensions;
+};
+
+typedef record<DOMString, any> AuthenticationExtensions;
+
+dictionary CollectedClientData {
+ required DOMString type;
+ required DOMString challenge;
+ required DOMString origin;
+ required DOMString hashAlgorithm;
+ DOMString tokenBindingId;
+ AuthenticationExtensions clientExtensions;
+ AuthenticationExtensions authenticatorExtensions;
+};
+
+enum PublicKeyCredentialType {
+ "public-key"
+};
+
+dictionary PublicKeyCredentialDescriptor {
+ required PublicKeyCredentialType type;
+ required BufferSource id;
+ sequence<AuthenticatorTransport> transports;
+};
+
+enum AuthenticatorTransport {
+ "usb",
+ "nfc",
+ "ble"
+};
+
+typedef long COSEAlgorithmIdentifier;
+
+enum UserVerificationRequirement {
+ "required",
+ "preferred",
+ "discouraged"
+};
+
+typedef sequence<AAGUID> AuthenticatorSelectionList;
+
+typedef BufferSource AAGUID;
Added: trunk/LayoutTests/http/wpt/webauthn/idl.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/idl.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/idl.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,55 @@
+Description
+
+This test verifies that the implementations of the WebAuthN API match with its WebIDL definition.
+
+
+PASS Setup for WebAuthN API IDL tests.
+PASS Credential interface: existence and properties of interface object
+PASS Credential interface object length
+PASS Credential interface object name
+PASS Credential interface: existence and properties of interface prototype object
+PASS Credential interface: existence and properties of interface prototype object's "constructor" property
+PASS Credential interface: attribute id
+PASS Credential interface: attribute type
+PASS PublicKeyCredential interface: existence and properties of interface object
+PASS PublicKeyCredential interface object length
+PASS PublicKeyCredential interface object name
+PASS PublicKeyCredential interface: existence and properties of interface prototype object
+PASS PublicKeyCredential interface: existence and properties of interface prototype object's "constructor" property
+PASS PublicKeyCredential interface: attribute rawId
+PASS PublicKeyCredential interface: attribute response
+PASS PublicKeyCredential interface: operation getClientExtensionResults()
+PASS PublicKeyCredential interface: operation isUserVerifyingPlatformAuthenticatorAvailable()
+PASS PublicKeyCredential must be primary interface of credential
+PASS Stringification of credential
+PASS PublicKeyCredential interface: credential must inherit property "rawId" with the proper type
+PASS PublicKeyCredential interface: credential must inherit property "response" with the proper type
+PASS PublicKeyCredential interface: credential must inherit property "getClientExtensionResults()" with the proper type
+PASS PublicKeyCredential interface: credential must inherit property "isUserVerifyingPlatformAuthenticatorAvailable()" with the proper type
+PASS Credential interface: credential must inherit property "id" with the proper type
+PASS Credential interface: credential must inherit property "type" with the proper type
+PASS AuthenticatorResponse interface: existence and properties of interface object
+PASS AuthenticatorResponse interface object length
+PASS AuthenticatorResponse interface object name
+PASS AuthenticatorResponse interface: existence and properties of interface prototype object
+PASS AuthenticatorResponse interface: existence and properties of interface prototype object's "constructor" property
+PASS AuthenticatorResponse interface: attribute clientDataJSON
+PASS AuthenticatorAttestationResponse interface: existence and properties of interface object
+PASS AuthenticatorAttestationResponse interface object length
+PASS AuthenticatorAttestationResponse interface object name
+PASS AuthenticatorAttestationResponse interface: existence and properties of interface prototype object
+PASS AuthenticatorAttestationResponse interface: existence and properties of interface prototype object's "constructor" property
+PASS AuthenticatorAttestationResponse interface: attribute attestationObject
+PASS AuthenticatorAttestationResponse must be primary interface of credential.response
+PASS Stringification of credential.response
+PASS AuthenticatorAttestationResponse interface: credential.response must inherit property "attestationObject" with the proper type
+PASS AuthenticatorResponse interface: credential.response must inherit property "clientDataJSON" with the proper type
+PASS AuthenticatorAssertionResponse interface: existence and properties of interface object
+PASS AuthenticatorAssertionResponse interface object length
+PASS AuthenticatorAssertionResponse interface object name
+PASS AuthenticatorAssertionResponse interface: existence and properties of interface prototype object
+PASS AuthenticatorAssertionResponse interface: existence and properties of interface prototype object's "constructor" property
+PASS AuthenticatorAssertionResponse interface: attribute authenticatorData
+PASS AuthenticatorAssertionResponse interface: attribute signature
+PASS AuthenticatorAssertionResponse interface: attribute userHandle
+
Added: trunk/LayoutTests/http/wpt/webauthn/idl.https.html (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/idl.https.html (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/idl.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,57 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>IDL check of WebAuthN</title>
+ <link rel="help" href=""
+ <script src=""
+ <script src=""
+ <script src=""
+ <script src=""
+ <script src=""
+</head>
+<body>
+
+<h1 class="instructions">Description</h1>
+
+<p class="instructions">This test verifies that the implementations of the WebAuthN API match with its WebIDL definition.</p>
+
+<div id='log'></div>
+
+<script>
+promise_test(async () => {
+ const idlURL = ["WebAuthN.idl"];
+ const idlArray = new IdlArray();
+ const idlText = await fetch(idlURL).then(r => r.text());
+
+ idlArray.add_untested_idls("interface ArrayBuffer {};");
+
+ idlArray.add_idls(`
+ [Exposed=Window, SecureContext]
+ interface Credential {
+ readonly attribute USVString id;
+ readonly attribute DOMString type;
+ };
+ `);
+ idlArray.add_idls(idlText);
+
+ const options = {
+ publicKey: {
+ rp: {
+ name: "localhost",
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "Appleseed",
+ },
+ challenge: Base64URL.parse("MTIzNDU2"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+ }
+ };
+ credential = await navigator.credentials.create(options);
+
+ idlArray.add_objects({"PublicKeyCredential": ["credential"], "AuthenticatorAttestationResponse": ["credential.response"]});
+ idlArray.test();
+}, "Setup for WebAuthN API IDL tests.");
+</script>
Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,6 @@
+
+PASS PublicKeyCredential's [[create]] with timeout
+PASS PublicKeyCredential's [[create]] with a mismatched RP ID
+PASS PublicKeyCredential's [[create]] with an empty pubKeyCredParams
+PASS PublicKeyCredential's [[create]] with user cancellations
+
Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<title>Web Authentication API: PublicKeyCredential's [[create]] failure cases.</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+ promise_test(function(t) {
+ const options = {
+ publicKey: {
+ rp: {
+ name: "example.com"
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "John",
+ },
+ challenge: asciiToUint8Array("123456"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+ timeout: 0,
+ }
+ };
+ return promise_rejects(t, "NotAllowedError",
+ navigator.credentials.create(options));
+ }, "PublicKeyCredential's [[create]] with timeout");
+
+ promise_test(function(t) {
+ const options = {
+ publicKey: {
+ rp: {
+ name: "example.com",
+ id: "example.com"
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "John",
+ },
+ challenge: asciiToUint8Array("123456"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+ }
+ };
+ return promise_rejects(t, "SecurityError",
+ navigator.credentials.create(options));
+ }, "PublicKeyCredential's [[create]] with a mismatched RP ID");
+
+ promise_test(function(t) {
+ const options = {
+ publicKey: {
+ rp: {
+ name: "localhost",
+ id: "localhost"
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "Appleseed",
+ },
+ challenge: asciiToUint8Array("123456"),
+ pubKeyCredParams: [ ],
+ }
+ };
+ return promise_rejects(t, "NotSupportedError",
+ navigator.credentials.create(options));
+ }, "PublicKeyCredential's [[create]] with an empty pubKeyCredParams");
+
+ // This test is targeting to the dummy authenticator, which always cancel the operation
+ // when user.displayName = "John".
+ promise_test(function(t) {
+ const options = {
+ publicKey: {
+ rp: {
+ name: "localhost",
+ id: "localhost"
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "John",
+ },
+ challenge: asciiToUint8Array("123456"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+ }
+ };
+ return promise_rejects(t, "NotAllowedError",
+ navigator.credentials.create(options));
+ }, "PublicKeyCredential's [[create]] with user cancellations");
+</script>
Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https-expected.txt (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https-expected.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,3 @@
+
+PASS PublicKeyCredential's [[create]] with minimum options
+
Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https.html (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https.html (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https.html 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Web Authentication API: PublicKeyCredential's [[create]] success cases.</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+ // The following test is specifically tuned for current dummy authenticator.
+ promise_test(function(t) {
+ const options = {
+ publicKey: {
+ rp: {
+ name: "localhost",
+ },
+ user: {
+ name: "John Appleseed",
+ id: asciiToUint8Array("123456"),
+ displayName: "Appleseed",
+ },
+ challenge: Base64URL.parse("MTIzNDU2"),
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+ }
+ };
+
+ return navigator.credentials.create(options).then(function(credential) {
+ assert_equals(credential.id, '_w');
+ assert_equals(credential.type, 'public-key');
+ assert_equals(bytesToHexString(credential.rawId), 'ff');
+ assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443","hashAlgorithm":"SHA-256"}');
+ // This field is completely fake 0x00*43 | 0x0001ff | SHA-256 hash of the clientDataJSON
+ assert_equals(bytesToHexString(credential.response.attestationObject), '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ff3374b98316b38046727a770b8e95c4580a292b9e2f4bb44a250a5402d6d3783a');
+ try {
+ assert_throws("NotSupportedError", credential.getClientExtensionResults());
+ } catch { }
+ });
+ }, "PublicKeyCredential's [[create]] with minimum options");
+</script>
Added: trunk/LayoutTests/http/wpt/webauthn/resources/util.js (0 => 227382)
--- trunk/LayoutTests/http/wpt/webauthn/resources/util.js (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/resources/util.js 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,45 @@
+function asciiToUint8Array(str)
+{
+ var chars = [];
+ for (var i = 0; i < str.length; ++i)
+ chars.push(str.charCodeAt(i));
+ return new Uint8Array(chars);
+}
+
+// Builds a hex string representation for an array-like input.
+// "bytes" can be an Array of bytes, an ArrayBuffer, or any TypedArray.
+// The output looks like this:
+// ab034c99
+function bytesToHexString(bytes)
+{
+ if (!bytes)
+ return null;
+
+ bytes = new Uint8Array(bytes);
+ var hexBytes = [];
+
+ for (var i = 0; i < bytes.length; ++i) {
+ var byteString = bytes[i].toString(16);
+ if (byteString.length < 2)
+ byteString = "0" + byteString;
+ hexBytes.push(byteString);
+ }
+
+ return hexBytes.join("");
+}
+
+function bytesToASCIIString(bytes)
+{
+ return String.fromCharCode.apply(null, new Uint8Array(bytes));
+}
+
+var Base64URL = {
+ stringify: function (a) {
+ var base64string = btoa(String.fromCharCode.apply(0, a));
+ return base64string.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
+ },
+ parse: function (s) {
+ s = s.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, '');
+ return new Uint8Array(Array.prototype.map.call(atob(s), function (c) { return c.charCodeAt(0) }));
+ }
+};
Modified: trunk/Source/WebCore/ChangeLog (227381 => 227382)
--- trunk/Source/WebCore/ChangeLog 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/ChangeLog 2018-01-23 03:00:59 UTC (rev 227382)
@@ -1,3 +1,92 @@
+2018-01-22 Jiewen Tan <jiewen_...@apple.com>
+
+ [WebAuthN] Implement PublicKeyCredential's [[Create]] with a dummy authenticator
+ https://bugs.webkit.org/show_bug.cgi?id=181928
+ <rdar://problem/36459893>
+
+ Reviewed by Brent Fulgham.
+
+ This patch implements PublicKeyCredential's [[Create]] from https://www.w3.org/TR/webauthn/#createCredential
+ as of 5 December 2017. In order to do testing, a dummy authenticator is implemented to exercise a failure
+ and a pass path. A number of dependencies need to be resolved later in order to comply with the spec.
+ Also, the current architecture of handling async WebAuthN operations including dispatching, timeout, and aborting
+ might need a redesign once the underlying authenticator is clear. Since this is our first attempt to implement
+ a prototype, all those limitations, in my opinion, can be marked as non-blocking to accelerate the whole
+ process. Those limitations will then be addressed once the first prototype is finshed.
+
+ Tests: http/tests/webauthn/public-key-credential-create-with-invalid-parameters.https.html
+ http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https.html
+ http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https.html
+ http/wpt/webauthn/idl.https.html
+ http/wpt/webauthn/public-key-credential-create-failure.https.html
+ http/wpt/webauthn/public-key-credential-create-success.https.html
+
+ * Modules/credentialmanagement/BasicCredential.h:
+ * Modules/credentialmanagement/BasicCredential.idl:
+ * Modules/credentialmanagement/CredentialsContainer.cpp:
+ (WebCore::CredentialsContainer::PendingPromise::PendingPromise):
+ (WebCore::CredentialsContainer::dispatchTask):
+ (WebCore::CredentialsContainer::get):
+ (WebCore::CredentialsContainer::isCreate):
+ (WebCore::CredentialsContainer::preventSilentAccess const):
+ (WebCore::CredentialsContainer::preventSilentAccess): Deleted.
+ * Modules/credentialmanagement/CredentialsContainer.h:
+ (WebCore::CredentialsContainer::PendingPromise::create):
+ * Modules/webauthn/Authenticator.cpp: Copied from Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp.
+ (WebCore::Authenticator::singleton):
+ (WebCore::Authenticator::makeCredential const):
+ * Modules/webauthn/Authenticator.h: Copied from Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h.
+ * Modules/webauthn/AuthenticatorAssertionResponse.cpp:
+ (WebCore::AuthenticatorAssertionResponse::authenticatorData const):
+ (WebCore::AuthenticatorAssertionResponse::signature const):
+ (WebCore::AuthenticatorAssertionResponse::userHandle const):
+ (WebCore::AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse): Deleted.
+ (WebCore::AuthenticatorAssertionResponse::authenticatorData): Deleted.
+ (WebCore::AuthenticatorAssertionResponse::signature): Deleted.
+ (WebCore::AuthenticatorAssertionResponse::userHandle): Deleted.
+ * Modules/webauthn/AuthenticatorAssertionResponse.h:
+ (WebCore::AuthenticatorAssertionResponse::create):
+ * Modules/webauthn/AuthenticatorAttestationResponse.cpp:
+ (WebCore::AuthenticatorAttestationResponse::attestationObject const):
+ (WebCore::AuthenticatorAttestationResponse::~AuthenticatorAttestationResponse): Deleted.
+ (WebCore::AuthenticatorAttestationResponse::attestationObject): Deleted.
+ * Modules/webauthn/AuthenticatorAttestationResponse.h:
+ (WebCore::AuthenticatorAttestationResponse::create):
+ * Modules/webauthn/AuthenticatorResponse.cpp:
+ (WebCore::AuthenticatorResponse::clientDataJSON const):
+ (WebCore::AuthenticatorResponse::~AuthenticatorResponse): Deleted.
+ (WebCore::AuthenticatorResponse::clientDataJSON): Deleted.
+ * Modules/webauthn/AuthenticatorResponse.h:
+ * Modules/webauthn/AuthenticatorResponse.idl:
+ * Modules/webauthn/PublicKeyCredential.cpp:
+ (WebCore::PublicKeyCredentialInternal::produceClientDataJson):
+ (WebCore::PublicKeyCredentialInternal::produceClientDataJsonHash):
+ (WebCore::PublicKeyCredentialInternal::getIdFromAttestationObject):
+ (WebCore::PublicKeyCredential::PublicKeyCredential):
+ (WebCore::PublicKeyCredential::discoverFromExternalSource):
+ (WebCore::PublicKeyCredential::create):
+ (WebCore::PublicKeyCredential::rawId const):
+ (WebCore::PublicKeyCredential::response const):
+ (WebCore::PublicKeyCredential::getClientExtensionResults const):
+ (WebCore::PublicKeyCredential::rawId): Deleted.
+ (WebCore::PublicKeyCredential::response): Deleted.
+ (WebCore::PublicKeyCredential::getClientExtensionResults): Deleted.
+ * Modules/webauthn/PublicKeyCredential.h:
+ * Modules/webauthn/PublicKeyCredential.idl:
+ * Modules/webauthn/PublicKeyCredentialCreationOptions.h:
+ (): Deleted.
+ * Modules/webauthn/PublicKeyCredentialDescriptor.h:
+ * Modules/webauthn/PublicKeyCredentialDescriptor.idl:
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSAuthenticatorResponseCustom.cpp: Copied from Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp.
+ (WebCore::toJSNewlyCreated):
+ (WebCore::toJS):
+ * bindings/js/JSBasicCredentialCustom.cpp: Copied from Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp.
+ (WebCore::toJSNewlyCreated):
+ (WebCore::toJS):
+ * bindings/js/JSBindingsAllInOne.cpp:
+
2018-01-22 Myles C. Maxfield <mmaxfi...@apple.com>
[Cocoa] Support font collections
Modified: trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -26,6 +26,7 @@
#pragma once
#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/TypeCasts.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -41,15 +42,15 @@
Remote,
};
+ BasicCredential(const String&, Type, Discovery);
virtual ~BasicCredential();
+ virtual Type credentialType() const = 0;
+
const String& id() const { return m_id; }
String type() const;
Discovery discovery() const { return m_discovery; }
-protected:
- BasicCredential(const String&, Type, Discovery);
-
private:
String m_id;
Type m_type;
@@ -57,3 +58,8 @@
};
} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_BASIC_CREDENTIAL(ToClassName, Type) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
+ static bool isType(const WebCore::BasicCredential& credential) { return credential.credentialType() == WebCore::Type; } \
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.idl (227381 => 227382)
--- trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.idl 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/credentialmanagement/BasicCredential.idl 2018-01-23 03:00:59 UTC (rev 227382)
@@ -25,6 +25,7 @@
[
InterfaceName=Credential,
+ CustomToJSObject,
EnabledAtRuntime=WebAuthentication,
Exposed=Window,
SecureContext
Modified: trunk/Source/WebCore/Modules/credentialmanagement/CredentialCreationOptions.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/credentialmanagement/CredentialCreationOptions.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/credentialmanagement/CredentialCreationOptions.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -32,8 +32,6 @@
namespace WebCore {
-class AbortSignal;
-
struct CredentialCreationOptions {
RefPtr<AbortSignal> signal;
std::optional<PublicKeyCredentialCreationOptions> publicKey;
Modified: trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp (227381 => 227382)
--- trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -35,9 +35,21 @@
#include "JSBasicCredential.h"
#include "PublicKeyCredential.h"
#include "SecurityOrigin.h"
+#include <wtf/MainThread.h>
namespace WebCore {
+CredentialsContainer::PendingPromise::PendingPromise(Ref<DeferredPromise>&& promise, std::unique_ptr<Timer>&& timer)
+ : promise(WTFMove(promise))
+ , timer(WTFMove(timer))
+{
+}
+
+CredentialsContainer::PendingPromise::PendingPromise(Ref<DeferredPromise>&& promise)
+ : promise(WTFMove(promise))
+{
+}
+
CredentialsContainer::CredentialsContainer(WeakPtr<Document>&& document)
: m_document(WTFMove(document))
, m_workQueue(WorkQueue::create("com.apple.WebKit.CredentialQueue"))
@@ -44,6 +56,8 @@
{
}
+// The following implements https://w3c.github.io/webappsec-credential-management/#same-origin-with-its-ancestors
+// as of 14 November 2017.
bool CredentialsContainer::doesHaveSameOriginAsItsAncestors()
{
if (!m_document)
@@ -57,21 +71,50 @@
return true;
}
+// FIXME: Since the underlying authenticator model is not clear at this moment, the timer is moved to CredentialsContainer such that
+// timer can stay with main thread and therefore can easily time out activities on the work queue.
+// https://bugs.webkit.org/show_bug.cgi?id=181946.
+// FIXME: The usages of AbortSignal are also moved here for the very same reason. Also the AbortSignal is kind of bogus at this moment
+// since it doesn't support observers (or other means) to trigger the actual abort action. Enhancement to AbortSignal is needed.
+// https://bugs.webkit.org/show_bug.cgi?id=181945.
template<typename OperationType>
-void CredentialsContainer::dispatchTask(OperationType&& operation, Ref<DeferredPromise>&& promise)
+void CredentialsContainer::dispatchTask(OperationType&& operation, Ref<DeferredPromise>&& promise, std::optional<unsigned long> timeOutInMs)
{
+ ASSERT(isMainThread());
+ if (!m_document)
+ return;
+
auto* promiseIndex = promise.ptr();
- m_pendingPromises.add(promiseIndex, WTFMove(promise));
auto weakThis = m_weakPtrFactory.createWeakPtr(*this);
- auto task = [promiseIndex, weakThis, isSameOriginWithItsAncestors = doesHaveSameOriginAsItsAncestors(), operation = WTFMove(operation)] () {
- auto result = operation(isSameOriginWithItsAncestors);
+ // FIXME: We should probably trim timeOutInMs to some max allowable number.
+ // https://bugs.webkit.org/show_bug.cgi?id=181947
+ if (timeOutInMs) {
+ auto pendingPromise = PendingPromise::create(WTFMove(promise), std::make_unique<Timer>([promiseIndex, weakThis] () {
+ ASSERT(isMainThread());
+ if (weakThis) {
+ // A lock should not be needed as all callbacks are executed in the main thread.
+ if (auto promise = weakThis->m_pendingPromises.take(promiseIndex))
+ promise.value()->promise->reject(Exception { NotAllowedError });
+ }
+ }));
+ pendingPromise->timer->startOneShot(Seconds(timeOutInMs.value() / 1000.0));
+ m_pendingPromises.add(promiseIndex, WTFMove(pendingPromise));
+ } else
+ m_pendingPromises.add(promiseIndex, PendingPromise::create(WTFMove(promise)));
+
+ auto task = [promiseIndex, weakThis, origin = m_document->securityOrigin().isolatedCopy(), isSameOriginWithItsAncestors = doesHaveSameOriginAsItsAncestors(), operation = WTFMove(operation)] () {
+ auto result = operation(origin, isSameOriginWithItsAncestors);
callOnMainThread([promiseIndex, weakThis, result = WTFMove(result)] () mutable {
if (weakThis) {
+ // A lock should not be needed as all callbacks are executed in the main thread.
if (auto promise = weakThis->m_pendingPromises.take(promiseIndex)) {
if (result.hasException())
- promise.value()->reject(result.releaseException());
- else
- promise.value()->resolve<IDLNullable<IDLInterface<BasicCredential>>>(result.releaseReturnValue().get());
+ promise.value()->promise->reject(result.releaseException());
+ else {
+ // FIXME: Got some crazy compile error when I was trying to pass RHS to the resolve method.
+ RefPtr<BasicCredential> credential = result.releaseReturnValue();
+ promise.value()->promise->resolve<IDLNullable<IDLInterface<BasicCredential>>>(credential.get());
+ }
}
}
});
@@ -99,10 +142,10 @@
return;
}
- auto operation = [options = WTFMove(options)] (bool isSameOriginWithItsAncestors) {
- return PublicKeyCredential::discoverFromExternalSource(options, isSameOriginWithItsAncestors);
+ auto operation = [options = WTFMove(options)] (const SecurityOrigin& origin, bool isSameOriginWithItsAncestors) {
+ return PublicKeyCredential::discoverFromExternalSource(origin, options, isSameOriginWithItsAncestors);
};
- dispatchTask(WTFMove(operation), WTFMove(promise));
+ dispatchTask(WTFMove(operation), WTFMove(promise), options.publicKey->timeout);
}
void CredentialsContainer::store(const BasicCredential&, Ref<DeferredPromise>&& promise)
@@ -112,6 +155,8 @@
void CredentialsContainer::isCreate(CredentialCreationOptions&& options, Ref<DeferredPromise>&& promise)
{
+ // The following implements https://www.w3.org/TR/credential-management-1/#algorithm-create as of 4 August 2017
+ // with enhancement from 14 November 2017 Editor's Draft.
// FIXME: Optional options are passed with no contents. It should be std::optional.
if ((!options.signal && !options.publicKey) || !m_document) {
promise->reject(Exception { NotSupportedError });
@@ -121,23 +166,25 @@
promise->reject(Exception { AbortError });
return;
}
+ // Step 1-2.
ASSERT(m_document->isSecureContext());
- // This is a shortcut to https://www.w3.org/TR/credential-management-1/#credentialrequestoptions-relevant-credential-interface-objects,
- // as we only support one kind of credentials.
+ // Step 3-4. Shortcut as we only support one kind of credentials.
if (!options.publicKey) {
promise->reject(Exception { NotSupportedError });
return;
}
- auto operation = [options = WTFMove(options)] (bool isSameOriginWithItsAncestors) {
+ auto timeout = options.publicKey->timeout;
+ // Step 5-7.
+ auto operation = [options = WTFMove(options.publicKey.value())] (const SecurityOrigin& origin, bool isSameOriginWithItsAncestors) {
// Shortcut as well.
- return PublicKeyCredential::create(options, isSameOriginWithItsAncestors);
+ return PublicKeyCredential::create(origin, options, isSameOriginWithItsAncestors);
};
- dispatchTask(WTFMove(operation), WTFMove(promise));
+ dispatchTask(WTFMove(operation), WTFMove(promise), options.publicKey->timeout);
}
-void CredentialsContainer::preventSilentAccess(Ref<DeferredPromise>&& promise)
+void CredentialsContainer::preventSilentAccess(Ref<DeferredPromise>&& promise) const
{
promise->reject(Exception { NotSupportedError });
}
Modified: trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -27,6 +27,7 @@
#pragma once
#include "JSDOMPromiseDeferred.h"
+#include "Timer.h"
#include <wtf/Function.h>
#include <wtf/RefCounted.h>
#include <wtf/WeakPtr.h>
@@ -50,7 +51,7 @@
void isCreate(CredentialCreationOptions&&, Ref<DeferredPromise>&&);
- void preventSilentAccess(Ref<DeferredPromise>&&);
+ void preventSilentAccess(Ref<DeferredPromise>&&) const;
private:
CredentialsContainer(WeakPtr<Document>&&);
@@ -57,12 +58,33 @@
bool doesHaveSameOriginAsItsAncestors();
template<typename OperationType>
- void dispatchTask(OperationType&&, Ref<DeferredPromise>&&);
+ void dispatchTask(OperationType&&, Ref<DeferredPromise>&&, std::optional<unsigned long> timeOutInMs = std::nullopt);
WeakPtr<Document> m_document;
- HashMap<DeferredPromise*, Ref<DeferredPromise>> m_pendingPromises;
Ref<WorkQueue> m_workQueue;
WeakPtrFactory<CredentialsContainer> m_weakPtrFactory;
+
+ // Bundle promise and timer, such that the timer can
+ // times out the corresponding promsie.
+ struct PendingPromise : public RefCounted<PendingPromise> {
+ static Ref<PendingPromise> create(Ref<DeferredPromise>&& promise, std::unique_ptr<Timer>&& timer)
+ {
+ return adoptRef(*new PendingPromise(WTFMove(promise), WTFMove(timer)));
+ }
+ static Ref<PendingPromise> create(Ref<DeferredPromise>&& promise)
+ {
+ return adoptRef(*new PendingPromise(WTFMove(promise)));
+ }
+
+ private:
+ PendingPromise(Ref<DeferredPromise>&&, std::unique_ptr<Timer>&&);
+ PendingPromise(Ref<DeferredPromise>&&);
+
+ public:
+ Ref<DeferredPromise> promise;
+ std::unique_ptr<Timer> timer;
+ };
+ HashMap<DeferredPromise*, Ref<PendingPromise>> m_pendingPromises;
};
} // namespace WebCore
Copied: trunk/Source/WebCore/Modules/webauthn/Authenticator.cpp (from rev 227381, trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp) (0 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/Authenticator.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/Authenticator.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Authenticator.h"
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+Authenticator& Authenticator::singleton()
+{
+ static NeverDestroyed<Authenticator> authenticator;
+ return authenticator;
+}
+
+ExceptionOr<Vector<uint8_t>> Authenticator::makeCredential(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions::RpEntity&, const PublicKeyCredentialCreationOptions::UserEntity& user, const Vector<PublicKeyCredentialCreationOptions::Parameters>&, const Vector<PublicKeyCredentialDescriptor>&) const
+{
+ // The followings is just a dummy implementaion to support initial development.
+ // User cancellation is effecively NotAllowedError.
+ if (user.displayName == "John")
+ return Exception { NotAllowedError };
+
+ // Fill all parts before CredentialID with 0x00
+ Vector<uint8_t> attestationObject(43, 0x00);
+ // Fill length of CredentialID: 1 Byte
+ attestationObject.append(0x00);
+ attestationObject.append(0x01);
+ // Fill CredentialID: 255
+ attestationObject.append(0xff);
+ // Append clientDataJsonHash
+ attestationObject.appendVector(hash);
+ return WTFMove(attestationObject);
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/Modules/webauthn/Authenticator.h (from rev 227381, trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h) (0 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/Authenticator.h (rev 0)
+++ trunk/Source/WebCore/Modules/webauthn/Authenticator.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ExceptionOr.h"
+#include "PublicKeyCredentialCreationOptions.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+// FIXME: Consider moving all static methods from PublicKeyCredential to here and making this
+// as an authenticator manager that controls all authenticator activities, mostly likely asnyc
+// for attestations.
+class Authenticator {
+ WTF_MAKE_NONCOPYABLE(Authenticator);
+ friend class NeverDestroyed<Authenticator>;
+public:
+ static Authenticator& singleton();
+
+ // Omit requireResidentKey, requireUserPresence, and requireUserVerification as we always provide resident keys and require user verification.
+ ExceptionOr<Vector<uint8_t>> makeCredential(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions::RpEntity&, const PublicKeyCredentialCreationOptions::UserEntity&, const Vector<PublicKeyCredentialCreationOptions::Parameters>&, const Vector<PublicKeyCredentialDescriptor>& excludeCredentialIds) const;
+
+#if !COMPILER(MSVC)
+private:
+#endif
+ Authenticator() = default;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -36,21 +36,17 @@
{
}
-AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse()
+ArrayBuffer* AuthenticatorAssertionResponse::authenticatorData() const
{
-}
-
-ArrayBuffer* AuthenticatorAssertionResponse::authenticatorData()
-{
return m_authenticatorData.get();
}
-ArrayBuffer* AuthenticatorAssertionResponse::signature()
+ArrayBuffer* AuthenticatorAssertionResponse::signature() const
{
return m_signature.get();
}
-ArrayBuffer* AuthenticatorAssertionResponse::userHandle()
+ArrayBuffer* AuthenticatorAssertionResponse::userHandle() const
{
return m_userHandle.get();
}
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -31,14 +31,22 @@
class AuthenticatorAssertionResponse : public AuthenticatorResponse {
public:
+ static Ref<AuthenticatorAssertionResponse> create(RefPtr<ArrayBuffer>&& clientDataJSON, RefPtr<ArrayBuffer>&& authenticatorData, RefPtr<ArrayBuffer>&& signature, RefPtr<ArrayBuffer>&& userHandle)
+ {
+ return adoptRef(*new AuthenticatorAssertionResponse(WTFMove(clientDataJSON), WTFMove(authenticatorData), WTFMove(signature), WTFMove(userHandle)));
+ }
+
+ virtual ~AuthenticatorAssertionResponse() = default;
+
+ ArrayBuffer* authenticatorData() const;
+ ArrayBuffer* signature() const;
+ ArrayBuffer* userHandle() const;
+
+private:
AuthenticatorAssertionResponse(RefPtr<ArrayBuffer>&& clientDataJSON, RefPtr<ArrayBuffer>&& authenticatorData, RefPtr<ArrayBuffer>&& signature, RefPtr<ArrayBuffer>&& userHandle);
- virtual ~AuthenticatorAssertionResponse();
- ArrayBuffer* authenticatorData();
- ArrayBuffer* signature();
- ArrayBuffer* userHandle();
+ Type type() const final { return Type::Assertion; }
-private:
RefPtr<ArrayBuffer> m_authenticatorData;
RefPtr<ArrayBuffer> m_signature;
RefPtr<ArrayBuffer> m_userHandle;
@@ -45,3 +53,5 @@
};
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_AUTHENTICATOR_RESPONSE(AuthenticatorAssertionResponse, AuthenticatorResponse::Type::Assertion)
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -34,12 +34,8 @@
{
}
-AuthenticatorAttestationResponse::~AuthenticatorAttestationResponse()
+ArrayBuffer* AuthenticatorAttestationResponse::attestationObject() const
{
-}
-
-ArrayBuffer* AuthenticatorAttestationResponse::attestationObject()
-{
return m_attestationObject.get();
}
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -31,13 +31,23 @@
class AuthenticatorAttestationResponse : public AuthenticatorResponse {
public:
+ static Ref<AuthenticatorAttestationResponse> create(RefPtr<ArrayBuffer>&& clientDataJSON, RefPtr<ArrayBuffer>&& attestationObject)
+ {
+ return adoptRef(*new AuthenticatorAttestationResponse(WTFMove(clientDataJSON), WTFMove(attestationObject)));
+ }
+
+ virtual ~AuthenticatorAttestationResponse() = default;
+
+ ArrayBuffer* attestationObject() const;
+
+private:
AuthenticatorAttestationResponse(RefPtr<ArrayBuffer>&& clientDataJSON, RefPtr<ArrayBuffer>&& attestationObject);
- virtual ~AuthenticatorAttestationResponse();
- ArrayBuffer* attestationObject();
+ Type type() const final { return Type::Attestation; }
-private:
RefPtr<ArrayBuffer> m_attestationObject;
};
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_AUTHENTICATOR_RESPONSE(AuthenticatorAttestationResponse, AuthenticatorResponse::Type::Attestation)
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -33,12 +33,8 @@
{
}
-AuthenticatorResponse::~AuthenticatorResponse()
+ArrayBuffer* AuthenticatorResponse::clientDataJSON() const
{
-}
-
-ArrayBuffer* AuthenticatorResponse::clientDataJSON()
-{
return m_clientDataJSON.get();
}
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -27,18 +27,31 @@
#include <runtime/ArrayBuffer.h>
#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/TypeCasts.h>
namespace WebCore {
class AuthenticatorResponse : public ThreadSafeRefCounted<AuthenticatorResponse> {
public:
+ enum class Type {
+ Assertion,
+ Attestation
+ };
+
explicit AuthenticatorResponse(RefPtr<ArrayBuffer>&&);
- virtual ~AuthenticatorResponse();
+ virtual ~AuthenticatorResponse() = default;
- ArrayBuffer* clientDataJSON();
+ virtual Type type() const = 0;
+ ArrayBuffer* clientDataJSON() const;
+
private:
RefPtr<ArrayBuffer> m_clientDataJSON;
};
} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_AUTHENTICATOR_RESPONSE(ToClassName, Type) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
+ static bool isType(const WebCore::AuthenticatorResponse& response) { return response.type() == WebCore::Type; } \
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.idl (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.idl 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.idl 2018-01-23 03:00:59 UTC (rev 227382)
@@ -24,6 +24,7 @@
*/
[
+ CustomToJSObject,
EnabledAtRuntime=WebAuthentication,
Exposed=Window,
SecureContext,
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -26,21 +26,86 @@
#include "config.h"
#include "PublicKeyCredential.h"
+#include "Authenticator.h"
+#include "AuthenticatorResponse.h"
+#include "CredentialCreationOptions.h"
#include "JSDOMPromiseDeferred.h"
+#include "SecurityOrigin.h"
+#include <pal/crypto/CryptoDigest.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/JSONValues.h>
+#include <wtf/text/Base64.h>
namespace WebCore {
-PublicKeyCredential::PublicKeyCredential(const String& id)
- : BasicCredential(id, Type::PublicKey, Discovery::Remote)
+namespace PublicKeyCredentialInternal {
+
+// The layout of attestation object: https://www.w3.org/TR/webauthn/#attestation-object as of 5 December 2017.
+// Here is a summary before CredentialID in the layout. All lengths are fixed.
+// RP ID hash (32) || FLAGS (1) || COUNTER (4) || AAGUID (16) || L (2) || CREDENTIAL ID (?) || ...
+static constexpr size_t CredentialIdLengthOffset = 43;
+
+enum class ClientDataType {
+ Create,
+ Get
+};
+
+// FIXME: Add token binding ID and extensions.
+// https://bugs.webkit.org/show_bug.cgi?id=181948
+// https://bugs.webkit.org/show_bug.cgi?id=181949
+static Ref<ArrayBuffer> produceClientDataJson(ClientDataType type, const BufferSource& challenge, const SecurityOrigin& origin)
{
+ auto object = JSON::Object::create();
+ switch (type) {
+ case ClientDataType::Create:
+ object->setString(ASCIILiteral("type"), ASCIILiteral("webauthn.create"));
+ break;
+ case ClientDataType::Get:
+ object->setString(ASCIILiteral("type"), ASCIILiteral("webauthn.get"));
+ break;
+ }
+ object->setString(ASCIILiteral("challenge"), WTF::base64URLEncode(challenge.data(), challenge.length()));
+ object->setString(ASCIILiteral("origin"), origin.toRawString());
+ // FIXME: This might be platform dependent.
+ object->setString(ASCIILiteral("hashAlgorithm"), ASCIILiteral("SHA-256"));
+
+ auto utf8JSONString = object->toJSONString().utf8();
+ return ArrayBuffer::create(utf8JSONString.data(), utf8JSONString.length());
}
+static Vector<uint8_t> produceClientDataJsonHash(const Ref<ArrayBuffer>& clientDataJson)
+{
+ auto crypto = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
+ crypto->addBytes(clientDataJson->data(), clientDataJson->byteLength());
+ return crypto->computeHash();
+}
+
+static RefPtr<ArrayBuffer> getIdFromAttestationObject(const Vector<uint8_t>& attestationObject)
+{
+ // The byte length of L is 2.
+ if (attestationObject.size() < CredentialIdLengthOffset + 2)
+ return nullptr;
+ size_t length = (attestationObject[CredentialIdLengthOffset] << 8) + attestationObject[CredentialIdLengthOffset + 1];
+ if (attestationObject.size() < CredentialIdLengthOffset + 2 + length)
+ return nullptr;
+ return ArrayBuffer::create(attestationObject.data() + CredentialIdLengthOffset + 2, length);
+}
+
+} // namespace PublicKeyCredentialInternal
+
+PublicKeyCredential::PublicKeyCredential(RefPtr<ArrayBuffer>&& id, RefPtr<AuthenticatorResponse>&& response)
+ : BasicCredential(WTF::base64URLEncode(id->data(), id->byteLength()), Type::PublicKey, Discovery::Remote)
+ , m_rawId(WTFMove(id))
+ , m_response(WTFMove(response))
+{
+}
+
Vector<Ref<BasicCredential>> PublicKeyCredential::collectFromCredentialStore(CredentialRequestOptions&&, bool)
{
return { };
}
-ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::discoverFromExternalSource(const CredentialRequestOptions&, bool)
+ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::discoverFromExternalSource(const SecurityOrigin&, const CredentialRequestOptions&, bool)
{
return Exception { NotSupportedError };
}
@@ -50,22 +115,66 @@
return nullptr;
}
-ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::create(const CredentialCreationOptions&, bool)
+ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::create(const SecurityOrigin& callerOrigin, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors)
{
- return Exception { NotSupportedError };
+ using namespace PublicKeyCredentialInternal;
+
+ // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017.
+ // FIXME: Extensions are not supported yet. Skip Step 11-12.
+ // Step 1, 3, 4, 17 are handled by the caller, including options sanitizing, timer and abort signal.
+ // Step 2.
+ if (!sameOriginWithAncestors)
+ return Exception { NotAllowedError };
+
+ // Step 5-7.
+ // FIXME: We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
+ // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
+ // domain suffix of another domain. Hence restrict the comparison to equal in Step 7.
+ // https://bugs.webkit.org/show_bug.cgi?id=181950
+ if (!options.rp.id.isEmpty() && !(callerOrigin.host() == options.rp.id))
+ return Exception { SecurityError };
+ if (options.rp.id.isEmpty())
+ options.rp.id = callerOrigin.host();
+
+ // Step 8-10.
+ // Most of the jobs are done by bindings. However, we can't know if the JSValue of options.pubKeyCredParams
+ // is empty or not. Return NotSupportedError as long as it is empty.
+ if (options.pubKeyCredParams.isEmpty())
+ return Exception { NotSupportedError };
+
+ // Step 13-15.
+ auto clientDataJson = produceClientDataJson(ClientDataType::Create, options.challenge, callerOrigin);
+ auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson);
+
+ // Step 18-21.
+ // Only platform attachments will be supported at this stage. Assuming one authenticator per device.
+ // Also, resident keys, user verifications and direct attestation are enforced at this tage.
+ // For better performance, no filtering is done here regarding to options.excludeCredentials.
+ // What's more, user cancellations effectively means NotAllowedError. Therefore, the below call
+ // will only returns either an exception or a PublicKeyCredential ref.
+ // FIXME: The following operation might need to perform async.
+ // https://bugs.webkit.org/show_bug.cgi?id=181946
+ auto result = Authenticator::singleton().makeCredential(clientDataJsonHash, options.rp, options.user, options.pubKeyCredParams, options.excludeCredentials);
+ if (result.hasException())
+ return result.releaseException();
+
+ auto attestationObject = result.releaseReturnValue();
+ // FIXME: Got some crazy compile error when I was trying to return RHS directly.
+ RefPtr<BasicCredential> credential = PublicKeyCredential::create(getIdFromAttestationObject(attestationObject), AuthenticatorAttestationResponse::create(WTFMove(clientDataJson), ArrayBuffer::create(attestationObject.data(), attestationObject.size())));
+ return WTFMove(credential);
}
-ArrayBuffer* PublicKeyCredential::rawId()
+ArrayBuffer* PublicKeyCredential::rawId() const
{
return m_rawId.get();
}
-AuthenticatorResponse* PublicKeyCredential::response()
+AuthenticatorResponse* PublicKeyCredential::response() const
{
return m_response.get();
}
-ExceptionOr<bool> PublicKeyCredential::getClientExtensionResults()
+ExceptionOr<bool> PublicKeyCredential::getClientExtensionResults() const
{
return Exception { NotSupportedError };
}
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -34,34 +34,39 @@
class AuthenticatorResponse;
class DeferredPromise;
+class SecurityOrigin;
-struct CredentialCreationOptions;
+struct PublicKeyCredentialCreationOptions;
struct CredentialRequestOptions;
class PublicKeyCredential final : public BasicCredential {
public:
- static Ref<PublicKeyCredential> create(const String& id)
+ static Ref<PublicKeyCredential> create(RefPtr<ArrayBuffer>&& id, RefPtr<AuthenticatorResponse>&& response)
{
- return adoptRef(*new PublicKeyCredential(id));
+ return adoptRef(*new PublicKeyCredential(WTFMove(id), WTFMove(response)));
}
static Vector<Ref<BasicCredential>> collectFromCredentialStore(CredentialRequestOptions&&, bool);
- static ExceptionOr<RefPtr<BasicCredential>> discoverFromExternalSource(const CredentialRequestOptions&, bool);
+ static ExceptionOr<RefPtr<BasicCredential>> discoverFromExternalSource(const SecurityOrigin&, const CredentialRequestOptions&, bool sameOriginWithAncestors);
static RefPtr<BasicCredential> store(RefPtr<BasicCredential>&&, bool);
- static ExceptionOr<RefPtr<BasicCredential>> create(const CredentialCreationOptions&, bool);
+ static ExceptionOr<RefPtr<BasicCredential>> create(const SecurityOrigin&, const PublicKeyCredentialCreationOptions&, bool sameOriginWithAncestors);
- ArrayBuffer* rawId();
- AuthenticatorResponse* response();
+ ArrayBuffer* rawId() const;
+ AuthenticatorResponse* response() const;
// Not support yet. Always throws.
- ExceptionOr<bool> getClientExtensionResults();
+ ExceptionOr<bool> getClientExtensionResults() const;
static void isUserVerifyingPlatformAuthenticatorAvailable(Ref<DeferredPromise>&&);
private:
- PublicKeyCredential(const String&);
+ PublicKeyCredential(RefPtr<ArrayBuffer>&& id, RefPtr<AuthenticatorResponse>&&);
+ Type credentialType() const final { return Type::PublicKey; }
+
RefPtr<ArrayBuffer> m_rawId;
RefPtr<AuthenticatorResponse> m_response;
};
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_BASIC_CREDENTIAL(PublicKeyCredential, BasicCredential::Type::PublicKey)
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.idl (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.idl 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.idl 2018-01-23 03:00:59 UTC (rev 227382)
@@ -29,7 +29,7 @@
EnabledAtRuntime=WebAuthentication,
Exposed=Window,
SecureContext,
-] interface PublicKeyCredential {
+] interface PublicKeyCredential : BasicCredential {
[SameObject] readonly attribute ArrayBuffer rawId;
[SameObject] readonly attribute AuthenticatorResponse response;
[MayThrowException] AuthenticationExtensions getClientExtensionResults();
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -39,7 +39,7 @@
};
struct RpEntity : public Entity {
- String id;
+ mutable String id;
};
struct UserEntity : public Entity {
@@ -49,7 +49,7 @@
struct Parameters {
PublicKeyCredentialType type;
- long alg { 0 };
+ long alg;
};
RpEntity rp;
@@ -58,7 +58,7 @@
BufferSource challenge;
Vector<Parameters> pubKeyCredParams;
- unsigned long timeout { 0 };
+ std::optional<unsigned long> timeout;
Vector<PublicKeyCredentialDescriptor> excludeCredentials;
};
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.h (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.h 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.h 2018-01-23 03:00:59 UTC (rev 227382)
@@ -31,8 +31,15 @@
namespace WebCore {
struct PublicKeyCredentialDescriptor {
+ enum class AuthenticatorTransport {
+ Usb,
+ Nfc,
+ Ble
+ };
+
PublicKeyCredentialType type;
BufferSource id;
+ Vector<AuthenticatorTransport> transports;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.idl (227381 => 227382)
--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.idl 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.idl 2018-01-23 03:00:59 UTC (rev 227382)
@@ -23,9 +23,14 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum AuthenticatorTransport {
+ "usb",
+ "nfc",
+ "ble"
+};
+
dictionary PublicKeyCredentialDescriptor {
required PublicKeyCredentialType type;
required BufferSource id;
- // We only allow platform attachment at this stage.
- // sequence<AuthenticatorTransport> transports;
+ sequence<AuthenticatorTransport> transports;
};
Modified: trunk/Source/WebCore/Sources.txt (227381 => 227382)
--- trunk/Source/WebCore/Sources.txt 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/Sources.txt 2018-01-23 03:00:59 UTC (rev 227382)
@@ -244,6 +244,7 @@
Modules/webaudio/WaveShaperNode.cpp
Modules/webaudio/WaveShaperProcessor.cpp
+Modules/webauthn/Authenticator.cpp
Modules/webauthn/AuthenticatorAssertionResponse.cpp
Modules/webauthn/AuthenticatorAttestationResponse.cpp
Modules/webauthn/AuthenticatorResponse.cpp
@@ -345,11 +346,13 @@
bindings/js/DOMWrapperWorld.cpp
bindings/js/GCController.cpp
bindings/js/IDBBindingUtilities.cpp
+bindings/js/JSAuthenticatorResponseCustom.cpp
bindings/js/JSAnimationEffectCustom.cpp
bindings/js/JSAnimationTimelineCustom.cpp
bindings/js/JSAttrCustom.cpp
bindings/js/JSAudioTrackCustom.cpp
bindings/js/JSAudioTrackListCustom.cpp
+bindings/js/JSBasicCredentialCustom.cpp
bindings/js/JSBlobCustom.cpp
bindings/js/JSCSSRuleCustom.cpp
bindings/js/JSCSSRuleListCustom.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (227381 => 227382)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-01-23 03:00:59 UTC (rev 227382)
@@ -1663,6 +1663,7 @@
57303C222009AF0300355965 /* JSAuthenticatorAttestationResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 57303C212009AEF600355965 /* JSAuthenticatorAttestationResponse.h */; };
57303C2C2009B4A800355965 /* AuthenticatorAssertionResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */; };
57303C2F2009B7E100355965 /* JSAuthenticatorAssertionResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 57303C2D2009B7D900355965 /* JSAuthenticatorAssertionResponse.h */; };
+ 57303C4620105D2F00355965 /* Authenticator.h in Headers */ = {isa = PBXBuildFile; fileRef = 57303C4320105B3D00355965 /* Authenticator.h */; };
573489391DAC6B6E00DC0667 /* CryptoAlgorithmParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */; };
5739E12F1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5739E12E1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h */; };
5750A9751E68D00000705C4A /* CryptoKeyEC.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9731E68D00000705C4A /* CryptoKeyEC.h */; };
@@ -8236,6 +8237,8 @@
57303C292009B2FC00355965 /* AuthenticatorAssertionResponse.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AuthenticatorAssertionResponse.idl; sourceTree = "<group>"; };
57303C2D2009B7D900355965 /* JSAuthenticatorAssertionResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAuthenticatorAssertionResponse.h; sourceTree = "<group>"; };
57303C2E2009B7DA00355965 /* JSAuthenticatorAssertionResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAuthenticatorAssertionResponse.cpp; sourceTree = "<group>"; };
+ 57303C4320105B3D00355965 /* Authenticator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Authenticator.h; sourceTree = "<group>"; };
+ 57303C4420105B3D00355965 /* Authenticator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Authenticator.cpp; sourceTree = "<group>"; };
573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmParameters.h; sourceTree = "<group>"; };
5739E12E1DAC7F7800E14383 /* JSCryptoAlgorithmParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCryptoAlgorithmParameters.h; sourceTree = "<group>"; };
5739E1301DAC7FD100E14383 /* JSCryptoAlgorithmParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCryptoAlgorithmParameters.cpp; sourceTree = "<group>"; };
@@ -8252,6 +8255,8 @@
5750A9851E6A216800705C4A /* CryptoAlgorithmECDH.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmECDH.h; sourceTree = "<group>"; };
575471991ECE5D2A00DD63B2 /* JSRsaPssParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRsaPssParams.h; sourceTree = "<group>"; };
5754719A1ECE5D2A00DD63B2 /* JSRsaPssParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRsaPssParams.cpp; sourceTree = "<group>"; };
+ 5760824F20118D8D00116678 /* JSBasicCredentialCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSBasicCredentialCustom.cpp; sourceTree = "<group>"; };
+ 576082562011BE0200116678 /* JSAuthenticatorResponseCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSAuthenticatorResponseCustom.cpp; sourceTree = "<group>"; };
576814281E6F98AD00E77754 /* EcdhKeyDeriveParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = EcdhKeyDeriveParams.idl; sourceTree = "<group>"; };
576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmEcdhKeyDeriveParams.h; sourceTree = "<group>"; };
576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmECDHMac.cpp; sourceTree = "<group>"; };
@@ -18200,6 +18205,8 @@
isa = PBXGroup;
children = (
57303BB32006C6ED00355965 /* cbor */,
+ 57303C4420105B3D00355965 /* Authenticator.cpp */,
+ 57303C4320105B3D00355965 /* Authenticator.h */,
57303C282009B2FC00355965 /* AuthenticatorAssertionResponse.cpp */,
57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */,
57303C292009B2FC00355965 /* AuthenticatorAssertionResponse.idl */,
@@ -19248,6 +19255,8 @@
BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */,
BE6DF70E171CA2DA00DD52B8 /* JSAudioTrackCustom.cpp */,
BE6DF710171CA2DA00DD52B8 /* JSAudioTrackListCustom.cpp */,
+ 576082562011BE0200116678 /* JSAuthenticatorResponseCustom.cpp */,
+ 5760824F20118D8D00116678 /* JSBasicCredentialCustom.cpp */,
8931DE5A14C44C44000DC9D2 /* JSBlobCustom.cpp */,
49EED14B1051971900099FAB /* JSCanvasRenderingContext2DCustom.cpp */,
BC46C1ED0C0DDBDF0020CFC3 /* JSCSSRuleCustom.cpp */,
@@ -26523,6 +26532,7 @@
934F713A0D5A6F1000018D69 /* AuthenticationChallengeBase.h in Headers */,
E124748410AA161D00B79493 /* AuthenticationClient.h in Headers */,
514C764C0CE9234E007EF3CD /* AuthenticationMac.h in Headers */,
+ 57303C4620105D2F00355965 /* Authenticator.h in Headers */,
57303C2C2009B4A800355965 /* AuthenticatorAssertionResponse.h in Headers */,
57303C1F2009AB4200355965 /* AuthenticatorAttestationResponse.h in Headers */,
57303BD220087A8300355965 /* AuthenticatorResponse.h in Headers */,
Copied: trunk/Source/WebCore/bindings/js/JSAuthenticatorResponseCustom.cpp (from rev 227381, trunk/Source/WebCore/Modules/webauthn/AuthenticatorAttestationResponse.cpp) (0 => 227382)
--- trunk/Source/WebCore/bindings/js/JSAuthenticatorResponseCustom.cpp (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSAuthenticatorResponseCustom.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSAuthenticatorResponse.h"
+
+#include "JSAuthenticatorAttestationResponse.h"
+#include "JSDOMBinding.h"
+
+namespace WebCore {
+using namespace JSC;
+
+JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<AuthenticatorResponse>&& response)
+{
+ if (is<AuthenticatorAttestationResponse>(response))
+ return createWrapper<AuthenticatorAttestationResponse>(globalObject, WTFMove(response));
+ return createWrapper<AuthenticatorResponse>(globalObject, WTFMove(response));
+}
+
+JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, AuthenticatorResponse& response)
+{
+ return wrap(state, globalObject, response);
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/bindings/js/JSBasicCredentialCustom.cpp (from rev 227381, trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponse.cpp) (0 => 227382)
--- trunk/Source/WebCore/bindings/js/JSBasicCredentialCustom.cpp (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSBasicCredentialCustom.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSBasicCredential.h"
+
+#include "JSDOMBinding.h"
+#include "JSPublicKeyCredential.h"
+
+
+namespace WebCore {
+using namespace JSC;
+
+JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<BasicCredential>&& credential)
+{
+ if (is<PublicKeyCredential>(credential))
+ return createWrapper<PublicKeyCredential>(globalObject, WTFMove(credential));
+ return createWrapper<BasicCredential>(globalObject, WTFMove(credential));
+}
+
+JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, BasicCredential& credential)
+{
+ return wrap(state, globalObject, credential);
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp (227381 => 227382)
--- trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -32,6 +32,7 @@
#include "JSAttrCustom.cpp"
#include "JSAudioTrackCustom.cpp"
#include "JSAudioTrackListCustom.cpp"
+#include "JSBasicCredentialCustom.cpp"
#include "JSBlobCustom.cpp"
#include "JSCSSRuleCustom.cpp"
#include "JSCSSRuleListCustom.cpp"
Modified: trunk/Source/WebCore/bindings/js/JSExtendableMessageEventCustom.cpp (227381 => 227382)
--- trunk/Source/WebCore/bindings/js/JSExtendableMessageEventCustom.cpp 2018-01-23 02:09:22 UTC (rev 227381)
+++ trunk/Source/WebCore/bindings/js/JSExtendableMessageEventCustom.cpp 2018-01-23 03:00:59 UTC (rev 227382)
@@ -29,6 +29,7 @@
#include "JSExtendableMessageEvent.h"
#include "JSDOMConstructor.h"
+#include "JSDOMConvertStrings.h"
namespace WebCore {