Changeset 254356 in webkit


Ignore:
Timestamp:
Jan 10, 2020 11:06:44 AM (4 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthn] Support authenticatorGetNextAssertion
https://bugs.webkit.org/show_bug.cgi?id=203346
<rdar://problem/56558488>

Reviewed by Brent Fulgham.

Source/WebCore:

Covered by new tests within existing test files.

  • Modules/webauthn/AuthenticatorAssertionResponse.h:

(WebCore::AuthenticatorAssertionResponse::setName):
(WebCore::AuthenticatorAssertionResponse::name const):
(WebCore::AuthenticatorAssertionResponse::setDisplayName):
(WebCore::AuthenticatorAssertionResponse::displayName const):
(WebCore::AuthenticatorAssertionResponse::setNumberOfCredentials):
(WebCore::AuthenticatorAssertionResponse::numberOfCredentials const):
Adds new members to store new fields of the response from the authenticator. Field "icon"
is omitted given it could be used to track users according to https://github.com/w3c/webauthn/issues/1285.

  • Modules/webauthn/fido/DeviceResponseConverter.cpp:

(fido::readCTAPGetAssertionResponse):
Adds new logic to parse above fields from an authenticator response.

Source/WebKit:

This patch implements authenticatorGetNextAssertion as suggested by the spec:
https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorGetNextAssertion

The work flow is as follow:
1) When a valid assertion response is received, check its numberOfCredentials member;
2) When it is larger then 1, use authenticatorGetNextAssertion to get all remaining responses;
3) Once all responses are gathered, ask UI clients to pick one to return.

  • UIProcess/API/APIWebAuthenticationPanelClient.h:

(API::WebAuthenticationPanelClient::selectAssertionResponses const):

  • UIProcess/WebAuthentication/Authenticator.h:
  • UIProcess/WebAuthentication/AuthenticatorManager.cpp:

(WebKit::AuthenticatorManager::selectAssertionResponses):

  • UIProcess/WebAuthentication/AuthenticatorManager.h:
  • UIProcess/WebAuthentication/Mock/MockHidConnection.cpp:

(WebKit::MockHidConnection::parseRequest):

  • UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:

(WebKit::CtapAuthenticator::continueGetAssertionAfterResponseReceived):
(WebKit::CtapAuthenticator::continueGetNextAssertionAfterResponseReceived):

  • UIProcess/WebAuthentication/fido/CtapAuthenticator.h:

Tools:

  • TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:

(TestWebKitAPI::TEST):

  • TestWebKitAPI/Tests/WebCore/FidoTestData.h:

Adds new test case for new logic in DeviceResponseConverter.

