Changeset 228572 in webkit
- Timestamp:
- Feb 16, 2018 12:43:28 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 21 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r228561 r228572 1 2018-02-16 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Implement PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() 4 https://bugs.webkit.org/show_bug.cgi?id=182771 5 <rdar://problem/36459988> 6 7 Reviewed by Brent Fulgham. 8 9 * http/wpt/webauthn/public-key-is-user-verifying-platform-authenticator-available-expected.txt: Added. 10 * http/wpt/webauthn/public-key-is-user-verifying-platform-authenticator-available.html: Added. 11 1 12 2018-02-16 Fujii Hironori <Hironori.Fujii@sony.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r228571 r228572 1 2018-02-16 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Implement PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() 4 https://bugs.webkit.org/show_bug.cgi?id=182771 5 <rdar://problem/36459988> 6 7 Reviewed by Brent Fulgham. 8 9 This patch implements PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() 10 per https://www.w3.org/TR/webauthn/#isUserVerifyingPlatformAuthenticatorAvailable with some 11 limitations. 12 13 In addition, it changes DeferredPromise to DOMPromiseDeferred<> for all CredentialsManagement 14 and WebAuthN API. 15 16 Test: http/wpt/webauthn/public-key-is-user-verifying-platform-authenticator-available.html 17 18 * Modules/credentialmanagement/CredentialsContainer.cpp: 19 (WebCore::CredentialsContainer::get): 20 (WebCore::CredentialsContainer::store): 21 (WebCore::CredentialsContainer::isCreate): 22 (WebCore::CredentialsContainer::preventSilentAccess const): 23 * Modules/credentialmanagement/CredentialsContainer.h: 24 * Modules/credentialmanagement/CredentialsMessenger.cpp: 25 (WebCore::CredentialsMessenger::addCreationCompletionHandler): 26 Remove a redundant assertion. 27 (WebCore::CredentialsMessenger::addRequestCompletionHandler): 28 Remove a redundant assertion. 29 (WebCore::CredentialsMessenger::addQueryCompletionHandler): 30 (WebCore::CredentialsMessenger::takeQueryCompletionHandler): 31 * Modules/credentialmanagement/CredentialsMessenger.h: 32 * Modules/webauthn/AuthenticatorManager.cpp: 33 (WebCore::AuthenticatorManagerInternal::initTimeoutTimer): 34 (WebCore::AuthenticatorManager::create const): 35 (WebCore::AuthenticatorManager::discoverFromExternalSource const): 36 (WebCore::AuthenticatorManager::isUserVerifyingPlatformAuthenticatorAvailable const): 37 * Modules/webauthn/AuthenticatorManager.h: 38 * Modules/webauthn/PublicKeyCredential.cpp: 39 (WebCore::PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable): 40 * Modules/webauthn/PublicKeyCredential.h: 41 * testing/MockCredentialsMessenger.cpp: 42 (WebCore::MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailable): 43 (WebCore::MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailableReply): 44 * testing/MockCredentialsMessenger.h: 45 * testing/MockCredentialsMessenger.idl: 46 1 47 2018-02-16 Tim Horton <timothy_horton@apple.com> 2 48 -
trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp
r228523 r228572 31 31 32 32 #include "AbortSignal.h" 33 #include "AuthenticatorManager.h"34 33 #include "CredentialCreationOptions.h" 35 34 #include "CredentialRequestOptions.h" … … 61 60 } 62 61 63 void CredentialsContainer::get(CredentialRequestOptions&& options, Ref<DeferredPromise>&& promise)62 void CredentialsContainer::get(CredentialRequestOptions&& options, CredentialPromise&& promise) 64 63 { 65 64 // The following implements https://www.w3.org/TR/credential-management-1/#algorithm-request as of 4 August 2017 66 65 // with enhancement from 14 November 2017 Editor's Draft. 67 66 if (!m_document) { 68 promise ->reject(Exception { NotSupportedError });67 promise.reject(Exception { NotSupportedError }); 69 68 return; 70 69 } 71 70 if (options.signal && options.signal->aborted()) { 72 promise ->reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") });71 promise.reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") }); 73 72 return; 74 73 } … … 80 79 // be requested from [[discoverFromExternalSource]]. 81 80 if (!options.publicKey) { 82 promise ->reject(Exception { NotSupportedError, ASCIILiteral("Only PublicKeyCredential is supported.") });81 promise.reject(Exception { NotSupportedError, ASCIILiteral("Only PublicKeyCredential is supported.") }); 83 82 return; 84 83 } … … 88 87 } 89 88 90 void CredentialsContainer::store(const BasicCredential&, Ref<DeferredPromise>&& promise)89 void CredentialsContainer::store(const BasicCredential&, CredentialPromise&& promise) 91 90 { 92 promise ->reject(Exception { NotSupportedError, ASCIILiteral("Not implemented.") });91 promise.reject(Exception { NotSupportedError, ASCIILiteral("Not implemented.") }); 93 92 } 94 93 95 void CredentialsContainer::isCreate(CredentialCreationOptions&& options, Ref<DeferredPromise>&& promise)94 void CredentialsContainer::isCreate(CredentialCreationOptions&& options, CredentialPromise&& promise) 96 95 { 97 96 // The following implements https://www.w3.org/TR/credential-management-1/#algorithm-create as of 4 August 2017 98 97 // with enhancement from 14 November 2017 Editor's Draft. 99 98 if (!m_document) { 100 promise ->reject(Exception { NotSupportedError });99 promise.reject(Exception { NotSupportedError }); 101 100 return; 102 101 } 103 102 if (options.signal && options.signal->aborted()) { 104 promise ->reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") });103 promise.reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") }); 105 104 return; 106 105 } … … 110 109 // Step 3-7. Shortcut as we only support one kind of credentials. 111 110 if (!options.publicKey) { 112 promise ->reject(Exception { NotSupportedError, ASCIILiteral("Only PublicKeyCredential is supported.") });111 promise.reject(Exception { NotSupportedError, ASCIILiteral("Only PublicKeyCredential is supported.") }); 113 112 return; 114 113 } … … 118 117 } 119 118 120 void CredentialsContainer::preventSilentAccess( Ref<DeferredPromise>&& promise) const119 void CredentialsContainer::preventSilentAccess(DOMPromiseDeferred<void>&& promise) const 121 120 { 122 promise ->reject(Exception { NotSupportedError, ASCIILiteral("Not implemented.") });121 promise.reject(Exception { NotSupportedError, ASCIILiteral("Not implemented.") }); 123 122 } 124 123 -
trunk/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h
r228523 r228572 29 29 #if ENABLE(WEB_AUTHN) 30 30 31 #include "AuthenticatorManager.h" 31 32 #include <wtf/RefCounted.h> 32 33 #include <wtf/WeakPtr.h> … … 34 35 namespace WebCore { 35 36 36 class BasicCredential;37 class DeferredPromise;38 37 class Document; 39 38 … … 45 44 static Ref<CredentialsContainer> create(WeakPtr<Document>&& document) { return adoptRef(*new CredentialsContainer(WTFMove(document))); } 46 45 47 void get(CredentialRequestOptions&&, Ref<DeferredPromise>&&);46 void get(CredentialRequestOptions&&, CredentialPromise&&); 48 47 49 void store(const BasicCredential&, Ref<DeferredPromise>&&);48 void store(const BasicCredential&, CredentialPromise&&); 50 49 51 void isCreate(CredentialCreationOptions&&, Ref<DeferredPromise>&&);50 void isCreate(CredentialCreationOptions&&, CredentialPromise&&); 52 51 53 void preventSilentAccess( Ref<DeferredPromise>&&) const;52 void preventSilentAccess(DOMPromiseDeferred<void>&&) const; 54 53 55 54 private: -
trunk/Source/WebCore/Modules/credentialmanagement/CredentialsMessenger.cpp
r228523 r228572 69 69 auto addResult = m_pendingCreationCompletionHandlers.add(messageId, WTFMove(handler)); 70 70 ASSERT_UNUSED(addResult, addResult.isNewEntry); 71 ASSERT(addResult);72 71 return messageId; 73 72 } … … 87 86 auto addResult = m_pendingRequestCompletionHandlers.add(messageId, WTFMove(handler)); 88 87 ASSERT_UNUSED(addResult, addResult.isNewEntry); 89 ASSERT(addResult);90 88 return messageId; 91 89 } … … 94 92 { 95 93 return m_pendingRequestCompletionHandlers.take(messageId); 94 } 95 96 uint64_t CredentialsMessenger::addQueryCompletionHandler(QueryCompletionHandler&& handler) 97 { 98 using namespace CredentialsMessengerInternal; 99 100 uint64_t messageId = m_accumulatedMessageId++; 101 ASSERT(messageId < maxMessageId); 102 messageId = messageId | CallBackClassifier::Query << callBackClassifierOffset; 103 auto addResult = m_pendingQueryCompletionHandlers.add(messageId, WTFMove(handler)); 104 ASSERT_UNUSED(addResult, addResult.isNewEntry); 105 return messageId; 106 } 107 108 QueryCompletionHandler CredentialsMessenger::takeQueryCompletionHandler(uint64_t messageId) 109 { 110 return m_pendingQueryCompletionHandlers.take(messageId); 96 111 } 97 112 -
trunk/Source/WebCore/Modules/credentialmanagement/CredentialsMessenger.h
r228523 r228572 69 69 using CreationCompletionHandler = CompletionHandler<void(ExceptionOr<CreationReturnBundle>&&)>; 70 70 using RequestCompletionHandler = CompletionHandler<void(ExceptionOr<AssertionReturnBundle>&&)>; 71 using QueryCompletionHandler = CompletionHandler<void(bool)>; 71 72 72 73 class CredentialsMessenger { … … 76 77 virtual void makeCredential(const Vector<uint8_t>& hash, const PublicKeyCredentialCreationOptions&, CreationCompletionHandler&&) = 0; 77 78 virtual void getAssertion(const Vector<uint8_t>& hash, const PublicKeyCredentialRequestOptions&, RequestCompletionHandler&&) = 0; 79 virtual void isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&&) = 0; 78 80 79 81 // receiver … … 81 83 virtual void makeCredentialReply(uint64_t messageId, const Vector<uint8_t>&) = 0; 82 84 virtual void getAssertionReply(uint64_t messageId, const Vector<uint8_t>& credentialId, const Vector<uint8_t>& authenticatorData, const Vector<uint8_t>& signature, const Vector<uint8_t>& userHandle) = 0; 85 virtual void isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool) = 0; 83 86 84 87 auto& weakPtrFactory() const { return m_weakFactory; } … … 91 94 WEBCORE_EXPORT uint64_t addRequestCompletionHandler(RequestCompletionHandler&&); 92 95 WEBCORE_EXPORT RequestCompletionHandler takeRequestCompletionHandler(uint64_t); 96 WEBCORE_EXPORT uint64_t addQueryCompletionHandler(QueryCompletionHandler&&); 97 WEBCORE_EXPORT QueryCompletionHandler takeQueryCompletionHandler(uint64_t); 93 98 94 99 private: … … 104 109 HashMap<uint64_t, CreationCompletionHandler> m_pendingCreationCompletionHandlers; 105 110 HashMap<uint64_t, RequestCompletionHandler> m_pendingRequestCompletionHandlers; 111 HashMap<uint64_t, QueryCompletionHandler> m_pendingQueryCompletionHandlers; 106 112 }; 107 113 -
trunk/Source/WebCore/Modules/webauthn/AuthenticatorManager.cpp
r228523 r228572 34 34 #include "CredentialsMessenger.h" 35 35 #include "JSBasicCredential.h" 36 #include "JSDOMPromiseDeferred.h"37 36 #include "PublicKeyCredential.h" 38 37 #include "PublicKeyCredentialCreationOptions.h" … … 84 83 85 84 // FIXME(181947): We should probably trim timeOutInMs to some max allowable number. 86 static std::unique_ptr<Timer> initTimeoutTimer(std::optional<unsigned long> timeOutInMs, const Ref<DeferredPromise>& promise)85 static std::unique_ptr<Timer> initTimeoutTimer(std::optional<unsigned long> timeOutInMs, const CredentialPromise& promise) 87 86 { 88 87 if (!timeOutInMs) 89 88 return nullptr; 90 89 91 auto timer = std::make_unique<Timer>([promise = promise .copyRef()] (){92 promise ->reject(Exception { NotAllowedError, ASCIILiteral("Operation timed out.") });90 auto timer = std::make_unique<Timer>([promise = promise] () mutable { 91 promise.reject(Exception { NotAllowedError, ASCIILiteral("Operation timed out.") }); 93 92 }); 94 93 timer->startOneShot(Seconds::fromMilliseconds(*timeOutInMs)); … … 120 119 } 121 120 122 void AuthenticatorManager::create(const SecurityOrigin& callerOrigin, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, Ref<DeferredPromise>&& promise) const121 void AuthenticatorManager::create(const SecurityOrigin& callerOrigin, const PublicKeyCredentialCreationOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const 123 122 { 124 123 using namespace AuthenticatorManagerInternal; … … 129 128 // Step 2. 130 129 if (!sameOriginWithAncestors) { 131 promise ->reject(Exception { NotAllowedError, ASCIILiteral("The origin of the document is not the same as its ancestors.") });130 promise.reject(Exception { NotAllowedError, ASCIILiteral("The origin of the document is not the same as its ancestors.") }); 132 131 return; 133 132 } … … 141 140 // domain suffix of another domain. Hence restrict the comparison to equal in Step 7. 142 141 if (!options.rp.id.isEmpty() && callerOrigin.host() != options.rp.id) { 143 promise ->reject(Exception { SecurityError, ASCIILiteral("The origin of the document is not a registrable domain suffix of the provided RP ID.") });142 promise.reject(Exception { SecurityError, ASCIILiteral("The origin of the document is not a registrable domain suffix of the provided RP ID.") }); 144 143 return; 145 144 } … … 151 150 // is empty or not. Return NotSupportedError as long as it is empty. 152 151 if (options.pubKeyCredParams.isEmpty()) { 153 promise ->reject(Exception { NotSupportedError, ASCIILiteral("No desired properties of the to be created credential are provided.") });152 promise.reject(Exception { NotSupportedError, ASCIILiteral("No desired properties of the to be created credential are provided.") }); 154 153 return; 155 154 } … … 164 163 // For better performance, no filtering is done here regarding to options.excludeCredentials. 165 164 if (!m_messenger) { 166 promise ->reject(Exception { UnknownError, ASCIILiteral("Unknown internal error.") });165 promise.reject(Exception { UnknownError, ASCIILiteral("Unknown internal error.") }); 167 166 return; 168 167 } … … 172 171 return; 173 172 if (abortSignal && abortSignal->aborted()) { 174 promise ->reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") });173 promise.reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") }); 175 174 return; 176 175 } 177 176 if (result.hasException()) { 178 promise ->reject(result.exception());177 promise.reject(result.exception()); 179 178 return; 180 179 } 181 180 182 181 auto bundle = result.releaseReturnValue(); 183 promise ->resolve<IDLNullable<IDLInterface<BasicCredential>>>(PublicKeyCredential::create(WTFMove(bundle.credentialId), AuthenticatorAttestationResponse::create(WTFMove(clientDataJson), ArrayBuffer::create(WTFMove(bundle.attestationObject)))).ptr());182 promise.resolve(PublicKeyCredential::create(WTFMove(bundle.credentialId), AuthenticatorAttestationResponse::create(WTFMove(clientDataJson), ArrayBuffer::create(WTFMove(bundle.attestationObject)))).ptr()); 184 183 }; 185 184 // Async operations are dispatched and handled in the messenger. … … 187 186 } 188 187 189 void AuthenticatorManager::discoverFromExternalSource(const SecurityOrigin& callerOrigin, const PublicKeyCredentialRequestOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, Ref<DeferredPromise>&& promise) const188 void AuthenticatorManager::discoverFromExternalSource(const SecurityOrigin& callerOrigin, const PublicKeyCredentialRequestOptions& options, bool sameOriginWithAncestors, RefPtr<AbortSignal>&& abortSignal, CredentialPromise&& promise) const 190 189 { 191 190 using namespace AuthenticatorManagerInternal; … … 196 195 // Step 2. 197 196 if (!sameOriginWithAncestors) { 198 promise ->reject(Exception { NotAllowedError, ASCIILiteral("The origin of the document is not the same as its ancestors.") });197 promise.reject(Exception { NotAllowedError, ASCIILiteral("The origin of the document is not the same as its ancestors.") }); 199 198 return; 200 199 } … … 208 207 // domain suffix of another domain. Hence restrict the comparison to equal in Step 7. 209 208 if (!options.rpId.isEmpty() && callerOrigin.host() != options.rpId) { 210 promise ->reject(Exception { SecurityError, ASCIILiteral("The origin of the document is not a registrable domain suffix of the provided RP ID.") });209 promise.reject(Exception { SecurityError, ASCIILiteral("The origin of the document is not a registrable domain suffix of the provided RP ID.") }); 211 210 return; 212 211 } … … 223 222 // For better performance, no filtering is done here regarding to options.allowCredentials. 224 223 if (!m_messenger) { 225 promise ->reject(Exception { UnknownError, ASCIILiteral("Unknown internal error.") });224 promise.reject(Exception { UnknownError, ASCIILiteral("Unknown internal error.") }); 226 225 return; 227 226 } … … 231 230 return; 232 231 if (abortSignal && abortSignal->aborted()) { 233 promise ->reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") });232 promise.reject(Exception { AbortError, ASCIILiteral("Aborted by AbortSignal.") }); 234 233 return; 235 234 } 236 235 if (result.hasException()) { 237 promise ->reject(result.exception());236 promise.reject(result.exception()); 238 237 return; 239 238 } 240 239 241 240 auto bundle = result.releaseReturnValue(); 242 promise ->resolve<IDLNullable<IDLInterface<BasicCredential>>>(PublicKeyCredential::create(WTFMove(bundle.credentialId), AuthenticatorAssertionResponse::create(WTFMove(clientDataJson), WTFMove(bundle.authenticatorData), WTFMove(bundle.signature), WTFMove(bundle.userHandle))).ptr());241 promise.resolve(PublicKeyCredential::create(WTFMove(bundle.credentialId), AuthenticatorAssertionResponse::create(WTFMove(clientDataJson), WTFMove(bundle.authenticatorData), WTFMove(bundle.signature), WTFMove(bundle.userHandle))).ptr()); 243 242 }; 244 243 // Async operations are dispatched and handled in the messenger. … … 246 245 } 247 246 247 void AuthenticatorManager::isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&& promise) const 248 { 249 // The following implements https://www.w3.org/TR/webauthn/#isUserVerifyingPlatformAuthenticatorAvailable 250 // as of 5 December 2017. 251 if (!m_messenger) { 252 promise.reject(Exception { UnknownError, ASCIILiteral("Unknown internal error.") }); 253 return; 254 } 255 256 // FIXME(182767): We should consider more on the assessment of the return value. Right now, we return true/false 257 // immediately according to platform specific procedures. 258 auto completionHandler = [promise = WTFMove(promise)] (bool result) mutable { 259 promise.resolve(result); 260 }; 261 // Async operation are dispatched and handled in the messenger. 262 m_messenger->isUserVerifyingPlatformAuthenticatorAvailable(WTFMove(completionHandler)); 263 } 264 248 265 } // namespace WebCore 249 266 -
trunk/Source/WebCore/Modules/webauthn/AuthenticatorManager.h
r228523 r228572 28 28 #if ENABLE(WEB_AUTHN) 29 29 30 #include "JSDOMPromiseDeferred.h" 30 31 #include <wtf/Forward.h> 31 32 #include <wtf/Noncopyable.h> … … 35 36 36 37 class AbortSignal; 38 class BasicCredential; 37 39 class CredentialsMessenger; 38 class DeferredPromise;39 40 class SecurityOrigin; 40 41 41 42 struct PublicKeyCredentialCreationOptions; 42 43 struct PublicKeyCredentialRequestOptions; 44 45 using CredentialPromise = DOMPromiseDeferred<IDLNullable<IDLInterface<BasicCredential>>>; 43 46 44 47 class AuthenticatorManager { … … 50 53 51 54 // The following methods implement static methods of PublicKeyCredential. 52 void create(const SecurityOrigin&, const PublicKeyCredentialCreationOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, Ref<DeferredPromise>&&) const; 53 void discoverFromExternalSource(const SecurityOrigin&, const PublicKeyCredentialRequestOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, Ref<DeferredPromise>&&) const; 55 void create(const SecurityOrigin&, const PublicKeyCredentialCreationOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, CredentialPromise&&) const; 56 void discoverFromExternalSource(const SecurityOrigin&, const PublicKeyCredentialRequestOptions&, bool sameOriginWithAncestors, RefPtr<AbortSignal>&&, CredentialPromise&&) const; 57 void isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&&) const; 54 58 55 59 private: -
trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.cpp
r228523 r228572 29 29 #if ENABLE(WEB_AUTHN) 30 30 31 #include "AuthenticatorManager.h" 31 32 #include "JSDOMPromiseDeferred.h" 32 33 #include <wtf/text/Base64.h> … … 46 47 } 47 48 48 void PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable( Ref<DeferredPromise>&& promise)49 void PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&& promise) 49 50 { 50 promise->reject(Exception { NotSupportedError });51 AuthenticatorManager::singleton().isUserVerifyingPlatformAuthenticatorAvailable(WTFMove(promise)); 51 52 } 52 53 -
trunk/Source/WebCore/Modules/webauthn/PublicKeyCredential.h
r228523 r228572 30 30 #include "BasicCredential.h" 31 31 #include "ExceptionOr.h" 32 #include "JSDOMPromiseDeferred.h" 32 33 #include <JavaScriptCore/ArrayBuffer.h> 33 34 #include <wtf/Forward.h> … … 36 37 37 38 class AuthenticatorResponse; 38 class DeferredPromise;39 39 40 40 class PublicKeyCredential final : public BasicCredential { … … 50 50 ExceptionOr<bool> getClientExtensionResults() const; 51 51 52 static void isUserVerifyingPlatformAuthenticatorAvailable( Ref<DeferredPromise>&&);52 static void isUserVerifyingPlatformAuthenticatorAvailable(DOMPromiseDeferred<IDLBoolean>&&); 53 53 54 54 private: -
trunk/Source/WebCore/testing/MockCredentialsMessenger.cpp
r228523 r228572 118 118 } 119 119 120 void MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&& handler) 121 { 122 auto messageId = addQueryCompletionHandler(WTFMove(handler)); 123 if (m_didUserVerifyingPlatformAuthenticatorPresent) { 124 isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, true); 125 m_didUserVerifyingPlatformAuthenticatorPresent = false; 126 } else 127 isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, false); 128 } 129 120 130 void MockCredentialsMessenger::makeCredentialReply(uint64_t messageId, const Vector<uint8_t>& attestationObject) 121 131 { … … 130 140 } 131 141 142 void MockCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool result) 143 { 144 auto handler = takeQueryCompletionHandler(messageId); 145 handler(result); 146 } 147 132 148 } // namespace WebCore 133 149 -
trunk/Source/WebCore/testing/MockCredentialsMessenger.h
r228523 r228572 43 43 void setDidTimeOut() { m_didTimeOut = true; } 44 44 void setDidUserCancel() { m_didUserCancel = true; } 45 void setDidUserVerifyingPlatformAuthenticatorPresent() { m_didUserVerifyingPlatformAuthenticatorPresent = true; } 45 46 void setAttestationObject(const BufferSource&); 46 47 void setAssertionReturnBundle(const BufferSource& credentialId, const BufferSource& authenticatorData, const BufferSource& signature, const BufferSource& userHandle); … … 52 53 void makeCredential(const Vector<uint8_t>&, const PublicKeyCredentialCreationOptions&, CreationCompletionHandler&&) final; 53 54 void getAssertion(const Vector<uint8_t>& hash, const PublicKeyCredentialRequestOptions&, RequestCompletionHandler&&) final; 55 void isUserVerifyingPlatformAuthenticatorAvailable(QueryCompletionHandler&&) final; 54 56 void makeCredentialReply(uint64_t messageId, const Vector<uint8_t>&) final; 55 57 void getAssertionReply(uint64_t messageId, const Vector<uint8_t>& credentialId, const Vector<uint8_t>& authenticatorData, const Vector<uint8_t>& signature, const Vector<uint8_t>& userHandle) final; 58 void isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool) final; 56 59 57 60 Internals& m_internals; … … 59 62 bool m_didTimeOut { false }; 60 63 bool m_didUserCancel { false }; 64 bool m_didUserVerifyingPlatformAuthenticatorPresent { false }; 61 65 Vector<uint8_t> m_attestationObject; 62 66 Vector<uint8_t> m_credentialId; -
trunk/Source/WebCore/testing/MockCredentialsMessenger.idl
r228523 r228572 30 30 void setDidTimeOut(); 31 31 void setDidUserCancel(); 32 void setDidUserVerifyingPlatformAuthenticatorPresent(); 32 33 void setAttestationObject(BufferSource attestationObject); 33 34 void setAssertionReturnBundle(BufferSource credentialId, BufferSource authenticatorData, BufferSource signature, BufferSource userHandle); -
trunk/Source/WebKit/ChangeLog
r228569 r228572 1 2018-02-16 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthN] Implement PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() 4 https://bugs.webkit.org/show_bug.cgi?id=182771 5 <rdar://problem/36459988> 6 7 Reviewed by Brent Fulgham. 8 9 This patch utilizes LocalAuthentication Framework to determine if biometrics 10 are enrolled on a device, which is the user verifying platform authenticator. 11 To do so, it links the framework to WebKit. 12 13 * UIProcess/CredentialManagement/WebCredentialsMessengerProxy.cpp: 14 (WebKit::WebCredentialsMessengerProxy::isUserVerifyingPlatformAuthenticatorAvailable): 15 (WebKit::WebCredentialsMessengerProxy::isUserVerifyingPlatformAuthenticatorAvailableReply): 16 * UIProcess/CredentialManagement/WebCredentialsMessengerProxy.h: 17 * UIProcess/CredentialManagement/WebCredentialsMessengerProxy.messages.in: 18 * UIProcess/CredentialManagement/cocoa/WebCredentialsMessengerProxyCocoa.mm: 19 (WebKit::WebCredentialsMessengerProxy::platformIsUserVerifyingPlatformAuthenticatorAvailable): 20 * WebKit.xcodeproj/project.pbxproj: 21 * WebProcess/CredentialManagement/WebCredentialsMessenger.cpp: 22 (WebKit::WebCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailable): 23 (WebKit::WebCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailableReply): 24 * WebProcess/CredentialManagement/WebCredentialsMessenger.h: 25 * WebProcess/CredentialManagement/WebCredentialsMessenger.messages.in: 26 1 27 2018-02-16 Per Arne Vollan <pvollan@apple.com> 2 28 -
trunk/Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.cpp
r228523 r228572 51 51 } 52 52 53 void WebCredentialsMessengerProxy::isUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId) 54 { 55 platformIsUserVerifyingPlatformAuthenticatorAvailable(messageId); 56 } 57 53 58 void WebCredentialsMessengerProxy::getAssertion(uint64_t) 54 59 { 60 } 61 62 void WebCredentialsMessengerProxy::isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool result) 63 { 64 m_webPageProxy.send(Messages::WebCredentialsMessenger::IsUserVerifyingPlatformAuthenticatorAvailableReply(messageId, result)); 55 65 } 56 66 -
trunk/Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.h
r228523 r228572 46 46 void makeCredential(uint64_t messageId); 47 47 void getAssertion(uint64_t messageId); 48 void isUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId); 49 50 // Senders. 51 void isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool); 52 53 // Platform specific procedures. 54 // FIXME(182768): Might change to some forms of delegates later on. 55 // FIXME(182769): Figure out a way to auto-test the followings. 56 void platformIsUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId); 48 57 49 58 WebPageProxy& m_webPageProxy; -
trunk/Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.messages.in
r228523 r228572 29 29 MakeCredential(uint64_t messageId); 30 30 GetAssertion(uint64_t messageId); 31 IsUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId); 31 32 } 32 33 -
trunk/Source/WebKit/UIProcess/CredentialManagement/cocoa/WebCredentialsMessengerProxyCocoa.mm
r228571 r228572 24 24 */ 25 25 26 #i nclude"config.h"27 #i nclude"WebCredentialsMessengerProxy.h"26 #import "config.h" 27 #import "WebCredentialsMessengerProxy.h" 28 28 29 29 #if ENABLE(WEB_AUTHN) 30 30 31 #include "WebCredentialsMessengerMessages.h" 32 #include "WebCredentialsMessengerProxyMessages.h" 33 #include "WebPageProxy.h" 34 #include "WebProcessProxy.h" 31 #import <LocalAuthentication/LocalAuthentication.h> 32 #import <WebCore/NotImplemented.h> 33 #import <wtf/RetainPtr.h> 35 34 36 35 namespace WebKit { 37 36 38 WebCredentialsMessengerProxy::WebCredentialsMessengerProxy(WebPageProxy& webPageProxy) 39 : m_webPageProxy(webPageProxy) 37 void WebCredentialsMessengerProxy::platformIsUserVerifyingPlatformAuthenticatorAvailable(uint64_t messageId) 40 38 { 41 m_webPageProxy.process().addMessageReceiver(Messages::WebCredentialsMessengerProxy::messageReceiverName(), m_webPageProxy.pageID(), *this); 42 } 39 #if defined(__i386__) 40 ASSERT_UNUSED(messageId, messageId); 41 notImplemented(); 42 #else 43 auto context = adoptNS([[LAContext alloc] init]); 44 NSError *error = nil; 43 45 44 WebCredentialsMessengerProxy::~WebCredentialsMessengerProxy() 45 { 46 m_webPageProxy.process().removeMessageReceiver(Messages::WebCredentialsMessengerProxy::messageReceiverName(), m_webPageProxy.pageID()); 47 } 48 49 void WebCredentialsMessengerProxy::makeCredential(uint64_t) 50 { 51 } 52 53 void WebCredentialsMessengerProxy::getAssertion(uint64_t) 54 { 46 if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) 47 isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, true); 48 else { 49 LOG_ERROR("Couldn't evaluate authentication with biometrics policy: %@", error); 50 isUserVerifyingPlatformAuthenticatorAvailableReply(messageId, false); 51 } 52 #endif // defined(__i386__) 55 53 } 56 54 -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r228557 r228572 1212 1212 53BA47D11DC2EF5E004DF4AD /* NetworkDataTaskBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 539EB5471DC2EE40009D48CF /* NetworkDataTaskBlob.h */; }; 1213 1213 53DEA3661DDE423100E82648 /* json.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 53DEA3651DDE422E00E82648 /* json.hpp */; }; 1214 5750F32B2032D4E500389347 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5750F32A2032D4E500389347 /* LocalAuthentication.framework */; }; 1214 1215 5760828E2029895E00116678 /* WebCredentialsMessenger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5760828C2029854200116678 /* WebCredentialsMessenger.cpp */; }; 1215 1216 57608298202BD8BA00116678 /* WebCredentialsMessengerProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57608296202BD8BA00116678 /* WebCredentialsMessengerProxy.cpp */; }; … … 1218 1219 5760829E202D2C4300116678 /* WebCredentialsMessengerProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5760829A202BEE5A00116678 /* WebCredentialsMessengerProxyMessageReceiver.cpp */; }; 1219 1220 5760829F202D2C4600116678 /* WebCredentialsMessengerProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 5760829B202BEE5A00116678 /* WebCredentialsMessengerProxyMessages.h */; }; 1221 57B90AAD203637F4000E61FA /* WebCredentialsMessengerProxyCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57B90AAC203637F4000E61FA /* WebCredentialsMessengerProxyCocoa.mm */; }; 1220 1222 5C0B17781E7C880E00E9123C /* NetworkSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17741E7C879C00E9123C /* NetworkSocketStreamMessageReceiver.cpp */; }; 1221 1223 5C0B17791E7C882100E9123C /* WebSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17761E7C879C00E9123C /* WebSocketStreamMessageReceiver.cpp */; }; … … 3641 3643 539EB5471DC2EE40009D48CF /* NetworkDataTaskBlob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkDataTaskBlob.h; path = NetworkProcess/NetworkDataTaskBlob.h; sourceTree = "<group>"; }; 3642 3644 53DEA3651DDE422E00E82648 /* json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = json.hpp; path = NetworkProcess/capture/json.hpp; sourceTree = "<group>"; }; 3645 5750F32A2032D4E500389347 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; }; 3643 3646 5760828B2029854200116678 /* WebCredentialsMessenger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCredentialsMessenger.h; sourceTree = "<group>"; }; 3644 3647 5760828C2029854200116678 /* WebCredentialsMessenger.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebCredentialsMessenger.cpp; sourceTree = "<group>"; }; … … 3651 3654 5760829A202BEE5A00116678 /* WebCredentialsMessengerProxyMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebCredentialsMessengerProxyMessageReceiver.cpp; sourceTree = "<group>"; }; 3652 3655 5760829B202BEE5A00116678 /* WebCredentialsMessengerProxyMessages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCredentialsMessengerProxyMessages.h; sourceTree = "<group>"; }; 3656 57B90AAC203637F4000E61FA /* WebCredentialsMessengerProxyCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCredentialsMessengerProxyCocoa.mm; sourceTree = "<group>"; }; 3653 3657 5C0B17741E7C879C00E9123C /* NetworkSocketStreamMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkSocketStreamMessageReceiver.cpp; sourceTree = "<group>"; }; 3654 3658 5C0B17751E7C879C00E9123C /* NetworkSocketStreamMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkSocketStreamMessages.h; sourceTree = "<group>"; }; … … 4723 4727 3766F9EE189A1241003CF19B /* JavaScriptCore.framework in Frameworks */, 4724 4728 3766F9F1189A1254003CF19B /* libicucore.dylib in Frameworks */, 4729 5750F32B2032D4E500389347 /* LocalAuthentication.framework in Frameworks */, 4725 4730 3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */, 4726 4731 37694525184FC6B600CDE21F /* Security.framework in Frameworks */, … … 4815 4820 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 4816 4821 034768DFFF38A50411DB9C8B /* Products */, 4822 5750F3292032D4E300389347 /* Frameworks */, 4817 4823 ); 4818 4824 name = WebKit2; … … 6703 6709 sourceTree = "<group>"; 6704 6710 }; 6711 5750F3292032D4E300389347 /* Frameworks */ = { 6712 isa = PBXGroup; 6713 children = ( 6714 5750F32A2032D4E500389347 /* LocalAuthentication.framework */, 6715 ); 6716 name = Frameworks; 6717 sourceTree = "<group>"; 6718 }; 6705 6719 5760828A202984C900116678 /* CredentialManagement */ = { 6706 6720 isa = PBXGroup; … … 6716 6730 isa = PBXGroup; 6717 6731 children = ( 6732 57B90AAB20363758000E61FA /* cocoa */, 6718 6733 57608296202BD8BA00116678 /* WebCredentialsMessengerProxy.cpp */, 6719 6734 57608295202BD8BA00116678 /* WebCredentialsMessengerProxy.h */, … … 6721 6736 ); 6722 6737 path = CredentialManagement; 6738 sourceTree = "<group>"; 6739 }; 6740 57B90AAB20363758000E61FA /* cocoa */ = { 6741 isa = PBXGroup; 6742 children = ( 6743 57B90AAC203637F4000E61FA /* WebCredentialsMessengerProxyCocoa.mm */, 6744 ); 6745 path = cocoa; 6723 6746 sourceTree = "<group>"; 6724 6747 }; … … 10856 10879 5760829C202D2C3C00116678 /* WebCredentialsMessengerMessageReceiver.cpp in Sources */, 10857 10880 57608298202BD8BA00116678 /* WebCredentialsMessengerProxy.cpp in Sources */, 10881 57B90AAD203637F4000E61FA /* WebCredentialsMessengerProxyCocoa.mm in Sources */, 10858 10882 5760829E202D2C4300116678 /* WebCredentialsMessengerProxyMessageReceiver.cpp in Sources */, 10859 10883 1AA83F6C1A5B63FF00026EC6 /* WebDatabaseProvider.cpp in Sources */, -
trunk/Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.cpp
r228523 r228572 55 55 } 56 56 57 void WebCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailable(WebCore::QueryCompletionHandler&& handler) 58 { 59 auto messageId = addQueryCompletionHandler(WTFMove(handler)); 60 m_webPage.send(Messages::WebCredentialsMessengerProxy::IsUserVerifyingPlatformAuthenticatorAvailable(messageId)); 61 } 62 57 63 void WebCredentialsMessenger::makeCredentialReply(uint64_t messageId, const Vector<uint8_t>&) 58 64 { … … 63 69 } 64 70 71 void WebCredentialsMessenger::isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool result) 72 { 73 auto handler = takeQueryCompletionHandler(messageId); 74 handler(result); 75 } 76 77 65 78 } // namespace WebKit 66 79 -
trunk/Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.h
r228523 r228572 45 45 void makeCredential(const Vector<uint8_t>&, const WebCore::PublicKeyCredentialCreationOptions&, WebCore::CreationCompletionHandler&&) final; 46 46 void getAssertion(const Vector<uint8_t>& hash, const WebCore::PublicKeyCredentialRequestOptions&, WebCore::RequestCompletionHandler&&) final; 47 void isUserVerifyingPlatformAuthenticatorAvailable(WebCore::QueryCompletionHandler&&) final; 47 48 48 49 // receiver 49 50 void makeCredentialReply(uint64_t messageId, const Vector<uint8_t>&) final; 50 51 void getAssertionReply(uint64_t messageId, const Vector<uint8_t>& credentialId, const Vector<uint8_t>& authenticatorData, const Vector<uint8_t>& signature, const Vector<uint8_t>& userHandle) final; 52 void isUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool) final; 51 53 52 54 // IPC::MessageReceiver. -
trunk/Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.messages.in
r228523 r228572 30 30 MakeCredentialReply(uint64_t messageId, Vector<uint8_t> attestationObject); 31 31 GetAssertionReply(uint64_t messageId, Vector<uint8_t> credentialId, Vector<uint8_t> authenticatorData, Vector<uint8_t> signature, Vector<uint8_t> userHandle); 32 IsUserVerifyingPlatformAuthenticatorAvailableReply(uint64_t messageId, bool result); 33 exceptionReply(uint64_t messageId, struct WebCore::ExceptionData exception); 32 34 } 33 35
Note: See TracChangeset
for help on using the changeset viewer.