| Index: third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
|
| diff --git a/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp b/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
|
| index 4ef1510f076777d7cb43ee2cc716734ad4cdb3d8..421a0fc1ad5d781637f595776988a9f11bf48a1e 100644
|
| --- a/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
|
| +++ b/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
|
| @@ -4,38 +4,37 @@
|
|
|
| #include "modules/webauth/WebAuthentication.h"
|
|
|
| -#include <stdint.h>
|
| -
|
| +#include "bindings/core/v8/ArrayBufferOrArrayBufferView.h"
|
| #include "bindings/core/v8/ScriptPromise.h"
|
| #include "bindings/core/v8/ScriptPromiseResolver.h"
|
| +#include "core/dom/DOMArrayBuffer.h"
|
| #include "core/dom/DOMException.h"
|
| #include "core/dom/Document.h"
|
| #include "core/dom/ExceptionCode.h"
|
| #include "core/frame/LocalFrame.h"
|
| -#include "modules/webauth/RelyingPartyAccount.h"
|
| -#include "modules/webauth/ScopedCredential.h"
|
| -#include "modules/webauth/ScopedCredentialOptions.h"
|
| -#include "modules/webauth/ScopedCredentialParameters.h"
|
| +#include "modules/webauth/AuthenticatorAttestationResponse.h"
|
| +#include "modules/webauth/MakeCredentialOptions.h"
|
| +#include "public/platform/InterfaceProvider.h"
|
| #include "services/service_manager/public/cpp/interface_provider.h"
|
|
|
| +namespace blink {
|
| +typedef ArrayBufferOrArrayBufferView BufferSource;
|
| +} // namespace blink
|
| +
|
| namespace {
|
| -const char kNoAuthenticatorError[] = "Authenticator unavailable.";
|
| +constexpr char kNoAuthenticatorError[] = "Authenticator unavailable.";
|
| // Time to wait for an authenticator to successfully complete an operation.
|
| -const int kAdjustedTimeoutLowerInSeconds = 60;
|
| -const int kAdjustedTimeoutUpperInSeconds = 120;
|
| +constexpr WTF::TimeDelta kAdjustedTimeoutLower = WTF::TimeDelta::FromMinutes(1);
|
| +constexpr WTF::TimeDelta kAdjustedTimeoutUpper = WTF::TimeDelta::FromMinutes(2);
|
| } // anonymous namespace
|
|
|
| namespace mojo {
|
| -using webauth::mojom::blink::RelyingPartyAccount;
|
| -using webauth::mojom::blink::RelyingPartyAccountPtr;
|
| using webauth::mojom::blink::AuthenticatorStatus;
|
| -using webauth::mojom::blink::ScopedCredentialDescriptor;
|
| -using webauth::mojom::blink::ScopedCredentialOptions;
|
| -using webauth::mojom::blink::ScopedCredentialOptionsPtr;
|
| -using webauth::mojom::blink::ScopedCredentialParameters;
|
| -using webauth::mojom::blink::ScopedCredentialParametersPtr;
|
| -using webauth::mojom::blink::ScopedCredentialType;
|
| -using webauth::mojom::blink::Transport;
|
| +using webauth::mojom::blink::MakeCredentialOptionsPtr;
|
| +using webauth::mojom::blink::PublicKeyCredentialEntityPtr;
|
| +using webauth::mojom::blink::PublicKeyCredentialParametersPtr;
|
| +using webauth::mojom::blink::PublicKeyCredentialType;
|
| +using webauth::mojom::blink::AuthenticatorTransport;
|
|
|
| // TODO(kpaulhamus): Make this a TypeConverter
|
| Vector<uint8_t> ConvertBufferSource(const blink::BufferSource& buffer) {
|
| @@ -45,6 +44,7 @@ Vector<uint8_t> ConvertBufferSource(const blink::BufferSource& buffer) {
|
| vector.Append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->Data()),
|
| buffer.getAsArrayBuffer()->ByteLength());
|
| } else {
|
| + DCHECK(buffer.isArrayBufferView());
|
| vector.Append(static_cast<uint8_t*>(
|
| buffer.getAsArrayBufferView().View()->BaseAddress()),
|
| buffer.getAsArrayBufferView().View()->byteLength());
|
| @@ -53,86 +53,101 @@ Vector<uint8_t> ConvertBufferSource(const blink::BufferSource& buffer) {
|
| }
|
|
|
| // TODO(kpaulhamus): Make this a TypeConverter
|
| -ScopedCredentialType ConvertScopedCredentialType(const String& cred_type) {
|
| - if (cred_type == "ScopedCred")
|
| - return ScopedCredentialType::SCOPEDCRED;
|
| +PublicKeyCredentialType ConvertPublicKeyCredentialType(const String& type) {
|
| + if (type == "public-key")
|
| + return PublicKeyCredentialType::PUBLIC_KEY;
|
| NOTREACHED();
|
| - return ScopedCredentialType::SCOPEDCRED;
|
| + return PublicKeyCredentialType::PUBLIC_KEY;
|
| }
|
|
|
| // TODO(kpaulhamus): Make this a TypeConverter
|
| -Transport ConvertTransport(const String& transport) {
|
| +AuthenticatorTransport ConvertTransport(const String& transport) {
|
| if (transport == "usb")
|
| - return Transport::USB;
|
| + return AuthenticatorTransport::USB;
|
| if (transport == "nfc")
|
| - return Transport::NFC;
|
| + return AuthenticatorTransport::NFC;
|
| if (transport == "ble")
|
| - return Transport::BLE;
|
| + return AuthenticatorTransport::BLE;
|
| NOTREACHED();
|
| - return Transport::USB;
|
| + return AuthenticatorTransport::USB;
|
| }
|
|
|
| // TODO(kpaulhamus): Make this a TypeConverter
|
| -RelyingPartyAccountPtr ConvertRelyingPartyAccount(
|
| - const blink::RelyingPartyAccount& account_information,
|
| - blink::ScriptPromiseResolver* resolver) {
|
| - auto mojo_account = RelyingPartyAccount::New();
|
| -
|
| - mojo_account->relying_party_display_name =
|
| - account_information.rpDisplayName();
|
| - mojo_account->display_name = account_information.displayName();
|
| - mojo_account->id = account_information.id();
|
| - mojo_account->name = account_information.name();
|
| - mojo_account->image_url = account_information.imageURL();
|
| - return mojo_account;
|
| +PublicKeyCredentialEntityPtr ConvertPublicKeyCredentialUserEntity(
|
| + const blink::PublicKeyCredentialUserEntity& user) {
|
| + auto entity = webauth::mojom::blink::PublicKeyCredentialEntity::New();
|
| + entity->id = user.id();
|
| + entity->name = user.name();
|
| + if (user.hasIcon()) {
|
| + entity->icon = blink::KURL(blink::KURL(), user.icon());
|
| + }
|
| + entity->display_name = user.displayName();
|
| + return entity;
|
| +}
|
| +
|
| +// TODO(kpaulhamus): Make this a TypeConverter
|
| +PublicKeyCredentialEntityPtr ConvertPublicKeyCredentialEntity(
|
| + const blink::PublicKeyCredentialEntity& rp) {
|
| + auto entity = webauth::mojom::blink::PublicKeyCredentialEntity::New();
|
| + entity->id = rp.id();
|
| + entity->name = rp.name();
|
| + if (rp.hasIcon()) {
|
| + entity->icon = blink::KURL(blink::KURL(), rp.icon());
|
| + }
|
| + return entity;
|
| +}
|
| +
|
| +// TODO(kpaulhamus): Make this a TypeConverter
|
| +PublicKeyCredentialParametersPtr ConvertPublicKeyCredentialParameters(
|
| + const blink::PublicKeyCredentialParameters parameter) {
|
| + auto mojo_parameter =
|
| + webauth::mojom::blink::PublicKeyCredentialParameters::New();
|
| + mojo_parameter->type = ConvertPublicKeyCredentialType(parameter.type());
|
| + // TODO(kpaulhamus): add AlgorithmIdentifier
|
| + return mojo_parameter;
|
| }
|
|
|
| // TODO(kpaulhamus): Make this a TypeConverter
|
| -ScopedCredentialOptionsPtr ConvertScopedCredentialOptions(
|
| - const blink::ScopedCredentialOptions options,
|
| - blink::ScriptPromiseResolver* resolver) {
|
| - auto mojo_options = ScopedCredentialOptions::New();
|
| - if (options.hasRpId()) {
|
| - // if rpID is missing, it will later be set to the origin of the page
|
| - // in the secure browser process.
|
| - mojo_options->relying_party_id = options.rpId();
|
| +MakeCredentialOptionsPtr ConvertMakeCredentialOptions(
|
| + const blink::MakeCredentialOptions options) {
|
| + auto mojo_options = webauth::mojom::blink::MakeCredentialOptions::New();
|
| + mojo_options->relying_party = ConvertPublicKeyCredentialEntity(options.rp());
|
| + mojo_options->user = ConvertPublicKeyCredentialUserEntity(options.user());
|
| + mojo_options->challenge = ConvertBufferSource(options.challenge());
|
| +
|
| + Vector<webauth::mojom::blink::PublicKeyCredentialParametersPtr> parameters;
|
| + for (const auto& parameter : options.parameters()) {
|
| + parameters.push_back(ConvertPublicKeyCredentialParameters(parameter));
|
| }
|
| + mojo_options->crypto_parameters = std::move(parameters);
|
|
|
| // Step 4 of https://w3c.github.io/webauthn/#createCredential
|
| - int predicted_timeout = kAdjustedTimeoutLowerInSeconds;
|
| - if (options.hasTimeoutSeconds()) {
|
| - predicted_timeout = static_cast<int>(options.timeoutSeconds());
|
| + WTF::TimeDelta adjusted_timeout;
|
| + if (options.hasTimeout()) {
|
| + adjusted_timeout = WTF::TimeDelta::FromMilliseconds(options.timeout());
|
| + } else {
|
| + adjusted_timeout = kAdjustedTimeoutLower;
|
| }
|
|
|
| - mojo_options->adjusted_timeout = static_cast<double>(
|
| - std::max(kAdjustedTimeoutLowerInSeconds,
|
| - std::min(kAdjustedTimeoutUpperInSeconds, predicted_timeout)));
|
| + mojo_options->adjusted_timeout = std::max(
|
| + kAdjustedTimeoutLower, std::min(kAdjustedTimeoutUpper, adjusted_timeout));
|
|
|
| - if (options.hasExcludeList()) {
|
| - // Adds the excludeList members (which are ScopedCredentialDescriptors)
|
| - for (const auto& descriptor : options.excludeList()) {
|
| - auto mojo_descriptor = ScopedCredentialDescriptor::New();
|
| - mojo_descriptor->type = ConvertScopedCredentialType(descriptor.type());
|
| + if (options.hasExcludeCredentials()) {
|
| + // Adds the excludeCredentials members
|
| + // (which are PublicKeyCredentialDescriptors)
|
| + for (const auto& descriptor : options.excludeCredentials()) {
|
| + auto mojo_descriptor =
|
| + webauth::mojom::blink::PublicKeyCredentialDescriptor::New();
|
| + mojo_descriptor->type = ConvertPublicKeyCredentialType(descriptor.type());
|
| mojo_descriptor->id = ConvertBufferSource(descriptor.id());
|
| for (const auto& transport : descriptor.transports())
|
| mojo_descriptor->transports.push_back(ConvertTransport(transport));
|
| - mojo_options->exclude_list.push_back(std::move(mojo_descriptor));
|
| + mojo_options->exclude_credentials.push_back(std::move(mojo_descriptor));
|
| }
|
| }
|
| - // TODO(kpaulhamus): add AuthenticationExtensions;
|
| return mojo_options;
|
| }
|
|
|
| -// TODO(kpaulhamus): Make this a TypeConverter
|
| -ScopedCredentialParametersPtr ConvertScopedCredentialParameter(
|
| - const blink::ScopedCredentialParameters parameter,
|
| - blink::ScriptPromiseResolver* resolver) {
|
| - auto mojo_parameter = ScopedCredentialParameters::New();
|
| - mojo_parameter->type = ConvertScopedCredentialType(parameter.type());
|
| - // TODO(kpaulhamus): add AlgorithmIdentifier
|
| - return mojo_parameter;
|
| -}
|
| -
|
| blink::DOMException* CreateExceptionFromStatus(AuthenticatorStatus status) {
|
| switch (status) {
|
| case AuthenticatorStatus::NOT_IMPLEMENTED:
|
| @@ -161,11 +176,18 @@ blink::DOMException* CreateExceptionFromStatus(AuthenticatorStatus status) {
|
| return nullptr;
|
| }
|
| }
|
| +
|
| } // namespace mojo
|
|
|
| namespace blink {
|
| +
|
| WebAuthentication::WebAuthentication(LocalFrame& frame)
|
| - : ContextLifecycleObserver(frame.GetDocument()) {}
|
| + : ContextLifecycleObserver(frame.GetDocument()) {
|
| + frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&authenticator_));
|
| + authenticator_.set_connection_error_handler(ConvertToBaseCallback(
|
| + WTF::Bind(&WebAuthentication::OnAuthenticatorConnectionError,
|
| + WrapWeakPersistent(this))));
|
| +}
|
|
|
| WebAuthentication::~WebAuthentication() {
|
| // |authenticator_| may still be valid but there should be no more
|
| @@ -175,40 +197,25 @@ WebAuthentication::~WebAuthentication() {
|
|
|
| ScriptPromise WebAuthentication::makeCredential(
|
| ScriptState* script_state,
|
| - const RelyingPartyAccount& account_information,
|
| - const HeapVector<ScopedCredentialParameters> crypto_parameters,
|
| - const BufferSource& attestation_challenge,
|
| - ScopedCredentialOptions& options) {
|
| + const MakeCredentialOptions& publicKey) {
|
| ScriptPromise promise = RejectIfNotSupported(script_state);
|
| if (!promise.IsEmpty())
|
| return promise;
|
|
|
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
|
|
|
| - Vector<uint8_t> buffer = mojo::ConvertBufferSource(attestation_challenge);
|
| - auto opts = mojo::ConvertScopedCredentialOptions(options, resolver);
|
| - Vector<webauth::mojom::blink::ScopedCredentialParametersPtr> parameters;
|
| - for (const auto& parameter : crypto_parameters) {
|
| - if (parameter.hasType()) {
|
| - parameters.push_back(
|
| - mojo::ConvertScopedCredentialParameter(parameter, resolver));
|
| - }
|
| - }
|
| - auto account =
|
| - mojo::ConvertRelyingPartyAccount(account_information, resolver);
|
| + auto options = mojo::ConvertMakeCredentialOptions(publicKey);
|
| authenticator_requests_.insert(resolver);
|
| authenticator_->MakeCredential(
|
| - std::move(account), std::move(parameters), buffer, std::move(opts),
|
| - ConvertToBaseCallback(WTF::Bind(&WebAuthentication::OnMakeCredential,
|
| - WrapPersistent(this),
|
| - WrapPersistent(resolver))));
|
| + std::move(options), ConvertToBaseCallback(WTF::Bind(
|
| + &WebAuthentication::OnMakeCredential,
|
| + WrapPersistent(this), WrapPersistent(resolver))));
|
| return resolver->Promise();
|
| }
|
|
|
| ScriptPromise WebAuthentication::getAssertion(
|
| ScriptState* script_state,
|
| - const BufferSource& assertion_challenge,
|
| - const AuthenticationAssertionOptions& options) {
|
| + const PublicKeyCredentialRequestOptions& publicKey) {
|
| NOTREACHED();
|
| return ScriptPromise();
|
| }
|
| @@ -220,7 +227,7 @@ void WebAuthentication::ContextDestroyed(ExecutionContext*) {
|
| void WebAuthentication::OnMakeCredential(
|
| ScriptPromiseResolver* resolver,
|
| webauth::mojom::blink::AuthenticatorStatus status,
|
| - webauth::mojom::blink::ScopedCredentialInfoPtr credential) {
|
| + webauth::mojom::blink::PublicKeyCredentialInfoPtr credential) {
|
| if (!MarkRequestComplete(resolver))
|
| return;
|
|
|
| @@ -232,33 +239,37 @@ void WebAuthentication::OnMakeCredential(
|
| return;
|
| }
|
|
|
| - if (credential->client_data.IsEmpty() || credential->attestation.IsEmpty()) {
|
| + if (credential->client_data_json.IsEmpty() ||
|
| + credential->response->attestation_object.IsEmpty()) {
|
| resolver->Reject(
|
| - DOMException::Create(kNotFoundError, "No credential returned."));
|
| - return;
|
| + DOMException::Create(kNotFoundError, "No credentials returned."));
|
| }
|
|
|
| - DOMArrayBuffer* clientDataBuffer = DOMArrayBuffer::Create(
|
| - static_cast<void*>(&credential->client_data.front()),
|
| - credential->client_data.size());
|
| + DOMArrayBuffer* client_data_buffer = DOMArrayBuffer::Create(
|
| + static_cast<void*>(&credential->client_data_json.front()),
|
| + credential->client_data_json.size());
|
|
|
| - DOMArrayBuffer* attestationBuffer = DOMArrayBuffer::Create(
|
| - static_cast<void*>(&credential->attestation.front()),
|
| - credential->attestation.size());
|
| + // Return AuthenticatorAttestationResponse
|
| + DOMArrayBuffer* attestation_buffer = DOMArrayBuffer::Create(
|
| + static_cast<void*>(&credential->response->attestation_object.front()),
|
| + credential->response->attestation_object.size());
|
|
|
| - ScopedCredentialInfo* scopedCredential =
|
| - ScopedCredentialInfo::Create(clientDataBuffer, attestationBuffer);
|
| - resolver->Resolve(scopedCredential);
|
| + AuthenticatorAttestationResponse* attestation_response =
|
| + AuthenticatorAttestationResponse::Create(client_data_buffer,
|
| + attestation_buffer);
|
| + resolver->Resolve(attestation_response);
|
| }
|
|
|
| ScriptPromise WebAuthentication::RejectIfNotSupported(
|
| ScriptState* script_state) {
|
| + LocalFrame* frame =
|
| + ToDocument(ExecutionContext::From(script_state))->GetFrame();
|
| if (!authenticator_) {
|
| - if (!GetFrame()) {
|
| + if (!frame) {
|
| return ScriptPromise::RejectWithDOMException(
|
| script_state, DOMException::Create(kNotSupportedError));
|
| }
|
| - GetFrame()->GetInterfaceProvider().GetInterface(
|
| + frame->GetInterfaceProvider().GetInterface(
|
| mojo::MakeRequest(&authenticator_));
|
|
|
| authenticator_.set_connection_error_handler(ConvertToBaseCallback(
|
|
|