LayoutTests:

  • http/wpt/webauthn/public-key-credential-get-failure-hid.https-expected.txt:
  • http/wpt/webauthn/public-key-credential-get-failure-hid.https.html:
  • http/wpt/webauthn/public-key-credential-get-success-hid.https-expected.txt:
  • http/wpt/webauthn/public-key-credential-get-success-hid.https.html:
  • http/wpt/webauthn/resources/util.js:
Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r254351 r254356  
     12020-01-10  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Support authenticatorGetNextAssertion
     4        https://bugs.webkit.org/show_bug.cgi?id=203346
     5        <rdar://problem/56558488>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * http/wpt/webauthn/public-key-credential-get-failure-hid.https-expected.txt:
     10        * http/wpt/webauthn/public-key-credential-get-failure-hid.https.html:
     11        * http/wpt/webauthn/public-key-credential-get-success-hid.https-expected.txt:
     12        * http/wpt/webauthn/public-key-credential-get-success-hid.https.html:
     13        * http/wpt/webauthn/resources/util.js:
     14
    1152020-01-10  Brent Fulgham  <bfulgham@apple.com>
    216
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-hid.https-expected.txt

    r251317 r254356  
    66PASS PublicKeyCredential's [[get]] with authenticator downgrade failed in a mock hid authenticator. 2
    77PASS PublicKeyCredential's [[get]] with authenticator downgrade succeeded and then U2F failed in a mock hid authenticator.
     8PASS PublicKeyCredential's [[get]] with getNextAssertion failed in a mock hid authenticator.
    89
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-hid.https.html

    r251317 r254356  
    8585        return promiseRejects(t, "UnknownError", navigator.credentials.get(options), "Unknown internal error. Error code: 34");
    8686    }, "PublicKeyCredential's [[get]] with authenticator downgrade succeeded and then U2F failed in a mock hid authenticator.");
     87
     88    promise_test(function(t) {
     89        const options = {
     90            publicKey: {
     91                challenge: asciiToUint8Array("123456")
     92            }
     93        };
     94
     95        if (window.internals)
     96            internals.setMockWebAuthenticationConfiguration({ hid: { stage: "request", subStage: "msg", error: "malicious-payload", payloadBase64: [testAssertionMessageLongBase64, testCtapErrNotAllowedResponseBase64] } });
     97        return promiseRejects(t, "UnknownError", navigator.credentials.get(options), "Unknown internal error. Error code: 48");
     98    }, "PublicKeyCredential's [[get]] with getNextAssertion failed in a mock hid authenticator.");
    8799</script>
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-hid.https-expected.txt

    r245043 r254356  
    66PASS PublicKeyCredential's [[get]] with mixed options in a mock hid authenticator.
    77PASS PublicKeyCredential's [[get]] with two consecutive requests.
     8PASS PublicKeyCredential's [[get]] with multiple accounts in a mock hid authenticator.
    89
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-hid.https.html

    r251489 r254356  
    102102        });
    103103    }, "PublicKeyCredential's [[get]] with two consecutive requests.");
     104
     105    promise_test(t => {
     106        const options = {
     107            publicKey: {
     108                challenge: Base64URL.parse("MTIzNDU2"),
     109                timeout: 100
     110            }
     111        };
     112
     113        if (window.internals)
     114            internals.setMockWebAuthenticationConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testAssertionMessageLongBase64, testAssertionMessageLongBase64] } });
     115        return navigator.credentials.get(options).then(credential => {
     116            return checkCtapGetAssertionResult(credential, "MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII=");
     117        });
     118    }, "PublicKeyCredential's [[get]] with multiple accounts in a mock hid authenticator.");
    104119</script>
  • trunk/LayoutTests/http/wpt/webauthn/resources/util.js

    r250249 r254356  
    6767    "4/F0VB7DlUVM09IHPmxe1MzHUwRoCRZbCAIgGKov6xoAx2MEf6/6qNs8OutzhP2C" +
    6868    "QoJ1L7Fe64G9uBc=";
     69const testAssertionMessageLongBase64 =
     70    "AKUBomJpZFhAKAitzuj+Tslzelf3/vZwIGtDQNgoKeFd5oEieYzhyzA65saf0tK2" +
     71    "w/mooa7tQtGgDdwZIjOhjcuZ0pQ1ajoE4GR0eXBlanB1YmxpYy1rZXkCWCVGzH+5" +
     72    "Z51VstuQkuHI2eXh0Ct1gPC0gSx3CWLh5I9a2AEAAABQA1hHMEUCIQCSFTuuBWgB" +
     73    "4/F0VB7DlUVM09IHPmxe1MzHUwRoCRZbCAIgGKov6xoAx2MEf6/6qNs8OutzhP2C" +
     74    "QoJ1L7Fe64G9uBcEpGJpZFggMIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGT" +
     75    "MIJkaWNvbngoaHR0cHM6Ly9waWNzLmFjbWUuY29tLzAwL3AvYUJqampwcVBiLnBu" +
     76    "Z2RuYW1ldmpvaG5wc21pdGhAZXhhbXBsZS5jb21rZGlzcGxheU5hbWVtSm9obiBQ" +
     77    "LiBTbWl0aAUC";
    6978const testU2fApduNoErrorOnlyResponseBase64 = "kAA=";
    7079const testU2fApduInsNotSupportedOnlyResponseBase64 = "bQA=";
     
    97106const testCtapErrCredentialExcludedOnlyResponseBase64 = "GQ==";
    98107const testCtapErrInvalidCredentialResponseBase64 = "Ig==";
     108const testCtapErrNotAllowedResponseBase64 = "MA==";
    99109const testNfcU2fVersionBase64 = "VTJGX1YykAA=";
    100110const testNfcCtapVersionBase64 = "RklET18yXzCQAA==";
     
    395405}
    396406
    397 function checkCtapGetAssertionResult(credential)
     407function checkCtapGetAssertionResult(credential, userHandleBase64 = null)
    398408{
    399409    // Check respond
     
    402412    assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64));
    403413    assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');
    404     assert_equals(credential.response.userHandle, null);
     414    if (userHandleBase64 == null)
     415        assert_equals(credential.response.userHandle, null);
     416    else
     417        assert_array_equals(new Uint8Array(credential.response.userHandle), Base64URL.parse(userHandleBase64));
    405418    assert_not_own_property(credential.getClientExtensionResults(), "appid");
    406419
  • trunk/Source/WebCore/ChangeLog

    r254350 r254356  
     12020-01-10  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Support authenticatorGetNextAssertion
     4        https://bugs.webkit.org/show_bug.cgi?id=203346
     5        <rdar://problem/56558488>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Covered by new tests within existing test files.
     10
     11        * Modules/webauthn/AuthenticatorAssertionResponse.h:
     12        (WebCore::AuthenticatorAssertionResponse::setName):
     13        (WebCore::AuthenticatorAssertionResponse::name const):
     14        (WebCore::AuthenticatorAssertionResponse::setDisplayName):
     15        (WebCore::AuthenticatorAssertionResponse::displayName const):
     16        (WebCore::AuthenticatorAssertionResponse::setNumberOfCredentials):
     17        (WebCore::AuthenticatorAssertionResponse::numberOfCredentials const):
     18        Adds new members to store new fields of the response from the authenticator. Field "icon"
     19        is omitted given it could be used to track users according to https://github.com/w3c/webauthn/issues/1285.
     20        * Modules/webauthn/fido/DeviceResponseConverter.cpp:
     21        (fido::readCTAPGetAssertionResponse):
     22        Adds new logic to parse above fields from an authenticator response.
     23
    1242020-01-10  Dean Jackson  <dino@apple.com>
    225
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorAssertionResponse.h

    r253398 r254356  
    4242    ArrayBuffer* userHandle() const { return m_userHandle.get(); }
    4343
     44    void setName(const String& name) { m_name = name; }
     45    String name() const { return m_name; }
     46    void setDisplayName(const String& displayName) { m_displayName = displayName; }
     47    String displayName() const { return m_displayName; }
     48    void setNumberOfCredentials(size_t numberOfCredentials) { m_numberOfCredentials = numberOfCredentials; }
     49    size_t numberOfCredentials() const { return m_numberOfCredentials; }
     50
    4451private:
    4552    AuthenticatorAssertionResponse(Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, Ref<ArrayBuffer>&&, RefPtr<ArrayBuffer>&&);
     
    5158    Ref<ArrayBuffer> m_signature;
    5259    RefPtr<ArrayBuffer> m_userHandle;
     60
     61    String m_name;
     62    String m_displayName;
     63    size_t m_numberOfCredentials { 0 };
    5364};
    5465
  • trunk/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp

    r254079 r254356  
    165165    auto& signature = it->second.getByteString();
    166166
     167    RefPtr<AuthenticatorAssertionResponse> response;
    167168    it = responseMap.find(CBOR(4));
    168169    if (it != responseMap.end() && it->second.isMap()) {
     
    172173            return nullptr;
    173174        auto& userHandle = itr->second.getByteString();
    174         return AuthenticatorAssertionResponse::create(credentialId, authData, signature, userHandle);
    175     }
    176 
    177     return AuthenticatorAssertionResponse::create(credentialId, authData, signature, { });
     175        response = AuthenticatorAssertionResponse::create(credentialId, authData, signature, userHandle);
     176
     177        itr = user.find(CBOR(kEntityNameMapKey));
     178        if (itr != user.end()) {
     179            if (!itr->second.isString())
     180                return nullptr;
     181            response->setName(itr->second.getString());
     182        }
     183
     184        itr = user.find(CBOR(kDisplayNameMapKey));
     185        if (itr != user.end()) {
     186            if (!itr->second.isString())
     187                return nullptr;
     188            response->setDisplayName(itr->second.getString());
     189        }
     190    } else {
     191        response = AuthenticatorAssertionResponse::create(credentialId, authData, signature, { });
     192    }
     193
     194    it = responseMap.find(CBOR(5));
     195    if (it != responseMap.end() && it->second.isUnsigned())
     196        response->setNumberOfCredentials(it->second.getUnsigned());
     197
     198    return response;
    178199}
    179200
  • trunk/Source/WebKit/ChangeLog

    r254351 r254356  
     12020-01-10  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Support authenticatorGetNextAssertion
     4        https://bugs.webkit.org/show_bug.cgi?id=203346
     5        <rdar://problem/56558488>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        This patch implements authenticatorGetNextAssertion as suggested by the spec:
     10        https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorGetNextAssertion
     11
     12        The work flow is as follow:
     13        1) When a valid assertion response is received, check its numberOfCredentials member;
     14        2) When it is larger then 1, use authenticatorGetNextAssertion to get all remaining responses;
     15        3) Once all responses are gathered, ask UI clients to pick one to return.
     16
     17        * UIProcess/API/APIWebAuthenticationPanelClient.h:
     18        (API::WebAuthenticationPanelClient::selectAssertionResponses const):
     19        * UIProcess/WebAuthentication/Authenticator.h:
     20        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
     21        (WebKit::AuthenticatorManager::selectAssertionResponses):
     22        * UIProcess/WebAuthentication/AuthenticatorManager.h:
     23        * UIProcess/WebAuthentication/Mock/MockHidConnection.cpp:
     24        (WebKit::MockHidConnection::parseRequest):
     25        * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp:
     26        (WebKit::CtapAuthenticator::continueGetAssertionAfterResponseReceived):
     27        (WebKit::CtapAuthenticator::continueGetNextAssertionAfterResponseReceived):
     28        * UIProcess/WebAuthentication/fido/CtapAuthenticator.h:
     29
    1302020-01-10  Brent Fulgham  <bfulgham@apple.com>
    231
  • trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanelClient.h

    r251317 r254356  
    2828#if ENABLE(WEB_AUTHN)
    2929
     30#include <wtf/CompletionHandler.h>
     31#include <wtf/HashSet.h>
     32#include <wtf/RefCounted.h>
     33
     34namespace WebCore {
     35class AuthenticatorAssertionResponse;
     36}
     37
    3038namespace WebKit {
    3139enum class WebAuthenticationStatus : bool;
     
    4250    virtual void updatePanel(WebKit::WebAuthenticationStatus) const { }
    4351    virtual void dismissPanel(WebKit::WebAuthenticationResult) const { }
     52    virtual void selectAssertionResponses(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>& responses, CompletionHandler<void(const Ref<WebCore::AuthenticatorAssertionResponse>&)>&& completionHandler) const { completionHandler(*responses.begin()); }
    4453};
    4554
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.h

    r253398 r254356  
    3636#include <wtf/WeakPtr.h>
    3737
     38namespace WebCore {
     39class AuthenticatorAssertionResponse;
     40}
     41
    3842namespace WebKit {
    3943
     
    4852        virtual void downgrade(Authenticator* id, Ref<Authenticator>&& downgradedAuthenticator) = 0;
    4953        virtual void authenticatorStatusUpdated(WebAuthenticationStatus) = 0;
     54        virtual void selectAssertionResponses(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, CompletionHandler<void(const Ref<WebCore::AuthenticatorAssertionResponse>&)>&&) = 0;
    5055    };
    5156
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp

    r253398 r254356  
    274274}
    275275
     276void AuthenticatorManager::selectAssertionResponses(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>& responses, CompletionHandler<void(const Ref<WebCore::AuthenticatorAssertionResponse>&)>&& completionHandler)
     277{
     278    if (auto* panel = m_pendingRequestData.panel.get())
     279        panel->client().selectAssertionResponses(responses, WTFMove(completionHandler));
     280}
     281
    276282UniqueRef<AuthenticatorTransportService> AuthenticatorManager::createService(AuthenticatorTransport transport, AuthenticatorTransportService::Observer& observer) const
    277283{
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h

    r253398 r254356  
    8282    void downgrade(Authenticator* id, Ref<Authenticator>&& downgradedAuthenticator) final;
    8383    void authenticatorStatusUpdated(WebAuthenticationStatus) final;
     84    void selectAssertionResponses(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, CompletionHandler<void(const Ref<WebCore::AuthenticatorAssertionResponse>&)>&&) final;
    8485
    8586    // Overriden by MockAuthenticatorManager.
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockHidConnection.cpp

    r251295 r254356  
    159159            payload.remove(0);
    160160            auto requestMap = CBORReader::read(payload);
    161             ASSERT(requestMap);
     161            ASSERT(requestMap || cmd == CtapRequestCommand::kAuthenticatorGetNextAssertion);
    162162
    163163            if (cmd == CtapRequestCommand::kAuthenticatorMakeCredential) {
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp

    r253398 r254356  
    101101        return;
    102102    }
    103     receiveRespond(response.releaseNonNull());
     103
     104    if (response->numberOfCredentials() <= 1) {
     105        receiveRespond(response.releaseNonNull());
     106        return;
     107    }
     108
     109    m_remainingAssertionResponses = response->numberOfCredentials() - 1;
     110    auto addResult = m_assertionResponses.add(response.releaseNonNull());
     111    ASSERT_UNUSED(addResult, addResult.isNewEntry);
     112    driver().transact(encodeEmptyAuthenticatorRequest(CtapRequestCommand::kAuthenticatorGetNextAssertion), [weakThis = makeWeakPtr(*this)](Vector<uint8_t>&& data) {
     113        ASSERT(RunLoop::isMain());
     114        if (!weakThis)
     115            return;
     116        weakThis->continueGetNextAssertionAfterResponseReceived(WTFMove(data));
     117    });
     118}
     119
     120void CtapAuthenticator::continueGetNextAssertionAfterResponseReceived(Vector<uint8_t>&& data)
     121{
     122    auto response = readCTAPGetAssertionResponse(data);
     123    if (!response) {
     124        auto error = getResponseCode(data);
     125        receiveRespond(ExceptionData { UnknownError, makeString("Unknown internal error. Error code: ", static_cast<uint8_t>(error)) });
     126        return;
     127    }
     128    m_remainingAssertionResponses--;
     129    auto addResult = m_assertionResponses.add(response.releaseNonNull());
     130    ASSERT_UNUSED(addResult, addResult.isNewEntry);
     131
     132    if (!m_remainingAssertionResponses) {
     133        if (auto* observer = this->observer()) {
     134            observer->selectAssertionResponses(m_assertionResponses, [this, weakThis = makeWeakPtr(*this)] (const Ref<AuthenticatorAssertionResponse>& response) {
     135                ASSERT(RunLoop::isMain());
     136                if (!weakThis)
     137                    return;
     138                auto returnResponse = m_assertionResponses.take(response);
     139                if (!returnResponse)
     140                    return;
     141                receiveRespond(WTFMove(*returnResponse));
     142            });
     143        }
     144        return;
     145    }
     146
     147    driver().transact(encodeEmptyAuthenticatorRequest(CtapRequestCommand::kAuthenticatorGetNextAssertion), [weakThis = makeWeakPtr(*this)](Vector<uint8_t>&& data) {
     148        ASSERT(RunLoop::isMain());
     149        if (!weakThis)
     150            return;
     151        weakThis->continueGetNextAssertionAfterResponseReceived(WTFMove(data));
     152    });
    104153}
    105154
  • trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h

    r251295 r254356  
    4949    void getAssertion() final;
    5050    void continueGetAssertionAfterResponseReceived(Vector<uint8_t>&&);
     51    void continueGetNextAssertionAfterResponseReceived(Vector<uint8_t>&&);
    5152
    5253    bool tryDowngrade();
     
    5556    fido::AuthenticatorGetInfoResponse m_info;
    5657    bool m_isDowngraded { false };
     58    size_t m_remainingAssertionResponses { 0 };
     59    HashSet<Ref<WebCore::AuthenticatorAssertionResponse>> m_assertionResponses;
    5760};
    5861
  • trunk/Tools/ChangeLog

    r254346 r254356  
     12020-01-10  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Support authenticatorGetNextAssertion
     4        https://bugs.webkit.org/show_bug.cgi?id=203346
     5        <rdar://problem/56558488>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp:
     10        (TestWebKitAPI::TEST):
     11        * TestWebKitAPI/Tests/WebCore/FidoTestData.h:
     12        Adds new test case for new logic in DeviceResponseConverter.
     13
    1142020-01-10  Jonathan Bedard  <jbedard@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/CtapResponseTest.cpp

    r253398 r254356  
    400400// Leveraging example 5 of section 6.1 of the CTAP spec.
    401401// https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
    402 TEST(CTAPResponseTest, TestReadGetAssertionResponse)
    403 {
    404     auto getAssertionResponse = readCTAPGetAssertionResponse(convertBytesToVector(TestData::kDeviceGetAssertionResponse, sizeof(TestData::kDeviceGetAssertionResponse)));
     402TEST(CTAPResponseTest, TestReadGetAssertionResponse1)
     403{
     404    auto getAssertionResponse = readCTAPGetAssertionResponse(convertBytesToVector(TestData::kDeviceGetAssertionResponseShort, sizeof(TestData::kDeviceGetAssertionResponseShort)));
    405405    ASSERT_TRUE(getAssertionResponse);
    406406
     
    409409    EXPECT_EQ(getAssertionResponse->signature()->byteLength(), sizeof(TestData::kCtap2GetAssertionSignature));
    410410    EXPECT_EQ(memcmp(getAssertionResponse->signature()->data(), TestData::kCtap2GetAssertionSignature, sizeof(TestData::kCtap2GetAssertionSignature)), 0);
     411}
     412
     413TEST(CTAPResponseTest, TestReadGetAssertionResponse2)
     414{
     415    auto getAssertionResponse = readCTAPGetAssertionResponse(convertBytesToVector(TestData::kDeviceGetAssertionResponse, sizeof(TestData::kDeviceGetAssertionResponse)));
     416    ASSERT_TRUE(getAssertionResponse);
     417
     418    EXPECT_EQ(getAssertionResponse->authenticatorData()->byteLength(), sizeof(TestData::kCtap2GetAssertionAuthData));
     419    EXPECT_EQ(memcmp(getAssertionResponse->authenticatorData()->data(), TestData::kCtap2GetAssertionAuthData, sizeof(TestData::kCtap2GetAssertionAuthData)), 0);
     420    EXPECT_EQ(getAssertionResponse->signature()->byteLength(), sizeof(TestData::kCtap2GetAssertionSignature));
     421    EXPECT_EQ(memcmp(getAssertionResponse->signature()->data(), TestData::kCtap2GetAssertionSignature, sizeof(TestData::kCtap2GetAssertionSignature)), 0);
     422    EXPECT_EQ(getAssertionResponse->userHandle()->byteLength(), sizeof(TestData::kCtap2GetAssertionUserHandle));
     423    EXPECT_EQ(memcmp(getAssertionResponse->userHandle()->data(), TestData::kCtap2GetAssertionUserHandle, sizeof(TestData::kCtap2GetAssertionUserHandle)), 0);
     424}
     425
     426TEST(CTAPResponseTest, TestReadGetAssertionResponse3)
     427{
     428    auto getAssertionResponse = readCTAPGetAssertionResponse(convertBytesToVector(TestData::kDeviceGetAssertionResponseLong, sizeof(TestData::kDeviceGetAssertionResponseLong)));
     429    ASSERT_TRUE(getAssertionResponse);
     430
     431    EXPECT_EQ(getAssertionResponse->authenticatorData()->byteLength(), sizeof(TestData::kCtap2GetAssertionAuthData));
     432    EXPECT_EQ(memcmp(getAssertionResponse->authenticatorData()->data(), TestData::kCtap2GetAssertionAuthData, sizeof(TestData::kCtap2GetAssertionAuthData)), 0);
     433    EXPECT_EQ(getAssertionResponse->signature()->byteLength(), sizeof(TestData::kCtap2GetAssertionSignature));
     434    EXPECT_EQ(memcmp(getAssertionResponse->signature()->data(), TestData::kCtap2GetAssertionSignature, sizeof(TestData::kCtap2GetAssertionSignature)), 0);
     435    EXPECT_EQ(getAssertionResponse->userHandle()->byteLength(), sizeof(TestData::kCtap2GetAssertionUserHandle));
     436    EXPECT_EQ(memcmp(getAssertionResponse->userHandle()->data(), TestData::kCtap2GetAssertionUserHandle, sizeof(TestData::kCtap2GetAssertionUserHandle)), 0);
     437    EXPECT_STREQ(getAssertionResponse->name().utf8().data(), "johnpsmith@example.com");
     438    EXPECT_STREQ(getAssertionResponse->displayName().utf8().data(), "John P. Smith");
     439    EXPECT_EQ(getAssertionResponse->numberOfCredentials(), 1u);
    411440}
    412441
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoTestData.h

    r253811 r254356  
    961961};
    962962
     963constexpr uint8_t kCtap2GetAssertionUserHandle[] = {
     964    0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02, 0x01,
     965    0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02,
     966    0x01, 0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82,
     967};
     968
     969constexpr uint8_t kDeviceGetAssertionResponseShort[] = {
     970    // Success response code
     971    0x00,
     972    // map(3)
     973    0xa3,
     974    // unsigned(1) - Credential
     975    0x01,
     976    // map(2)
     977    0xa2,
     978    // text(2)
     979    0x62,
     980    // "id"
     981    0x69, 0x64,
     982    // bytes(64)
     983    0x58, 0x40,
     984    // credential id
     985    0xf2, 0x20, 0x06, 0xde, 0x4f, 0x90, 0x5a, 0xf6, 0x8a, 0x43, 0x94, 0x2f,
     986    0x02, 0x4f, 0x2a, 0x5e, 0xce, 0x60, 0x3d, 0x9c, 0x6d, 0x4b, 0x3d, 0xf8,
     987    0xbe, 0x08, 0xed, 0x01, 0xfc, 0x44, 0x26, 0x46, 0xd0, 0x34, 0x85, 0x8a,
     988    0xc7, 0x5b, 0xed, 0x3f, 0xd5, 0x80, 0xbf, 0x98, 0x08, 0xd9, 0x4f, 0xcb,
     989    0xee, 0x82, 0xb9, 0xb2, 0xef, 0x66, 0x77, 0xaf, 0x0a, 0xdc, 0xc3, 0x58,
     990    0x52, 0xea, 0x6b, 0x9e,
     991    // text(4)
     992    0x64,
     993    // "type"
     994    0x74, 0x79, 0x70, 0x65,
     995    // text(10)
     996    0x6a,
     997    // "public-key"
     998    0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79,
     999    // unsigned(2) - Auth data
     1000    0x02,
     1001    // bytes(37)
     1002    0x58, 0x25,
     1003    // auth data
     1004    0x62, 0x5d, 0xda, 0xdf, 0x74, 0x3f, 0x57, 0x27, 0xe6, 0x6b, 0xba, 0x8c,
     1005    0x2e, 0x38, 0x79, 0x22, 0xd1, 0xaf, 0x43, 0xc5, 0x03, 0xd9, 0x11, 0x4a,
     1006    0x8f, 0xba, 0x10, 0x4d, 0x84, 0xd0, 0x2b, 0xfa, 0x01, 0x00, 0x00, 0x00,
     1007    0x11,
     1008    // unsigned(3) - signature
     1009    0x03,
     1010    // bytes(71)
     1011    0x58, 0x47,
     1012    // signature
     1013    0x30, 0x45, 0x02, 0x20, 0x4a, 0x5a, 0x9d, 0xd3, 0x92, 0x98, 0x14, 0x9d,
     1014    0x90, 0x47, 0x69, 0xb5, 0x1a, 0x45, 0x14, 0x33, 0x00, 0x6f, 0x18, 0x2a,
     1015    0x34, 0xfb, 0xdf, 0x66, 0xde, 0x5f, 0xc7, 0x17, 0xd7, 0x5f, 0xb3, 0x50,
     1016    0x02, 0x21, 0x00, 0xa4, 0x6b, 0x8e, 0xa3, 0xc3, 0xb9, 0x33, 0x82, 0x1c,
     1017    0x6e, 0x7f, 0x5e, 0xf9, 0xda, 0xae, 0x94, 0xab, 0x47, 0xf1, 0x8d, 0xb4,
     1018    0x74, 0xc7, 0x47, 0x90, 0xea, 0xab, 0xb1, 0x44, 0x11, 0xe7, 0xa0,
     1019};
     1020
    9631021constexpr uint8_t kDeviceGetAssertionResponse[] = {
     1022    // Success response code
     1023    0x00,
     1024    // map(4)
     1025    0xa4,
     1026    // unsigned(1) - Credential
     1027    0x01,
     1028    // map(2)
     1029    0xa2,
     1030    // text(2)
     1031    0x62,
     1032    // "id"
     1033    0x69, 0x64,
     1034    // bytes(64)
     1035    0x58, 0x40,
     1036    // credential id
     1037    0xf2, 0x20, 0x06, 0xde, 0x4f, 0x90, 0x5a, 0xf6, 0x8a, 0x43, 0x94, 0x2f,
     1038    0x02, 0x4f, 0x2a, 0x5e, 0xce, 0x60, 0x3d, 0x9c, 0x6d, 0x4b, 0x3d, 0xf8,
     1039    0xbe, 0x08, 0xed, 0x01, 0xfc, 0x44, 0x26, 0x46, 0xd0, 0x34, 0x85, 0x8a,
     1040    0xc7, 0x5b, 0xed, 0x3f, 0xd5, 0x80, 0xbf, 0x98, 0x08, 0xd9, 0x4f, 0xcb,
     1041    0xee, 0x82, 0xb9, 0xb2, 0xef, 0x66, 0x77, 0xaf, 0x0a, 0xdc, 0xc3, 0x58,
     1042    0x52, 0xea, 0x6b, 0x9e,
     1043    // text(4)
     1044    0x64,
     1045    // "type"
     1046    0x74, 0x79, 0x70, 0x65,
     1047    // text(10)
     1048    0x6a,
     1049    // "public-key"
     1050    0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79,
     1051    // unsigned(2) - Auth data
     1052    0x02,
     1053    // bytes(37)
     1054    0x58, 0x25,
     1055    // auth data
     1056    0x62, 0x5d, 0xda, 0xdf, 0x74, 0x3f, 0x57, 0x27, 0xe6, 0x6b, 0xba, 0x8c,
     1057    0x2e, 0x38, 0x79, 0x22, 0xd1, 0xaf, 0x43, 0xc5, 0x03, 0xd9, 0x11, 0x4a,
     1058    0x8f, 0xba, 0x10, 0x4d, 0x84, 0xd0, 0x2b, 0xfa, 0x01, 0x00, 0x00, 0x00,
     1059    0x11,
     1060    // unsigned(3) - signature
     1061    0x03,
     1062    // bytes(71)
     1063    0x58, 0x47,
     1064    // signature
     1065    0x30, 0x45, 0x02, 0x20, 0x4a, 0x5a, 0x9d, 0xd3, 0x92, 0x98, 0x14, 0x9d,
     1066    0x90, 0x47, 0x69, 0xb5, 0x1a, 0x45, 0x14, 0x33, 0x00, 0x6f, 0x18, 0x2a,
     1067    0x34, 0xfb, 0xdf, 0x66, 0xde, 0x5f, 0xc7, 0x17, 0xd7, 0x5f, 0xb3, 0x50,
     1068    0x02, 0x21, 0x00, 0xa4, 0x6b, 0x8e, 0xa3, 0xc3, 0xb9, 0x33, 0x82, 0x1c,
     1069    0x6e, 0x7f, 0x5e, 0xf9, 0xda, 0xae, 0x94, 0xab, 0x47, 0xf1, 0x8d, 0xb4,
     1070    0x74, 0xc7, 0x47, 0x90, 0xea, 0xab, 0xb1, 0x44, 0x11, 0xe7, 0xa0,
     1071    // unsigned(4) - publicKeyCredentialUserEntity
     1072    0x04,
     1073    // map(1)
     1074    0xa1,
     1075    // text(2)
     1076    0x62,
     1077    // "id"
     1078    0x69, 0x64,
     1079    // bytes(32) - user id
     1080    0x58, 0x20,
     1081    // user id
     1082    0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02, 0x01,
     1083    0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02,
     1084    0x01, 0x02, 0x30, 0x82, 0x01, 0x93, 0x30, 0x82,
     1085};
     1086
     1087constexpr uint8_t kDeviceGetAssertionResponseLong[] = {
    9641088    // Success response code
    9651089    0x00,
Note: See TracChangeset for help on using the changeset viewer.