Changeset 250659 in webkit
- Timestamp:
- Oct 3, 2019 10:39:32 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r250655 r250659 1 2019-10-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 Support googleLegacyAppidSupport extension 4 https://bugs.webkit.org/show_bug.cgi?id=202427 5 <rdar://problem/55887473> 6 7 Reviewed by Brent Fulgham. 8 9 Add tests to confirm the googleLegacyAppidSupport extension is ignored for RP ID != google.com. 10 11 * http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt: 12 * http/wpt/webauthn/public-key-credential-create-success-hid.https.html: 13 1 14 2019-10-03 Yury Semikhatsky <yurys@chromium.org> 2 15 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt
r249059 r250659 10 10 PASS PublicKeyCredential's [[create]] with direct attestation in a mock hid authenticator. 11 11 PASS PublicKeyCredential's [[create]] with indirect attestation in a mock hid authenticator. 12 PASS PublicKeyCredential's [[create]] with googleLegacyAppidSupport extension in a mock hid authenticator. 13 PASS PublicKeyCredential's [[create]] with googleLegacyAppidSupport and appid extensions in a mock hid authenticator. 12 14 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html
r249059 r250659 238 238 }); 239 239 }, "PublicKeyCredential's [[create]] with indirect attestation in a mock hid authenticator."); 240 241 // When RP ID is not google.com, googleLegacyAppidSupport should not have any effects. 242 promise_test(t => { 243 const options = { 244 publicKey: { 245 rp: { 246 name: "localhost", 247 }, 248 user: { 249 name: "John Appleseed", 250 id: Base64URL.parse(testUserhandleBase64), 251 displayName: "Appleseed", 252 }, 253 challenge: Base64URL.parse("MTIzNDU2"), 254 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 255 extensions: { googleLegacyAppidSupport: true }, 256 timeout: 100 257 } 258 }; 259 260 return navigator.credentials.create(options).then(credential => { 261 checkCtapMakeCredentialResult(credential); 262 }); 263 }, "PublicKeyCredential's [[create]] with googleLegacyAppidSupport extension in a mock hid authenticator."); 264 265 promise_test(t => { 266 const options = { 267 publicKey: { 268 rp: { 269 name: "localhost", 270 }, 271 user: { 272 name: "John Appleseed", 273 id: Base64URL.parse(testUserhandleBase64), 274 displayName: "Appleseed", 275 }, 276 challenge: Base64URL.parse("MTIzNDU2"), 277 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 278 extensions: { googleLegacyAppidSupport: true, appid: "" }, 279 timeout: 100 280 } 281 }; 282 283 return navigator.credentials.create(options).then(credential => { 284 checkCtapMakeCredentialResult(credential); 285 }); 286 }, "PublicKeyCredential's [[create]] with googleLegacyAppidSupport and appid extensions in a mock hid authenticator."); 240 287 </script> -
trunk/Source/WebCore/ChangeLog
r250655 r250659 1 2019-10-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 Support googleLegacyAppidSupport extension 4 https://bugs.webkit.org/show_bug.cgi?id=202427 5 <rdar://problem/55887473> 6 7 Reviewed by Brent Fulgham. 8 9 This patch adds support for googleLegacyAppidSupport extension, when set: 10 1) user agent should only use the U2F transport protocol, 11 2) should only communicate with roaming authenticators, and 12 3) should use a hard-coded appID of https://www.gstatic.com/securitykey/origins.json. 13 To be noticed as the name implies, this extension is exclusively for RP ID = google.com. 14 15 Implementation wise, all operations are captured in methods with name processGoogleLegacyAppIdSupportExtension. 16 1) AuthenticatorCoordinator takes care of setting the value. 17 2) U2fCommandConstructor takes care of hard coding the AppID. 18 3) AuthenticatorManager takes care of removing AuthenticatorTransport::Internal from TransportSet, so startDiscovery 19 will not poke platform authenticators. 20 4) CtapAuthenticator takes care of downgrading to U2fAuthenticator. 21 5) U2fAuthenticator takes care of setting the AppID in the response. 22 23 Partially covered by new test cases in existing tests, and remaining will be covered by manual tests. 24 25 * Modules/webauthn/AuthenticationExtensionsClientInputs.h: 26 (WebCore::AuthenticationExtensionsClientInputs::encode const): 27 (WebCore::AuthenticationExtensionsClientInputs::decode): 28 * Modules/webauthn/AuthenticationExtensionsClientInputs.idl: 29 * Modules/webauthn/AuthenticatorCoordinator.cpp: 30 (WebCore::AuthenticatorCoordinatorInternal::processGoogleLegacyAppIdSupportExtension): 31 (WebCore::AuthenticatorCoordinator::create const): 32 * Modules/webauthn/PublicKeyCredentialCreationOptions.h: 33 (WebCore::PublicKeyCredentialCreationOptions::encode const): 34 (WebCore::PublicKeyCredentialCreationOptions::decode): 35 * Modules/webauthn/fido/U2fCommandConstructor.cpp: 36 (fido::convertToU2fRegisterCommand): 37 (fido::processGoogleLegacyAppIdSupportExtension): 38 * Modules/webauthn/fido/U2fCommandConstructor.h: 39 1 40 2019-10-03 Yury Semikhatsky <yurys@chromium.org> 2 41 -
trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h
r243193 r250659 34 34 struct AuthenticationExtensionsClientInputs { 35 35 String appid; 36 bool googleLegacyAppidSupport; 36 37 37 38 template<class Encoder> void encode(Encoder&) const; … … 42 43 void AuthenticationExtensionsClientInputs::encode(Encoder& encoder) const 43 44 { 44 encoder << appid ;45 encoder << appid << googleLegacyAppidSupport; 45 46 } 46 47 … … 56 57 result.appid = WTFMove(*appid); 57 58 59 Optional<bool> googleLegacyAppidSupport; 60 decoder >> googleLegacyAppidSupport; 61 if (!googleLegacyAppidSupport) 62 return WTF::nullopt; 63 result.googleLegacyAppidSupport = WTFMove(*googleLegacyAppidSupport); 64 58 65 return result; 59 66 } -
trunk/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.idl
r243193 r250659 28 28 ] dictionary AuthenticationExtensionsClientInputs { 29 29 USVString appid; 30 // For Google to turn off the legacy AppID support. 31 boolean googleLegacyAppidSupport = true; 30 32 }; -
trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp
r244938 r250659 55 55 }; 56 56 57 // FIXME(181948): Add token binding ID and extensions.57 // FIXME(181948): Add token binding ID. 58 58 static Ref<ArrayBuffer> produceClientDataJson(ClientDataType type, const BufferSource& challenge, const SecurityOrigin& origin) 59 59 { … … 113 113 } 114 114 115 // The default behaviour for google.com is to always turn on the legacy AppID support. 116 static bool processGoogleLegacyAppIdSupportExtension(const Optional<AuthenticationExtensionsClientInputs>& extensions, const String& rpId) 117 { 118 if (rpId != "google.com"_s) 119 return false; 120 if (!extensions) 121 return true; 122 return extensions->googleLegacyAppidSupport; 123 } 124 115 125 } // namespace AuthenticatorCoordinatorInternal 116 126 … … 130 140 131 141 // The following implements https://www.w3.org/TR/webauthn/#createCredential as of 5 December 2017. 132 // Extensions are not supported. Skip Step 11-12.133 142 // Step 1, 3, 16 are handled by the caller. 134 143 // Step 2. … … 161 170 return; 162 171 } 172 173 // Step 11-12. 174 // Only Google Legacy AppID Support Extension is supported. 175 options.extensions = AuthenticationExtensionsClientInputs { String(), processGoogleLegacyAppIdSupportExtension(options.extensions, options.rp.id) }; 163 176 164 177 // Step 13-15. -
trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h
r245638 r250659 87 87 Optional<AuthenticatorSelectionCriteria> authenticatorSelection; 88 88 AttestationConveyancePreference attestation; 89 Optional<AuthenticationExtensionsClientInputs> extensions; // A place holder, but never used.89 mutable Optional<AuthenticationExtensionsClientInputs> extensions; 90 90 91 91 template<class Encoder> void encode(Encoder&) const; … … 145 145 encoder << static_cast<uint64_t>(user.id.length()); 146 146 encoder.encodeFixedLengthData(user.id.data(), user.id.length(), 1); 147 encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection << attestation ;147 encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection << attestation << extensions; 148 148 } 149 149 … … 190 190 result.attestation = WTFMove(*attestation); 191 191 192 Optional<Optional<AuthenticationExtensionsClientInputs>> extensions; 193 decoder >> extensions; 194 if (!extensions) 195 return WTF::nullopt; 196 result.extensions = WTFMove(*extensions); 197 192 198 return result; 193 199 } … … 196 202 197 203 namespace WTF { 198 // Not every member is copied.199 template<> struct CrossThreadCopierBase<false, false, WebCore::PublicKeyCredentialCreationOptions> {200 typedef WebCore::PublicKeyCredentialCreationOptions Type;201 static Type copy(const Type& source)202 {203 Type result;204 result.rp.name = source.rp.name.isolatedCopy();205 result.rp.icon = source.rp.icon.isolatedCopy();206 result.rp.id = source.rp.id.isolatedCopy();207 208 result.user.name = source.user.name.isolatedCopy();209 result.user.icon = source.user.icon.isolatedCopy();210 result.user.displayName = source.user.displayName.isolatedCopy();211 result.user.idVector = source.user.idVector;212 return result;213 }214 };215 204 216 205 template<> struct EnumTraits<WebCore::PublicKeyCredentialCreationOptions::AuthenticatorAttachment> { -
trunk/Source/WebCore/Modules/webauthn/fido/U2fCommandConstructor.cpp
r243193 r250659 104 104 return WTF::nullopt; 105 105 106 return constructU2fRegisterCommand(produceRpIdHash(request.rp.id), clientDataHash); 106 auto appId = processGoogleLegacyAppIdSupportExtension(request.extensions); 107 return constructU2fRegisterCommand(produceRpIdHash(!appId ? request.rp.id : appId), clientDataHash); 107 108 } 108 109 … … 131 132 } 132 133 134 String processGoogleLegacyAppIdSupportExtension(const Optional<AuthenticationExtensionsClientInputs>& extensions) 135 { 136 // AuthenticatorCoordinator::create should always set it. 137 ASSERT(!!extensions); 138 if (!extensions->googleLegacyAppidSupport) 139 return String(); 140 return "https://www.gstatic.com/securitykey/origins.json"_s; 141 } 142 133 143 } // namespace fido 134 144 -
trunk/Source/WebCore/Modules/webauthn/fido/U2fCommandConstructor.h
r243193 r250659 35 35 36 36 namespace WebCore { 37 struct AuthenticationExtensionsClientInputs; 37 38 struct PublicKeyCredentialCreationOptions; 38 39 struct PublicKeyCredentialDescriptor; … … 67 68 WEBCORE_EXPORT Vector<uint8_t> constructBogusU2fRegistrationCommand(); 68 69 70 // Returns "https://www.gstatic.com/securitykey/origins.json" as an AppID when googleLegacyAppidSupport is true. 71 WEBCORE_EXPORT String processGoogleLegacyAppIdSupportExtension(const Optional<WebCore::AuthenticationExtensionsClientInputs>&); 72 69 73 } // namespace fido 70 74 -
trunk/Source/WebKit/ChangeLog
r250658 r250659 1 2019-10-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 Support googleLegacyAppidSupport extension 4 https://bugs.webkit.org/show_bug.cgi?id=202427 5 <rdar://problem/55887473> 6 7 Reviewed by Brent Fulgham. 8 9 * UIProcess/WebAuthentication/AuthenticatorManager.cpp: 10 (WebKit::AuthenticatorManagerInternal::collectTransports): 11 (WebKit::AuthenticatorManagerInternal::processGoogleLegacyAppIdSupportExtension): 12 (WebKit::AuthenticatorManager::handleRequest): 13 * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp: 14 (WebKit::CtapAuthenticator::makeCredential): 15 (WebKit::CtapAuthenticator::processGoogleLegacyAppIdSupportExtension): 16 * UIProcess/WebAuthentication/fido/CtapAuthenticator.h: 17 * UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp: 18 (WebKit::U2fAuthenticator::continueRegisterCommandAfterResponseReceived): 19 1 20 2019-10-03 Jiewen Tan <jiewen_tan@apple.com> 2 21 -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
r249949 r250659 75 75 } 76 76 77 // FIXME(18862 4, 188625): Support NFC andBLE authenticators.77 // FIXME(188625): Support BLE authenticators. 78 78 // The goal is to find a union of different transports from allowCredentials. 79 79 // If it is not specified or any of its credentials doesn't specify its own. We should discover all. … … 100 100 return result; 101 101 } 102 if (!result.contains(AuthenticatorTransport::Internal) && allowCredential.transports.contains(AuthenticatorTransport::Internal)) 103 result.add(AuthenticatorTransport::Internal);104 if (!result.contains(AuthenticatorTransport::Usb) && allowCredential.transports.contains(AuthenticatorTransport::Usb))105 result.add(AuthenticatorTransport::Usb);106 if (!result.contains(AuthenticatorTransport::Nfc) && allowCredential.transports.contains(AuthenticatorTransport::Nfc))107 result.add(AuthenticatorTransport::Nfc);108 if (result.size() >= maxTransportNumber)109 return result;102 103 for (const auto& transport : allowCredential.transports) { 104 if (transport == AuthenticatorTransport::Ble) 105 continue; 106 result.add(transport); 107 if (result.size() >= maxTransportNumber) 108 return result; 109 } 110 110 } 111 111 112 112 ASSERT(result.size() < maxTransportNumber); 113 113 return result; 114 } 115 116 // Only roaming authenticators are supported for Google legacy AppID support. 117 static void processGoogleLegacyAppIdSupportExtension(const Optional<AuthenticationExtensionsClientInputs>& extensions, AuthenticatorManager::TransportSet& transports) 118 { 119 // AuthenticatorCoordinator::create should always set it. 120 ASSERT(!!extensions); 121 if (!extensions->googleLegacyAppidSupport) 122 return; 123 transports.remove(AuthenticatorTransport::Internal); 114 124 } 115 125 … … 138 148 WTF::switchOn(m_pendingRequestData.options, [&](const PublicKeyCredentialCreationOptions& options) { 139 149 initTimeOutTimer(options.timeout); 140 startDiscovery(collectTransports(options.authenticatorSelection)); 150 151 auto transports = collectTransports(options.authenticatorSelection); 152 processGoogleLegacyAppIdSupportExtension(options.extensions, transports); 153 startDiscovery(WTFMove(transports)); 141 154 }, [&](const PublicKeyCredentialRequestOptions& options) { 142 155 initTimeOutTimer(options.timeout); -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp
r249949 r250659 53 53 { 54 54 ASSERT(!m_isDowngraded); 55 if (processGoogleLegacyAppIdSupportExtension()) 56 return; 55 57 auto cborCmd = encodeMakeCredenitalRequestAsCBOR(requestData().hash, WTF::get<PublicKeyCredentialCreationOptions>(requestData().options), m_info.options().userVerificationAvailability()); 56 58 m_driver->transact(WTFMove(cborCmd), [weakThis = makeWeakPtr(*this)](Vector<uint8_t>&& data) { … … 114 116 } 115 117 118 // Only U2F protocol is supported for Google legacy AppID support. 119 bool CtapAuthenticator::processGoogleLegacyAppIdSupportExtension() 120 { 121 // AuthenticatorCoordinator::create should always set it. 122 auto& extensions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).extensions; 123 ASSERT(!!extensions); 124 if (extensions->googleLegacyAppidSupport) 125 tryDowngrade(); 126 return extensions->googleLegacyAppidSupport; 127 } 128 116 129 } // namespace WebKit 117 130 -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h
r249059 r250659 51 51 52 52 bool tryDowngrade(); 53 bool processGoogleLegacyAppIdSupportExtension(); 53 54 54 55 std::unique_ptr<CtapDriver> m_driver; -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp
r249949 r250659 156 156 switch (apduResponse.status()) { 157 157 case ApduResponse::Status::SW_NO_ERROR: { 158 auto response = readU2fRegisterResponse(WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).rp.id, apduResponse.data(), WTF::get<PublicKeyCredentialCreationOptions>(requestData().options).attestation); 158 auto& options = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options); 159 auto appId = processGoogleLegacyAppIdSupportExtension(options.extensions); 160 auto response = readU2fRegisterResponse(!appId ? options.rp.id : appId, apduResponse.data(), options.attestation); 159 161 if (!response) { 160 162 receiveRespond(ExceptionData { UnknownError, "Couldn't parse the U2F register response."_s }); -
trunk/Tools/ChangeLog
r250652 r250659 1 2019-10-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 Support googleLegacyAppidSupport extension 4 https://bugs.webkit.org/show_bug.cgi?id=202427 5 <rdar://problem/55887473> 6 7 Reviewed by Brent Fulgham. 8 9 Adds an API test for googleLegacyAppidSupport extension. 10 11 * TestWebKitAPI/Tests/WebCore/FidoTestData.h: 12 * TestWebKitAPI/Tests/WebCore/U2fCommandConstructorTest.cpp: 13 (TestWebKitAPI::constructMakeCredentialRequest): 14 (TestWebKitAPI::constructMakeCredentialRequestWithGoogleLegacyAppidSupport): 15 (TestWebKitAPI::TEST): 16 1 17 2019-10-03 Thibault Saunier <tsaunier@igalia.com> 2 18 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/FidoTestData.h
r249927 r250659 63 63 0xB6, 0x59, 0x5C, 0xFD, 0x70, 0xA5, 0x0D, 0x70, 0xC6, 0x40, 0x7B, 0xCF, 64 64 0x01, 0x3D, 0xE9, 0x6D, 0x4E, 0xFB, 0x17, 0xDE, 65 // Max response length 66 0x00, 0x00, 67 }; 68 69 constexpr uint8_t kU2fRegisterCommandApduWithGoogleLegacyAppidSupport[] = { 70 // CLA, INS, P1, P2 APDU instructions 71 0x00, 0x01, 0x03, 0x00, 72 // Data length in 3 bytes in big endian order. 73 0x00, 0x00, 0x40, 74 // Challenge parameter -- see kClientDataHash 75 0x68, 0x71, 0x34, 0x96, 0x82, 0x22, 0xec, 0x17, 0x20, 0x2e, 0x42, 76 0x50, 0x5f, 0x8e, 0xd2, 0xb1, 0x6a, 0xe2, 0x2f, 0x16, 0xbb, 0x05, 77 0xb8, 0x8c, 0x25, 0xdb, 0x9e, 0x60, 0x26, 0x45, 0xf1, 0x41, 78 // Application parameter 79 0xA5, 0x46, 0x72, 0xB2, 0x22, 0xC4, 0xCF, 0x95, 0xE1, 0x51, 0xED, 80 0x8D, 0x4D, 0x3C, 0x76, 0x7A, 0x6C, 0xC3, 0x49, 0x43, 0x59, 0x43, 81 0x79, 0x4E, 0x88, 0x4F, 0x3D, 0x02, 0x3A, 0x82, 0x29, 0xFD, 65 82 // Max response length 66 83 0x00, 0x00, -
trunk/Tools/TestWebKitAPI/Tests/WebCore/U2fCommandConstructorTest.cpp
r243193 r250659 60 60 params.alg = COSE::ES256; 61 61 62 AuthenticationExtensionsClientInputs extensions; 63 extensions.googleLegacyAppidSupport = false; 64 62 65 PublicKeyCredentialCreationOptions options; 63 66 options.rp = WTFMove(rp); 64 67 options.user = WTFMove(user); 65 68 options.pubKeyCredParams.append(WTFMove(params)); 66 69 options.extensions = WTFMove(extensions); 70 71 return options; 72 } 73 74 PublicKeyCredentialCreationOptions constructMakeCredentialRequestWithGoogleLegacyAppidSupport() 75 { 76 auto options = constructMakeCredentialRequest(); 77 options.extensions->googleLegacyAppidSupport = true; 67 78 return options; 68 79 } … … 84 95 ASSERT_TRUE(u2fRegisterCommand); 85 96 EXPECT_EQ(*u2fRegisterCommand, convertBytesToVector(TestData::kU2fRegisterCommandApdu, sizeof(TestData::kU2fRegisterCommandApdu))); 97 } 98 99 TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegisterWithGoogleLegacyAppidSupport) 100 { 101 const auto makeCredentialParam = constructMakeCredentialRequestWithGoogleLegacyAppidSupport(); 102 103 EXPECT_TRUE(isConvertibleToU2fRegisterCommand(makeCredentialParam)); 104 105 const auto u2fRegisterCommand = convertToU2fRegisterCommand(convertBytesToVector(TestData::kClientDataHash, sizeof(TestData::kClientDataHash)), makeCredentialParam); 106 ASSERT_TRUE(u2fRegisterCommand); 107 EXPECT_EQ(*u2fRegisterCommand, convertBytesToVector(TestData::kU2fRegisterCommandApduWithGoogleLegacyAppidSupport, sizeof(TestData::kU2fRegisterCommandApduWithGoogleLegacyAppidSupport))); 86 108 } 87 109
Note: See TracChangeset
for help on using the changeset viewer.