WebKit Bugzilla
Attachment 370389 Details for
Bug 192722
: [WebAuthN] Support Attestation Conveyance Preference
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192722-20190522020619.patch (text/plain), 58.53 KB, created by
Jiewen Tan
on 2019-05-22 02:06:20 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jiewen Tan
Created:
2019-05-22 02:06:20 PDT
Size:
58.53 KB
patch
obsolete
>Subversion Revision: 245539 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 7a302d330abfe72ab2175a524657d064c1ddcf04..69fa7eab5a89940770239e55d7b9ee9bc9a94341 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,46 @@ >+2019-05-22 Jiewen Tan <jiewen_tan@apple.com> >+ >+ [WebAuthN] Support Attestation Conveyance Preference >+ https://bugs.webkit.org/show_bug.cgi?id=192722 >+ <rdar://problem/49939647> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch implements https://www.w3.org/TR/webauthn/#enumdef-attestationconveyancepreference, together with >+ Step 20 with regard to AttestationConveyancePreference of https://www.w3.org/TR/webauthn/#createCredential. >+ Few notes with regard to Step 20: 1) We treat indirect attestation as direct attestation as we don't MITM >+ the attestation process; 2) We won't distinguish self attestation and return it to keep consistency between >+ the response and the request. If callers want none attestation, they will very likely ignore fmt and attStmt >+ of the attestation object, and therefore it is meaningless to return self attestation. >+ >+ Covered by new tests within existing files. >+ >+ * CMakeLists.txt: >+ * DerivedSources-input.xcfilelist: >+ * DerivedSources-output.xcfilelist: >+ * DerivedSources.make: >+ * Headers.cmake: >+ * Modules/webauthn/AttestationConveyancePreference.h: Copied from Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h. >+ * Modules/webauthn/AttestationConveyancePreference.idl: Copied from Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h. >+ * Modules/webauthn/PublicKeyCredentialCreationOptions.h: >+ (WebCore::PublicKeyCredentialCreationOptions::encode const): >+ (WebCore::PublicKeyCredentialCreationOptions::decode): >+ * Modules/webauthn/PublicKeyCredentialCreationOptions.idl: >+ * Modules/webauthn/WebAuthenticationConstants.h: >+ * Modules/webauthn/WebAuthenticationUtils.cpp: >+ (WebCore::buildAttestationObject): >+ * Modules/webauthn/WebAuthenticationUtils.h: >+ * Modules/webauthn/fido/DeviceResponseConverter.cpp: >+ (fido::readCTAPMakeCredentialResponse): >+ * Modules/webauthn/fido/DeviceResponseConverter.h: >+ * Modules/webauthn/fido/FidoConstants.h: >+ noneAttestationValue is moved to WebAuthenticationConstants.h. >+ * Modules/webauthn/fido/U2fResponseConverter.cpp: >+ (fido::readU2fRegisterResponse): >+ * Modules/webauthn/fido/U2fResponseConverter.h: >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ > 2019-05-20 Jer Noble <jer.noble@apple.com> > > Provide an explicit UIModalPresentation style when creating an AVPlayerViewController for fullscreen. >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index efeb55cb9dfdb9285f49803219f25e319ffd9e6f..95e8d3d7274979ceab51253f74d875525600c9ed 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,18 @@ >+2019-05-22 Jiewen Tan <jiewen_tan@apple.com> >+ >+ [WebAuthN] Support Attestation Conveyance Preference >+ https://bugs.webkit.org/show_bug.cgi?id=192722 >+ <rdar://problem/49939647> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm: >+ (WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested): >+ * UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp: >+ (WebKit::CtapHidAuthenticator::continueMakeCredentialAfterResponseReceived const): >+ * UIProcess/WebAuthentication/fido/U2fHidAuthenticator.cpp: >+ (WebKit::U2fHidAuthenticator::continueRegisterCommandAfterResponseReceived): >+ > 2019-05-20 Ross Kirsling <ross.kirsling@sony.com> > > [WinCairo] Implement Remote Web Inspector Client. >diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt >index 4416f25ed2776c17f3e62f9fd9f58c8193a9308e..840d0f5984c9f827afb2d4d9334396af7231e914 100644 >--- a/Source/WebCore/CMakeLists.txt >+++ b/Source/WebCore/CMakeLists.txt >@@ -441,6 +441,7 @@ set(WebCore_NON_SVG_IDL_FILES > Modules/webaudio/ScriptProcessorNode.idl > Modules/webaudio/WaveShaperNode.idl > >+ Modules/webauthn/AttestationConveyancePreference.idl > Modules/webauthn/AuthenticationExtensionsClientInputs.idl > Modules/webauthn/AuthenticatorAssertionResponse.idl > Modules/webauthn/AuthenticatorAttestationResponse.idl >diff --git a/Source/WebCore/DerivedSources-input.xcfilelist b/Source/WebCore/DerivedSources-input.xcfilelist >index 6c034ce7cbc7e0e7e0659b7aebf9ec752cf9eaf9..ac56c7abe7bf4386e4c462ef2ad6e3358492ba99 100644 >--- a/Source/WebCore/DerivedSources-input.xcfilelist >+++ b/Source/WebCore/DerivedSources-input.xcfilelist >@@ -294,6 +294,7 @@ $(PROJECT_DIR)/Modules/webaudio/PannerNode.idl > $(PROJECT_DIR)/Modules/webaudio/PeriodicWave.idl > $(PROJECT_DIR)/Modules/webaudio/ScriptProcessorNode.idl > $(PROJECT_DIR)/Modules/webaudio/WaveShaperNode.idl >+$(PROJECT_DIR)/Modules/webauthn/AttestationConveyancePreference.idl > $(PROJECT_DIR)/Modules/webauthn/AuthenticationExtensionsClientInputs.idl > $(PROJECT_DIR)/Modules/webauthn/AuthenticatorAssertionResponse.idl > $(PROJECT_DIR)/Modules/webauthn/AuthenticatorAttestationResponse.idl >diff --git a/Source/WebCore/DerivedSources-output.xcfilelist b/Source/WebCore/DerivedSources-output.xcfilelist >index 5074158c5463aaf02ad7beabd1b60f888e5ef94e..3dd908ee185cdcfdeb1a86d9155405064828300d 100644 >--- a/Source/WebCore/DerivedSources-output.xcfilelist >+++ b/Source/WebCore/DerivedSources-output.xcfilelist >@@ -124,6 +124,8 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSApplePayValidateMerchantEvent.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSApplePayValidateMerchantEvent.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAriaAttributes.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAriaAttributes.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAttestationConveyancePreference.cpp >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAttestationConveyancePreference.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAttr.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAttr.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSAudioBuffer.cpp >diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make >index dafe52207e8ec5872d9c5112dad8bdc9410ee138..b988da23dc3b462fe13bac97a3e0b5c3d54eb234 100644 >--- a/Source/WebCore/DerivedSources.make >+++ b/Source/WebCore/DerivedSources.make >@@ -351,6 +351,7 @@ JS_BINDING_IDLS = \ > $(WebCore)/Modules/webaudio/PeriodicWave.idl \ > $(WebCore)/Modules/webaudio/ScriptProcessorNode.idl \ > $(WebCore)/Modules/webaudio/WaveShaperNode.idl \ >+ $(WebCore)/Modules/webauthn/AttestationConveyancePreference.idl \ > $(WebCore)/Modules/webauthn/AuthenticationExtensionsClientInputs.idl \ > $(WebCore)/Modules/webauthn/AuthenticatorAssertionResponse.idl \ > $(WebCore)/Modules/webauthn/AuthenticatorAttestationResponse.idl \ >diff --git a/Source/WebCore/Headers.cmake b/Source/WebCore/Headers.cmake >index 83427f0375de1e6d8e7bfde1dde88a7e00a637f7..1980f0d73dbefdc8030b0a53507ab7a45b67535a 100644 >--- a/Source/WebCore/Headers.cmake >+++ b/Source/WebCore/Headers.cmake >@@ -112,6 +112,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > Modules/streams/ReadableStreamSink.h > Modules/streams/ReadableStreamSource.h > >+ Modules/webauthn/AttestationConveyancePreference.h > Modules/webauthn/AuthenticationExtensionsClientInputs.h > Modules/webauthn/AuthenticatorCoordinator.h > Modules/webauthn/AuthenticatorCoordinatorClient.h >diff --git a/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.h b/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.h >new file mode 100644 >index 0000000000000000000000000000000000000000..019e8535fe4855317d64b3aaa21e860af8f2c7d7 >--- /dev/null >+++ b/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.h >@@ -0,0 +1,55 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEB_AUTHN) >+ >+#include <wtf/Forward.h> >+ >+namespace WebCore { >+ >+enum class AttestationConveyancePreference { >+ None, >+ Indirect, >+ Direct >+}; >+ >+} // namespace WebCore >+ >+namespace WTF { >+ >+template<> struct EnumTraits<WebCore::AttestationConveyancePreference> { >+ using values = EnumValues< >+ WebCore::AttestationConveyancePreference, >+ WebCore::AttestationConveyancePreference::None, >+ WebCore::AttestationConveyancePreference::Indirect, >+ WebCore::AttestationConveyancePreference::Direct >+ >; >+}; >+ >+} // namespace WTF >+ >+#endif // ENABLE(WEB_AUTHN) >diff --git a/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.idl b/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.idl >new file mode 100644 >index 0000000000000000000000000000000000000000..20c352f5f8e5ea50dab96e8abd0162519d8c6d09 >--- /dev/null >+++ b/Source/WebCore/Modules/webauthn/AttestationConveyancePreference.idl >@@ -0,0 +1,32 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+[ >+ Conditional=WEB_AUTHN, >+] enum AttestationConveyancePreference { >+ "none", >+ "indirect", >+ "direct" >+}; >diff --git a/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h b/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h >index 491645891923005f2e0b6fa3fbcbe99395f37964..d548aad5b0786d3397aa26c5503660be130d0aeb 100644 >--- a/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h >+++ b/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h >@@ -27,6 +27,7 @@ > > #if ENABLE(WEB_AUTHN) > >+#include "AttestationConveyancePreference.h" > #include "AuthenticationExtensionsClientInputs.h" > #include "BufferSource.h" > #include "PublicKeyCredentialDescriptor.h" >@@ -84,6 +85,7 @@ struct PublicKeyCredentialCreationOptions { > Optional<unsigned> timeout; > Vector<PublicKeyCredentialDescriptor> excludeCredentials; > Optional<AuthenticatorSelectionCriteria> authenticatorSelection; >+ AttestationConveyancePreference attestation; > Optional<AuthenticationExtensionsClientInputs> extensions; // A place holder, but never used. > > template<class Encoder> void encode(Encoder&) const; >@@ -142,7 +144,7 @@ void PublicKeyCredentialCreationOptions::encode(Encoder& encoder) const > encoder << rp.id << rp.name << rp.icon; > encoder << static_cast<uint64_t>(user.id.length()); > encoder.encodeFixedLengthData(user.id.data(), user.id.length(), 1); >- encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection; >+ encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection << attestation; > } > > template<class Decoder> >@@ -181,6 +183,12 @@ Optional<PublicKeyCredentialCreationOptions> PublicKeyCredentialCreationOptions: > return WTF::nullopt; > result.authenticatorSelection = WTFMove(*authenticatorSelection); > >+ Optional<AttestationConveyancePreference> attestation; >+ decoder >> attestation; >+ if (!attestation) >+ return WTF::nullopt; >+ result.attestation = WTFMove(*attestation); >+ > return result; > } > >diff --git a/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.idl b/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.idl >index 033e0dc87959b73f1b5fd9ba6bcc80bd1eeeadb8..ecb6701c6dc2233db19f00c8868109820015ba78 100644 >--- a/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.idl >+++ b/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.idl >@@ -37,8 +37,7 @@ typedef long COSEAlgorithmIdentifier; > unsigned long timeout; > sequence<PublicKeyCredentialDescriptor> excludeCredentials = []; > AuthenticatorSelectionCriteria authenticatorSelection; >- // Always "direct" for us. >- // AttestationConveyancePreference attestation = "none"; >+ AttestationConveyancePreference attestation = "none"; > AuthenticationExtensionsClientInputs extensions; > }; > >diff --git a/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h b/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h >index 6145261ac0281aa3e0ecca7833632a165f725509..e4fd12bc6477c294eae965f4fe5b8bfbcdcaf31f 100644 >--- a/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h >+++ b/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h >@@ -67,4 +67,7 @@ const size_t credentialIdLengthLength = 2; > // Per Section 2.3.5 of http://www.secg.org/sec1-v2.pdf > const size_t ES256FieldElementLength = 32; > >+// https://www.w3.org/TR/webauthn/#none-attestation >+const char noneAttestationValue[] = "none"; >+ > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp b/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp >index 13326191ac2fe610b00d0446bb7a0dffc38d639b..be92612d81d3179097cbabb65ca220b290a015dc 100644 >--- a/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp >+++ b/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.cpp >@@ -110,9 +110,20 @@ Vector<uint8_t> buildAuthData(const String& rpId, const uint8_t flags, const uin > return authData; > } > >-Vector<uint8_t> buildAttestationObject(Vector<uint8_t>&& authData, String&& format, cbor::CBORValue::MapValue&& statementMap) >+Vector<uint8_t> buildAttestationObject(Vector<uint8_t>&& authData, String&& format, cbor::CBORValue::MapValue&& statementMap, const AttestationConveyancePreference& attestation) > { > cbor::CBORValue::MapValue attestationObjectMap; >+ // The following implements Step 20 with regard to AttestationConveyancePreference >+ // of https://www.w3.org/TR/webauthn/#createCredential as of 4 March 2019. >+ // None attestation is always returned if it is requested to keep consistency, and therefore skip the >+ // step to return self attestation. >+ if (attestation == AttestationConveyancePreference::None) { >+ const size_t aaguidOffset = rpIdHashLength + flagsLength + signCounterLength; >+ if (authData.size() >= aaguidOffset + aaguidLength) >+ memset(authData.data() + aaguidOffset, 0, aaguidLength); >+ format = noneAttestationValue; >+ statementMap.clear(); >+ } > attestationObjectMap[cbor::CBORValue("authData")] = cbor::CBORValue(WTFMove(authData)); > attestationObjectMap[cbor::CBORValue("fmt")] = cbor::CBORValue(WTFMove(format)); > attestationObjectMap[cbor::CBORValue("attStmt")] = cbor::CBORValue(WTFMove(statementMap)); >diff --git a/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h b/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h >index 17f022e16078217b1918001807d31bcf708a2170..51f056e6d33fa88b757742f49f904335d633d928 100644 >--- a/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h >+++ b/Source/WebCore/Modules/webauthn/WebAuthenticationUtils.h >@@ -27,6 +27,7 @@ > > #if ENABLE(WEB_AUTHN) > >+#include "AttestationConveyancePreference.h" > #include "CBORValue.h" > #include <wtf/Forward.h> > >@@ -46,7 +47,7 @@ WEBCORE_EXPORT Vector<uint8_t> buildAttestedCredentialData(const Vector<uint8_t> > WEBCORE_EXPORT Vector<uint8_t> buildAuthData(const String& rpId, const uint8_t flags, const uint32_t counter, const Vector<uint8_t>& optionalAttestedCredentialData); > > // https://www.w3.org/TR/webauthn/#attestation-object >-WEBCORE_EXPORT Vector<uint8_t> buildAttestationObject(Vector<uint8_t>&& authData, String&& format, cbor::CBORValue::MapValue&& statementMap); >+WEBCORE_EXPORT Vector<uint8_t> buildAttestationObject(Vector<uint8_t>&& authData, String&& format, cbor::CBORValue::MapValue&& statementMap, const AttestationConveyancePreference&); > > } // namespace WebCore > >diff --git a/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp b/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp >index 12442b125c79029d8cf4a5ac416db114fb256625..dafbefd9c7db683b1495052ebc2d19bb8240e84b 100644 >--- a/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp >+++ b/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.cpp >@@ -36,6 +36,7 @@ > #include "CBORReader.h" > #include "CBORWriter.h" > #include "WebAuthenticationConstants.h" >+#include "WebAuthenticationUtils.h" > #include <wtf/StdSet.h> > #include <wtf/Vector.h> > >@@ -84,7 +85,7 @@ static Vector<uint8_t> getCredentialId(const Vector<uint8_t>& authenticatorData) > > // Decodes byte array response from authenticator to CBOR value object and > // checks for correct encoding format. >-Optional<PublicKeyCredentialData> readCTAPMakeCredentialResponse(const Vector<uint8_t>& inBuffer) >+Optional<PublicKeyCredentialData> readCTAPMakeCredentialResponse(const Vector<uint8_t>& inBuffer, const WebCore::AttestationConveyancePreference& attestation) > { > if (inBuffer.size() <= kResponseCodeLength) > return WTF::nullopt; >@@ -115,11 +116,19 @@ Optional<PublicKeyCredentialData> readCTAPMakeCredentialResponse(const Vector<ui > return WTF::nullopt; > auto attStmt = it->second.clone(); > >- CBOR::MapValue attestationObjectMap; >- attestationObjectMap[CBOR("authData")] = WTFMove(authenticatorData); >- attestationObjectMap[CBOR("fmt")] = WTFMove(format); >- attestationObjectMap[CBOR("attStmt")] = WTFMove(attStmt); >- auto attestationObject = cbor::CBORWriter::write(CBOR(WTFMove(attestationObjectMap))); >+ Optional<Vector<uint8_t>> attestationObject; >+ if (attestation == AttestationConveyancePreference::None) { >+ // The reason why we can't directly pass authenticatorData/format/attStmt to buildAttestationObject >+ // is that they are CBORValue instead of the raw type. >+ // Also, format and attStmt are omitted as they are not useful in none attestation. >+ attestationObject = buildAttestationObject(Vector<uint8_t>(authenticatorData.getByteString()), "", { }, attestation); >+ } else { >+ CBOR::MapValue attestationObjectMap; >+ attestationObjectMap[CBOR("authData")] = WTFMove(authenticatorData); >+ attestationObjectMap[CBOR("fmt")] = WTFMove(format); >+ attestationObjectMap[CBOR("attStmt")] = WTFMove(attStmt); >+ attestationObject = cbor::CBORWriter::write(CBOR(WTFMove(attestationObjectMap))); >+ } > > return PublicKeyCredentialData { ArrayBuffer::create(credentialId.data(), credentialId.size()), true, nullptr, ArrayBuffer::create(attestationObject.value().data(), attestationObject.value().size()), nullptr, nullptr, nullptr, WTF::nullopt }; > } >diff --git a/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.h b/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.h >index affb54c79e453df18cd7dec77ea70c96bf3f2d1c..04be8b99a42d91b403c052b677ee60bc25575929 100644 >--- a/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.h >+++ b/Source/WebCore/Modules/webauthn/fido/DeviceResponseConverter.h >@@ -31,6 +31,7 @@ > > #if ENABLE(WEB_AUTHN) > >+#include "AttestationConveyancePreference.h" > #include "AuthenticatorGetInfoResponse.h" > #include "FidoConstants.h" > #include "PublicKeyCredentialData.h" >@@ -48,7 +49,7 @@ WEBCORE_EXPORT CtapDeviceResponseCode getResponseCode(const Vector<uint8_t>&); > // and converts response to AuthenticatorMakeCredentialResponse object with > // CBOR map keys that conform to format of attestation object defined by the > // WebAuthN spec : https://w3c.github.io/webauthn/#fig-attStructs >-WEBCORE_EXPORT Optional<WebCore::PublicKeyCredentialData> readCTAPMakeCredentialResponse(const Vector<uint8_t>&); >+WEBCORE_EXPORT Optional<WebCore::PublicKeyCredentialData> readCTAPMakeCredentialResponse(const Vector<uint8_t>&, const WebCore::AttestationConveyancePreference& attestation = WebCore::AttestationConveyancePreference::Direct); > > // De-serializes CBOR encoded response to AuthenticatorGetAssertion / > // AuthenticatorGetNextAssertion request to AuthenticatorGetAssertionResponse >diff --git a/Source/WebCore/Modules/webauthn/fido/FidoConstants.h b/Source/WebCore/Modules/webauthn/fido/FidoConstants.h >index 530a174867ea53db7c000e53144b29cff4b61c1f..211e3c81f3f0de2fe5bcbfce63e3e4fc81502a20 100644 >--- a/Source/WebCore/Modules/webauthn/fido/FidoConstants.h >+++ b/Source/WebCore/Modules/webauthn/fido/FidoConstants.h >@@ -207,7 +207,6 @@ enum class U2fApduInstruction : uint8_t { > const char kFormatKey[] = "fmt"; > const char kAttestationStatementKey[] = "attStmt"; > const char kAuthDataKey[] = "authData"; >-const char kNoneAttestationValue[] = "none"; > > // String representation of public key credential enum. > // https://w3c.github.io/webauthn/#credentialType >diff --git a/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.cpp b/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.cpp >index 32a1853bac47060594504b66a9798ad39563e64a..9324f18f91adf180b07c83fce4267060083b6bf0 100644 >--- a/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.cpp >+++ b/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.cpp >@@ -147,7 +147,7 @@ static cbor::CBORValue::MapValue createFidoAttestationStatementFromU2fRegisterRe > > } // namespace > >-Optional<PublicKeyCredentialData> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData) >+Optional<PublicKeyCredentialData> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, const AttestationConveyancePreference& attestation) > { > auto publicKey = extractECPublicKeyFromU2fRegistrationResponse(u2fData); > if (publicKey.isEmpty()) >@@ -168,7 +168,7 @@ Optional<PublicKeyCredentialData> readU2fRegisterResponse(const String& rpId, co > if (fidoAttestationStatement.empty()) > return WTF::nullopt; > >- auto attestationObject = buildAttestationObject(WTFMove(authData), "fido-u2f", WTFMove(fidoAttestationStatement)); >+ auto attestationObject = buildAttestationObject(WTFMove(authData), "fido-u2f", WTFMove(fidoAttestationStatement), attestation); > > return PublicKeyCredentialData { ArrayBuffer::create(credentialId.data(), credentialId.size()), true, nullptr, ArrayBuffer::create(attestationObject.data(), attestationObject.size()), nullptr, nullptr, nullptr, WTF::nullopt }; > } >diff --git a/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.h b/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.h >index 4c6d24e5b4f7e22a66b334f5f8734f9e4f148c42..9af282d34e8e7d934142bd5416432ad8703706ad 100644 >--- a/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.h >+++ b/Source/WebCore/Modules/webauthn/fido/U2fResponseConverter.h >@@ -31,6 +31,7 @@ > > #if ENABLE(WEB_AUTHN) > >+#include "AttestationConveyancePreference.h" > #include "PublicKeyCredentialData.h" > #include <wtf/Forward.h> > >@@ -38,7 +39,7 @@ namespace fido { > > // Converts a U2F register response to WebAuthN makeCredential response. > // https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html#u2f-authenticatorMakeCredential-interoperability >-WEBCORE_EXPORT Optional<WebCore::PublicKeyCredentialData> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData); >+WEBCORE_EXPORT Optional<WebCore::PublicKeyCredentialData> readU2fRegisterResponse(const String& rpId, const Vector<uint8_t>& u2fData, const WebCore::AttestationConveyancePreference& attestation = WebCore::AttestationConveyancePreference::Direct); > > // Converts a U2F authentication response to WebAuthN getAssertion response. > // https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html#u2f-authenticatorGetAssertion-interoperability >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 3675e004b8673e9d68b1c6bd8d468a0d4d41257e..897e712772388f713375b017892f2b198fa9da68 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -2516,6 +2516,7 @@ JSAudioListener.cpp > JSAudioNode.cpp > JSAudioParam.cpp > JSAudioProcessingEvent.cpp >+JSAttestationConveyancePreference.cpp > JSAuthenticationExtensionsClientInputs.cpp > JSAuthenticatorAssertionResponse.cpp > JSAuthenticatorAttestationResponse.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index f69cff232128cbbe8ea5cc1dee84070cb6f8701e..e8ff448c2cef591da184431908b15971a0285a62 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -1809,6 +1809,9 @@ > 57C7A68C1E56967500C67D71 /* BasicCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57C7A68B1E56967500C67D71 /* BasicCredential.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 57C7A69F1E57917800C67D71 /* JSBasicCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57C7A69D1E57910D00C67D71 /* JSBasicCredential.h */; }; > 57D0018D1DD5413200ED19D9 /* JSCryptoKeyUsage.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D0018C1DD5413200ED19D9 /* JSCryptoKeyUsage.h */; }; >+ 57D135252294A33C00827401 /* AttestationConveyancePreference.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D135212294973400827401 /* AttestationConveyancePreference.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 57D1352A2294AA3900827401 /* JSAuthenticationExtensionsClientInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 57DA47AD224032DD002A4612 /* JSAuthenticationExtensionsClientInputs.h */; }; >+ 57D1352C2294AA3D00827401 /* JSAttestationConveyancePreference.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D135262294A7A700827401 /* JSAttestationConveyancePreference.h */; }; > 57D8462E1FEAF69900CA3682 /* PublicKeyCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D8462B1FEAF68F00CA3682 /* PublicKeyCredential.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 57D846351FEAFCD300CA3682 /* JSPublicKeyCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D846301FEAFC2F00CA3682 /* JSPublicKeyCredential.h */; }; > 57DA47B0224034E4002A4612 /* AuthenticationExtensionsClientInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 57DA47A522401E0F002A4612 /* AuthenticationExtensionsClientInputs.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -8687,6 +8690,10 @@ > 57D0018B1DD3DBA400ED19D9 /* CryptoKeyUsage.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = CryptoKeyUsage.idl; sourceTree = "<group>"; }; > 57D0018C1DD5413200ED19D9 /* JSCryptoKeyUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCryptoKeyUsage.h; sourceTree = "<group>"; }; > 57D0018E1DD5415300ED19D9 /* JSCryptoKeyUsage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCryptoKeyUsage.cpp; sourceTree = "<group>"; }; >+ 57D135212294973400827401 /* AttestationConveyancePreference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AttestationConveyancePreference.h; sourceTree = "<group>"; }; >+ 57D135232294973400827401 /* AttestationConveyancePreference.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AttestationConveyancePreference.idl; sourceTree = "<group>"; }; >+ 57D135262294A7A700827401 /* JSAttestationConveyancePreference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAttestationConveyancePreference.h; sourceTree = "<group>"; }; >+ 57D135272294A7A800827401 /* JSAttestationConveyancePreference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAttestationConveyancePreference.cpp; sourceTree = "<group>"; }; > 57D846241FE895F500CA3682 /* NavigatorCredentials.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NavigatorCredentials.cpp; sourceTree = "<group>"; }; > 57D846251FE895F600CA3682 /* NavigatorCredentials.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorCredentials.idl; sourceTree = "<group>"; }; > 57D846261FE895F800CA3682 /* NavigatorCredentials.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorCredentials.h; sourceTree = "<group>"; }; >@@ -19526,6 +19533,8 @@ > 57152B5321CB2CE3000C37CA /* apdu */, > 57303BB32006C6ED00355965 /* cbor */, > 578A4BFA2166AE0000D08F34 /* fido */, >+ 57D135212294973400827401 /* AttestationConveyancePreference.h */, >+ 57D135232294973400827401 /* AttestationConveyancePreference.idl */, > 57DA47A522401E0F002A4612 /* AuthenticationExtensionsClientInputs.h */, > 57DA47A722401E0F002A4612 /* AuthenticationExtensionsClientInputs.idl */, > 57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */, >@@ -19564,6 +19573,8 @@ > 57D8462F1FEAFB0500CA3682 /* WebAuthN */ = { > isa = PBXGroup; > children = ( >+ 57D135272294A7A800827401 /* JSAttestationConveyancePreference.cpp */, >+ 57D135262294A7A700827401 /* JSAttestationConveyancePreference.h */, > 57DA47AC224032DC002A4612 /* JSAuthenticationExtensionsClientInputs.cpp */, > 57DA47AD224032DD002A4612 /* JSAuthenticationExtensionsClientInputs.h */, > 57303C2E2009B7DA00355965 /* JSAuthenticatorAssertionResponse.cpp */, >@@ -28178,6 +28189,7 @@ > FD5686CA13AC180200B69C68 /* AsyncAudioDecoder.h in Headers */, > E1CDE9221501916900862CC5 /* AsyncFileStream.h in Headers */, > 0FFD4D6118651FA300512F6E /* AsyncScrollingCoordinator.h in Headers */, >+ 57D135252294A33C00827401 /* AttestationConveyancePreference.h in Headers */, > A8C4A80D09D563270003AC8D /* Attr.h in Headers */, > A8C4A80B09D563270003AC8D /* Attribute.h in Headers */, > E4A814DA1C70E10D00BF85AC /* AttributeChangeInvalidation.h in Headers */, >@@ -29541,6 +29553,7 @@ > 7C6579F41E00856600E3A27A /* JSApplePayShippingMethod.h in Headers */, > 1AE96A931D1A0DDD00B86768 /* JSApplePayShippingMethodSelectedEvent.h in Headers */, > A12C59FE20360B4A0012236B /* JSApplePayShippingMethodUpdate.h in Headers */, >+ 57D1352C2294AA3D00827401 /* JSAttestationConveyancePreference.h in Headers */, > 65DF31DB09D1C123000BE325 /* JSAttr.h in Headers */, > FDA15E9E12B03EE1003A583A /* JSAudioBuffer.h in Headers */, > FDF7E9C413AC21DB00A51EAC /* JSAudioBufferCallback.h in Headers */, >@@ -29553,6 +29566,7 @@ > FDA15EB612B03EE1003A583A /* JSAudioProcessingEvent.h in Headers */, > BE8EF043171C8FF9009B48C3 /* JSAudioTrack.h in Headers */, > BE8EF045171C8FF9009B48C3 /* JSAudioTrackList.h in Headers */, >+ 57D1352A2294AA3900827401 /* JSAuthenticationExtensionsClientInputs.h in Headers */, > 57303C2F2009B7E100355965 /* JSAuthenticatorAssertionResponse.h in Headers */, > 57303C222009AF0300355965 /* JSAuthenticatorAttestationResponse.h in Headers */, > 57303BE120095D6100355965 /* JSAuthenticatorResponse.h in Headers */, >diff --git a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm b/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm >index 69ffedbacc794e9268ca86357c9b2847adb7e2a6..9c0314f9b3f689ca2148a369373717fec93e20ae 100644 >--- a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm >+++ b/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm >@@ -324,7 +324,7 @@ void LocalAuthenticator::continueMakeCredentialAfterAttested(SecKeyRef privateKe > cborArray.append(cbor::CBORValue(toVector((NSData *)adoptCF(SecCertificateCopyData((__bridge SecCertificateRef)certificates[i])).get()))); > attestationStatementMap[cbor::CBORValue("x5c")] = cbor::CBORValue(WTFMove(cborArray)); > } >- auto attestationObject = buildAttestationObject(WTFMove(authData), "Apple", WTFMove(attestationStatementMap)); >+ auto attestationObject = buildAttestationObject(WTFMove(authData), "Apple", WTFMove(attestationStatementMap), requestData().creationOptions.attestation); > > receiveRespond(PublicKeyCredentialData { ArrayBuffer::create(credentialId.data(), credentialId.size()), true, nullptr, ArrayBuffer::create(attestationObject.data(), attestationObject.size()), nullptr, nullptr, nullptr, WTF::nullopt }); > #endif // !PLATFORM(IOS_FAMILY) >diff --git a/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp b/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp >index 3541a8ca4e666f1b3e9b3ab2f70750592a96521e..dac805436332a5595ba8a19ee01649d4acd41609 100644 >--- a/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp >+++ b/Source/WebKit/UIProcess/WebAuthentication/fido/CtapHidAuthenticator.cpp >@@ -62,7 +62,7 @@ void CtapHidAuthenticator::makeCredential() > > void CtapHidAuthenticator::continueMakeCredentialAfterResponseReceived(Vector<uint8_t>&& data) const > { >- auto response = readCTAPMakeCredentialResponse(data); >+ auto response = readCTAPMakeCredentialResponse(data, requestData().creationOptions.attestation); > if (!response) { > auto error = getResponseCode(data); > if (error == CtapDeviceResponseCode::kCtap2ErrCredentialExcluded) >diff --git a/Source/WebKit/UIProcess/WebAuthentication/fido/U2fHidAuthenticator.cpp b/Source/WebKit/UIProcess/WebAuthentication/fido/U2fHidAuthenticator.cpp >index 1cde8291ec349aa065da224c99154cc316cc31b4..eceec0f7e87f722dc0fc8d84eaac7a3bf9b4e51b 100644 >--- a/Source/WebKit/UIProcess/WebAuthentication/fido/U2fHidAuthenticator.cpp >+++ b/Source/WebKit/UIProcess/WebAuthentication/fido/U2fHidAuthenticator.cpp >@@ -152,7 +152,7 @@ void U2fHidAuthenticator::continueRegisterCommandAfterResponseReceived(ApduRespo > { > switch (apduResponse.status()) { > case ApduResponse::Status::SW_NO_ERROR: { >- auto response = readU2fRegisterResponse(requestData().creationOptions.rp.id, apduResponse.data()); >+ auto response = readU2fRegisterResponse(requestData().creationOptions.rp.id, apduResponse.data(), requestData().creationOptions.attestation); > if (!response) { > receiveRespond(ExceptionData { UnknownError, "Couldn't parse the U2F register response."_s }); > return; >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index dbef1cc36c1db01e7a35196bbbbe16207e1af24a..cf5f63b22be6ce8140792f746d15ef27537fbfb9 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,15 @@ >+2019-05-22 Jiewen Tan <jiewen_tan@apple.com> >+ >+ [WebAuthN] Support Attestation Conveyance Preference >+ https://bugs.webkit.org/show_bug.cgi?id=192722 >+ <rdar://problem/49939647> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp: >+ (TestWebKitAPI::TEST): >+ Updates the test with AttestationConveyancePreference. >+ > 2019-05-20 Keith Rollin <krollin@apple.com> > > generate-xcfilelists is stranding temporary files >diff --git a/Tools/TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp b/Tools/TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp >index f5e4f143c69ea8529b58f7098fefeab7ab263b84..d3f02f6e90e11579ec76f7d851f8076039fdcb3c 100644 >--- a/Tools/TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp >+++ b/Tools/TestWebKitAPI/Tests/WebCore/CtapRequestTest.cpp >@@ -59,7 +59,7 @@ TEST(CTAPRequestTest, TestConstructMakeCredentialRequestParam) > Vector<PublicKeyCredentialCreationOptions::Parameters> params { { PublicKeyCredentialType::PublicKey, 7 }, { PublicKeyCredentialType::PublicKey, 257 } }; > PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria selection { PublicKeyCredentialCreationOptions::AuthenticatorAttachment::Platform, true, UserVerificationRequirement::Preferred }; > >- PublicKeyCredentialCreationOptions options { rp, user, { }, params, WTF::nullopt, { }, selection, WTF::nullopt }; >+ PublicKeyCredentialCreationOptions options { rp, user, { }, params, WTF::nullopt, { }, selection, AttestationConveyancePreference::None, WTF::nullopt }; > Vector<uint8_t> hash; > hash.append(TestData::kClientDataHash, sizeof(TestData::kClientDataHash)); > auto serializedData = encodeMakeCredenitalRequestAsCBOR(hash, options, AuthenticatorSupportedOptions::UserVerificationAvailability::kSupportedButNotConfigured); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index d725d104c55bb83fe99a25b055174bd7a704f833..f41b1e1eb8732fceb893bf8b2133f153556fa724 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,18 @@ >+2019-05-22 Jiewen Tan <jiewen_tan@apple.com> >+ >+ [WebAuthN] Support Attestation Conveyance Preference >+ https://bugs.webkit.org/show_bug.cgi?id=192722 >+ <rdar://problem/49939647> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt: >+ * http/wpt/webauthn/public-key-credential-create-success-hid.https.html: >+ * http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt: >+ * http/wpt/webauthn/public-key-credential-create-success-local.https.html: >+ * http/wpt/webauthn/public-key-credential-create-success-u2f.https-expected.txt: >+ * http/wpt/webauthn/public-key-credential-create-success-u2f.https.html: >+ > 2019-05-20 Chris Dumez <cdumez@apple.com> > > Fix security check in ScriptController::canAccessFromCurrentOrigin() >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt >index 59b2df747c7b99ca40d7c7ff0340b3bf189911dd..312de930e4db660127377f968ceacf80e51adfa6 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt >@@ -6,4 +6,7 @@ PASS PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a > PASS PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock local authenticator. > PASS PublicKeyCredential's [[create]] with mixed options in a mock local authenticator. > PASS PublicKeyCredential's [[create]] with two consecutive requests. >+PASS PublicKeyCredential's [[create]] with none attestation in a mock local authenticator. >+PASS PublicKeyCredential's [[create]] with direct attestation in a mock local authenticator. >+PASS PublicKeyCredential's [[create]] with indirect attestation in a mock local authenticator. > >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html >index 8437e9e76f2d125c51f217c1b6eb405013e7ce8b..a147ef37d5393deb969865f40b1eec75e95c7a5b 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html >@@ -9,7 +9,7 @@ > if (window.testRunner) > testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testCreationMessageBase64] } }); > >- function checkResult(credential) >+ function checkResult(credential, isNoneAttestation = true) > { > // Check response > assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64)); >@@ -20,18 +20,28 @@ > > // Check attestation > const attestationObject = CBOR.decode(credential.response.attestationObject); >- assert_equals(attestationObject.fmt, "packed"); >+ if (isNoneAttestation) >+ assert_equals(attestationObject.fmt, "none"); >+ else >+ assert_equals(attestationObject.fmt, "packed"); > // Check authData > const authData = decodeAuthData(attestationObject.authData); > assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8"); > assert_equals(authData.flags, 65); > assert_equals(authData.counter, 78); >- assert_equals(bytesToHexString(authData.aaguid), "f8a011f38c0a4d15800617111f9edc7d"); >+ if (isNoneAttestation) >+ assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000"); >+ else >+ assert_equals(bytesToHexString(authData.aaguid), "f8a011f38c0a4d15800617111f9edc7d"); > assert_array_equals(authData.credentialID, Base64URL.parse(testHidCredentialIdBase64)); > // Check packed attestation >- assert_equals(attestationObject.attStmt.alg, -7); > assert_true(checkPublicKey(authData.publicKey)); >- assert_equals(attestationObject.attStmt.x5c.length, 1); >+ if (isNoneAttestation) >+ assert_object_equals(attestationObject.attStmt, { }); >+ else { >+ assert_equals(attestationObject.attStmt.alg, -7); >+ assert_equals(attestationObject.attStmt.x5c.length, 1); >+ } > } > > promise_test(t => { >@@ -193,4 +203,73 @@ > checkResult(credential); > }); > }, "PublicKeyCredential's [[create]] with two consecutive requests."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "none", >+ timeout: 100 >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential); >+ }); >+ }, "PublicKeyCredential's [[create]] with none attestation in a mock local authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "direct", >+ timeout: 100 >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with direct attestation in a mock local authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "indirect", >+ timeout: 100 >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with indirect attestation in a mock local authenticator."); > </script> >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt >index f66c2676d979f6cb38fe9901d364d0431a9f9404..fadac211a7ce07f25a5d20ac9eeb22906c70fef7 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https-expected.txt >@@ -2,4 +2,7 @@ > PASS PublicKeyCredential's [[create]] with minimum options in a mock local authenticator. > PASS PublicKeyCredential's [[create]] with authenticatorSelection { 'platform' } in a mock local authenticator. > PASS PublicKeyCredential's [[create]] with matched exclude credential ids but not transports in a mock local authenticator. >+PASS PublicKeyCredential's [[create]] with none attestation in a mock local authenticator. >+PASS PublicKeyCredential's [[create]] with indirect attestation in a mock local authenticator. >+PASS PublicKeyCredential's [[create]] with direct attestation in a mock local authenticator. > >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html >index 69465b53349a951efcdf0e83481efc6a99a553a3..f155008c284bad9fcb4ec4f4f793ee2d2fcc7592 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html >@@ -17,7 +17,7 @@ > } > }); > >- function checkResult(credential) >+ function checkResult(credential, isNoneAttestation = true) > { > // Check keychain > if (window.testRunner) { >@@ -34,7 +34,10 @@ > > // Check attestation > const attestationObject = CBOR.decode(credential.response.attestationObject); >- assert_equals(attestationObject.fmt, "Apple"); >+ if (isNoneAttestation) >+ assert_equals(attestationObject.fmt, "none"); >+ else >+ assert_equals(attestationObject.fmt, "Apple"); > // Check authData > const authData = decodeAuthData(attestationObject.authData); > assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); >@@ -43,22 +46,32 @@ > assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000"); > assert_array_equals(authData.credentialID, Base64URL.parse(testCredentialIdBase64)); > // Check self attestation >- assert_equals(attestationObject.attStmt.alg, -7); > assert_true(checkPublicKey(authData.publicKey)); >- assert_equals(attestationObject.attStmt.x5c.length, 2); >- assert_array_equals(attestationObject.attStmt.x5c[0], Base64URL.parse(testAttestationCertificateBase64)); >- assert_array_equals(attestationObject.attStmt.x5c[1], Base64URL.parse(testAttestationIssuingCACertificateBase64)); >- >- // Check signature >- let publicKeyData = new Uint8Array(65); >- publicKeyData[0] = 0x04; >- publicKeyData.set(authData.publicKey['-2'], 1); >- publicKeyData.set(authData.publicKey['-3'], 33); >- return crypto.subtle.importKey("raw", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => { >- return crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, publicKey, extractRawSignature(attestationObject.attStmt.sig), attestationObject.authData).then( verified => { >- assert_true(verified); >+ if (isNoneAttestation) >+ assert_object_equals(attestationObject.attStmt, { }); >+ else { >+ assert_equals(attestationObject.attStmt.alg, -7); >+ assert_equals(attestationObject.attStmt.x5c.length, 2); >+ assert_array_equals(attestationObject.attStmt.x5c[0], Base64URL.parse(testAttestationCertificateBase64)); >+ assert_array_equals(attestationObject.attStmt.x5c[1], Base64URL.parse(testAttestationIssuingCACertificateBase64)); >+ >+ // Check signature >+ let publicKeyData = new Uint8Array(65); >+ publicKeyData[0] = 0x04; >+ publicKeyData.set(authData.publicKey['-2'], 1); >+ publicKeyData.set(authData.publicKey['-3'], 33); >+ return crypto.subtle.importKey("raw", publicKeyData, { >+ name: "ECDSA", >+ namedCurve: "P-256" >+ }, false, ['verify']).then(publicKey => { >+ return crypto.subtle.verify({ >+ name: "ECDSA", >+ hash: "SHA-256" >+ }, publicKey, extractRawSignature(attestationObject.attStmt.sig), attestationObject.authData).then(verified => { >+ assert_true(verified); >+ }); > }); >- }); >+ } > } > > promise_test(t => { >@@ -131,4 +144,70 @@ > checkResult(credential); > }); > }, "PublicKeyCredential's [[create]] with matched exclude credential ids but not transports in a mock local authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "none" >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential); >+ }); >+ }, "PublicKeyCredential's [[create]] with none attestation in a mock local authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "indirect" >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with indirect attestation in a mock local authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "direct" >+ } >+ }; >+ >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with direct attestation in a mock local authenticator."); > </script> >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https-expected.txt b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https-expected.txt >index 57b2617fa887f7131c2c0d8d239a8979bb3c4e5f..c85834d0d822545f55ce7b2224f3bb18a49297ea 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https-expected.txt >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https-expected.txt >@@ -3,4 +3,7 @@ PASS PublicKeyCredential's [[create]] with minimum options in a mock u2f authent > PASS PublicKeyCredential's [[create]] with excludeCredentials in a mock u2f authenticator. > PASS PublicKeyCredential's [[create]] with excludeCredentials in a mock u2f authenticator. 2 > PASS PublicKeyCredential's [[create]] with test of user presence in a mock u2f authenticator. >+PASS PublicKeyCredential's [[create]] with none attestation in a mock u2f authenticator. >+PASS PublicKeyCredential's [[create]] with indirect attestation in a mock u2f authenticator. >+PASS PublicKeyCredential's [[create]] with direct attestation in a mock u2f authenticator. > >diff --git a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html >index f50e5cbbb320e319b0975abba6bda82e0d652065..8fa1c3c48fa95c9c3b2b088861cb889e0fc1cc69 100644 >--- a/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html >+++ b/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html >@@ -5,7 +5,7 @@ > <script src="./resources/util.js"></script> > <script src="./resources/cbor.js"></script> > <script> >- function checkResult(credential) >+ function checkResult(credential, isNoneAttestation = true) > { > // Check response > assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testU2fCredentialIdBase64)); >@@ -16,7 +16,10 @@ > > // Check attestation > const attestationObject = CBOR.decode(credential.response.attestationObject); >- assert_equals(attestationObject.fmt, "fido-u2f"); >+ if (isNoneAttestation) >+ assert_equals(attestationObject.fmt, "none"); >+ else >+ assert_equals(attestationObject.fmt, "fido-u2f"); > // Check authData > const authData = decodeAuthData(attestationObject.authData); > assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); >@@ -26,7 +29,10 @@ > assert_array_equals(authData.credentialID, Base64URL.parse(testU2fCredentialIdBase64)); > // Check fido-u2f attestation > assert_true(checkPublicKey(authData.publicKey)); >- assert_equals(attestationObject.attStmt.x5c.length, 1); >+ if (isNoneAttestation) >+ assert_object_equals(attestationObject.attStmt, { }); >+ else >+ assert_equals(attestationObject.attStmt.x5c.length, 1); > } > > promise_test(t => { >@@ -126,4 +132,79 @@ > checkResult(credential); > }); > }, "PublicKeyCredential's [[create]] with test of user presence in a mock u2f authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "none", >+ timeout: 100 >+ } >+ }; >+ >+ if (window.testRunner) >+ testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential); >+ }); >+ }, "PublicKeyCredential's [[create]] with none attestation in a mock u2f authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "indirect", >+ timeout: 100 >+ } >+ }; >+ >+ if (window.testRunner) >+ testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with indirect attestation in a mock u2f authenticator."); >+ >+ promise_test(t => { >+ const options = { >+ publicKey: { >+ rp: { >+ name: "localhost", >+ }, >+ user: { >+ name: "John Appleseed", >+ id: Base64URL.parse(testUserhandleBase64), >+ displayName: "Appleseed", >+ }, >+ challenge: Base64URL.parse("MTIzNDU2"), >+ pubKeyCredParams: [{ type: "public-key", alg: -7 }], >+ attestation: "direct", >+ timeout: 100 >+ } >+ }; >+ >+ if (window.testRunner) >+ testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); >+ return navigator.credentials.create(options).then(credential => { >+ checkResult(credential, false); >+ }); >+ }, "PublicKeyCredential's [[create]] with direct attestation in a mock u2f authenticator."); > </script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192722
: 370389