Changeset 227589 in webkit


Ignore:
Timestamp:
Jan 24, 2018 5:28:47 PM (6 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthN] Implement PublicKeyCredential’s DiscoverFromExternalSource? with a dummy authenticator
https://bugs.webkit.org/show_bug.cgi?id=182032
<rdar://problem/36459922>

Reviewed by Brent Fulgham.

Source/WebCore:

This patch implements PublicKeyCredential's DiscoverFromExternalSource? from
https://www.w3.org/TR/webauthn/#getAssertion 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, which are marked by FIXME in the patch and tracked by proper
bugs. Those dependencies will be addressed once the first prototype is finshed.

Tests: http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https.html

http/wpt/credential-management/credentialscontainer-store-basics.https.html
http/wpt/webauthn/public-key-credential-get-failure.https.html
http/wpt/webauthn/public-key-credential-get-success.https.html

  • Modules/credentialmanagement/CredentialsContainer.cpp:

(WebCore::CredentialsContainer::get):
(WebCore::CredentialsContainer::isCreate):
Fixes some minor issues.

  • Modules/webauthn/Authenticator.cpp:

(WebCore::Authenticator::getAssertion const):

  • Modules/webauthn/Authenticator.h:

(WebCore::Authenticator::AssertionReturnBundle::AssertionReturnBundle):

  • Modules/webauthn/PublicKeyCredential.cpp:

(WebCore::PublicKeyCredential::collectFromCredentialStore):
Changed a parameter type.
(WebCore::PublicKeyCredential::discoverFromExternalSource):
(WebCore::PublicKeyCredential::create):
Improved some comments.

  • Modules/webauthn/PublicKeyCredential.h:
  • Modules/webauthn/PublicKeyCredentialRequestOptions.h:

(): Deleted.

  • bindings/js/JSAuthenticatorResponseCustom.cpp:

(WebCore::toJSNewlyCreated):

LayoutTests:

  • http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https-expected.txt: Added.
  • http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https.html: Added.
  • http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt:
  • http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt:
  • http/tests/webauthn/resources/last-layer-frame.https.html:
  • http/wpt/credential-management/credentialscontainer-store-basics.https-expected.txt: Added.
  • http/wpt/credential-management/credentialscontainer-store-basics.https.html: Added.
  • http/wpt/webauthn/idl.https-expected.txt:
  • http/wpt/webauthn/idl.https.html:
  • http/wpt/webauthn/public-key-credential-create-success.https.html:
  • http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-get-failure.https.html: Added.
  • http/wpt/webauthn/public-key-credential-get-success.https-expected.txt: Added.
  • http/wpt/webauthn/public-key-credential-get-success.https.html: Added.
