[WebAuthN] Implement authenticatorMakeCredential
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Mar 2018 01:12:48 +0000 (01:12 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Mar 2018 01:12:48 +0000 (01:12 +0000)
commitb1e327ed39cb2eb7269f2449c31e7947b03810e4
tree7fa41d14806234e8fb335e3b3baeb4209f739ad1
parentf1e366d885313b101497dc9b1bfc03a75cfc11ee
[WebAuthN] Implement authenticatorMakeCredential
https://bugs.webkit.org/show_bug.cgi?id=183527
<rdar://problem/35275886>

Reviewed by Brent Fulgham.

Source/WebCore:

This patch does the following few things:
1) It implements the authenticatorMakeCredential logic from the spec: https://www.w3.org/TR/webauthn/#op-make-cred.
2) It tweaks enocding and deocding of PublicKeyCredentialCreationOptions between UIProccess and WebProcess.
3) It soft links LocalAuthentication.Framework to WebCore, which was linked to WebKit.
4) It creates SPI header for DeviceIdentity.Framework, and provides stubs to link it to WebCore.

Here is a detailed explanantion of 1):
1. A helper class called LocalAuthenticator is crafted to represent Apple platform attached authenticator, i.e.
the devices themselves. All operations are currently restricted to iOS at this moment as macOS lacks attestation
support.
2. To do testing, this helper class is then moved from WebKit to WebCore even though all operations can only happens
in the UIProcess. We currently lack the ability to pretend a https environment in TestWebKitAPI which is required by
the WebAuthN API, and thus it is moved to WebCore to perform unit tesing flavor API tests. This is not enough as it
can't test message exchange between the UI and Web processes. We will address this in a subsequent patch.
3. More on testing: The attestation process is abstracted into a protected method such that the testing enviroment can
override it with self attestation as network access is restricted in the WebKit testing enviroment. Also, swizzlers of
LocalAuthentication API are provided to override the behavoir of LAContext.
4. More on testing: The actual Apple attestation can only happen in real device and with network access, therefore
it can only be covered by manual tests at this moment.
5. Back to LocalAuthenticator, it currently has two public methods:
        5.1. makeCredential(): This method is the one does all the magic.
        + It first checks some parameters.
        + It then invokes LAContext to get user consent.
        + It then talks to Apple Attestation Privacy CA to do attestations.
        + It then stores necessary information into the Keychain.
        + Finally it generates the attestation object.
        5.2 isAvailable():
        To check if a LocalAuthenticator is available or not.
6. Even though files are of .mm format, they are written in a way that mixes NS, CF and C++ types. Here is the rule:
        6.1 Use CF type only if it is requested by APIs.
        6.2 Use NS type to manipulate all Objc objects.
        6.3 Use C++ otherwise.

Covered by API tests.

* Configurations/WebCore.xcconfig:
* Modules/credentialmanagement/CredentialsMessenger.cpp:
(WebCore::getIdFromAttestationObject): Deleted.
Decoding attestation object is tedious. UIProcess will instead return credential ID and attestation object
at the same time. Therefore, this method is removed.
* Modules/credentialmanagement/CredentialsMessenger.h:
(WebCore::CreationReturnBundle::CreationReturnBundle): Deleted.
(WebCore::AssertionReturnBundle::AssertionReturnBundle): Deleted.
* Modules/webauthn/COSEConstants.h: Copied from Source/WebCore/Modules/webauthn/PublicKeyCredentialType.h.
* Modules/webauthn/PublicKeyCredentialCreationOptions.h:
(WebCore::PublicKeyCredentialCreationOptions::isolatedPartialCopyPtr const):
(WebCore::PublicKeyCredentialCreationOptions::Parameters::encode const):
(WebCore::PublicKeyCredentialCreationOptions::Parameters::decode):
(WebCore::PublicKeyCredentialCreationOptions::encode const):
(WebCore::PublicKeyCredentialCreationOptions::decode):
* Modules/webauthn/PublicKeyCredentialDescriptor.h:
(WebCore::PublicKeyCredentialDescriptor::encode const):
(WebCore::PublicKeyCredentialDescriptor::decode):
* Modules/webauthn/PublicKeyCredentialType.h:
* Modules/webauthn/cocoa/LocalAuthenticator.h: Copied from Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h.
* Modules/webauthn/cocoa/LocalAuthenticator.mm: Added.
(WebCore::LocalAuthenticatorInternal::freePtrs):
(WebCore::LocalAuthenticator::makeCredential const):
(WebCore::LocalAuthenticator::isAvailable const):
(WebCore::LocalAuthenticator::issueClientCertificate const):
* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/cocoa/LocalAuthenticationSoftLink.h: Copied from Source/WebCore/Modules/webauthn/PublicKeyCredentialType.h.
* platform/cocoa/LocalAuthenticationSoftLink.mm: Added.
* testing/MockCredentialsMessenger.cpp:
(WebCore::MockCredentialsMessenger::setCreationReturnBundle):
(WebCore::MockCredentialsMessenger::makeCredential):
(WebCore::MockCredentialsMessenger::makeCredentialReply):
(WebCore::MockCredentialsMessenger::setAttestationObject): Deleted.
* testing/MockCredentialsMessenger.h:
* testing/MockCredentialsMessenger.idl:

