Changeset 249059 in webkit
- Timestamp:
- Aug 23, 2019, 11:56:03 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 16 added
- 31 edited
- 9 copied
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/wpt/webauthn/ctap-nfc-failure.https-expected.txt (added)
-
LayoutTests/http/wpt/webauthn/ctap-nfc-failure.https.html (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-nfc.https-expected.txt (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-nfc.https.html (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt (modified) (1 diff)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html (modified) (10 diffs)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-success-nfc.https-expected.txt (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-success-nfc.https.html (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html (modified) (8 diffs)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-nfc.https-expected.txt (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-nfc.https.html (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-success-hid.https.html (modified) (7 diffs)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-success-nfc.https-expected.txt (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-success-nfc.https.html (added)
-
LayoutTests/http/wpt/webauthn/public-key-credential-get-success-u2f.https.html (modified) (12 diffs)
-
LayoutTests/http/wpt/webauthn/resources/util.js (modified) (2 diffs)
-
LayoutTests/platform/ios-simulator-wk2/TestExpectations (modified) (1 diff)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/Platform.h (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/webauthn/apdu/ApduResponse.h (modified) (1 diff)
-
Source/WebCore/Modules/webauthn/fido/FidoConstants.h (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/Platform/spi/Cocoa/NearFieldSPI.h (added)
-
Source/WebKit/Sources.txt (modified) (1 diff)
-
Source/WebKit/SourcesCocoa.txt (modified) (1 diff)
-
Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (modified) (4 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp (modified) (7 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.cpp (modified) (3 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h (modified) (3 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.mm (modified) (3 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.mm (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcConnection.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcConnection.mm (added)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.mm (added)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.mm (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Mock/MockHidConnection.cpp (modified) (12 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Mock/MockNfcService.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/Mock/MockNfcService.mm (added)
-
Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h (modified) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp (added)
-
Source/WebKit/UIProcess/WebAuthentication/fido/CtapNfcDriver.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/fido/FidoService.cpp (added)
-
Source/WebKit/UIProcess/WebAuthentication/fido/FidoService.h (copied) (copied from trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h ) (3 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.h (modified) (2 diffs)
-
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (modified) (1 diff)
-
Source/WebKit/WebKit.xcodeproj/project.pbxproj (modified) (16 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r249051 r249059 1 2019-08-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Support NFC authenticators for iOS 4 https://bugs.webkit.org/show_bug.cgi?id=188624 5 <rdar://problem/43354214> 6 7 Reviewed by Chris Dumez. 8 9 * http/wpt/webauthn/ctap-nfc-failure.https-expected.txt: Added. 10 * http/wpt/webauthn/ctap-nfc-failure.https.html: Added. 11 * http/wpt/webauthn/public-key-credential-create-failure-nfc.https-expected.txt: Added. 12 * http/wpt/webauthn/public-key-credential-create-failure-nfc.https.html: Added. 13 * http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt: 14 * http/wpt/webauthn/public-key-credential-create-success-hid.https.html: 15 This patch replaces the "local" keyword with "hid". 16 * http/wpt/webauthn/public-key-credential-create-success-nfc.https-expected.txt: Added. 17 * http/wpt/webauthn/public-key-credential-create-success-nfc.https.html: Added. 18 * http/wpt/webauthn/public-key-credential-get-failure-nfc.https-expected.txt: Added. 19 * http/wpt/webauthn/public-key-credential-get-failure-nfc.https.html: Added. 20 * http/wpt/webauthn/public-key-credential-get-success-nfc.https-expected.txt: Added. 21 * http/wpt/webauthn/public-key-credential-get-success-nfc.https.html: Added. 22 * http/wpt/webauthn/resources/util.js: 23 * platform/ios-simulator-wk2/TestExpectations: 24 Skip NFC tests for simulators. 25 1 26 2019-08-23 Russell Epstein <repstein@apple.com> 2 27 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https-expected.txt
r245638 r249059 1 1 2 PASS PublicKeyCredential's [[create]] with minimum options in a mock localauthenticator.3 PASS PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock localauthenticator.4 PASS PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock localauthenticator.5 PASS PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock localauthenticator.6 PASS PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock localauthenticator.7 PASS PublicKeyCredential's [[create]] with mixed options in a mock localauthenticator.2 PASS PublicKeyCredential's [[create]] with minimum options in a mock hid authenticator. 3 PASS PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock hid authenticator. 4 PASS PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock hid authenticator. 5 PASS PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock hid authenticator. 6 PASS PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock hid authenticator. 7 PASS PublicKeyCredential's [[create]] with mixed options in a mock hid authenticator. 8 8 PASS PublicKeyCredential's [[create]] with two consecutive requests. 9 PASS PublicKeyCredential's [[create]] with none attestation in a mock localauthenticator.10 PASS PublicKeyCredential's [[create]] with direct attestation in a mock localauthenticator.11 PASS PublicKeyCredential's [[create]] with indirect attestation in a mock localauthenticator.9 PASS PublicKeyCredential's [[create]] with none attestation in a mock hid authenticator. 10 PASS PublicKeyCredential's [[create]] with direct attestation in a mock hid authenticator. 11 PASS PublicKeyCredential's [[create]] with indirect attestation in a mock hid authenticator. 12 12 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-hid.https.html
r245638 r249059 10 10 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testCreationMessageBase64] } }); 11 11 12 function checkResult(credential, isNoneAttestation = true) 13 { 14 // Check response 15 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64)); 16 assert_equals(credential.type, 'public-key'); 17 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64)); 18 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); 19 assert_not_exists(credential.getClientExtensionResults(), "appid"); 20 21 // Check attestation 22 const attestationObject = CBOR.decode(credential.response.attestationObject); 23 if (isNoneAttestation) 24 assert_equals(attestationObject.fmt, "none"); 25 else 26 assert_equals(attestationObject.fmt, "packed"); 27 // Check authData 28 const authData = decodeAuthData(attestationObject.authData); 29 assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8"); 30 assert_equals(authData.flags, 65); 31 assert_equals(authData.counter, 78); 32 if (isNoneAttestation) 33 assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000"); 34 else 35 assert_equals(bytesToHexString(authData.aaguid), "f8a011f38c0a4d15800617111f9edc7d"); 36 assert_array_equals(authData.credentialID, Base64URL.parse(testHidCredentialIdBase64)); 37 // Check packed attestation 38 assert_true(checkPublicKey(authData.publicKey)); 39 if (isNoneAttestation) 40 assert_object_equals(attestationObject.attStmt, { }); 41 else { 42 assert_equals(attestationObject.attStmt.alg, -7); 43 assert_equals(attestationObject.attStmt.x5c.length, 1); 44 } 45 } 46 47 promise_test(t => { 48 const options = { 49 publicKey: { 50 rp: { 51 name: "localhost", 52 }, 53 user: { 54 name: "John Appleseed", 55 id: Base64URL.parse(testUserhandleBase64), 56 displayName: "Appleseed", 57 }, 58 challenge: Base64URL.parse("MTIzNDU2"), 59 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 60 timeout: 100 61 } 62 }; 63 64 return navigator.credentials.create(options).then(credential => { 65 checkResult(credential); 66 }); 67 }, "PublicKeyCredential's [[create]] with minimum options in a mock local authenticator."); 12 promise_test(t => { 13 const options = { 14 publicKey: { 15 rp: { 16 name: "localhost", 17 }, 18 user: { 19 name: "John Appleseed", 20 id: Base64URL.parse(testUserhandleBase64), 21 displayName: "Appleseed", 22 }, 23 challenge: Base64URL.parse("MTIzNDU2"), 24 pubKeyCredParams: [{ type: "public-key", alg: -7 }], 25 timeout: 100 26 } 27 }; 28 29 return navigator.credentials.create(options).then(credential => { 30 checkCtapMakeCredentialResult(credential); 31 }); 32 }, "PublicKeyCredential's [[create]] with minimum options in a mock hid authenticator."); 68 33 69 34 promise_test(t => { … … 86 51 87 52 return navigator.credentials.create(options).then(credential => { 88 check Result(credential);89 }); 90 }, "PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock localauthenticator.");53 checkCtapMakeCredentialResult(credential); 54 }); 55 }, "PublicKeyCredential's [[create]] with authenticatorSelection { 'cross-platform' } in a mock hid authenticator."); 91 56 92 57 promise_test(t => { … … 109 74 110 75 return navigator.credentials.create(options).then(credential => { 111 check Result(credential);112 }); 113 }, "PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock localauthenticator.");76 checkCtapMakeCredentialResult(credential); 77 }); 78 }, "PublicKeyCredential's [[create]] with requireResidentKey { false } in a mock hid authenticator."); 114 79 115 80 promise_test(t => { … … 132 97 133 98 return navigator.credentials.create(options).then(credential => { 134 check Result(credential);135 }); 136 }, "PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock localauthenticator.");99 checkCtapMakeCredentialResult(credential); 100 }); 101 }, "PublicKeyCredential's [[create]] with userVerification { 'preferred' } in a mock hid authenticator."); 137 102 138 103 promise_test(t => { … … 155 120 156 121 return navigator.credentials.create(options).then(credential => { 157 check Result(credential);158 }); 159 }, "PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock localauthenticator.");122 checkCtapMakeCredentialResult(credential); 123 }); 124 }, "PublicKeyCredential's [[create]] with userVerification { 'discouraged' } in a mock hid authenticator."); 160 125 161 126 promise_test(t => { … … 178 143 179 144 return navigator.credentials.create(options).then(credential => { 180 check Result(credential);181 }); 182 }, "PublicKeyCredential's [[create]] with mixed options in a mock localauthenticator.");145 checkCtapMakeCredentialResult(credential); 146 }); 147 }, "PublicKeyCredential's [[create]] with mixed options in a mock hid authenticator."); 183 148 184 149 promise_test(t => { … … 201 166 promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "This request has been voided by a new request."); 202 167 return navigator.credentials.create(options).then(credential => { 203 check Result(credential);168 checkCtapMakeCredentialResult(credential); 204 169 }); 205 170 }, "PublicKeyCredential's [[create]] with two consecutive requests."); … … 224 189 225 190 return navigator.credentials.create(options).then(credential => { 226 check Result(credential);227 }); 228 }, "PublicKeyCredential's [[create]] with none attestation in a mock localauthenticator.");191 checkCtapMakeCredentialResult(credential); 192 }); 193 }, "PublicKeyCredential's [[create]] with none attestation in a mock hid authenticator."); 229 194 230 195 promise_test(t => { … … 247 212 248 213 return navigator.credentials.create(options).then(credential => { 249 check Result(credential, false);250 }); 251 }, "PublicKeyCredential's [[create]] with direct attestation in a mock localauthenticator.");214 checkCtapMakeCredentialResult(credential, false); 215 }); 216 }, "PublicKeyCredential's [[create]] with direct attestation in a mock hid authenticator."); 252 217 253 218 promise_test(t => { … … 270 235 271 236 return navigator.credentials.create(options).then(credential => { 272 check Result(credential, false);273 }); 274 }, "PublicKeyCredential's [[create]] with indirect attestation in a mock localauthenticator.");237 checkCtapMakeCredentialResult(credential, false); 238 }); 239 }, "PublicKeyCredential's [[create]] with indirect attestation in a mock hid authenticator."); 275 240 </script> -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-u2f.https.html
r245638 r249059 6 6 <script src="./resources/cbor.js"></script> 7 7 <script> 8 function checkResult(credential, isNoneAttestation = true)9 {10 // Check response11 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testU2fCredentialIdBase64));12 assert_equals(credential.type, 'public-key');13 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testU2fCredentialIdBase64));14 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');15 assert_not_exists(credential.getClientExtensionResults(), "appid");16 17 // Check attestation18 const attestationObject = CBOR.decode(credential.response.attestationObject);19 if (isNoneAttestation)20 assert_equals(attestationObject.fmt, "none");21 else22 assert_equals(attestationObject.fmt, "fido-u2f");23 // Check authData24 const authData = decodeAuthData(attestationObject.authData);25 assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");26 assert_equals(authData.flags, 65);27 assert_equals(authData.counter, 0);28 assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000");29 assert_array_equals(authData.credentialID, Base64URL.parse(testU2fCredentialIdBase64));30 // Check fido-u2f attestation31 assert_true(checkPublicKey(authData.publicKey));32 if (isNoneAttestation)33 assert_object_equals(attestationObject.attStmt, { });34 else35 assert_equals(attestationObject.attStmt.x5c.length, 1);36 }37 38 8 promise_test(t => { 39 9 const options = { … … 56 26 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); 57 27 return navigator.credentials.create(options).then(credential => { 58 check Result(credential);28 checkU2fMakeCredentialResult(credential); 59 29 }); 60 30 }, "PublicKeyCredential's [[create]] with minimum options in a mock u2f authenticator."); … … 81 51 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fRegisterResponse] } }); 82 52 return navigator.credentials.create(options).then(credential => { 83 check Result(credential);53 checkU2fMakeCredentialResult(credential); 84 54 }); 85 55 }, "PublicKeyCredential's [[create]] with excludeCredentials in a mock u2f authenticator."); … … 106 76 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fApduWrongDataOnlyResponseBase64, testU2fRegisterResponse] } }); 107 77 return navigator.credentials.create(options).then(credential => { 108 check Result(credential);78 checkU2fMakeCredentialResult(credential); 109 79 }); 110 80 }, "PublicKeyCredential's [[create]] with excludeCredentials in a mock u2f authenticator. 2"); … … 130 100 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduConditionsNotSatisfiedOnlyResponseBase64, testU2fApduConditionsNotSatisfiedOnlyResponseBase64, testU2fRegisterResponse] } }); 131 101 return navigator.credentials.create(options).then(credential => { 132 check Result(credential);102 checkU2fMakeCredentialResult(credential); 133 103 }); 134 104 }, "PublicKeyCredential's [[create]] with test of user presence in a mock u2f authenticator."); … … 155 125 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); 156 126 return navigator.credentials.create(options).then(credential => { 157 check Result(credential);127 checkU2fMakeCredentialResult(credential); 158 128 }); 159 129 }, "PublicKeyCredential's [[create]] with none attestation in a mock u2f authenticator."); … … 180 150 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); 181 151 return navigator.credentials.create(options).then(credential => { 182 check Result(credential, false);152 checkU2fMakeCredentialResult(credential, false); 183 153 }); 184 154 }, "PublicKeyCredential's [[create]] with indirect attestation in a mock u2f authenticator."); … … 205 175 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fRegisterResponse] } }); 206 176 return navigator.credentials.create(options).then(credential => { 207 check Result(credential, false);177 checkU2fMakeCredentialResult(credential, false); 208 178 }); 209 179 }, "PublicKeyCredential's [[create]] with direct attestation in a mock u2f authenticator."); -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-hid.https.html
r245052 r249059 9 9 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", payloadBase64: [testAssertionMessageBase64] } }); 10 10 11 function checkResult(credential)12 {13 // Check respond14 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64));15 assert_equals(credential.type, 'public-key');16 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64));17 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');18 assert_equals(credential.response.userHandle, null);19 assert_not_exists(credential.getClientExtensionResults(), "appid");20 21 // Check authData22 const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData));23 assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8");24 assert_equals(authData.flags, 1);25 assert_equals(authData.counter, 80);26 }27 28 11 promise_test(t => { 29 12 const options = { … … 35 18 36 19 return navigator.credentials.get(options).then(credential => { 37 return check Result(credential);20 return checkCtapGetAssertionResult(credential); 38 21 }); 39 22 }, "PublicKeyCredential's [[get]] with minimum options in a mock hid authenticator."); … … 51 34 52 35 return navigator.credentials.get(options).then(credential => { 53 return check Result(credential);36 return checkCtapGetAssertionResult(credential); 54 37 }); 55 38 }, "PublicKeyCredential's [[get]] with matched allow credentials in a mock hid authenticator."); … … 65 48 66 49 return navigator.credentials.get(options).then(credential => { 67 return check Result(credential);50 return checkCtapGetAssertionResult(credential); 68 51 }); 69 52 }, "PublicKeyCredential's [[get]] with userVerification { preferred } in a mock hid authenticator."); … … 79 62 80 63 return navigator.credentials.get(options).then(credential => { 81 return check Result(credential);64 return checkCtapGetAssertionResult(credential); 82 65 }); 83 66 }, "PublicKeyCredential's [[get]] with userVerification { discouraged } in a mock hid authenticator."); … … 96 79 97 80 return navigator.credentials.get(options).then(credential => { 98 return check Result(credential);81 return checkCtapGetAssertionResult(credential); 99 82 }); 100 83 }, "PublicKeyCredential's [[get]] with mixed options in a mock hid authenticator."); … … 110 93 promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "This request has been voided by a new request."); 111 94 return navigator.credentials.get(options).then(credential => { 112 return check Result(credential);95 return checkCtapGetAssertionResult(credential); 113 96 }); 114 97 }, "PublicKeyCredential's [[get]] with two consecutive requests."); -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-u2f.https.html
r245500 r249059 5 5 <script src="./resources/util.js"></script> 6 6 <script> 7 const defaultAppIDHash = "c2671b6eb9233197d5f2b1288a55ba4f0860f96f7199bba32fe6da7c3f0f31e5";8 9 function checkResult(credential, isAppID = false, appIDHash = defaultAppIDHash)10 {11 // Check respond12 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testU2fCredentialIdBase64));13 assert_equals(credential.type, 'public-key');14 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testU2fCredentialIdBase64));15 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}');16 assert_equals(credential.response.userHandle, null);17 if (!isAppID)18 assert_not_exists(credential.getClientExtensionResults(), "appid");19 else20 assert_true(credential.getClientExtensionResults().appid);21 22 // Check authData23 const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData));24 if (!isAppID)25 assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");26 else27 assert_equals(bytesToHexString(authData.rpIdHash), appIDHash);28 assert_equals(authData.flags, 1);29 assert_equals(authData.counter, 59);30 }31 32 7 promise_test(t => { 33 8 const options = { … … 42 17 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fSignResponse] } }); 43 18 return navigator.credentials.get(options).then(credential => { 44 return check Result(credential);19 return checkU2fGetAssertionResult(credential); 45 20 }); 46 21 }, "PublicKeyCredential's [[get]] with minimum options in a mock hid authenticator."); … … 58 33 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 59 34 return navigator.credentials.get(options).then(credential => { 60 return check Result(credential);35 return checkU2fGetAssertionResult(credential); 61 36 }); 62 37 }, "PublicKeyCredential's [[get]] with more allow credentials in a mock hid authenticator."); … … 74 49 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduConditionsNotSatisfiedOnlyResponseBase64, testU2fApduConditionsNotSatisfiedOnlyResponseBase64, testU2fSignResponse] } }); 75 50 return navigator.credentials.get(options).then(credential => { 76 return check Result(credential);51 return checkU2fGetAssertionResult(credential); 77 52 }); 78 53 }, "PublicKeyCredential's [[get]] with test of user presence in a mock hid authenticator."); … … 92 67 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fSignResponse] } }); 93 68 return navigator.credentials.get(options).then(credential => { 94 return check Result(credential);69 return checkU2fGetAssertionResult(credential); 95 70 }); 96 71 }, "PublicKeyCredential's [[get]] with empty extensions in a mock hid authenticator."); … … 109 84 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fSignResponse] } }); 110 85 return navigator.credentials.get(options).then(credential => { 111 return check Result(credential);86 return checkU2fGetAssertionResult(credential); 112 87 }); 113 88 }, "PublicKeyCredential's [[get]] with same site AppID but not used in a mock hid authenticator."); … … 126 101 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 127 102 return navigator.credentials.get(options).then(credential => { 128 return check Result(credential, true);103 return checkU2fGetAssertionResult(credential, true); 129 104 }); 130 105 }, "PublicKeyCredential's [[get]] with empty AppID in a mock hid authenticator."); … … 144 119 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 145 120 return navigator.credentials.get(options).then(credential => { 146 return check Result(credential, true, "7eabc5cc3251bdc59115ef87b5f7ee74cb03747e39ba8341748565cc129c0719");121 return checkU2fGetAssertionResult(credential, true, "7eabc5cc3251bdc59115ef87b5f7ee74cb03747e39ba8341748565cc129c0719"); 147 122 }); 148 123 }, "PublicKeyCredential's [[get]] with an AppID in a mock hid authenticator."); … … 161 136 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 162 137 return navigator.credentials.get(options).then(credential => { 163 return check Result(credential);138 return checkU2fGetAssertionResult(credential); 164 139 }); 165 140 }, "PublicKeyCredential's [[get]] with multiple credentials and AppID is not used in a mock hid authenticator."); … … 178 153 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", isU2f: true, payloadBase64: [testU2fApduWrongDataOnlyResponseBase64, testU2fApduWrongDataOnlyResponseBase64, testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 179 154 return navigator.credentials.get(options).then(credential => { 180 return check Result(credential, true);155 return checkU2fGetAssertionResult(credential, true); 181 156 }); 182 157 }, "PublicKeyCredential's [[get]] with multiple credentials and AppID is used in a mock hid authenticator."); … … 195 170 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", canDowngrade: true, payloadBase64: [testCtapErrInvalidCredentialResponseBase64, testU2fSignResponse] } }); 196 171 return navigator.credentials.get(options).then(credential => { 197 return check Result(credential);172 return checkU2fGetAssertionResult(credential); 198 173 }); 199 174 }, "PublicKeyCredential's [[get]] with downgraded authenticator in a mock hid authenticator."); … … 212 187 testRunner.setWebAuthenticationMockConfiguration({ hid: { stage: "request", subStage: "msg", error: "success", canDowngrade: true, payloadBase64: [testCtapErrInvalidCredentialResponseBase64, testU2fApduWrongDataOnlyResponseBase64, testU2fSignResponse] } }); 213 188 return navigator.credentials.get(options).then(credential => { 214 return check Result(credential, true, "7eabc5cc3251bdc59115ef87b5f7ee74cb03747e39ba8341748565cc129c0719");189 return checkU2fGetAssertionResult(credential, true, "7eabc5cc3251bdc59115ef87b5f7ee74cb03747e39ba8341748565cc129c0719"); 215 190 }); 216 191 }, "PublicKeyCredential's [[get]] with downgraded authenticator in a mock hid authenticator. (AppID)"); -
trunk/LayoutTests/http/wpt/webauthn/resources/util.js
r245500 r249059 100 100 const testCtapErrCredentialExcludedOnlyResponseBase64 = "GQ=="; 101 101 const testCtapErrInvalidCredentialResponseBase64 = "Ig=="; 102 const testNfcU2fVersionBase64 = "VTJGX1YykAA="; 103 const testNfcCtapVersionBase64 = "RklET18yXzCQAA=="; 104 const testGetInfoResponseApduBase64 = 105 "AKYBgmZVMkZfVjJoRklET18yXzACgWtobWFjLXNlY3JldANQbUS6m/bsLkm5MAyP" + 106 "6SDLcwSkYnJr9WJ1cPVkcGxhdPRpY2xpZW50UGlu9AUZBLAGgQGQAA=="; 107 const testCreationMessageApduBase64 = 108 "AKMBZnBhY2tlZAJYxEbMf7lnnVWy25CS4cjZ5eHQK3WA8LSBLHcJYuHkj1rYQQAA" + 109 "AE74oBHzjApNFYAGFxEfntx9AEAoCK3O6P5OyXN6V/f+9nAga0NA2Cgp4V3mgSJ5" + 110 "jOHLMDrmxp/S0rbD+aihru1C0aAN3BkiM6GNy5nSlDVqOgTgpQECAyYgASFYIEFb" + 111 "he3RkNud6sgyraBGjlh1pzTlCZehQlL/b18HZ6WGIlggJgfUd/en9p5AIqMQbUni" + 112 "nEeXdFLkvW0/zV5BpEjjNxADo2NhbGcmY3NpZ1hHMEUCIQDKg+ZBmEBtf0lWq4Re" + 113 "dH4/i/LOYqOR4uR2NAj2zQmw9QIgbTXb4hvFbj4T27bv/rGrc+y+0puoYOBkBk9P" + 114 "mCewWlNjeDVjgVkCwjCCAr4wggGmoAMCAQICBHSG/cIwDQYJKoZIhvcNAQELBQAw" + 115 "LjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEw" + 116 "IBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG8xCzAJBgNVBAYTAlNF" + 117 "MRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0" + 118 "ZXN0YXRpb24xKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2VyaWFsIDE5NTUwMDM4" + 119 "NDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVXfOt9yR9MXXv/ZzE8xpOh466" + 120 "4YEJVmFQ+ziLLl9lJ79XQJqlgaUNCsUvGERcChNUihNTyKTlmnBOUjvATevto2ww" + 121 "ajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLl" + 122 "HAIBAQQEAwIFIDAhBgsrBgEEAYLlHAEBBAQSBBD4oBHzjApNFYAGFxEfntx9MAwG" + 123 "A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADFcSIDmmlJ+OGaJvWn9Cqhv" + 124 "SeueToVFQVVvqtALOgCKHdwB+Wx29mg2GpHiMsgQp5xjB0ybbnpG6x212FxESJ+G" + 125 "inZD0ipchi7APwPlhIvjgH16zVX44a4e4hOsc6tLIOP71SaMsHuHgCcdH0vg5d2s" + 126 "c006WJe9TXO6fzV+ogjJnYpNKQLmCXoAXE3JBNwKGBIOCvfQDPyWmiiG5bGxYfPt" + 127 "y8Z3pnjX+1MDnM2hhr40ulMxlSNDnX/ZSnDyMGIbk8TOQmjTF02UO8auP8k3wt5D" + 128 "1rROIRU9+FCSX5WQYi68RuDrGMZB8P5+byoJqbKQdxn2LmE1oZAyohPAmLcoPO6Q" + 129 "AA=="; 130 const testAssertionMessageApduBase64 = 131 "AKMBomJpZFhAKAitzuj+Tslzelf3/vZwIGtDQNgoKeFd5oEieYzhyzA65saf0tK2" + 132 "w/mooa7tQtGgDdwZIjOhjcuZ0pQ1ajoE4GR0eXBlanB1YmxpYy1rZXkCWCVGzH+5" + 133 "Z51VstuQkuHI2eXh0Ct1gPC0gSx3CWLh5I9a2AEAAABQA1hHMEUCIQCSFTuuBWgB" + 134 "4/F0VB7DlUVM09IHPmxe1MzHUwRoCRZbCAIgGKov6xoAx2MEf6/6qNs8OutzhP2C" + 135 "QoJ1L7Fe64G9uBeQAA=="; 102 136 103 137 const RESOURCES_DIR = "/WebKit/webauthn/resources/"; … … 298 332 return true; 299 333 } 334 335 function checkCtapMakeCredentialResult(credential, isNoneAttestation = true) 336 { 337 // Check response 338 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64)); 339 assert_equals(credential.type, 'public-key'); 340 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64)); 341 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); 342 assert_not_exists(credential.getClientExtensionResults(), "appid"); 343 344 // Check attestation 345 const attestationObject = CBOR.decode(credential.response.attestationObject); 346 if (isNoneAttestation) 347 assert_equals(attestationObject.fmt, "none"); 348 else 349 assert_equals(attestationObject.fmt, "packed"); 350 // Check authData 351 const authData = decodeAuthData(attestationObject.authData); 352 assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8"); 353 assert_equals(authData.flags, 65); 354 assert_equals(authData.counter, 78); 355 if (isNoneAttestation) 356 assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000"); 357 else 358 assert_equals(bytesToHexString(authData.aaguid), "f8a011f38c0a4d15800617111f9edc7d"); 359 assert_array_equals(authData.credentialID, Base64URL.parse(testHidCredentialIdBase64)); 360 // Check packed attestation 361 assert_true(checkPublicKey(authData.publicKey)); 362 if (isNoneAttestation) 363 assert_object_equals(attestationObject.attStmt, { }); 364 else { 365 assert_equals(attestationObject.attStmt.alg, -7); 366 assert_equals(attestationObject.attStmt.x5c.length, 1); 367 } 368 } 369 370 function checkU2fMakeCredentialResult(credential, isNoneAttestation = true) 371 { 372 // Check response 373 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testU2fCredentialIdBase64)); 374 assert_equals(credential.type, 'public-key'); 375 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testU2fCredentialIdBase64)); 376 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); 377 assert_not_exists(credential.getClientExtensionResults(), "appid"); 378 379 // Check attestation 380 const attestationObject = CBOR.decode(credential.response.attestationObject); 381 if (isNoneAttestation) 382 assert_equals(attestationObject.fmt, "none"); 383 else 384 assert_equals(attestationObject.fmt, "fido-u2f"); 385 // Check authData 386 const authData = decodeAuthData(attestationObject.authData); 387 assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); 388 assert_equals(authData.flags, 65); 389 assert_equals(authData.counter, 0); 390 assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000"); 391 assert_array_equals(authData.credentialID, Base64URL.parse(testU2fCredentialIdBase64)); 392 // Check fido-u2f attestation 393 assert_true(checkPublicKey(authData.publicKey)); 394 if (isNoneAttestation) 395 assert_object_equals(attestationObject.attStmt, { }); 396 else 397 assert_equals(attestationObject.attStmt.x5c.length, 1); 398 } 399 400 function checkCtapGetAssertionResult(credential) 401 { 402 // Check respond 403 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testHidCredentialIdBase64)); 404 assert_equals(credential.type, 'public-key'); 405 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testHidCredentialIdBase64)); 406 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); 407 assert_equals(credential.response.userHandle, null); 408 assert_not_exists(credential.getClientExtensionResults(), "appid"); 409 410 // Check authData 411 const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData)); 412 assert_equals(bytesToHexString(authData.rpIdHash), "46cc7fb9679d55b2db9092e1c8d9e5e1d02b7580f0b4812c770962e1e48f5ad8"); 413 assert_equals(authData.flags, 1); 414 assert_equals(authData.counter, 80); 415 } 416 417 function checkU2fGetAssertionResult(credential, isAppID = false, appIDHash = "c2671b6eb9233197d5f2b1288a55ba4f0860f96f7199bba32fe6da7c3f0f31e5") 418 { 419 // Check respond 420 assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testU2fCredentialIdBase64)); 421 assert_equals(credential.type, 'public-key'); 422 assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testU2fCredentialIdBase64)); 423 assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443"}'); 424 assert_equals(credential.response.userHandle, null); 425 if (!isAppID) 426 assert_not_exists(credential.getClientExtensionResults(), "appid"); 427 else 428 assert_true(credential.getClientExtensionResults().appid); 429 430 // Check authData 431 const authData = decodeAuthData(new Uint8Array(credential.response.authenticatorData)); 432 if (!isAppID) 433 assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763"); 434 else 435 assert_equals(bytesToHexString(authData.rpIdHash), appIDHash); 436 assert_equals(authData.flags, 1); 437 assert_equals(authData.counter, 59); 438 } -
trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations
r248734 r249059 90 90 91 91 webkit.org/b/172001 scrollingcoordinator/ios/sync-layer-positions-after-scroll.html [ Pass Failure ] 92 93 # NearField.framework doesn't present in the simulator, and therefore skip all WebAuthn NFC tests 94 http/wpt/webauthn/ctap-nfc-failure.https.html [ Skip ] 95 http/wpt/webauthn/public-key-credential-create-failure-nfc.https.html [ Skip ] 96 http/wpt/webauthn/public-key-credential-create-success-nfc.https.html [ Skip ] 97 http/wpt/webauthn/public-key-credential-get-failure-nfc.https.html [ Skip ] 98 http/wpt/webauthn/public-key-credential-get-success-nfc.https.html [ Skip ] -
trunk/Source/WTF/ChangeLog
r249036 r249059 1 2019-08-21 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Support NFC authenticators for iOS 4 https://bugs.webkit.org/show_bug.cgi?id=188624 5 <rdar://problem/43354214> 6 7 Reviewed by Chris Dumez. 8 9 * wtf/Platform.h: 10 Add a feature flag for NearField. 11 1 12 2019-08-22 Andy Estes <aestes@apple.com> 2 13 -
trunk/Source/WTF/wtf/Platform.h
r249036 r249059 1642 1642 #define HAVE_DATA_PROTECTION_KEYCHAIN 1 1643 1643 #endif 1644 1645 #if !PLATFORM(IOS_FAMILY_SIMULATOR) 1646 #define HAVE_NEAR_FIELD 1 1647 #endif 1648 1649 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) 1650 #define HAVE_NF_READER_SESSION_UPDATE_UI_ALERT_MESSAGE 1 1651 #endif -
trunk/Source/WebCore/ChangeLog
r249058 r249059 1 2019-08-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Support NFC authenticators for iOS 4 https://bugs.webkit.org/show_bug.cgi?id=188624 5 <rdar://problem/43354214> 6 7 Reviewed by Chris Dumez. 8 9 Tests: http/wpt/webauthn/ctap-nfc-failure.https.html 10 http/wpt/webauthn/public-key-credential-create-failure-nfc.https.html 11 http/wpt/webauthn/public-key-credential-create-success-nfc.https.html 12 http/wpt/webauthn/public-key-credential-get-failure-nfc.https.html 13 http/wpt/webauthn/public-key-credential-get-success-nfc.https.html 14 15 * Modules/webauthn/apdu/ApduResponse.h: 16 Adds a new method to support moving m_data. 17 * Modules/webauthn/fido/FidoConstants.h: 18 Adds constants for NFC applet selection. 19 1 20 2019-08-23 Ross Kirsling <ross.kirsling@sony.com> 2 21 -
trunk/Source/WebCore/Modules/webauthn/apdu/ApduResponse.h
r242776 r249059 62 62 63 63 const Vector<uint8_t>& data() const { return m_data; } 64 Vector<uint8_t>& data() { return m_data; } 64 65 Status status() const { return m_responseStatus; } 65 66 -
trunk/Source/WebCore/Modules/webauthn/fido/FidoConstants.h
r245638 r249059 221 221 // CTAPHID Usage Page and Usage 222 222 // https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html#hid-report-descriptor-and-device-discovery 223 const uint32_t kCTAPHIDUsagePage = 0xF1D0; 224 const uint32_t kCTAPHIDUsage = 0x01; 223 const uint32_t kCtapHidUsagePage = 0xF1D0; 224 const uint32_t kCtapHidUsage = 0x01; 225 226 // CTAPNFC Applet selection command and responses 227 // https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#nfc-applet-selection 228 const uint8_t kCtapNfcAppletSelectionCommand[] = { 229 0x00, 0xA4, 0x04, 0x00, // CLA, INS, P1, P2 230 0x08, // L 231 0xA0, 0x00, 0x00, 0x06, 0x47, // RID 232 0x2F, 0x00, 0x01 // PIX 233 }; 234 235 const uint8_t kCtapNfcAppletSelectionU2f[] = { 236 0x55, 0x32, 0x46, 0x5F, 0x56, 0x32, // Version 237 0x90, 0x00 // APDU response code 238 }; 239 240 const uint8_t kCtapNfcAppletSelectionCtap[] = { 241 0x46, 0x49, 0x44, 0x4f, 0x5f, 0x32, 0x5f, 0x30, // Version 242 0x90, 0x00 // APDU response code 243 }; 244 245 // https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#nfc-command-framing 246 const uint8_t kCtapNfcApduCla = 0x80; 247 const uint8_t kCtapNfcApduIns = 0x10; 225 248 226 249 } // namespace fido -
trunk/Source/WebKit/ChangeLog
r249056 r249059 1 2019-08-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Support NFC authenticators for iOS 4 https://bugs.webkit.org/show_bug.cgi?id=188624 5 <rdar://problem/43354214> 6 7 Reviewed by Chris Dumez. 8 9 This patch implements support for NFC authenticators including both FIDO2 and U2F ones. It utilizes a private 10 framework called NearField instead of CoreNFC to be able to supply a custom UI later if necessary. 11 12 The patch follows almost the same flow as previous HID and Local authenticator support. 13 1) Discovery is via NfcService which will invoke NFHardwareManager to start a generic NFC reader session. 14 2) Once a reader session is established, a NfcConnection is created to start the polling and register the WKNFReaderSessionDelegate 15 to wait for 'didDetectTags'. 16 3) When tags are detected, NfcConnection will determine if it meets our requriements: { type, connectability, fido applet availability }. 17 The first tag that meets all requirement will then be returned for WebAuthn operations. 18 4) The first WebAuthn operation is to send authenticatorGetInfo command to determine the supported protocol, and then initialize corresponding 19 authenticators. Noted, the sending/receiving of this command is now abstracted into FidoService which will be shared across HidService and NfcService. 20 5) From then, the actual WebAuthn request, either makeCredential or getAssertion will be sent. 21 22 For testing, this patch follows the same flow as well. 23 1) MockNfcService overrides NfcService to mock the behavior of NFC Tags discovery. 24 2) The same class also swizzles methods from NFReaderSession to mock tag connection and communication. 25 26 * Platform/spi/Cocoa/NearFieldSPI.h: Added. 27 * Sources.txt: 28 * SourcesCocoa.txt: 29 * UIProcess/API/C/WKWebsiteDataStoreRef.cpp: 30 (WKWebsiteDataStoreSetWebAuthenticationMockConfiguration): 31 * UIProcess/WebAuthentication/AuthenticatorManager.cpp: 32 (WebKit::AuthenticatorManagerInternal::collectTransports): 33 * UIProcess/WebAuthentication/AuthenticatorTransportService.cpp: 34 (WebKit::AuthenticatorTransportService::create): 35 (WebKit::AuthenticatorTransportService::createMock): 36 * UIProcess/WebAuthentication/Cocoa/HidService.h: 37 * UIProcess/WebAuthentication/Cocoa/HidService.mm: 38 (WebKit::HidService::HidService): 39 (WebKit::HidService::deviceAdded): 40 (WebKit::HidService::continueAddDeviceAfterGetInfo): Deleted. 41 * UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 42 * UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.mm: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 43 * UIProcess/WebAuthentication/Cocoa/NfcConnection.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 44 * UIProcess/WebAuthentication/Cocoa/NfcConnection.mm: Added. 45 (WebKit::fido::compareVersion): 46 (WebKit::NfcConnection::NfcConnection): 47 (WebKit::NfcConnection::~NfcConnection): 48 (WebKit::NfcConnection::transact const): 49 (WebKit::NfcConnection::didDetectTags const): 50 * UIProcess/WebAuthentication/Cocoa/NfcService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 51 * UIProcess/WebAuthentication/Cocoa/NfcService.mm: Added. 52 (WebKit::NfcService::NfcService): 53 (WebKit::NfcService::~NfcService): 54 (WebKit::NfcService::didConnectTag): 55 (WebKit::NfcService::startDiscoveryInternal): 56 (WebKit::NfcService::platformStartDiscovery): 57 * UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 58 * UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.mm: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 59 (-[WKNFReaderSessionDelegate initWithConnection:]): 60 (-[WKNFReaderSessionDelegate readerSession:didDetectTags:]): 61 * UIProcess/WebAuthentication/Mock/MockHidConnection.cpp: 62 (WebKit::MockHidConnection::send): 63 (WebKit::MockHidConnection::registerDataReceivedCallbackInternal): 64 (WebKit::MockHidConnection::parseRequest): 65 (WebKit::MockHidConnection::feedReports): 66 (WebKit::MockHidConnection::shouldContinueFeedReports): 67 * UIProcess/WebAuthentication/Mock/MockNfcService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 68 * UIProcess/WebAuthentication/Mock/MockNfcService.mm: Added. 69 (-[WKMockNFTag type]): 70 (-[WKMockNFTag initWithNFTag:]): 71 (-[WKMockNFTag description]): 72 (-[WKMockNFTag isEqualToNFTag:]): 73 (-[WKMockNFTag initWithType:]): 74 (WebKit::MockNfcService::MockNfcService): 75 (WebKit::MockNfcService::transceive): 76 (WebKit::MockNfcService::platformStartDiscovery): 77 (WebKit::MockNfcService::detectTags const): 78 * UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h: 79 * UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp: 80 * UIProcess/WebAuthentication/fido/CtapAuthenticator.h: 81 * UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp: Added. 82 (WebKit::CtapNfcDriver::CtapNfcDriver): 83 (WebKit::CtapNfcDriver::transact): 84 (WebKit::CtapNfcDriver::respondAsync const): 85 * UIProcess/WebAuthentication/fido/CtapNfcDriver.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 86 * UIProcess/WebAuthentication/fido/FidoService.cpp: Added. 87 (WebKit::FidoService::FidoService): 88 (WebKit::FidoService::getInfo): 89 (WebKit::FidoService::continueAfterGetInfo): 90 * UIProcess/WebAuthentication/fido/FidoService.h: Copied from Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h. 91 * UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp: 92 * UIProcess/WebAuthentication/fido/U2fAuthenticator.h: 93 * UIProcess/ios/WebPageProxyIOS.mm: 94 * WebKit.xcodeproj/project.pbxproj: 95 1 96 2019-08-23 Kate Cheney <katherine_cheney@apple.com> 2 97 -
trunk/Source/WebKit/Sources.txt
r248734 r249059 409 409 UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp 410 410 UIProcess/WebAuthentication/fido/CtapHidDriver.cpp 411 UIProcess/WebAuthentication/fido/CtapNfcDriver.cpp 412 UIProcess/WebAuthentication/fido/FidoService.cpp 411 413 UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp 412 414 -
trunk/Source/WebKit/SourcesCocoa.txt
r249001 r249059 498 498 UIProcess/WebAuthentication/Cocoa/LocalConnection.mm 499 499 UIProcess/WebAuthentication/Cocoa/LocalService.mm 500 UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.mm @no-unify 501 UIProcess/WebAuthentication/Cocoa/NfcConnection.mm 502 UIProcess/WebAuthentication/Cocoa/NfcService.mm 503 UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.mm 500 504 501 505 UIProcess/WebAuthentication/Mock/MockLocalConnection.mm 502 506 UIProcess/WebAuthentication/Mock/MockLocalService.mm 507 UIProcess/WebAuthentication/Mock/MockNfcService.mm 503 508 504 509 UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm -
trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
r248734 r249059 633 633 if (stage == "info") 634 634 hid.stage = WebKit::MockWebAuthenticationConfiguration::Hid::Stage::Info; 635 if (stage == "request")635 else if (stage == "request") 636 636 hid.stage = WebKit::MockWebAuthenticationConfiguration::Hid::Stage::Request; 637 637 … … 639 639 if (subStage == "init") 640 640 hid.subStage = WebKit::MockWebAuthenticationConfiguration::Hid::SubStage::Init; 641 if (subStage == "msg")641 else if (subStage == "msg") 642 642 hid.subStage = WebKit::MockWebAuthenticationConfiguration::Hid::SubStage::Msg; 643 643 … … 645 645 if (error == "success") 646 646 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::Success; 647 if (error == "data-not-sent")647 else if (error == "data-not-sent") 648 648 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::DataNotSent; 649 if (error == "empty-report")649 else if (error == "empty-report") 650 650 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::EmptyReport; 651 if (error == "wrong-channel-id")651 else if (error == "wrong-channel-id") 652 652 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::WrongChannelId; 653 if (error == "malicious-payload")653 else if (error == "malicious-payload") 654 654 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::MaliciousPayload; 655 if (error == "unsupported-options")655 else if (error == "unsupported-options") 656 656 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::UnsupportedOptions; 657 if (error == "wrong-nonce")657 else if (error == "wrong-nonce") 658 658 hid.error = WebKit::MockWebAuthenticationConfiguration::Hid::Error::WrongNonce; 659 659 … … 679 679 } 680 680 681 if (auto nfcRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Nfc")).get()))) { 682 WebKit::MockWebAuthenticationConfiguration::Nfc nfc; 683 684 auto error = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(nfcRef, adoptWK(WKStringCreateWithUTF8CString("Error")).get())))->string(); 685 if (error == "success") 686 nfc.error = WebKit::MockWebAuthenticationConfiguration::Nfc::Error::Success; 687 else if (error == "no-tags") 688 nfc.error = WebKit::MockWebAuthenticationConfiguration::Nfc::Error::NoTags; 689 else if (error == "wrong-tag-type") 690 nfc.error = WebKit::MockWebAuthenticationConfiguration::Nfc::Error::WrongTagType; 691 else if (error == "no-connections") 692 nfc.error = WebKit::MockWebAuthenticationConfiguration::Nfc::Error::NoConnections; 693 else if (error == "malicious-payload") 694 nfc.error = WebKit::MockWebAuthenticationConfiguration::Nfc::Error::MaliciousPayload; 695 696 if (auto payloadBase64 = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(nfcRef, adoptWK(WKStringCreateWithUTF8CString("PayloadBase64")).get()))) 697 nfc.payloadBase64 = WebKit::toImpl(payloadBase64)->toStringVector(); 698 699 if (auto multipleTags = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(nfcRef, adoptWK(WKStringCreateWithUTF8CString("MultipleTags")).get()))) 700 nfc.multipleTags = WKBooleanGetValue(multipleTags); 701 702 configuration.nfc = WTFMove(nfc); 703 } 704 681 705 WebKit::toImpl(dataStoreRef)->websiteDataStore().setMockWebAuthenticationConfiguration(WTFMove(configuration)); 682 706 #endif -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
r246369 r249059 39 39 40 40 #if PLATFORM(MAC) 41 const size_t maxTransportNumber = 3; 42 #else 41 43 const size_t maxTransportNumber = 2; 42 #else43 const size_t maxTransportNumber = 1;44 44 #endif 45 45 … … 47 47 const unsigned maxTimeOutValue = 120000; 48 48 49 // FIXME(18862 4, 188625): Support NFC andBLE authenticators.49 // FIXME(188625): Support BLE authenticators. 50 50 static AuthenticatorManager::TransportSet collectTransports(const Optional<PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria>& authenticatorSelection) 51 51 { … … 58 58 ASSERT_UNUSED(addResult, addResult.isNewEntry); 59 59 #endif 60 addResult = result.add(AuthenticatorTransport::Nfc); 61 ASSERT_UNUSED(addResult, addResult.isNewEntry); 60 62 return result; 61 63 } … … 67 69 } 68 70 if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform) { 69 #if PLATFORM(MAC) 70 auto addResult = result.add(AuthenticatorTransport::Usb); 71 auto addResult = result.add(AuthenticatorTransport::Nfc); 72 ASSERT_UNUSED(addResult, addResult.isNewEntry); 73 #if PLATFORM(MAC) 74 addResult = result.add(AuthenticatorTransport::Usb); 71 75 ASSERT_UNUSED(addResult, addResult.isNewEntry); 72 76 #endif … … 93 97 ASSERT_UNUSED(addResult, addResult.isNewEntry); 94 98 #endif 99 addResult = result.add(AuthenticatorTransport::Nfc); 100 ASSERT_UNUSED(addResult, addResult.isNewEntry); 95 101 return result; 96 102 } … … 101 107 #if PLATFORM(MAC) 102 108 result.add(AuthenticatorTransport::Usb); 109 #endif 110 result.add(AuthenticatorTransport::Nfc); 103 111 return result; 104 #endif105 112 } 106 113 if (!result.contains(AuthenticatorTransport::Internal) && allowCredential.transports.contains(AuthenticatorTransport::Internal)) … … 110 117 result.add(AuthenticatorTransport::Usb); 111 118 #endif 119 if (!result.contains(AuthenticatorTransport::Nfc) && allowCredential.transports.contains(AuthenticatorTransport::Nfc)) 120 result.add(AuthenticatorTransport::Nfc); 112 121 if (result.size() >= maxTransportNumber) 113 122 return result; -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorTransportService.cpp
r238166 r249059 33 33 #include "MockHidService.h" 34 34 #include "MockLocalService.h" 35 #include "MockNfcService.h" 36 #include "NfcService.h" 35 37 #include <wtf/RunLoop.h> 36 38 … … 46 48 return makeUniqueRef<HidService>(observer); 47 49 #endif 50 case WebCore::AuthenticatorTransport::Nfc: 51 return makeUniqueRef<NfcService>(observer); 48 52 default: 49 53 ASSERT_NOT_REACHED(); … … 61 65 return makeUniqueRef<MockHidService>(observer, configuration); 62 66 #endif 67 case WebCore::AuthenticatorTransport::Nfc: 68 return makeUniqueRef<MockNfcService>(observer, configuration); 63 69 default: 64 70 ASSERT_NOT_REACHED(); -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.h
r238468 r249059 28 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC) 29 29 30 #include " AuthenticatorTransportService.h"30 #include "FidoService.h" 31 31 #include <IOKit/hid/IOHIDManager.h> 32 32 #include <wtf/RetainPtr.h> … … 35 35 namespace WebKit { 36 36 37 class CtapHidDriver;38 37 class HidConnection; 39 38 40 class HidService : public AuthenticatorTransportService {39 class HidService : public FidoService { 41 40 public: 42 41 explicit HidService(Observer&); … … 52 51 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 52 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info);55 56 53 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators.58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers;59 54 }; 60 55 -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/HidService.mm
r248846 r249059 29 29 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC) 30 30 31 #import "CtapAuthenticator.h"32 31 #import "CtapHidDriver.h" 33 32 #import "HidConnection.h" 34 #import "U2fAuthenticator.h"35 #import <WebCore/DeviceRequestConverter.h>36 #import <WebCore/DeviceResponseConverter.h>37 #import <WebCore/FidoConstants.h>38 #import <WebCore/FidoHidMessage.h>39 #import <wtf/RunLoop.h>40 33 41 34 namespace WebKit { … … 57 50 58 51 HidService::HidService(Observer& observer) 59 : AuthenticatorTransportService(observer)52 : FidoService(observer) 60 53 { 61 54 m_manager = adoptCF(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); 62 55 NSDictionary *matchingDictionary = @{ 63 @kIOHIDPrimaryUsagePageKey: adoptNS([NSNumber numberWithInt:kC TAPHIDUsagePage]).get(),64 @kIOHIDPrimaryUsageKey: adoptNS([NSNumber numberWithInt:kC TAPHIDUsage]).get()56 @kIOHIDPrimaryUsagePageKey: adoptNS([NSNumber numberWithInt:kCtapHidUsagePage]).get(), 57 @kIOHIDPrimaryUsageKey: adoptNS([NSNumber numberWithInt:kCtapHidUsage]).get() 65 58 }; 66 59 IOHIDManagerSetDeviceMatching(m_manager.get(), (__bridge CFDictionaryRef)matchingDictionary); … … 93 86 void HidService::deviceAdded(IOHIDDeviceRef device) 94 87 { 95 auto driver = makeUnique<CtapHidDriver>(createHidConnection(device)); 96 // Get authenticator info from the device. 97 driver->transact(encodeEmptyAuthenticatorRequest(CtapRequestCommand::kAuthenticatorGetInfo), [weakThis = makeWeakPtr(*this), ptr = driver.get()](Vector<uint8_t>&& response) { 98 ASSERT(RunLoop::isMain()); 99 if (!weakThis) 100 return; 101 weakThis->continueAddDeviceAfterGetInfo(ptr, WTFMove(response)); 102 }); 103 auto addResult = m_drivers.add(WTFMove(driver)); 104 ASSERT_UNUSED(addResult, addResult.isNewEntry); 105 } 106 107 void HidService::continueAddDeviceAfterGetInfo(CtapHidDriver* ptr, Vector<uint8_t>&& response) 108 { 109 std::unique_ptr<CtapHidDriver> driver = m_drivers.take(ptr); 110 if (!driver || !observer() || response.isEmpty()) 111 return; 112 113 auto info = readCTAPGetInfoResponse(response); 114 if (info && info->versions().find(ProtocolVersion::kCtap) != info->versions().end()) { 115 observer()->authenticatorAdded(CtapAuthenticator::create(WTFMove(driver), WTFMove(*info))); 116 return; 117 } 118 LOG_ERROR("Couldn't parse a ctap get info response."); 119 driver->setProtocol(ProtocolVersion::kU2f); 120 observer()->authenticatorAdded(U2fAuthenticator::create(WTFMove(driver))); 88 getInfo(WTF::makeUnique<CtapHidDriver>(createHidConnection(device))); 121 89 } 122 90 -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 30 #import "NearFieldSPI.h" 31 #import <wtf/SoftLinking.h> 34 32 35 namespace WebKit { 33 SOFT_LINK_FRAMEWORK_FOR_HEADER(WebKit, NearField); 36 34 37 class CtapHidDriver; 38 class HidConnection; 35 SOFT_LINK_CLASS_FOR_HEADER(WebKit, NFTag); 36 SOFT_LINK_CLASS_FOR_HEADER(WebKit, NFSession); 37 SOFT_LINK_CLASS_FOR_HEADER(WebKit, NFReaderSession); 38 SOFT_LINK_CLASS_FOR_HEADER(WebKit, NFHardwareManager); 39 39 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 44 45 void deviceAdded(IOHIDDeviceRef); 46 47 private: 48 void startDiscoveryInternal() final; 49 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 59 }; 60 61 } // namespace WebKit 62 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC) 40 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NearFieldSoftLink.mm
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 # pragma once26 #import "config.h" 27 27 28 #i f ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #import <wtf/SoftLinking.h> 29 29 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 30 #if ENABLE(WEB_AUTHN) 34 31 35 namespace WebKit { 32 SOFT_LINK_PRIVATE_FRAMEWORK_FOR_SOURCE(WebKit, NearField); 36 33 37 class CtapHidDriver; 38 class HidConnection; 34 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, NearField, NFTag); 35 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, NearField, NFSession); 36 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, NearField, NFReaderSession); 39 37 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 38 #if PLATFORM(MAC) 39 SOFT_LINK_CLASS_FOR_SOURCE_OPTIONAL(WebKit, NearField, NFHardwareManager); 40 #else 41 SOFT_LINK_CLASS_FOR_SOURCE(WebKit, NearField, NFHardwareManager); 42 #endif 44 43 45 void deviceAdded(IOHIDDeviceRef); 46 47 private: 48 void startDiscoveryInternal() final; 49 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 59 }; 60 61 } // namespace WebKit 62 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC) 44 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcConnection.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) 29 29 30 #include "AuthenticatorTransportService.h"31 #include < IOKit/hid/IOHIDManager.h>30 #include <wtf/FastMalloc.h> 31 #include <wtf/Noncopyable.h> 32 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 33 #include <wtf/WeakPtr.h> 34 35 OBJC_CLASS NFReaderSession; 36 OBJC_CLASS NSArray; 37 OBJC_CLASS WKNFReaderSessionDelegate; 34 38 35 39 namespace WebKit { 36 40 37 class CtapHidDriver; 38 class HidConnection; 41 class NfcService; 39 42 40 class HidService : public AuthenticatorTransportService { 43 class NfcConnection : public CanMakeWeakPtr<NfcConnection> { 44 WTF_MAKE_FAST_ALLOCATED; 45 WTF_MAKE_NONCOPYABLE(NfcConnection); 41 46 public: 42 explicit HidService(Observer&);43 ~ HidService();47 NfcConnection(RetainPtr<NFReaderSession>&&, NfcService&); 48 ~NfcConnection(); 44 49 45 void deviceAdded(IOHIDDeviceRef); 50 Vector<uint8_t> transact(Vector<uint8_t>&& data) const; 51 52 // For WKNFReaderSessionDelegate 53 void didDetectTags(NSArray *) const; 46 54 47 55 private: 48 void startDiscoveryInternal() final; 49 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 56 RetainPtr<NFReaderSession> m_session; 57 RetainPtr<WKNFReaderSessionDelegate> m_delegate; 58 WeakPtr<NfcService> m_service; 59 59 }; 60 60 61 61 } // namespace WebKit 62 62 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)63 #endif // ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 30 #include "FidoService.h" 31 32 OBJC_CLASS NFReaderSession; 34 33 35 34 namespace WebKit { 36 35 37 class CtapHidDriver; 38 class HidConnection; 36 class CtapNfcDriver; 39 37 40 class HidService : public AuthenticatorTransportService {38 class NfcService : public FidoService { 41 39 public: 42 explicit HidService(Observer&);43 ~ HidService();40 explicit NfcService(Observer&); 41 ~NfcService(); 44 42 45 void deviceAdded(IOHIDDeviceRef); 43 // For NfcConnection. 44 void didConnectTag(); 45 46 #if HAVE(NEAR_FIELD) 47 protected: 48 void setDriver(std::unique_ptr<CtapNfcDriver>&&); 49 #endif 46 50 47 51 private: 48 52 void startDiscoveryInternal() final; 53 void continueAddDeviceAfterGetInfo(Vector<uint8_t>&& response); 49 54 50 // Overrided by Mock HidService.55 // Overrided by MockNfcService. 51 56 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const;53 57 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager;57 // Keeping drivers alive when they are initializing authenticators.58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 58 #if HAVE(NEAR_FIELD) 59 // Only one reader session is allowed per time. 60 // Keep the reader session alive here when it tries to connect to a tag. 61 std::unique_ptr<CtapNfcDriver> m_driver; 62 #endif 59 63 }; 60 64 61 65 } // namespace WebKit 62 66 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)67 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) 29 29 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 30 #import "NearFieldSPI.h" 34 31 35 32 namespace WebKit { 33 class NfcConnection; 34 } 36 35 37 class CtapHidDriver; 38 class HidConnection; 36 @interface WKNFReaderSessionDelegate : NSObject <NFReaderSessionDelegate> 39 37 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 38 - (instancetype)initWithConnection:(WebKit::NfcConnection&)connection; 44 39 45 void deviceAdded(IOHIDDeviceRef); 40 @end 46 41 47 private: 48 void startDiscoveryInternal() final; 49 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 59 }; 60 61 } // namespace WebKit 62 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC) 42 #endif // ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKNFReaderSessionDelegate.mm
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #pragma once 26 #import "config.h" 27 #import "WKNFReaderSessionDelegate.h" 27 28 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)29 #if ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) 29 30 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 31 #import "NfcConnection.h" 32 #import <wtf/RunLoop.h> 33 #import <wtf/WeakPtr.h> 34 34 35 namespace WebKit { 35 #import "NearFieldSoftLink.h" 36 36 37 class CtapHidDriver; 38 class HidConnection; 37 @implementation WKNFReaderSessionDelegate { 38 WeakPtr<WebKit::NfcConnection> _connection; 39 } 39 40 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 41 - (instancetype)initWithConnection:(WebKit::NfcConnection&)connection 42 { 43 if ((self = [super init])) 44 _connection = makeWeakPtr(connection); 45 return self; 46 } 44 47 45 void deviceAdded(IOHIDDeviceRef); 48 // Executed in a different thread. 49 - (void)readerSession:(NFReaderSession*)theSession didDetectTags:(NSArray<NFTag *> *)tags 50 { 51 ASSERT(!RunLoop::isMain()); 46 52 47 private: 48 void startDiscoveryInternal() final; 53 RunLoop::main().dispatch([connection = _connection, tags = retainPtr(tags)] { 54 if (!connection) 55 return; 56 connection->didDetectTags(tags.get()); 57 }); 58 } 49 59 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 60 @end 53 61 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 59 }; 60 61 } // namespace WebKit 62 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC) 62 #endif // ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockHidConnection.cpp
r245852 r249059 39 39 40 40 namespace WebKit { 41 using Mock = MockWebAuthenticationConfiguration::Hid;41 using MockHid = MockWebAuthenticationConfiguration::Hid; 42 42 using namespace WebCore; 43 43 using namespace cbor; … … 83 83 84 84 auto sent = DataSent::Yes; 85 if (weakThis->stagesMatch() && weakThis->m_configuration.hid->error == Mock ::Error::DataNotSent)85 if (weakThis->stagesMatch() && weakThis->m_configuration.hid->error == MockHid::Error::DataNotSent) 86 86 sent = DataSent::No; 87 87 callback(sent); … … 93 93 void MockHidConnection::registerDataReceivedCallbackInternal() 94 94 { 95 if (stagesMatch() && m_configuration.hid->error == Mock ::Error::EmptyReport) {95 if (stagesMatch() && m_configuration.hid->error == MockHid::Error::EmptyReport) { 96 96 receiveReport({ }); 97 97 shouldContinueFeedReports(); … … 124 124 if (m_requestMessage->cmd() == FidoHidDeviceCommand::kInit) { 125 125 auto previousSubStage = m_subStage; 126 m_subStage = Mock ::SubStage::Init;127 if (previousSubStage == Mock ::SubStage::Msg)128 m_stage = Mock ::Stage::Request;126 m_subStage = MockHid::SubStage::Init; 127 if (previousSubStage == MockHid::SubStage::Msg) 128 m_stage = MockHid::Stage::Request; 129 129 } 130 130 if (m_requestMessage->cmd() == FidoHidDeviceCommand::kCbor || m_requestMessage->cmd() == FidoHidDeviceCommand::kMsg) 131 m_subStage = Mock ::SubStage::Msg;132 133 if (m_stage == Mock ::Stage::Request && m_subStage == Mock::SubStage::Msg) {131 m_subStage = MockHid::SubStage::Msg; 132 133 if (m_stage == MockHid::Stage::Request && m_subStage == MockHid::SubStage::Msg) { 134 134 // Make sure we issue different msg cmd for CTAP and U2F. 135 135 if (m_configuration.hid->canDowngrade && !m_configuration.hid->isU2f) … … 177 177 178 178 // Store nonce. 179 if (m_subStage == Mock ::SubStage::Init) {179 if (m_subStage == MockHid::SubStage::Init) { 180 180 m_nonce = m_requestMessage->getMessagePayload(); 181 181 ASSERT(m_nonce.size() == kHidInitNonceLength); … … 192 192 using namespace MockHidConnectionInternal; 193 193 194 if (m_subStage == Mock ::SubStage::Init) {194 if (m_subStage == MockHid::SubStage::Init) { 195 195 Vector<uint8_t> payload; 196 196 payload.reserveInitialCapacity(kHidInitResponseSize); 197 197 payload.appendVector(m_nonce); 198 198 size_t writePosition = payload.size(); 199 if (stagesMatch() && m_configuration.hid->error == Mock ::Error::WrongNonce)199 if (stagesMatch() && m_configuration.hid->error == MockHid::Error::WrongNonce) 200 200 payload[0]--; 201 201 payload.grow(kHidInitResponseSize); 202 202 cryptographicallyRandomValues(payload.data() + writePosition, CtapChannelIdSize); 203 203 auto channel = kHidBroadcastChannel; 204 if (stagesMatch() && m_configuration.hid->error == Mock ::Error::WrongChannelId)204 if (stagesMatch() && m_configuration.hid->error == MockHid::Error::WrongChannelId) 205 205 channel--; 206 206 FidoHidInitPacket initPacket(channel, FidoHidDeviceCommand::kInit, WTFMove(payload), payload.size()); … … 211 211 212 212 Optional<FidoHidMessage> message; 213 if (m_stage == Mock ::Stage::Info && m_subStage == Mock::SubStage::Msg) {213 if (m_stage == MockHid::Stage::Info && m_subStage == MockHid::SubStage::Msg) { 214 214 Vector<uint8_t> infoData; 215 215 if (m_configuration.hid->canDowngrade) … … 218 218 infoData = encodeAsCBOR(AuthenticatorGetInfoResponse({ ProtocolVersion::kCtap }, Vector<uint8_t>(aaguidLength, 0u))); 219 219 infoData.insert(0, static_cast<uint8_t>(CtapDeviceResponseCode::kSuccess)); // Prepend status code. 220 if (stagesMatch() && m_configuration.hid->error == Mock ::Error::WrongChannelId)220 if (stagesMatch() && m_configuration.hid->error == MockHid::Error::WrongChannelId) 221 221 message = FidoHidMessage::create(m_currentChannel - 1, FidoHidDeviceCommand::kCbor, infoData); 222 222 else { … … 228 228 } 229 229 230 if (m_stage == Mock ::Stage::Request && m_subStage == Mock::SubStage::Msg) {230 if (m_stage == MockHid::Stage::Request && m_subStage == MockHid::SubStage::Msg) { 231 231 if (m_configuration.hid->keepAlive) { 232 232 m_configuration.hid->keepAlive = false; … … 236 236 return; 237 237 } 238 if (stagesMatch() && m_configuration.hid->error == Mock ::Error::UnsupportedOptions && (m_requireResidentKey || m_requireUserVerification))238 if (stagesMatch() && m_configuration.hid->error == MockHid::Error::UnsupportedOptions && (m_requireResidentKey || m_requireUserVerification)) 239 239 message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, { static_cast<uint8_t>(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption) }); 240 240 else { … … 255 255 while (message->numPackets()) { 256 256 auto report = message->popNextPacket(); 257 if (!isFirst && stagesMatch() && m_configuration.hid->error == Mock ::Error::WrongChannelId)257 if (!isFirst && stagesMatch() && m_configuration.hid->error == MockHid::Error::WrongChannelId) 258 258 report = FidoHidContinuationPacket(m_currentChannel - 1, 0, { }).getSerializedData(); 259 259 // Packets are feed asynchronously to mimic actual data transmission. … … 277 277 return; 278 278 m_configuration.hid->continueAfterErrorData = false; 279 m_configuration.hid->error = Mock ::Error::Success;279 m_configuration.hid->error = MockHid::Error::Success; 280 280 continueFeedReports(); 281 281 } -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockNfcService.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 #include " AuthenticatorTransportService.h"31 #include <IOKit/hid/IOHIDManager.h>32 #include <wtf/RetainPtr.h> 33 #include <wtf/UniqueRef.h> 30 #include "MockWebAuthenticationConfiguration.h" 31 #include "NfcService.h" 32 33 OBJC_CLASS NSData; 34 34 35 35 namespace WebKit { 36 36 37 class CtapHidDriver; 38 class HidConnection; 37 struct MockWebAuthenticationConfiguration; 39 38 40 class HidService : public AuthenticatorTransportService {39 class MockNfcService final : public NfcService { 41 40 public: 42 explicit HidService(Observer&); 43 ~HidService(); 41 MockNfcService(Observer&, const MockWebAuthenticationConfiguration&); 44 42 45 void deviceAdded(IOHIDDeviceRef);43 NSData* transceive(); 46 44 47 45 private: 48 void startDiscoveryInternal() final;46 void platformStartDiscovery() final; 49 47 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 48 void detectTags() const; 53 49 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 50 MockWebAuthenticationConfiguration m_configuration; 59 51 }; 60 52 61 53 } // namespace WebKit 62 54 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)55 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h
r245500 r249059 73 73 }; 74 74 75 struct Nfc { 76 enum class Error : uint8_t { 77 Success, 78 NoTags, 79 WrongTagType, 80 NoConnections, 81 MaliciousPayload 82 }; 83 84 Error error { Error::Success }; 85 Vector<String> payloadBase64; 86 bool multipleTags { false }; 87 }; 88 75 89 bool silentFailure { false }; 76 90 Optional<Local> local; 77 91 Optional<Hid> hid; 92 Optional<Nfc> nfc; 78 93 }; 79 94 -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.cpp
r248631 r249059 27 27 #include "CtapAuthenticator.h" 28 28 29 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)29 #if ENABLE(WEB_AUTHN) 30 30 31 31 #include "CtapDriver.h" … … 116 116 } // namespace WebKit 117 117 118 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)118 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapAuthenticator.h
r248631 r249059 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 30 #include "Authenticator.h" … … 59 59 } // namespace WebKit 60 60 61 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)61 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/CtapNfcDriver.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) 29 29 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h> 32 #include <wtf/RetainPtr.h> 30 #include "CtapDriver.h" 31 #include "NfcConnection.h" 33 32 #include <wtf/UniqueRef.h> 34 33 35 34 namespace WebKit { 36 35 37 class CtapHidDriver; 38 class HidConnection; 36 // The following implements the CTAP NFC protocol: 37 // https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#nfc 38 class CtapNfcDriver : public CtapDriver { 39 public: 40 explicit CtapNfcDriver(UniqueRef<NfcConnection>&&); 39 41 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 44 45 void deviceAdded(IOHIDDeviceRef); 42 void transact(Vector<uint8_t>&& data, ResponseCallback&&) final; 46 43 47 44 private: 48 void startDiscoveryInternal() final;45 void respondAsync(ResponseCallback&&, Vector<uint8_t>&& response) const; 49 46 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 47 UniqueRef<NfcConnection> m_connection; 59 48 }; 60 49 61 50 } // namespace WebKit 62 51 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)52 #endif // ENABLE(WEB_AUTHN) && HAVE(NEAR_FIELD) -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/FidoService.h
r249058 r249059 1 1 /* 2 * Copyright (C) 201 8Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 30 #include "AuthenticatorTransportService.h" 31 #include <IOKit/hid/IOHIDManager.h>31 #include "CtapDriver.h" 32 32 #include <wtf/RetainPtr.h> 33 33 #include <wtf/UniqueRef.h> … … 35 35 namespace WebKit { 36 36 37 class CtapHidDriver; 38 class HidConnection; 37 class FidoService : public AuthenticatorTransportService { 38 public: 39 explicit FidoService(Observer&); 39 40 40 class HidService : public AuthenticatorTransportService { 41 public: 42 explicit HidService(Observer&); 43 ~HidService(); 44 45 void deviceAdded(IOHIDDeviceRef); 41 protected: 42 void getInfo(std::unique_ptr<CtapDriver>&&); 46 43 47 44 private: 48 void startDiscoveryInternal() final;45 void continueAfterGetInfo(WeakPtr<CtapDriver>&&, Vector<uint8_t>&& info); 49 46 50 // Overrided by MockHidService. 51 virtual void platformStartDiscovery(); 52 virtual UniqueRef<HidConnection> createHidConnection(IOHIDDeviceRef) const; 53 54 void continueAddDeviceAfterGetInfo(CtapHidDriver* deviceRef, Vector<uint8_t>&& info); 55 56 RetainPtr<IOHIDManagerRef> m_manager; 57 // Keeping drivers alive when they are initializing authenticators. 58 HashSet<std::unique_ptr<CtapHidDriver>> m_drivers; 47 // Keeping drivers alive when they are getting info from devices. 48 HashSet<std::unique_ptr<CtapDriver>> m_drivers; 59 49 }; 60 50 61 51 } // namespace WebKit 62 52 63 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)53 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp
r248631 r249059 27 27 #include "U2fAuthenticator.h" 28 28 29 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)29 #if ENABLE(WEB_AUTHN) 30 30 31 31 #include "CtapDriver.h" … … 239 239 } // namespace WebKit 240 240 241 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)241 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.h
r248631 r249059 26 26 #pragma once 27 27 28 #if ENABLE(WEB_AUTHN) && PLATFORM(MAC)28 #if ENABLE(WEB_AUTHN) 29 29 30 30 #include "Authenticator.h" … … 80 80 } // namespace WebKit 81 81 82 #endif // ENABLE(WEB_AUTHN) && PLATFORM(MAC)82 #endif // ENABLE(WEB_AUTHN) -
trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
r249051 r249059 49 49 #import "UIKitSPI.h" 50 50 #import "UserData.h" 51 #import "VersionChecks.h" 51 52 #import "VideoFullscreenManagerProxy.h" 52 53 #import "ViewUpdateDispatcherMessages.h" -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r249001 r249059 1036 1036 53CFBBC82224D1B500266546 /* TextCheckerCompletion.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CFBBC72224D1B000266546 /* TextCheckerCompletion.h */; }; 1037 1037 570AB8F320AE3BD700B8BE87 /* SecKeyProxyStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 570AB8F220AE3BD700B8BE87 /* SecKeyProxyStore.h */; }; 1038 570DAAAE23026F5C00E8FC04 /* NfcService.h in Headers */ = {isa = PBXBuildFile; fileRef = 570DAAAC23026F5C00E8FC04 /* NfcService.h */; }; 1039 570DAAC22303730300E8FC04 /* NfcConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 570DAAC02303730300E8FC04 /* NfcConnection.h */; }; 1040 570DAAC623037F7F00E8FC04 /* WKNFReaderSessionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 570DAAC423037F7E00E8FC04 /* WKNFReaderSessionDelegate.h */; }; 1041 570DAACA230385FD00E8FC04 /* CtapNfcDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 570DAAC8230385FD00E8FC04 /* CtapNfcDriver.h */; }; 1038 1042 572FD44322265CE200A1ECC3 /* WebViewDidMoveToWindowObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 572FD44122265CE200A1ECC3 /* WebViewDidMoveToWindowObserver.h */; }; 1039 1043 57597EB921811D9A0037F924 /* CtapHidDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 57597EB721811D9A0037F924 /* CtapHidDriver.h */; }; … … 1044 1048 57AC8F50217FEED90055438C /* HidConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 57AC8F4E217FEED90055438C /* HidConnection.h */; }; 1045 1049 57B4B46020B504AC00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B4B45E20B504AB00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h */; }; 1050 57B826412304EB3E00B72EB0 /* NearFieldSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B826402304EB3E00B72EB0 /* NearFieldSPI.h */; }; 1051 57B826442304F14000B72EB0 /* NearFieldSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B826422304F14000B72EB0 /* NearFieldSoftLink.h */; }; 1052 57B826452304F14000B72EB0 /* NearFieldSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57B826432304F14000B72EB0 /* NearFieldSoftLink.mm */; }; 1053 57B8264823050C5100B72EB0 /* FidoService.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B8264623050C5100B72EB0 /* FidoService.h */; }; 1054 57B8264C230603C100B72EB0 /* MockNfcService.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B8264A230603C100B72EB0 /* MockNfcService.h */; }; 1046 1055 57BBEA6D22BC0BFE00273995 /* SOAuthorizationLoadPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 57BBEA6C22BC0BFE00273995 /* SOAuthorizationLoadPolicy.h */; }; 1047 1056 57DCED6E2142EE5E0016B847 /* WebAuthenticatorCoordinatorMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57DCED6B2142EAE20016B847 /* WebAuthenticatorCoordinatorMessageReceiver.cpp */; }; … … 3476 3485 570AB90320B2541C00B8BE87 /* SecKeyProxyStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SecKeyProxyStore.mm; sourceTree = "<group>"; }; 3477 3486 570B73CF230236DD00FAEC53 /* CtapDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CtapDriver.h; sourceTree = "<group>"; }; 3487 570DAAAC23026F5C00E8FC04 /* NfcService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NfcService.h; sourceTree = "<group>"; }; 3488 570DAAAD23026F5C00E8FC04 /* NfcService.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NfcService.mm; sourceTree = "<group>"; }; 3489 570DAAB0230273D200E8FC04 /* NearField.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NearField.framework; path = System/Library/PrivateFrameworks/NearField.framework; sourceTree = SDKROOT; }; 3490 570DAAC02303730300E8FC04 /* NfcConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NfcConnection.h; sourceTree = "<group>"; }; 3491 570DAAC12303730300E8FC04 /* NfcConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NfcConnection.mm; sourceTree = "<group>"; }; 3492 570DAAC423037F7E00E8FC04 /* WKNFReaderSessionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKNFReaderSessionDelegate.h; sourceTree = "<group>"; }; 3493 570DAAC523037F7E00E8FC04 /* WKNFReaderSessionDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKNFReaderSessionDelegate.mm; sourceTree = "<group>"; }; 3494 570DAAC8230385FD00E8FC04 /* CtapNfcDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CtapNfcDriver.h; sourceTree = "<group>"; }; 3495 570DAAC9230385FD00E8FC04 /* CtapNfcDriver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CtapNfcDriver.cpp; sourceTree = "<group>"; }; 3478 3496 572FD44122265CE200A1ECC3 /* WebViewDidMoveToWindowObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewDidMoveToWindowObserver.h; sourceTree = "<group>"; }; 3479 3497 575075A720AB763600693EA9 /* WebCredentialMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCredentialMac.mm; sourceTree = "<group>"; }; … … 3500 3518 57B4B45D20B504AB00D4AD79 /* AuthenticationManagerCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AuthenticationManagerCocoa.mm; sourceTree = "<group>"; }; 3501 3519 57B4B45E20B504AB00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientCertificateAuthenticationXPCConstants.h; sourceTree = "<group>"; }; 3520 57B826402304EB3E00B72EB0 /* NearFieldSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NearFieldSPI.h; sourceTree = "<group>"; }; 3521 57B826422304F14000B72EB0 /* NearFieldSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NearFieldSoftLink.h; sourceTree = "<group>"; }; 3522 57B826432304F14000B72EB0 /* NearFieldSoftLink.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NearFieldSoftLink.mm; sourceTree = "<group>"; }; 3523 57B8264623050C5100B72EB0 /* FidoService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FidoService.h; sourceTree = "<group>"; }; 3524 57B8264723050C5100B72EB0 /* FidoService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FidoService.cpp; sourceTree = "<group>"; }; 3525 57B8264A230603C100B72EB0 /* MockNfcService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockNfcService.h; sourceTree = "<group>"; }; 3526 57B8264B230603C100B72EB0 /* MockNfcService.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockNfcService.mm; sourceTree = "<group>"; }; 3502 3527 57BBEA6C22BC0BFE00273995 /* SOAuthorizationLoadPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOAuthorizationLoadPolicy.h; sourceTree = "<group>"; }; 3503 3528 57DCED6A2142EAE20016B847 /* WebAuthenticatorCoordinatorMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAuthenticatorCoordinatorMessages.h; path = DerivedSources/WebKit2/WebAuthenticatorCoordinatorMessages.h; sourceTree = BUILT_PRODUCTS_DIR; }; … … 6196 6221 57DCEDAA214B9B430016B847 /* DeviceIdentitySPI.h */, 6197 6222 2DAADA8E2298C21000E36B0C /* DeviceManagementSPI.h */, 6223 57B826402304EB3E00B72EB0 /* NearFieldSPI.h */, 6198 6224 3754D5441B3A29FD003A4C7F /* NSInvocationSPI.h */, 6199 6225 37B47E2C1D64DB76005F4EFF /* objcSPI.h */, … … 6962 6988 children = ( 6963 6989 5750F32A2032D4E500389347 /* LocalAuthentication.framework */, 6990 570DAAB0230273D200E8FC04 /* NearField.framework */, 6964 6991 ); 6965 6992 name = Frameworks; … … 6974 7001 57597EC021818BE20037F924 /* CtapHidDriver.cpp */, 6975 7002 57597EB721811D9A0037F924 /* CtapHidDriver.h */, 7003 570DAAC9230385FD00E8FC04 /* CtapNfcDriver.cpp */, 7004 570DAAC8230385FD00E8FC04 /* CtapNfcDriver.h */, 7005 57B8264723050C5100B72EB0 /* FidoService.cpp */, 7006 57B8264623050C5100B72EB0 /* FidoService.h */, 6976 7007 57EB2E3921E1983E00B89CDF /* U2fAuthenticator.cpp */, 6977 7008 57EB2E3821E1983E00B89CDF /* U2fAuthenticator.h */, … … 7037 7068 57DCED9A2148B0830016B847 /* LocalService.h */, 7038 7069 57DCEDA02148FA0F0016B847 /* LocalService.mm */, 7070 57B826422304F14000B72EB0 /* NearFieldSoftLink.h */, 7071 57B826432304F14000B72EB0 /* NearFieldSoftLink.mm */, 7072 570DAAC02303730300E8FC04 /* NfcConnection.h */, 7073 570DAAC12303730300E8FC04 /* NfcConnection.mm */, 7074 570DAAAC23026F5C00E8FC04 /* NfcService.h */, 7075 570DAAAD23026F5C00E8FC04 /* NfcService.mm */, 7076 570DAAC423037F7E00E8FC04 /* WKNFReaderSessionDelegate.h */, 7077 570DAAC523037F7E00E8FC04 /* WKNFReaderSessionDelegate.mm */, 7039 7078 ); 7040 7079 path = Cocoa; … … 7054 7093 57DCEDC1214F114C0016B847 /* MockLocalService.h */, 7055 7094 57DCEDC2214F114C0016B847 /* MockLocalService.mm */, 7095 57B8264A230603C100B72EB0 /* MockNfcService.h */, 7096 57B8264B230603C100B72EB0 /* MockNfcService.mm */, 7056 7097 57DCEDBE214CA01B0016B847 /* MockWebAuthenticationConfiguration.h */, 7057 7098 ); … … 9360 9401 57597EBD218184900037F924 /* CtapAuthenticator.h in Headers */, 9361 9402 57597EB921811D9A0037F924 /* CtapHidDriver.h in Headers */, 9403 570DAACA230385FD00E8FC04 /* CtapNfcDriver.h in Headers */, 9362 9404 C55F91711C59676E0029E92D /* DataDetectionResult.h in Headers */, 9363 9405 1AC75380183BE50F0072CB15 /* DataReference.h in Headers */, … … 9391 9433 51B15A8513843A3900321AD8 /* EnvironmentUtilities.h in Headers */, 9392 9434 1AA575FB1496B52600A4EE06 /* EventDispatcher.h in Headers */, 9435 57B8264823050C5100B72EB0 /* FidoService.h in Headers */, 9393 9436 00B9661A18E25AE100CE1F88 /* FindClient.h in Headers */, 9394 9437 1A90C1F41264FD71003E44D4 /* FindController.h in Headers */, … … 9479 9522 57DCEDC7214F18300016B847 /* MockLocalConnection.h in Headers */, 9480 9523 57DCEDC3214F114C0016B847 /* MockLocalService.h in Headers */, 9524 57B8264C230603C100B72EB0 /* MockNfcService.h in Headers */, 9481 9525 57DCEDBF214F0DCF0016B847 /* MockWebAuthenticationConfiguration.h in Headers */, 9482 9526 C0E3AA7C1209E83C00A49D01 /* Module.h in Headers */, … … 9486 9530 57FD318022B35158008D0E8B /* NavigationSOAuthorizationSession.h in Headers */, 9487 9531 1ABC3DF61899E437004F0626 /* NavigationState.h in Headers */, 9532 57B826442304F14000B72EB0 /* NearFieldSoftLink.h in Headers */, 9533 57B826412304EB3E00B72EB0 /* NearFieldSPI.h in Headers */, 9488 9534 1A6FBA2A11E6862700DB1371 /* NetscapeBrowserFuncs.h in Headers */, 9489 9535 1A6FBD2811E69BC200DB1371 /* NetscapePlugin.h in Headers */, … … 9531 9577 532159551DBAE7290054AA3C /* NetworkSessionCocoa.h in Headers */, 9532 9578 417915B92257046F00D6F97E /* NetworkSocketChannel.h in Headers */, 9579 570DAAC22303730300E8FC04 /* NfcConnection.h in Headers */, 9580 570DAAAE23026F5C00E8FC04 /* NfcService.h in Headers */, 9533 9581 31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */, 9534 9582 3131261F148FF82C00BA2A39 /* NotificationPermissionRequestManager.h in Headers */, … … 10159 10207 1AA13212191D5924009C1489 /* WKNavigationResponsePrivate.h in Headers */, 10160 10208 2D3A65DF1A7C3A7D00CAC637 /* WKNavigationResponseRef.h in Headers */, 10209 570DAAC623037F7F00E8FC04 /* WKNFReaderSessionDelegate.h in Headers */, 10161 10210 318BE17914743E6F00A8FBB2 /* WKNotification.h in Headers */, 10162 10211 318BE17114743DB100A8FBB2 /* WKNotificationManager.h in Headers */, … … 11143 11192 2D92A782212B6A7100F493FD /* MessageSender.cpp in Sources */, 11144 11193 2D92A77A212B6A6100F493FD /* Module.cpp in Sources */, 11194 57B826452304F14000B72EB0 /* NearFieldSoftLink.mm in Sources */, 11145 11195 2D913443212CF9F000128AFD /* NetscapeBrowserFuncs.cpp in Sources */, 11146 11196 2D913444212CF9F000128AFD /* NetscapePlugin.cpp in Sources */, -
trunk/Tools/ChangeLog
r249046 r249059 1 2019-08-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Support NFC authenticators for iOS 4 https://bugs.webkit.org/show_bug.cgi?id=188624 5 <rdar://problem/43354214> 6 7 Reviewed by Chris Dumez. 8 9 * WebKitTestRunner/InjectedBundle/TestRunner.cpp: 10 (WTR::TestRunner::setWebAuthenticationMockConfiguration): 11 Setup NFC mock testing configuration. 12 1 13 2019-08-23 Aakash Jain <aakash_jain@apple.com> 2 14 -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
r249013 r249059 2710 2710 } 2711 2711 2712 JSRetainPtr<JSStringRef> nfcPropertyName(Adopt, JSStringCreateWithUTF8CString("nfc")); 2713 JSValueRef nfcValue = JSObjectGetProperty(context, configuration, nfcPropertyName.get(), 0); 2714 if (!JSValueIsUndefined(context, nfcValue) && !JSValueIsNull(context, nfcValue)) { 2715 if (!JSValueIsObject(context, nfcValue)) 2716 return; 2717 JSObjectRef nfc = JSValueToObject(context, nfcValue, 0); 2718 2719 JSRetainPtr<JSStringRef> errorPropertyName(Adopt, JSStringCreateWithUTF8CString("error")); 2720 JSValueRef errorValue = JSObjectGetProperty(context, nfc, errorPropertyName.get(), 0); 2721 if (!JSValueIsString(context, errorValue)) 2722 return; 2723 2724 Vector<WKRetainPtr<WKStringRef>> nfcKeys; 2725 Vector<WKRetainPtr<WKTypeRef>> nfcValues; 2726 nfcKeys.append(adoptWK(WKStringCreateWithUTF8CString("Error"))); 2727 nfcValues.append(toWK(adopt(JSValueToStringCopy(context, errorValue, 0)).get())); 2728 2729 JSRetainPtr<JSStringRef> payloadBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("payloadBase64")); 2730 JSValueRef payloadBase64Value = JSObjectGetProperty(context, nfc, payloadBase64PropertyName.get(), 0); 2731 if (!JSValueIsUndefined(context, payloadBase64Value) && !JSValueIsNull(context, payloadBase64Value)) { 2732 if (!JSValueIsArray(context, payloadBase64Value)) 2733 return; 2734 2735 JSObjectRef payloadBase64 = JSValueToObject(context, payloadBase64Value, nullptr); 2736 static auto lengthProperty = adopt(JSStringCreateWithUTF8CString("length")); 2737 JSValueRef payloadBase64LengthValue = JSObjectGetProperty(context, payloadBase64, lengthProperty.get(), nullptr); 2738 if (!JSValueIsNumber(context, payloadBase64LengthValue)) 2739 return; 2740 2741 auto payloadBase64s = adoptWK(WKMutableArrayCreate()); 2742 auto payloadBase64Length = static_cast<size_t>(JSValueToNumber(context, payloadBase64LengthValue, nullptr)); 2743 for (size_t i = 0; i < payloadBase64Length; ++i) { 2744 JSValueRef payloadBase64Value = JSObjectGetPropertyAtIndex(context, payloadBase64, i, nullptr); 2745 if (!JSValueIsString(context, payloadBase64Value)) 2746 continue; 2747 WKArrayAppendItem(payloadBase64s.get(), toWK(adopt(JSValueToStringCopy(context, payloadBase64Value, 0)).get()).get()); 2748 } 2749 2750 nfcKeys.append(adoptWK(WKStringCreateWithUTF8CString("PayloadBase64"))); 2751 nfcValues.append(payloadBase64s); 2752 } 2753 2754 JSRetainPtr<JSStringRef> multipleTagsPropertyName(Adopt, JSStringCreateWithUTF8CString("multipleTags")); 2755 JSValueRef multipleTagsValue = JSObjectGetProperty(context, nfc, multipleTagsPropertyName.get(), 0); 2756 if (!JSValueIsUndefined(context, multipleTagsValue) && !JSValueIsNull(context, multipleTagsValue)) { 2757 if (!JSValueIsBoolean(context, multipleTagsValue)) 2758 return; 2759 bool multipleTags = JSValueToBoolean(context, multipleTagsValue); 2760 nfcKeys.append(adoptWK(WKStringCreateWithUTF8CString("MultipleTags"))); 2761 nfcValues.append(adoptWK(WKBooleanCreate(multipleTags)).get()); 2762 } 2763 2764 Vector<WKStringRef> rawNfcKeys; 2765 Vector<WKTypeRef> rawNfcValues; 2766 rawNfcKeys.resize(nfcKeys.size()); 2767 rawNfcValues.resize(nfcValues.size()); 2768 for (size_t i = 0; i < nfcKeys.size(); ++i) { 2769 rawNfcKeys[i] = nfcKeys[i].get(); 2770 rawNfcValues[i] = nfcValues[i].get(); 2771 } 2772 2773 configurationKeys.append(adoptWK(WKStringCreateWithUTF8CString("Nfc"))); 2774 configurationValues.append(adoptWK(WKDictionaryCreate(rawNfcKeys.data(), rawNfcValues.data(), rawNfcKeys.size()))); 2775 } 2776 2712 2777 Vector<WKStringRef> rawConfigurationKeys; 2713 2778 Vector<WKTypeRef> rawConfigurationValues;
Note:
See TracChangeset
for help on using the changeset viewer.