Location:
trunk
Files:
8 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r227581 r227589  
     12018-01-24  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Implement PublicKeyCredential’s [[DiscoverFromExternalSource]] with a dummy authenticator
     4        https://bugs.webkit.org/show_bug.cgi?id=182032
     5        <rdar://problem/36459922>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https-expected.txt: Added.
     10        * http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https.html: Added.
     11        * http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt:
     12        * http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt:
     13        * http/tests/webauthn/resources/last-layer-frame.https.html:
     14        * http/wpt/credential-management/credentialscontainer-store-basics.https-expected.txt: Added.
     15        * http/wpt/credential-management/credentialscontainer-store-basics.https.html: Added.
     16        * http/wpt/webauthn/idl.https-expected.txt:
     17        * http/wpt/webauthn/idl.https.html:
     18        * http/wpt/webauthn/public-key-credential-create-success.https.html:
     19        * http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt: Added.
     20        * http/wpt/webauthn/public-key-credential-get-failure.https.html: Added.
     21        * http/wpt/webauthn/public-key-credential-get-success.https-expected.txt: Added.
     22        * http/wpt/webauthn/public-key-credential-get-success.https.html: Added.
     23
    1242018-01-24  Youenn Fablet  <youenn@apple.com>
    225
  • trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors-2.https-expected.txt

    r227382 r227589  
    44
    55
    6 PASS Throw NotAllowedError.
     6PASS Throw NotAllowedError for both PublicKeyCredential's [[create]] and [[get]].
    77PASS successfullyParsed is true
    88
  • trunk/LayoutTests/http/tests/webauthn/public-key-credential-same-origin-with-ancestors.https-expected.txt

    r227382 r227589  
    44
    55
    6 PASS Throw NotAllowedError.
     6PASS Throw NotAllowedError for both PublicKeyCredential's [[create]] and [[get]].
    77PASS successfullyParsed is true
    88
  • trunk/LayoutTests/http/tests/webauthn/resources/last-layer-frame.https.html

    r227382 r227589  
    88    }
    99
    10     const options = {
     10    const makeOptions = {
    1111        publicKey: {
    1212            rp: {
     
    1616                name: "John Appleseed",
    1717                id: asciiToUint8Array("123456"),
    18                 displayName: "John",
     18                displayName: "Appleseed",
    1919            },
    2020            challenge: asciiToUint8Array("123456"),
     
    2222        }
    2323    };
    24     navigator.credentials.create(options).then(
     24    const requestOptions = {
     25        publicKey: {
     26            challenge: asciiToUint8Array("123456"),
     27        }
     28    };
     29
     30    navigator.credentials.create(makeOptions).then(
    2531        function(value) {
    2632            messageToTop("Access granted. " + value);
     
    2834        function(exception) {
    2935            if (exception.name == "NotAllowedError")
    30                 messageToTop("PASS Throw NotAllowedError.");
     36                return navigator.credentials.get(requestOptions)
    3137            else
    3238                messageToTop("Throw " + exception.name  + ".");
    3339        }
    34     );
     40    ).then(function(value) {
     41            messageToTop("Access granted. " + value);
     42        },
     43        function(exception) {
     44            if (exception.name == "NotAllowedError")
     45                messageToTop("PASS Throw NotAllowedError for both PublicKeyCredential's [[create]] and [[get]].");
     46            else
     47                messageToTop("Throw " + exception.name  + ".");
     48    });
    3549    </script>
    3650</head>
  • trunk/LayoutTests/http/wpt/webauthn/idl.https-expected.txt

    r227382 r227589  
    2121PASS PublicKeyCredential interface: operation getClientExtensionResults()
    2222PASS PublicKeyCredential interface: operation isUserVerifyingPlatformAuthenticatorAvailable()
    23 PASS PublicKeyCredential must be primary interface of credential
    24 PASS Stringification of credential
    25 PASS PublicKeyCredential interface: credential must inherit property "rawId" with the proper type
    26 PASS PublicKeyCredential interface: credential must inherit property "response" with the proper type
    27 PASS PublicKeyCredential interface: credential must inherit property "getClientExtensionResults()" with the proper type
    28 PASS PublicKeyCredential interface: credential must inherit property "isUserVerifyingPlatformAuthenticatorAvailable()" with the proper type
    29 PASS Credential interface: credential must inherit property "id" with the proper type
    30 PASS Credential interface: credential must inherit property "type" with the proper type
     23PASS PublicKeyCredential must be primary interface of createdCredential
     24PASS Stringification of createdCredential
     25PASS PublicKeyCredential interface: createdCredential must inherit property "rawId" with the proper type
     26PASS PublicKeyCredential interface: createdCredential must inherit property "response" with the proper type
     27PASS PublicKeyCredential interface: createdCredential must inherit property "getClientExtensionResults()" with the proper type
     28PASS PublicKeyCredential interface: createdCredential must inherit property "isUserVerifyingPlatformAuthenticatorAvailable()" with the proper type
     29PASS Credential interface: createdCredential must inherit property "id" with the proper type
     30PASS Credential interface: createdCredential must inherit property "type" with the proper type
    3131PASS AuthenticatorResponse interface: existence and properties of interface object
    3232PASS AuthenticatorResponse interface object length
     
    4141PASS AuthenticatorAttestationResponse interface: existence and properties of interface prototype object's "constructor" property
    4242PASS AuthenticatorAttestationResponse interface: attribute attestationObject
    43 PASS AuthenticatorAttestationResponse must be primary interface of credential.response
    44 PASS Stringification of credential.response
    45 PASS AuthenticatorAttestationResponse interface: credential.response must inherit property "attestationObject" with the proper type
    46 PASS AuthenticatorResponse interface: credential.response must inherit property "clientDataJSON" with the proper type
     43PASS AuthenticatorAttestationResponse must be primary interface of createdCredential.response
     44PASS Stringification of createdCredential.response
     45PASS AuthenticatorAttestationResponse interface: createdCredential.response must inherit property "attestationObject" with the proper type
     46PASS AuthenticatorResponse interface: createdCredential.response must inherit property "clientDataJSON" with the proper type
    4747PASS AuthenticatorAssertionResponse interface: existence and properties of interface object
    4848PASS AuthenticatorAssertionResponse interface object length
     
    5353PASS AuthenticatorAssertionResponse interface: attribute signature
    5454PASS AuthenticatorAssertionResponse interface: attribute userHandle
     55PASS AuthenticatorAssertionResponse must be primary interface of requestedCredential.response
     56PASS Stringification of requestedCredential.response
     57PASS AuthenticatorAssertionResponse interface: requestedCredential.response must inherit property "authenticatorData" with the proper type
     58PASS AuthenticatorAssertionResponse interface: requestedCredential.response must inherit property "signature" with the proper type
     59PASS AuthenticatorAssertionResponse interface: requestedCredential.response must inherit property "userHandle" with the proper type
     60PASS AuthenticatorResponse interface: requestedCredential.response must inherit property "clientDataJSON" with the proper type
    5561
  • trunk/LayoutTests/http/wpt/webauthn/idl.https.html

    r227382 r227589  
    3636    idlArray.add_idls(idlText);
    3737
    38     const options = {
     38    const creationOptions = {
    3939        publicKey: {
    4040            rp: {
     
    5050        }
    5151    };
    52     credential = await navigator.credentials.create(options);
     52    createdCredential = await navigator.credentials.create(creationOptions);
    5353
    54     idlArray.add_objects({"PublicKeyCredential": ["credential"], "AuthenticatorAttestationResponse": ["credential.response"]});
     54
     55    const requestOptions = {
     56        publicKey: {
     57            challenge: Base64URL.parse("MTIzNDU2"),
     58        }
     59    };
     60    requestedCredential = await navigator.credentials.get(requestOptions);
     61
     62    idlArray.add_objects({"PublicKeyCredential": ["createdCredential"], "AuthenticatorAttestationResponse": ["createdCredential.response"], "AuthenticatorAssertionResponse": ["requestedCredential.response"]});
    5563    idlArray.test();
    5664}, "Setup for WebAuthN API IDL tests.");
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https.html

    r227382 r227589  
    3131                try {
    3232                    assert_throws("NotSupportedError", credential.getClientExtensionResults());
    33                 } catch { }
     33                } catch(error) { }
    3434            });
    3535    }, "PublicKeyCredential's [[create]] with minimum options");
  • trunk/Source/WebCore/ChangeLog

    r227588 r227589  
     12018-01-24  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Implement PublicKeyCredential’s [[DiscoverFromExternalSource]] with a dummy authenticator
     4        https://bugs.webkit.org/show_bug.cgi?id=182032
     5        <rdar://problem/36459922>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch implements PublicKeyCredential's [[DiscoverFromExternalSource]] from
     10        https://www.w3.org/TR/webauthn/#getAssertion as of 5 December 2017. In order to
     11        do testing, a dummy authenticator is implemented to exercise a failure and a
     12        pass path. A number of dependencies need to be resolved later in order to comply
     13        with the spec, which are marked by FIXME in the patch and tracked by proper
     14        bugs. Those dependencies will be addressed once the first prototype is finshed.
     15
     16        Tests: http/tests/webauthn/public-key-credential-get-with-invalid-parameters.https.html
     17               http/wpt/credential-management/credentialscontainer-store-basics.https.html
     18               http/wpt/webauthn/public-key-credential-get-failure.https.html
     19               http/wpt/webauthn/public-key-credential-get-success.https.html
     20
     21        * Modules/credentialmanagement/CredentialsContainer.cpp:
     22        (WebCore::CredentialsContainer::get):
     23        (WebCore::CredentialsContainer::isCreate):
     24        Fixes some minor issues.
     25        * Modules/webauthn/Authenticator.cpp:
     26        (WebCore::Authenticator::getAssertion const):
     27        * Modules/webauthn/Authenticator.h:
     28        (WebCore::Authenticator::AssertionReturnBundle::AssertionReturnBundle):
     29        * Modules/webauthn/PublicKeyCredential.cpp:
     30        (WebCore::PublicKeyCredential::collectFromCredentialStore):
     31        Changed a parameter type.
     32        (WebCore::PublicKeyCredential::discoverFromExternalSource):
     33        (WebCore::PublicKeyCredential::create):
     34        Improved some comments.
     35        * Modules/webauthn/PublicKeyCredential.h:
     36        * Modules/webauthn/PublicKeyCredentialRequestOptions.h:
     37        (): Deleted.
     38        * bindings/js/JSAuthenticatorResponseCustom.cpp:
     39        (WebCore::toJSNewlyCreated):
     40
    1412018-01-24  Dean Jackson  <dino@apple.com>
    242
  • trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp

    r227382 r227589  
    7272}
    7373
    74 // FIXME: Since the underlying authenticator model is not clear at this moment, the timer is moved to CredentialsContainer such that
     74// FIXME(181946): Since the underlying authenticator model is not clear at this moment, the timer is moved to CredentialsContainer such that
    7575// timer can stay with main thread and therefore can easily time out activities on the work queue.
    76 // https://bugs.webkit.org/show_bug.cgi?id=181946.
    77 // FIXME: The usages of AbortSignal are also moved here for the very same reason. Also the AbortSignal is kind of bogus at this moment
     76// FIXME(181945): The usages of AbortSignal are also moved here for the very same reason. Also the AbortSignal is kind of bogus at this moment
    7877// since it doesn't support observers (or other means) to trigger the actual abort action. Enhancement to AbortSignal is needed.
    79 // https://bugs.webkit.org/show_bug.cgi?id=181945.
    8078template<typename OperationType>
    8179void CredentialsContainer::dispatchTask(OperationType&& operation, Ref<DeferredPromise>&& promise, std::optional<unsigned long> timeOutInMs)
     
    8785    auto* promiseIndex = promise.ptr();
    8886    auto weakThis = m_weakPtrFactory.createWeakPtr(*this);
    89     // FIXME: We should probably trim timeOutInMs to some max allowable number.
    90     // https://bugs.webkit.org/show_bug.cgi?id=181947
     87    // FIXME(181947): We should probably trim timeOutInMs to some max allowable number.
    9188    if (timeOutInMs) {
    9289        auto pendingPromise = PendingPromise::create(WTFMove(promise), std::make_unique<Timer>([promiseIndex, weakThis] () {
     
    111108                    if (result.hasException())
    112109                        promise.value()->promise->reject(result.releaseException());
    113                     else {
    114                         // FIXME: Got some crazy compile error when I was trying to pass RHS to the resolve method.
    115                         RefPtr<BasicCredential> credential = result.releaseReturnValue();
    116                         promise.value()->promise->resolve<IDLNullable<IDLInterface<BasicCredential>>>(credential.get());
    117                     }
     110                    else
     111                        promise.value()->promise->resolve<IDLNullable<IDLInterface<BasicCredential>>>(result.returnValue().get());
    118112                }
    119113            }
     
    125119void CredentialsContainer::get(CredentialRequestOptions&& options, Ref<DeferredPromise>&& promise)
    126120{
     121    // The following implements https://www.w3.org/TR/credential-management-1/#algorithm-request as of 4 August 2017
     122    // with enhancement from 14 November 2017 Editor's Draft.
    127123    // FIXME: Optional options are passed with no contents. It should be std::optional.
    128124    if ((!options.signal && !options.publicKey) || !m_document) {
     
    134130        return;
    135131    }
     132    // Step 1-2.
    136133    ASSERT(m_document->isSecureContext());
    137134
    138     // The followings is a shortcut to https://www.w3.org/TR/credential-management-1/#algorithm-request,
    139     // as we only support PublicKeyCredential which can only be requested from [[discoverFromExternalSource]].
     135    // Step 3 is enhanced with doesHaveSameOriginAsItsAncestors.
     136    // Step 4-6. Shortcut as we only support PublicKeyCredential which can only
     137    // be requested from [[discoverFromExternalSource]].
    140138    if (!options.publicKey) {
    141139        promise->reject(Exception { NotSupportedError });
     
    143141    }
    144142
    145     auto operation = [options = WTFMove(options)] (const SecurityOrigin& origin, bool isSameOriginWithItsAncestors) {
     143    auto timeout = options.publicKey->timeout;
     144    auto operation = [options = WTFMove(options.publicKey.value())] (const SecurityOrigin& origin, bool isSameOriginWithItsAncestors) {
    146145        return PublicKeyCredential::discoverFromExternalSource(origin, options, isSameOriginWithItsAncestors);
    147146    };
    148     dispatchTask(WTFMove(operation), WTFMove(promise), options.publicKey->timeout);
     147    dispatchTask(WTFMove(operation), WTFMove(promise), timeout);
    149148}
    150149
     
    182181        return PublicKeyCredential::create(origin, options, isSameOriginWithItsAncestors);
    183182    };
    184     dispatchTask(WTFMove(operation), WTFMove(promise), options.publicKey->timeout);
     183    dispatchTask(WTFMove(operation), WTFMove(promise), timeout);
    185184}
    186185
  • trunk/Source/WebCore/Modules/webauthn/Authenticator.cpp

    r227382 r227589  
    2727#include "Authenticator.h"
    2828
     29#include <AuthenticatorAttestationResponse.h>
     30#include <wtf/CurrentTime.h>
    2931#include <wtf/NeverDestroyed.h>
    3032
     
    5658}
    5759
     60ExceptionOr<Authenticator::AssertionReturnBundle> Authenticator::getAssertion(const String&, const Vector<uint8_t>& hash, const Vector<PublicKeyCredentialDescriptor>& allowCredentialIds) const
     61{
     62    // The followings is just a dummy implementaion to support initial development.
     63    // User cancellation is effecively NotAllowedError.
     64    if (!allowCredentialIds.isEmpty())
     65        return Exception { NotAllowedError };
     66
     67    // FIXME: Delay processing for 0.1 seconds to simulate a timeout condition. This code will be removed
     68    // when the full test infrastructure is set up.
     69    WTF::sleep(0.1);
     70
     71    // Fill all parts with hash
     72    return AssertionReturnBundle(ArrayBuffer::create(hash.data(), hash.size()), ArrayBuffer::create(hash.data(), hash.size()), ArrayBuffer::create(hash.data(), hash.size()), ArrayBuffer::create(hash.data(), hash.size()));
     73}
     74
    5875} // namespace WebCore
  • trunk/Source/WebCore/Modules/webauthn/Authenticator.h

    r227382 r227589  
    3333namespace WebCore {
    3434
    35 // FIXME: Consider moving all static methods from PublicKeyCredential to here and making this
     35// FIXME(181946): Consider moving all static methods from PublicKeyCredential to here and making this
    3636// as an authenticator manager that controls all authenticator activities, mostly likely asnyc
    3737// for attestations.
     
    4040    friend class NeverDestroyed<Authenticator>;
    4141public:
     42    // FIXME(181946): After moving all static methods from PublicKeyCredential to here, we will probably
     43    // return PublicKeyCredential directly and get rid of the following return type.
     44    struct AssertionReturnBundle {
     45        AssertionReturnBundle(Ref<ArrayBuffer>&& id, Ref<ArrayBuffer>&& data, Ref<ArrayBuffer>&& sig, Ref<ArrayBuffer>&& handle)
     46            : credentialID(WTFMove(id))
     47            , authenticatorData(WTFMove(data))
     48            , signature(WTFMove(sig))
     49            , userHandle(WTFMove(handle))
     50        {
     51        }
     52
     53        Ref<ArrayBuffer> credentialID;
     54        Ref<ArrayBuffer> authenticatorData;
     55        Ref<ArrayBuffer> signature;
     56        Ref<ArrayBuffer> userHandle;
     57    };
     58
    4259    static Authenticator& singleton();
    4360
    4461    // Omit requireResidentKey, requireUserPresence, and requireUserVerification as we always provide resident keys and require user verification.
    4562    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;
     63    ExceptionOr<AssertionReturnBundle> getAssertion(const String& rpId, const Vector<uint8_t>& hash, const Vector<PublicKeyCredentialDescriptor>& allowCredentialIds) const;
    4664
    4765#if !COMPILER(MSVC)
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp

    r227382 r227589  
    2929#include "Authenticator.h"
    3030#include "AuthenticatorResponse.h"
    31 #include "CredentialCreationOptions.h"
    3231#include "JSDOMPromiseDeferred.h"
     32#include "PublicKeyCredentialCreationOptions.h"
     33#include "PublicKeyCredentialRequestOptions.h"
    3334#include "SecurityOrigin.h"
    3435#include <pal/crypto/CryptoDigest.h>
     
    5152};
    5253
    53 // FIXME: Add token binding ID and extensions.
    54 // https://bugs.webkit.org/show_bug.cgi?id=181948
    55 // https://bugs.webkit.org/show_bug.cgi?id=181949
     54// FIXME(181948): Add token binding ID and extensions.
    5655static Ref<ArrayBuffer> produceClientDataJson(ClientDataType type, const BufferSource& challenge, const SecurityOrigin& origin)
    5756{
     
    101100}
    102101
    103 Vector<Ref<BasicCredential>> PublicKeyCredential::collectFromCredentialStore(CredentialRequestOptions&&, bool)
     102Vector<Ref<BasicCredential>> PublicKeyCredential::collectFromCredentialStore(PublicKeyCredentialRequestOptions&&, bool)
    104103{
    105104    return { };
    106105}
    107106
    108 ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::discoverFromExternalSource(const SecurityOrigin&, const CredentialRequestOptions&, bool)
    109 {
    110     return Exception { NotSupportedError };
    111 }
    112 
    113 RefPtr<BasicCredential> PublicKeyCredential::store(RefPtr<BasicCredential>&&, bool)
    114 {
    115     return nullptr;
    116 }
    117 
    118 ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::create(const SecurityOrigin& callerOrigin, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors)
     107ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::discoverFromExternalSource(const SecurityOrigin& callerOrigin, const PublicKeyCredentialRequestOptions& options, bool sameOriginWithAncestors)
    119108{
    120109    using namespace PublicKeyCredentialInternal;
    121110
    122111    // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017.
    123     // FIXME: Extensions are not supported yet. Skip Step 11-12.
    124     // Step 1, 3, 4, 17 are handled by the caller, including options sanitizing, timer and abort signal.
     112    // FIXME: Extensions are not supported yet. Skip Step 8-9.
     113    // Step 1, 3-4, 13, 16 are handled by the caller, including options sanitizing, timer and abort signal.
    125114    // Step 2.
    126115    if (!sameOriginWithAncestors)
     
    128117
    129118    // Step 5-7.
    130     // FIXME: We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
     119    // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
    131120    // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
    132121    // domain suffix of another domain. Hence restrict the comparison to equal in Step 7.
    133     // https://bugs.webkit.org/show_bug.cgi?id=181950
     122    if (!options.rpId.isEmpty() && !(callerOrigin.host() == options.rpId))
     123        return Exception { SecurityError };
     124    if (options.rpId.isEmpty())
     125        options.rpId = callerOrigin.host();
     126
     127    // Step 10-12.
     128    auto clientDataJson = produceClientDataJson(ClientDataType::Get, options.challenge, callerOrigin);
     129    auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson);
     130
     131    // Step 14-15, 17-19.
     132    // Only platform attachments will be supported at this stage. Assuming one authenticator per device.
     133    // Also, resident keys, user verifications and direct attestation are enforced at this tage.
     134    // For better performance, no filtering is done here regarding to options.excludeCredentials.
     135    // What's more, user cancellations effectively means NotAllowedError. Therefore, the below call
     136    // will only returns either an exception or a PublicKeyCredential ref.
     137    // FIXME(181946): The following operation might need to perform async.
     138    auto result = Authenticator::singleton().getAssertion(options.rpId, clientDataJsonHash, options.allowCredentials);
     139    if (result.hasException())
     140        return result.releaseException();
     141
     142    auto bundle = result.releaseReturnValue();
     143    return ExceptionOr<RefPtr<BasicCredential>>(PublicKeyCredential::create(WTFMove(bundle.credentialID), AuthenticatorAssertionResponse::create(WTFMove(clientDataJson), WTFMove(bundle.authenticatorData), WTFMove(bundle.signature), WTFMove(bundle.userHandle))));
     144}
     145
     146RefPtr<BasicCredential> PublicKeyCredential::store(RefPtr<BasicCredential>&&, bool)
     147{
     148    return nullptr;
     149}
     150
     151ExceptionOr<RefPtr<BasicCredential>> PublicKeyCredential::create(const SecurityOrigin& callerOrigin, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors)
     152{
     153    using namespace PublicKeyCredentialInternal;
     154
     155    // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017.
     156    // FIXME: Extensions are not supported yet. Skip Step 11-12.
     157    // Step 1, 3-4, 16-17 are handled by the caller, including options sanitizing, timer and abort signal.
     158    // Step 2.
     159    if (!sameOriginWithAncestors)
     160        return Exception { NotAllowedError };
     161
     162    // Step 5-7.
     163    // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
     164    // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
     165    // domain suffix of another domain. Hence restrict the comparison to equal in Step 7.
    134166    if (!options.rp.id.isEmpty() && !(callerOrigin.host() == options.rp.id))
    135167        return Exception { SecurityError };
     
    153185    // What's more, user cancellations effectively means NotAllowedError. Therefore, the below call
    154186    // will only returns either an exception or a PublicKeyCredential ref.
    155     // FIXME: The following operation might need to perform async.
    156     // https://bugs.webkit.org/show_bug.cgi?id=181946
     187    // FIXME(181946): The following operation might need to perform async.
    157188    auto result = Authenticator::singleton().makeCredential(clientDataJsonHash, options.rp, options.user, options.pubKeyCredParams, options.excludeCredentials);
    158189    if (result.hasException())
     
    160191
    161192    auto attestationObject = result.releaseReturnValue();
    162     // FIXME: Got some crazy compile error when I was trying to return RHS directly.
    163     RefPtr<BasicCredential> credential = PublicKeyCredential::create(getIdFromAttestationObject(attestationObject), AuthenticatorAttestationResponse::create(WTFMove(clientDataJson), ArrayBuffer::create(attestationObject.data(), attestationObject.size())));
    164     return WTFMove(credential);
     193    return ExceptionOr<RefPtr<BasicCredential>>(PublicKeyCredential::create(getIdFromAttestationObject(attestationObject), AuthenticatorAttestationResponse::create(WTFMove(clientDataJson), ArrayBuffer::create(attestationObject.data(), attestationObject.size()))));
    165194}
    166195
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.h

    r227382 r227589  
    3838
    3939struct PublicKeyCredentialCreationOptions;
    40 struct CredentialRequestOptions;
     40struct PublicKeyCredentialRequestOptions;
    4141
    4242class PublicKeyCredential final : public BasicCredential {
     
    4747    }
    4848
    49     static Vector<Ref<BasicCredential>> collectFromCredentialStore(CredentialRequestOptions&&, bool);
    50     static ExceptionOr<RefPtr<BasicCredential>> discoverFromExternalSource(const SecurityOrigin&, const CredentialRequestOptions&, bool sameOriginWithAncestors);
     49    static Vector<Ref<BasicCredential>> collectFromCredentialStore(PublicKeyCredentialRequestOptions&&, bool);
     50    static ExceptionOr<RefPtr<BasicCredential>> discoverFromExternalSource(const SecurityOrigin&, const PublicKeyCredentialRequestOptions&, bool sameOriginWithAncestors);
    5151    static RefPtr<BasicCredential> store(RefPtr<BasicCredential>&&, bool);
    5252    static ExceptionOr<RefPtr<BasicCredential>> create(const SecurityOrigin&, const PublicKeyCredentialCreationOptions&, bool sameOriginWithAncestors);
  • trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialRequestOptions.h

    r227007 r227589  
    3434struct PublicKeyCredentialRequestOptions {
    3535    BufferSource challenge;
    36     unsigned long timeout { 0 };
    37     String rpId;
     36    std::optional<unsigned long> timeout;
     37    mutable String rpId;
    3838    Vector<PublicKeyCredentialDescriptor> allowCredentials;
    3939};
  • trunk/Source/WebCore/bindings/js/JSAuthenticatorResponseCustom.cpp

    r227382 r227589  
    2727#include "JSAuthenticatorResponse.h"
    2828
     29#include "JSAuthenticatorAssertionResponse.h"
    2930#include "JSAuthenticatorAttestationResponse.h"
    3031#include "JSDOMBinding.h"
     
    3738    if (is<AuthenticatorAttestationResponse>(response))
    3839        return createWrapper<AuthenticatorAttestationResponse>(globalObject, WTFMove(response));
     40    if (is<AuthenticatorAssertionResponse>(response))
     41        return createWrapper<AuthenticatorAssertionResponse>(globalObject, WTFMove(response));
    3942    return createWrapper<AuthenticatorResponse>(globalObject, WTFMove(response));
    4043}
Note: See TracChangeset for help on using the changeset viewer.