| OLD | NEW | 
|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "modules/webauth/WebAuthentication.h" | 5 #include "modules/webauth/WebAuthentication.h" | 
| 6 | 6 | 
| 7 #include <stdint.h> | 7 #include "bindings/core/v8/ArrayBufferOrArrayBufferView.h" | 
| 8 |  | 
| 9 #include "bindings/core/v8/ScriptPromise.h" | 8 #include "bindings/core/v8/ScriptPromise.h" | 
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 
|  | 10 #include "core/dom/DOMArrayBuffer.h" | 
| 11 #include "core/dom/DOMException.h" | 11 #include "core/dom/DOMException.h" | 
| 12 #include "core/dom/Document.h" | 12 #include "core/dom/Document.h" | 
| 13 #include "core/dom/ExceptionCode.h" | 13 #include "core/dom/ExceptionCode.h" | 
| 14 #include "core/frame/LocalFrame.h" | 14 #include "core/frame/LocalFrame.h" | 
| 15 #include "modules/webauth/RelyingPartyAccount.h" | 15 #include "modules/webauth/AuthenticatorAttestationResponse.h" | 
| 16 #include "modules/webauth/ScopedCredential.h" | 16 #include "modules/webauth/MakeCredentialOptions.h" | 
| 17 #include "modules/webauth/ScopedCredentialOptions.h" | 17 #include "public/platform/InterfaceProvider.h" | 
| 18 #include "modules/webauth/ScopedCredentialParameters.h" |  | 
| 19 #include "services/service_manager/public/cpp/interface_provider.h" | 18 #include "services/service_manager/public/cpp/interface_provider.h" | 
| 20 | 19 | 
|  | 20 namespace blink { | 
|  | 21 typedef ArrayBufferOrArrayBufferView BufferSource; | 
|  | 22 }  // namespace blink | 
|  | 23 | 
| 21 namespace { | 24 namespace { | 
| 22 const char kNoAuthenticatorError[] = "Authenticator unavailable."; | 25 constexpr char kNoAuthenticatorError[] = "Authenticator unavailable."; | 
| 23 // Time to wait for an authenticator to successfully complete an operation. | 26 // Time to wait for an authenticator to successfully complete an operation. | 
| 24 const int kAdjustedTimeoutLowerInSeconds = 60; | 27 constexpr WTF::TimeDelta kAdjustedTimeoutLower = WTF::TimeDelta::FromMinutes(1); | 
| 25 const int kAdjustedTimeoutUpperInSeconds = 120; | 28 constexpr WTF::TimeDelta kAdjustedTimeoutUpper = WTF::TimeDelta::FromMinutes(2); | 
| 26 }  // anonymous namespace | 29 }  // anonymous namespace | 
| 27 | 30 | 
| 28 namespace mojo { | 31 namespace mojo { | 
| 29 using webauth::mojom::blink::RelyingPartyAccount; |  | 
| 30 using webauth::mojom::blink::RelyingPartyAccountPtr; |  | 
| 31 using webauth::mojom::blink::AuthenticatorStatus; | 32 using webauth::mojom::blink::AuthenticatorStatus; | 
| 32 using webauth::mojom::blink::ScopedCredentialDescriptor; | 33 using webauth::mojom::blink::MakeCredentialOptionsPtr; | 
| 33 using webauth::mojom::blink::ScopedCredentialOptions; | 34 using webauth::mojom::blink::PublicKeyCredentialEntityPtr; | 
| 34 using webauth::mojom::blink::ScopedCredentialOptionsPtr; | 35 using webauth::mojom::blink::PublicKeyCredentialParametersPtr; | 
| 35 using webauth::mojom::blink::ScopedCredentialParameters; | 36 using webauth::mojom::blink::PublicKeyCredentialType; | 
| 36 using webauth::mojom::blink::ScopedCredentialParametersPtr; | 37 using webauth::mojom::blink::AuthenticatorTransport; | 
| 37 using webauth::mojom::blink::ScopedCredentialType; |  | 
| 38 using webauth::mojom::blink::Transport; |  | 
| 39 | 38 | 
| 40 // TODO(kpaulhamus): Make this a TypeConverter | 39 // TODO(kpaulhamus): Make this a TypeConverter | 
| 41 Vector<uint8_t> ConvertBufferSource(const blink::BufferSource& buffer) { | 40 Vector<uint8_t> ConvertBufferSource(const blink::BufferSource& buffer) { | 
| 42   DCHECK(!buffer.isNull()); | 41   DCHECK(!buffer.isNull()); | 
| 43   Vector<uint8_t> vector; | 42   Vector<uint8_t> vector; | 
| 44   if (buffer.isArrayBuffer()) { | 43   if (buffer.isArrayBuffer()) { | 
| 45     vector.Append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->Data()), | 44     vector.Append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->Data()), | 
| 46                   buffer.getAsArrayBuffer()->ByteLength()); | 45                   buffer.getAsArrayBuffer()->ByteLength()); | 
| 47   } else { | 46   } else { | 
|  | 47     DCHECK(buffer.isArrayBufferView()); | 
| 48     vector.Append(static_cast<uint8_t*>( | 48     vector.Append(static_cast<uint8_t*>( | 
| 49                       buffer.getAsArrayBufferView().View()->BaseAddress()), | 49                       buffer.getAsArrayBufferView().View()->BaseAddress()), | 
| 50                   buffer.getAsArrayBufferView().View()->byteLength()); | 50                   buffer.getAsArrayBufferView().View()->byteLength()); | 
| 51   } | 51   } | 
| 52   return vector; | 52   return vector; | 
| 53 } | 53 } | 
| 54 | 54 | 
| 55 // TODO(kpaulhamus): Make this a TypeConverter | 55 // TODO(kpaulhamus): Make this a TypeConverter | 
| 56 ScopedCredentialType ConvertScopedCredentialType(const String& cred_type) { | 56 PublicKeyCredentialType ConvertPublicKeyCredentialType(const String& type) { | 
| 57   if (cred_type == "ScopedCred") | 57   if (type == "public-key") | 
| 58     return ScopedCredentialType::SCOPEDCRED; | 58     return PublicKeyCredentialType::PUBLIC_KEY; | 
| 59   NOTREACHED(); | 59   NOTREACHED(); | 
| 60   return ScopedCredentialType::SCOPEDCRED; | 60   return PublicKeyCredentialType::PUBLIC_KEY; | 
| 61 } | 61 } | 
| 62 | 62 | 
| 63 // TODO(kpaulhamus): Make this a TypeConverter | 63 // TODO(kpaulhamus): Make this a TypeConverter | 
| 64 Transport ConvertTransport(const String& transport) { | 64 AuthenticatorTransport ConvertTransport(const String& transport) { | 
| 65   if (transport == "usb") | 65   if (transport == "usb") | 
| 66     return Transport::USB; | 66     return AuthenticatorTransport::USB; | 
| 67   if (transport == "nfc") | 67   if (transport == "nfc") | 
| 68     return Transport::NFC; | 68     return AuthenticatorTransport::NFC; | 
| 69   if (transport == "ble") | 69   if (transport == "ble") | 
| 70     return Transport::BLE; | 70     return AuthenticatorTransport::BLE; | 
| 71   NOTREACHED(); | 71   NOTREACHED(); | 
| 72   return Transport::USB; | 72   return AuthenticatorTransport::USB; | 
| 73 } | 73 } | 
| 74 | 74 | 
| 75 // TODO(kpaulhamus): Make this a TypeConverter | 75 // TODO(kpaulhamus): Make this a TypeConverter | 
| 76 RelyingPartyAccountPtr ConvertRelyingPartyAccount( | 76 PublicKeyCredentialEntityPtr ConvertPublicKeyCredentialUserEntity( | 
| 77     const blink::RelyingPartyAccount& account_information, | 77     const blink::PublicKeyCredentialUserEntity& user) { | 
| 78     blink::ScriptPromiseResolver* resolver) { | 78   auto entity = webauth::mojom::blink::PublicKeyCredentialEntity::New(); | 
| 79   auto mojo_account = RelyingPartyAccount::New(); | 79   entity->id = user.id(); | 
| 80 | 80   entity->name = user.name(); | 
| 81   mojo_account->relying_party_display_name = | 81   if (user.hasIcon()) { | 
| 82       account_information.rpDisplayName(); | 82     entity->icon = blink::KURL(blink::KURL(), user.icon()); | 
| 83   mojo_account->display_name = account_information.displayName(); | 83   } | 
| 84   mojo_account->id = account_information.id(); | 84   entity->display_name = user.displayName(); | 
| 85   mojo_account->name = account_information.name(); | 85   return entity; | 
| 86   mojo_account->image_url = account_information.imageURL(); |  | 
| 87   return mojo_account; |  | 
| 88 } | 86 } | 
| 89 | 87 | 
| 90 // TODO(kpaulhamus): Make this a TypeConverter | 88 // TODO(kpaulhamus): Make this a TypeConverter | 
| 91 ScopedCredentialOptionsPtr ConvertScopedCredentialOptions( | 89 PublicKeyCredentialEntityPtr ConvertPublicKeyCredentialEntity( | 
| 92     const blink::ScopedCredentialOptions options, | 90     const blink::PublicKeyCredentialEntity& rp) { | 
| 93     blink::ScriptPromiseResolver* resolver) { | 91   auto entity = webauth::mojom::blink::PublicKeyCredentialEntity::New(); | 
| 94   auto mojo_options = ScopedCredentialOptions::New(); | 92   entity->id = rp.id(); | 
| 95   if (options.hasRpId()) { | 93   entity->name = rp.name(); | 
| 96     // if rpID is missing, it will later be set to the origin of the page | 94   if (rp.hasIcon()) { | 
| 97     // in the secure browser process. | 95     entity->icon = blink::KURL(blink::KURL(), rp.icon()); | 
| 98     mojo_options->relying_party_id = options.rpId(); | 96   } | 
|  | 97   return entity; | 
|  | 98 } | 
|  | 99 | 
|  | 100 // TODO(kpaulhamus): Make this a TypeConverter | 
|  | 101 PublicKeyCredentialParametersPtr ConvertPublicKeyCredentialParameters( | 
|  | 102     const blink::PublicKeyCredentialParameters parameter) { | 
|  | 103   auto mojo_parameter = | 
|  | 104       webauth::mojom::blink::PublicKeyCredentialParameters::New(); | 
|  | 105   mojo_parameter->type = ConvertPublicKeyCredentialType(parameter.type()); | 
|  | 106   // TODO(kpaulhamus): add AlgorithmIdentifier | 
|  | 107   return mojo_parameter; | 
|  | 108 } | 
|  | 109 | 
|  | 110 // TODO(kpaulhamus): Make this a TypeConverter | 
|  | 111 MakeCredentialOptionsPtr ConvertMakeCredentialOptions( | 
|  | 112     const blink::MakeCredentialOptions options) { | 
|  | 113   auto mojo_options = webauth::mojom::blink::MakeCredentialOptions::New(); | 
|  | 114   mojo_options->relying_party = ConvertPublicKeyCredentialEntity(options.rp()); | 
|  | 115   mojo_options->user = ConvertPublicKeyCredentialUserEntity(options.user()); | 
|  | 116   mojo_options->challenge = ConvertBufferSource(options.challenge()); | 
|  | 117 | 
|  | 118   Vector<webauth::mojom::blink::PublicKeyCredentialParametersPtr> parameters; | 
|  | 119   for (const auto& parameter : options.parameters()) { | 
|  | 120     parameters.push_back(ConvertPublicKeyCredentialParameters(parameter)); | 
|  | 121   } | 
|  | 122   mojo_options->crypto_parameters = std::move(parameters); | 
|  | 123 | 
|  | 124   // Step 4 of https://w3c.github.io/webauthn/#createCredential | 
|  | 125   WTF::TimeDelta adjusted_timeout; | 
|  | 126   if (options.hasTimeout()) { | 
|  | 127     adjusted_timeout = WTF::TimeDelta::FromMilliseconds(options.timeout()); | 
|  | 128   } else { | 
|  | 129     adjusted_timeout = kAdjustedTimeoutLower; | 
| 99   } | 130   } | 
| 100 | 131 | 
| 101   // Step 4 of https://w3c.github.io/webauthn/#createCredential | 132   mojo_options->adjusted_timeout = std::max( | 
| 102   int predicted_timeout = kAdjustedTimeoutLowerInSeconds; | 133       kAdjustedTimeoutLower, std::min(kAdjustedTimeoutUpper, adjusted_timeout)); | 
| 103   if (options.hasTimeoutSeconds()) { |  | 
| 104     predicted_timeout = static_cast<int>(options.timeoutSeconds()); |  | 
| 105   } |  | 
| 106 | 134 | 
| 107   mojo_options->adjusted_timeout = static_cast<double>( | 135   if (options.hasExcludeCredentials()) { | 
| 108       std::max(kAdjustedTimeoutLowerInSeconds, | 136     // Adds the excludeCredentials members | 
| 109                std::min(kAdjustedTimeoutUpperInSeconds, predicted_timeout))); | 137     // (which are PublicKeyCredentialDescriptors) | 
| 110 | 138     for (const auto& descriptor : options.excludeCredentials()) { | 
| 111   if (options.hasExcludeList()) { | 139       auto mojo_descriptor = | 
| 112     // Adds the excludeList members (which are ScopedCredentialDescriptors) | 140           webauth::mojom::blink::PublicKeyCredentialDescriptor::New(); | 
| 113     for (const auto& descriptor : options.excludeList()) { | 141       mojo_descriptor->type = ConvertPublicKeyCredentialType(descriptor.type()); | 
| 114       auto mojo_descriptor = ScopedCredentialDescriptor::New(); |  | 
| 115       mojo_descriptor->type = ConvertScopedCredentialType(descriptor.type()); |  | 
| 116       mojo_descriptor->id = ConvertBufferSource(descriptor.id()); | 142       mojo_descriptor->id = ConvertBufferSource(descriptor.id()); | 
| 117       for (const auto& transport : descriptor.transports()) | 143       for (const auto& transport : descriptor.transports()) | 
| 118         mojo_descriptor->transports.push_back(ConvertTransport(transport)); | 144         mojo_descriptor->transports.push_back(ConvertTransport(transport)); | 
| 119       mojo_options->exclude_list.push_back(std::move(mojo_descriptor)); | 145       mojo_options->exclude_credentials.push_back(std::move(mojo_descriptor)); | 
| 120     } | 146     } | 
| 121   } | 147   } | 
| 122   // TODO(kpaulhamus): add AuthenticationExtensions; |  | 
| 123   return mojo_options; | 148   return mojo_options; | 
| 124 } | 149 } | 
| 125 | 150 | 
| 126 // TODO(kpaulhamus): Make this a TypeConverter |  | 
| 127 ScopedCredentialParametersPtr ConvertScopedCredentialParameter( |  | 
| 128     const blink::ScopedCredentialParameters parameter, |  | 
| 129     blink::ScriptPromiseResolver* resolver) { |  | 
| 130   auto mojo_parameter = ScopedCredentialParameters::New(); |  | 
| 131   mojo_parameter->type = ConvertScopedCredentialType(parameter.type()); |  | 
| 132   // TODO(kpaulhamus): add AlgorithmIdentifier |  | 
| 133   return mojo_parameter; |  | 
| 134 } |  | 
| 135 |  | 
| 136 blink::DOMException* CreateExceptionFromStatus(AuthenticatorStatus status) { | 151 blink::DOMException* CreateExceptionFromStatus(AuthenticatorStatus status) { | 
| 137   switch (status) { | 152   switch (status) { | 
| 138     case AuthenticatorStatus::NOT_IMPLEMENTED: | 153     case AuthenticatorStatus::NOT_IMPLEMENTED: | 
| 139       return blink::DOMException::Create(blink::kNotSupportedError, | 154       return blink::DOMException::Create(blink::kNotSupportedError, | 
| 140                                          "Not implemented."); | 155                                          "Not implemented."); | 
| 141     case AuthenticatorStatus::NOT_ALLOWED_ERROR: | 156     case AuthenticatorStatus::NOT_ALLOWED_ERROR: | 
| 142       return blink::DOMException::Create(blink::kNotAllowedError, | 157       return blink::DOMException::Create(blink::kNotAllowedError, | 
| 143                                          "Not allowed."); | 158                                          "Not allowed."); | 
| 144     case AuthenticatorStatus::NOT_SUPPORTED_ERROR: | 159     case AuthenticatorStatus::NOT_SUPPORTED_ERROR: | 
| 145       return blink::DOMException::Create( | 160       return blink::DOMException::Create( | 
| 146           blink::kNotSupportedError, | 161           blink::kNotSupportedError, | 
| 147           "Parameters for this operation are not supported."); | 162           "Parameters for this operation are not supported."); | 
| 148     case AuthenticatorStatus::SECURITY_ERROR: | 163     case AuthenticatorStatus::SECURITY_ERROR: | 
| 149       return blink::DOMException::Create(blink::kSecurityError, | 164       return blink::DOMException::Create(blink::kSecurityError, | 
| 150                                          "The operation was not allowed."); | 165                                          "The operation was not allowed."); | 
| 151     case AuthenticatorStatus::UNKNOWN_ERROR: | 166     case AuthenticatorStatus::UNKNOWN_ERROR: | 
| 152       return blink::DOMException::Create(blink::kUnknownError, | 167       return blink::DOMException::Create(blink::kUnknownError, | 
| 153                                          "Request failed."); | 168                                          "Request failed."); | 
| 154     case AuthenticatorStatus::CANCELLED: | 169     case AuthenticatorStatus::CANCELLED: | 
| 155       return blink::DOMException::Create(blink::kNotAllowedError, | 170       return blink::DOMException::Create(blink::kNotAllowedError, | 
| 156                                          "User canceled the operation."); | 171                                          "User canceled the operation."); | 
| 157     case AuthenticatorStatus::SUCCESS: | 172     case AuthenticatorStatus::SUCCESS: | 
| 158       return nullptr; | 173       return nullptr; | 
| 159     default: | 174     default: | 
| 160       NOTREACHED(); | 175       NOTREACHED(); | 
| 161       return nullptr; | 176       return nullptr; | 
| 162   } | 177   } | 
| 163 } | 178 } | 
|  | 179 | 
| 164 }  // namespace mojo | 180 }  // namespace mojo | 
| 165 | 181 | 
| 166 namespace blink { | 182 namespace blink { | 
|  | 183 | 
| 167 WebAuthentication::WebAuthentication(LocalFrame& frame) | 184 WebAuthentication::WebAuthentication(LocalFrame& frame) | 
| 168     : ContextLifecycleObserver(frame.GetDocument()) {} | 185     : ContextLifecycleObserver(frame.GetDocument()) { | 
|  | 186   frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&authenticator_)); | 
|  | 187   authenticator_.set_connection_error_handler(ConvertToBaseCallback( | 
|  | 188       WTF::Bind(&WebAuthentication::OnAuthenticatorConnectionError, | 
|  | 189                 WrapWeakPersistent(this)))); | 
|  | 190 } | 
| 169 | 191 | 
| 170 WebAuthentication::~WebAuthentication() { | 192 WebAuthentication::~WebAuthentication() { | 
| 171   // |authenticator_| may still be valid but there should be no more | 193   // |authenticator_| may still be valid but there should be no more | 
| 172   // outstanding requests because each holds a persistent handle to this object. | 194   // outstanding requests because each holds a persistent handle to this object. | 
| 173   DCHECK(authenticator_requests_.IsEmpty()); | 195   DCHECK(authenticator_requests_.IsEmpty()); | 
| 174 } | 196 } | 
| 175 | 197 | 
| 176 ScriptPromise WebAuthentication::makeCredential( | 198 ScriptPromise WebAuthentication::makeCredential( | 
| 177     ScriptState* script_state, | 199     ScriptState* script_state, | 
| 178     const RelyingPartyAccount& account_information, | 200     const MakeCredentialOptions& publicKey) { | 
| 179     const HeapVector<ScopedCredentialParameters> crypto_parameters, |  | 
| 180     const BufferSource& attestation_challenge, |  | 
| 181     ScopedCredentialOptions& options) { |  | 
| 182   ScriptPromise promise = RejectIfNotSupported(script_state); | 201   ScriptPromise promise = RejectIfNotSupported(script_state); | 
| 183   if (!promise.IsEmpty()) | 202   if (!promise.IsEmpty()) | 
| 184     return promise; | 203     return promise; | 
| 185 | 204 | 
| 186   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); | 205   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); | 
| 187 | 206 | 
| 188   Vector<uint8_t> buffer = mojo::ConvertBufferSource(attestation_challenge); | 207   auto options = mojo::ConvertMakeCredentialOptions(publicKey); | 
| 189   auto opts = mojo::ConvertScopedCredentialOptions(options, resolver); |  | 
| 190   Vector<webauth::mojom::blink::ScopedCredentialParametersPtr> parameters; |  | 
| 191   for (const auto& parameter : crypto_parameters) { |  | 
| 192     if (parameter.hasType()) { |  | 
| 193       parameters.push_back( |  | 
| 194           mojo::ConvertScopedCredentialParameter(parameter, resolver)); |  | 
| 195     } |  | 
| 196   } |  | 
| 197   auto account = |  | 
| 198       mojo::ConvertRelyingPartyAccount(account_information, resolver); |  | 
| 199   authenticator_requests_.insert(resolver); | 208   authenticator_requests_.insert(resolver); | 
| 200   authenticator_->MakeCredential( | 209   authenticator_->MakeCredential( | 
| 201       std::move(account), std::move(parameters), buffer, std::move(opts), | 210       std::move(options), ConvertToBaseCallback(WTF::Bind( | 
| 202       ConvertToBaseCallback(WTF::Bind(&WebAuthentication::OnMakeCredential, | 211                               &WebAuthentication::OnMakeCredential, | 
| 203                                       WrapPersistent(this), | 212                               WrapPersistent(this), WrapPersistent(resolver)))); | 
| 204                                       WrapPersistent(resolver)))); |  | 
| 205   return resolver->Promise(); | 213   return resolver->Promise(); | 
| 206 } | 214 } | 
| 207 | 215 | 
| 208 ScriptPromise WebAuthentication::getAssertion( | 216 ScriptPromise WebAuthentication::getAssertion( | 
| 209     ScriptState* script_state, | 217     ScriptState* script_state, | 
| 210     const BufferSource& assertion_challenge, | 218     const PublicKeyCredentialRequestOptions& publicKey) { | 
| 211     const AuthenticationAssertionOptions& options) { |  | 
| 212   NOTREACHED(); | 219   NOTREACHED(); | 
| 213   return ScriptPromise(); | 220   return ScriptPromise(); | 
| 214 } | 221 } | 
| 215 | 222 | 
| 216 void WebAuthentication::ContextDestroyed(ExecutionContext*) { | 223 void WebAuthentication::ContextDestroyed(ExecutionContext*) { | 
| 217   Cleanup(); | 224   Cleanup(); | 
| 218 } | 225 } | 
| 219 | 226 | 
| 220 void WebAuthentication::OnMakeCredential( | 227 void WebAuthentication::OnMakeCredential( | 
| 221     ScriptPromiseResolver* resolver, | 228     ScriptPromiseResolver* resolver, | 
| 222     webauth::mojom::blink::AuthenticatorStatus status, | 229     webauth::mojom::blink::AuthenticatorStatus status, | 
| 223     webauth::mojom::blink::ScopedCredentialInfoPtr credential) { | 230     webauth::mojom::blink::PublicKeyCredentialInfoPtr credential) { | 
| 224   if (!MarkRequestComplete(resolver)) | 231   if (!MarkRequestComplete(resolver)) | 
| 225     return; | 232     return; | 
| 226 | 233 | 
| 227   DOMException* error = mojo::CreateExceptionFromStatus(status); | 234   DOMException* error = mojo::CreateExceptionFromStatus(status); | 
| 228   if (error) { | 235   if (error) { | 
| 229     DCHECK(!credential); | 236     DCHECK(!credential); | 
| 230     resolver->Reject(error); | 237     resolver->Reject(error); | 
| 231     Cleanup(); | 238     Cleanup(); | 
| 232     return; | 239     return; | 
| 233   } | 240   } | 
| 234 | 241 | 
| 235   if (credential->client_data.IsEmpty() || credential->attestation.IsEmpty()) { | 242   if (credential->client_data_json.IsEmpty() || | 
|  | 243       credential->response->attestation_object.IsEmpty()) { | 
| 236     resolver->Reject( | 244     resolver->Reject( | 
| 237         DOMException::Create(kNotFoundError, "No credential returned.")); | 245         DOMException::Create(kNotFoundError, "No credentials returned.")); | 
| 238     return; |  | 
| 239   } | 246   } | 
| 240 | 247 | 
| 241   DOMArrayBuffer* clientDataBuffer = DOMArrayBuffer::Create( | 248   DOMArrayBuffer* client_data_buffer = DOMArrayBuffer::Create( | 
| 242       static_cast<void*>(&credential->client_data.front()), | 249       static_cast<void*>(&credential->client_data_json.front()), | 
| 243       credential->client_data.size()); | 250       credential->client_data_json.size()); | 
| 244 | 251 | 
| 245   DOMArrayBuffer* attestationBuffer = DOMArrayBuffer::Create( | 252   // Return AuthenticatorAttestationResponse | 
| 246       static_cast<void*>(&credential->attestation.front()), | 253   DOMArrayBuffer* attestation_buffer = DOMArrayBuffer::Create( | 
| 247       credential->attestation.size()); | 254       static_cast<void*>(&credential->response->attestation_object.front()), | 
|  | 255       credential->response->attestation_object.size()); | 
| 248 | 256 | 
| 249   ScopedCredentialInfo* scopedCredential = | 257   AuthenticatorAttestationResponse* attestation_response = | 
| 250       ScopedCredentialInfo::Create(clientDataBuffer, attestationBuffer); | 258       AuthenticatorAttestationResponse::Create(client_data_buffer, | 
| 251   resolver->Resolve(scopedCredential); | 259                                                attestation_buffer); | 
|  | 260   resolver->Resolve(attestation_response); | 
| 252 } | 261 } | 
| 253 | 262 | 
| 254 ScriptPromise WebAuthentication::RejectIfNotSupported( | 263 ScriptPromise WebAuthentication::RejectIfNotSupported( | 
| 255     ScriptState* script_state) { | 264     ScriptState* script_state) { | 
|  | 265   LocalFrame* frame = | 
|  | 266       ToDocument(ExecutionContext::From(script_state))->GetFrame(); | 
| 256   if (!authenticator_) { | 267   if (!authenticator_) { | 
| 257     if (!GetFrame()) { | 268     if (!frame) { | 
| 258       return ScriptPromise::RejectWithDOMException( | 269       return ScriptPromise::RejectWithDOMException( | 
| 259           script_state, DOMException::Create(kNotSupportedError)); | 270           script_state, DOMException::Create(kNotSupportedError)); | 
| 260     } | 271     } | 
| 261     GetFrame()->GetInterfaceProvider().GetInterface( | 272     frame->GetInterfaceProvider().GetInterface( | 
| 262         mojo::MakeRequest(&authenticator_)); | 273         mojo::MakeRequest(&authenticator_)); | 
| 263 | 274 | 
| 264     authenticator_.set_connection_error_handler(ConvertToBaseCallback( | 275     authenticator_.set_connection_error_handler(ConvertToBaseCallback( | 
| 265         WTF::Bind(&WebAuthentication::OnAuthenticatorConnectionError, | 276         WTF::Bind(&WebAuthentication::OnAuthenticatorConnectionError, | 
| 266                   WrapWeakPersistent(this)))); | 277                   WrapWeakPersistent(this)))); | 
| 267   } | 278   } | 
| 268   return ScriptPromise(); | 279   return ScriptPromise(); | 
| 269 } | 280 } | 
| 270 | 281 | 
| 271 void WebAuthentication::OnAuthenticatorConnectionError() { | 282 void WebAuthentication::OnAuthenticatorConnectionError() { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 289   ContextLifecycleObserver::Trace(visitor); | 300   ContextLifecycleObserver::Trace(visitor); | 
| 290 } | 301 } | 
| 291 | 302 | 
| 292 // Clears the promise resolver, timer, and closes the Mojo connection. | 303 // Clears the promise resolver, timer, and closes the Mojo connection. | 
| 293 void WebAuthentication::Cleanup() { | 304 void WebAuthentication::Cleanup() { | 
| 294   authenticator_.reset(); | 305   authenticator_.reset(); | 
| 295   authenticator_requests_.clear(); | 306   authenticator_requests_.clear(); | 
| 296 } | 307 } | 
| 297 | 308 | 
| 298 }  // namespace blink | 309 }  // namespace blink | 
| OLD | NEW | 
|---|