Source/WebCore/PAL:

* PAL.xcodeproj/project.pbxproj:
* pal/spi/cocoa/DeviceIdentitySPI.h: Copied from Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.h.

Source/WebKit:

* UIProcess/CredentialManagement/WebCredentialsMessengerProxy.cpp:
(WebKit::WebCredentialsMessengerProxy::WebCredentialsMessengerProxy):
(WebKit::WebCredentialsMessengerProxy::makeCredential):
(WebKit::WebCredentialsMessengerProxy::getAssertion):
(WebKit::WebCredentialsMessengerProxy::isUserVerifyingPlatformAuthenticatorAvailable):
(WebKit::WebCredentialsMessengerProxy::exceptionReply):
(WebKit::WebCredentialsMessengerProxy::makeCredentialReply):
* UIProcess/CredentialManagement/WebCredentialsMessengerProxy.h:
* UIProcess/CredentialManagement/WebCredentialsMessengerProxy.messages.in:
* UIProcess/CredentialManagement/cocoa/WebCredentialsMessengerProxyCocoa.mm: Removed.
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/CredentialManagement/WebCredentialsMessenger.cpp:
(WebKit::WebCredentialsMessenger::makeCredential):
(WebKit::WebCredentialsMessenger::makeCredentialReply):
* WebProcess/CredentialManagement/WebCredentialsMessenger.h:
* WebProcess/CredentialManagement/WebCredentialsMessenger.messages.in:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/LocalAuthenticator.mm: Added.
(TestWebKitAPI::getTestKey):
(TestWebKitAPI::cleanUpKeychain):
(TestWebKitAPI::LACantEvaluatePolicySwizzler::LACantEvaluatePolicySwizzler):
(TestWebKitAPI::LACantEvaluatePolicySwizzler::cantEvaluatePolicy):
(TestWebKitAPI::LACanEvaluatePolicySwizzler::LACanEvaluatePolicySwizzler):
(TestWebKitAPI::LACanEvaluatePolicySwizzler::canEvaluatePolicy):
(TestWebKitAPI::LAEvaluatePolicyFailedSwizzler::LAEvaluatePolicyFailedSwizzler):
(TestWebKitAPI::LAEvaluatePolicyFailedSwizzler::evaluatePolicyFailed):
(TestWebKitAPI::LAEvaluatePolicyPassedSwizzler::LAEvaluatePolicyPassedSwizzler):
(TestWebKitAPI::LAEvaluatePolicyPassedSwizzler::evaluatePolicyPassed):
(TestWebKitAPI::TestLocalAuthenticator::setFailureFlag):
(TestWebKitAPI::TEST):

WebKitLibraries:

* WebKitPrivateFrameworkStubs/iOS/11/DeviceIdentity.framework/DeviceIdentity.tbd: Added.

LayoutTests:

* http/wpt/credential-management/credentialscontainer-store-basics.https.html:
* http/wpt/webauthn/idl.https.html:
* http/wpt/webauthn/public-key-credential-create-success.https.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229699 268f45cc-cd09-0410-ab3c-d52691b4dbfc
37 files changed:
LayoutTests/ChangeLog
LayoutTests/http/wpt/credential-management/credentialscontainer-store-basics.https.html
LayoutTests/http/wpt/webauthn/idl.https.html
LayoutTests/http/wpt/webauthn/public-key-credential-create-success.https.html
Source/WebCore/ChangeLog
Source/WebCore/Configurations/WebCore.xcconfig
Source/WebCore/Modules/credentialmanagement/CredentialsMessenger.cpp
Source/WebCore/Modules/credentialmanagement/CredentialsMessenger.h
Source/WebCore/Modules/webauthn/COSEConstants.h [new file with mode: 0644]
Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h
Source/WebCore/Modules/webauthn/PublicKeyCredentialDescriptor.h
Source/WebCore/Modules/webauthn/PublicKeyCredentialType.h
Source/WebCore/Modules/webauthn/cocoa/LocalAuthenticator.h [new file with mode: 0644]
Source/WebCore/Modules/webauthn/cocoa/LocalAuthenticator.mm [new file with mode: 0644]
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj
Source/WebCore/PAL/pal/spi/cocoa/DeviceIdentitySPI.h [new file with mode: 0644]
Source/WebCore/SourcesCocoa.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/cocoa/LocalAuthenticationSoftLink.h [moved from Source/WebKit/UIProcess/CredentialManagement/cocoa/WebCredentialsMessengerProxyCocoa.mm with 59% similarity]
Source/WebCore/platform/cocoa/LocalAuthenticationSoftLink.mm [new file with mode: 0644]
Source/WebCore/testing/MockCredentialsMessenger.cpp
Source/WebCore/testing/MockCredentialsMessenger.h
Source/WebCore/testing/MockCredentialsMessenger.idl
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.cpp
Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.h
Source/WebKit/UIProcess/CredentialManagement/WebCredentialsMessengerProxy.messages.in
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.cpp
Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.h
Source/WebKit/WebProcess/CredentialManagement/WebCredentialsMessenger.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/ios/LocalAuthenticator.mm [new file with mode: 0644]
WebKitLibraries/ChangeLog
WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/11/DeviceIdentity.framework/DeviceIdentity.tbd [new file with mode: 0644]