| 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(
 | 
| 
 |