Changeset 273209 in webkit
- Timestamp:
- Feb 20, 2021 3:17:32 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r273206 r273209 1 2021-02-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 PCM: Store and report source unlinkable tokens 4 https://bugs.webkit.org/show_bug.cgi?id=222208 5 <rdar://problem/73582032> 6 7 Reviewed by John Wilander. 8 9 * http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start-expected.txt: 10 * http/tests/privateClickMeasurement/resources/signToken.php: 11 * http/tests/privateClickMeasurement/send-attribution-conversion-request-expected.txt: 12 * http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt: 13 * http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html: 14 Modifies the test to mock the whole round trip. 15 1 16 2021-02-20 Rob Buis <rbuis@igalia.com> 2 17 -
trunk/LayoutTests/http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start-expected.txt
r270598 r273209 12 12 No cookies in attribution request. 13 13 Request body: 14 {"source_engagement_type":"click","source_site":"127.0.0.1","source_id":3,"attributed_on_site":"localhost","trigger_data":12,"version": 1}14 {"source_engagement_type":"click","source_site":"127.0.0.1","source_id":3,"attributed_on_site":"localhost","trigger_data":12,"version":2} 15 15 16 16 -
trunk/LayoutTests/http/tests/privateClickMeasurement/resources/signToken.php
r273133 r273209 5 5 $httpHeaders = $_SERVER; 6 6 $cookiesFound = false; 7 // This php will respond to twoconsecutive server requests.8 // It will only complete the transaction when the secondrequest finishes.9 $is SecondRequest = false;7 // This php will respond to four consecutive server requests. 8 // It will only complete the transaction when the last request finishes. 9 $isLastRequest = false; 10 10 11 11 if ($value = $httpHeaders["REQUEST_METHOD"]) { … … 35 35 fwrite($tokenSigningFile, "REQUEST_URI: $outputURL\n"); 36 36 37 $positionOfDummy = strpos($value, "& second=");37 $positionOfDummy = strpos($value, "&last="); 38 38 if ($positionOfDummy != false) 39 $is SecondRequest = true;39 $isLastRequest = true; 40 40 } 41 41 … … 49 49 fclose($tokenSigningFile); 50 50 // Complete the transaction. 51 if ($is SecondRequest)51 if ($isLastRequest) 52 52 rename($tokenSigningFilePath . ".tmp", $tokenSigningFilePath); 53 53 54 54 header("HTTP/1.1 201 Created"); 55 header("unlinkable_token_public_key: ABCD"); 56 header("secret_token_signature: ABCD"); 55 57 setcookie("cookieSetInTokenSigningResponse", "1", 0, "/"); 56 58 -
trunk/LayoutTests/http/tests/privateClickMeasurement/send-attribution-conversion-request-expected.txt
r270598 r273209 17 17 No cookies in attribution request. 18 18 Request body: 19 {"source_engagement_type":"click","source_site":"127.0.0.1","source_id":3,"attributed_on_site":"localhost","trigger_data":12,"version": 1}19 {"source_engagement_type":"click","source_site":"127.0.0.1","source_id":3,"attributed_on_site":"localhost","trigger_data":12,"version":2} 20 20 21 21 -
trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt
r273167 r273209 19 19 No cookies in token signing request. 20 20 Request body: 21 {} 21 {"source_engagement_type":"click","source_nonce":"ABCDEFabcdef0123456789","source_secret_token":"secretToken","version":2} 22 REQUEST_METHOD: GET 23 HTTP_HOST: 127.0.0.1:8000 24 REQUEST_URI: /privateClickMeasurement/resources/signToken.php 25 No cookies in token signing request. 26 Request body: 22 27 23 Unattributed Private Click Measurements: 24 WebCore::PrivateClickMeasurement 1 25 Source site: 127.0.0.1 26 Attribute on site: localhost 27 Source ID: 3 28 No attribution trigger data. 28 REQUEST_METHOD: POST 29 HTTP_HOST: 127.0.0.1:8000 30 Content type: application/json 31 REQUEST_URI: /privateClickMeasurement/resources/signToken.php 32 No cookies in token signing request. 33 Request body: 34 {"source_engagement_type":"click","source_site":"127.0.0.1","source_id":3,"attributed_on_site":"localhost","trigger_data":12,"version":2,"source_unlinkable_token":"unlinkableToken","source_unlinkable_token_signature":"signature"} 35 36 37 No stored Private Click Measurement data. -
trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html
r273133 r273209 12 12 <div id="output"></div> 13 13 <script> 14 const currentTimeMillis = (new Date()).getTime(); 15 const highEntropyBits = currentTimeMillis - (Math.floor(currentTimeMillis / 1000000) * 1000000); 16 const dummy = highEntropyBits + "" + Math.floor(Math.random() * 100); 17 14 18 if (!window.location.search) 15 19 prepareTest(); … … 48 52 if (window.testRunner) { 49 53 if (!window.location.search) { 50 const currentTimeMillis = (new Date()).getTime();51 const highEntropyBits = currentTimeMillis - (Math.floor(currentTimeMillis / 1000000) * 1000000);52 const dummy = highEntropyBits + "" + Math.floor(Math.random() * 100);53 54 testRunner.setPrivateClickMeasurementTokenPublicKeyURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/signToken.php?dummy=" + dummy); 54 testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/signToken.php?dummy=" + dummy + "&second=true"); 55 testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/signToken.php?dummy=" + dummy); 56 testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/signToken.php?dummy=" + dummy + "&last=true"); 57 testRunner.setPrivateClickMeasurementOverrideTimerForTesting(true); 58 testRunner.setFraudPreventionValuesForTesting("secretToken", "unlinkableToken", "signature", "WF3Ugg"); 59 55 60 targetLink.href = "http://localhost:8000/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html?dummy=" + dummy; 56 61 activateElement("targetLink"); 57 62 } else { 58 63 let params = new URLSearchParams(window.location.search); 59 appendTokenSignatureIframeAndFinish(params.get("dummy")); 64 65 let imageElement = document.createElement("img"); 66 imageElement.src = "https://127.0.0.1:8443/privateClickMeasurement/resources/redirectToConversion.php?conversionData=12&nonce=" + dummy + "&delay_ms=500"; 67 imageElement.id = "pixel"; 68 imageElement.onerror = function() { 69 appendTokenSignatureIframeAndFinish(params.get("dummy")); 70 }; 71 document.body.appendChild(imageElement); 60 72 } 61 73 } else { -
trunk/Source/WebCore/ChangeLog
r273206 r273209 1 2021-02-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 PCM: Store and report source unlinkable tokens 4 https://bugs.webkit.org/show_bug.cgi?id=222208 5 <rdar://problem/73582032> 6 7 Reviewed by John Wilander. 8 9 This patch hooks up the network process with the PCM fraud prevention feature to 10 enable the generation, storing and reporting the source unlinkable token. 11 12 Existing tests updated. 13 14 * loader/PrivateClickMeasurement.h: 15 (WebCore::PrivateClickMeasurement::setSourceSecretTokenValue): 16 Adds infrastructure to mock the crypto operations such that layout tests can be 17 conducted without the server side crypto support. 18 19 * loader/PrivateClickMeasurement.cpp: 20 (WebCore::PrivateClickMeasurement::attributionReportJSON const): 21 (WebCore::PrivateClickMeasurement::tokenSignatureJSON const): 22 (WebCore::PrivateClickMeasurement::setSourceUnlinkableToken): 23 (WebCore::PrivateClickMeasurement::tokenSignatureJSON): Deleted. 24 * loader/PrivateClickMeasurement.h: 25 (WebCore::PrivateClickMeasurement::sourceUnlinkableToken const): 26 * loader/cocoa/PrivateClickMeasurementCocoa.mm: 27 (WebCore::PrivateClickMeasurement::calculateAndUpdateSourceSecretToken): 28 (WebCore::PrivateClickMeasurement::calculateAndUpdateSourceUnlinkableToken): 29 (WebCore::PrivateClickMeasurement::sourceSecretToken): Deleted. 30 (WebCore::PrivateClickMeasurement::calculateSourceUnlinkableToken): Deleted. 31 Update interfaces to service the use cases in the Networking process better. 32 1 33 2021-02-20 Rob Buis <rbuis@igalia.com> 2 34 -
trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp
r273167 r273209 145 145 reportDetails->setString("attributed_on_site"_s, m_attributeOnSite.registrableDomain.string()); 146 146 reportDetails->setInteger("trigger_data"_s, m_attributionTriggerData->data); 147 reportDetails->setInteger("version"_s, 1); 147 reportDetails->setInteger("version"_s, 2); 148 149 if (m_sourceUnlinkableToken) { 150 reportDetails->setString("source_unlinkable_token"_s, m_sourceUnlinkableToken->tokenBase64URL); 151 reportDetails->setString("source_unlinkable_token_signature"_s, m_sourceUnlinkableToken->signatureBase64URL); 152 } 153 148 154 return reportDetails; 149 155 } … … 201 207 } 202 208 203 Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON( const String& serverPublicKeyBase64URL)209 Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON() const 204 210 { 205 211 auto reportDetails = JSON::Object::create(); … … 207 213 return reportDetails; 208 214 209 String token; 210 #if PLATFORM(COCOA) 211 token = sourceSecretToken(serverPublicKeyBase64URL); 212 #endif 213 if (token.isEmpty()) 215 if (m_sourceSecretToken.valueBase64URL.isEmpty()) 214 216 return reportDetails; 215 217 216 218 reportDetails->setString("source_engagement_type"_s, "click"_s); 217 219 reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce); 218 reportDetails->setString("source_secret_token"_s, token);220 reportDetails->setString("source_secret_token"_s, m_sourceSecretToken.valueBase64URL); 219 221 reportDetails->setInteger("version"_s, 2); 220 222 return reportDetails; 221 223 } 222 224 225 void PrivateClickMeasurement::setSourceUnlinkableToken(SourceUnlinkableToken&& token) 226 { 227 if (!token.isValid()) 228 return; 229 m_sourceUnlinkableToken = WTFMove(token); 230 } 231 232 bool PrivateClickMeasurement::SourceUnlinkableToken::isValid() const 233 { 234 return !(tokenBase64URL.isEmpty() || signatureBase64URL.isEmpty() || keyIDBase64URL.isEmpty()); 235 } 236 223 237 } // namespace WebCore -
trunk/Source/WebCore/loader/PrivateClickMeasurement.h
r273167 r273209 278 278 279 279 // MARK: - Fraud Prevention 280 WEBCORE_EXPORT URL tokenPublicKeyURL() const; 281 WEBCORE_EXPORT URL tokenSignatureURL() const; 282 283 WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON() const; 284 280 285 struct EphemeralSourceNonce { 281 286 String nonce; … … 293 298 struct SourceUnlinkableToken { 294 299 String tokenBase64URL; 300 String signatureBase64URL; 295 301 String keyIDBase64URL; 296 String signatureBase64URL; 297 }; 298 299 WEBCORE_EXPORT URL tokenPublicKeyURL() const; 300 WEBCORE_EXPORT URL tokenSignatureURL() const; 301 302 WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON(const String& serverPublicKeyBase64URL); 303 WEBCORE_EXPORT Optional<SourceUnlinkableToken> calculateSourceUnlinkableToken(const String& serverResponseBase64URL); 302 303 bool isValid() const; 304 }; 305 306 #if PLATFORM(COCOA) 307 WEBCORE_EXPORT bool calculateAndUpdateSourceSecretToken(const String& serverPublicKeyBase64URL); 308 WEBCORE_EXPORT bool calculateAndUpdateSourceUnlinkableToken(const String& serverResponseBase64URL); 309 #endif 310 311 void setSourceSecretTokenValue(const String& value) { m_sourceSecretToken.valueBase64URL = value; } 312 const Optional<SourceUnlinkableToken>& sourceUnlinkableToken() const { return m_sourceUnlinkableToken; } 313 WEBCORE_EXPORT void setSourceUnlinkableToken(SourceUnlinkableToken&&); 304 314 305 315 template<class Encoder> void encode(Encoder&) const; … … 308 318 private: 309 319 bool isValid() const; 310 #if PLATFORM(COCOA)311 String sourceSecretToken(const String& serverPublicKeyBase64URL);312 #endif313 320 314 321 SourceID m_sourceID; … … 328 335 RetainPtr<RSABSSATokenReady> readyToken; 329 336 #endif 337 String valueBase64URL; 330 338 }; 331 339 332 340 Optional<EphemeralSourceNonce> m_ephemeralSourceNonce; 333 341 SourceSecretToken m_sourceSecretToken; 342 Optional<SourceUnlinkableToken> m_sourceUnlinkableToken; 334 343 }; 335 344 -
trunk/Source/WebCore/loader/cocoa/PrivateClickMeasurementCocoa.mm
r273167 r273209 31 31 namespace WebCore { 32 32 33 String PrivateClickMeasurement::sourceSecretToken(const String& serverPublicKeyBase64URL)33 bool PrivateClickMeasurement::calculateAndUpdateSourceSecretToken(const String& serverPublicKeyBase64URL) 34 34 { 35 35 #if HAVE(RSA_BSSA) … … 37 37 Vector<uint8_t> serverPublicKeyData; 38 38 if (!base64URLDecode(serverPublicKeyBase64URL, serverPublicKeyData)) 39 return emptyString();39 return false; 40 40 auto serverPublicKey = adoptNS([[NSData alloc] initWithBytes:serverPublicKeyData.data() length:serverPublicKeyData.size()]); 41 41 … … 43 43 m_sourceSecretToken.blinder = adoptNS([PAL::allocRSABSSATokenBlinderInstance() initWithPublicKey:serverPublicKey.get() error:nullptr]); 44 44 if (!m_sourceSecretToken.blinder) 45 return emptyString();45 return false; 46 46 } 47 47 … … 49 49 m_sourceSecretToken.waitingToken = [m_sourceSecretToken.blinder tokenWaitingActivationWithContent:nullptr error:nullptr]; 50 50 if (!m_sourceSecretToken.waitingToken) 51 return emptyString();51 return false; 52 52 53 return WTF::base64URLEncode([m_sourceSecretToken.waitingToken blindedMessage].bytes, [m_sourceSecretToken.waitingToken blindedMessage].length); 53 m_sourceSecretToken.valueBase64URL = WTF::base64URLEncode([m_sourceSecretToken.waitingToken blindedMessage].bytes, [m_sourceSecretToken.waitingToken blindedMessage].length); 54 return true; 54 55 #else 55 56 UNUSED_PARAM(serverPublicKeyBase64URL); 56 return emptyString();57 return false; 57 58 #endif // HAVE(RSA_BSSA) 58 59 } 59 60 60 auto PrivateClickMeasurement::calculateSourceUnlinkableToken(const String& serverResponseBase64URL) -> Optional<SourceUnlinkableToken> 61 bool PrivateClickMeasurement::calculateAndUpdateSourceUnlinkableToken(const String& serverResponseBase64URL) 61 62 { 62 63 #if HAVE(RSA_BSSA) 63 64 if (!m_sourceSecretToken.waitingToken) 64 return WTF::nullopt;65 return false; 65 66 66 67 { 67 68 Vector<uint8_t> serverResponseData; 68 69 if (!base64URLDecode(serverResponseBase64URL, serverResponseData)) 69 return WTF::nullopt;70 return false; 70 71 auto serverResponse = adoptNS([[NSData alloc] initWithBytes:serverResponseData.data() length:serverResponseData.size()]); 71 72 … … 73 74 m_sourceSecretToken.readyToken = [m_sourceSecretToken.waitingToken activateTokenWithServerResponse:serverResponse.get() error:nullptr]; 74 75 if (!m_sourceSecretToken.readyToken) 75 return WTF::nullopt;76 return false; 76 77 } 77 78 … … 81 82 token.signatureBase64URL = WTF::base64URLEncode([m_sourceSecretToken.readyToken signature].bytes, [m_sourceSecretToken.readyToken signature].length); 82 83 83 return token; 84 m_sourceUnlinkableToken = WTFMove(token); 85 return true; 84 86 #else 85 87 UNUSED_PARAM(serverResponseBase64URL); 86 return WTF::nullopt;88 return false; 87 89 #endif // HAVE(RSA_BSSA) 88 90 } -
trunk/Source/WebKit/ChangeLog
r273204 r273209 1 2021-02-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 PCM: Store and report source unlinkable tokens 4 https://bugs.webkit.org/show_bug.cgi?id=222208 5 <rdar://problem/73582032> 6 7 Reviewed by John Wilander. 8 9 * NetworkProcess/NetworkProcess.cpp: 10 (WebKit::NetworkProcess::setFraudPreventionValuesForTesting): 11 * NetworkProcess/NetworkProcess.h: 12 * NetworkProcess/NetworkProcess.messages.in: 13 * NetworkProcess/NetworkSession.cpp: 14 (WebKit::NetworkSession::setFraudPreventionValuesForTesting): 15 * NetworkProcess/NetworkSession.h: 16 * NetworkProcess/PrivateClickMeasurementManager.cpp: 17 (WebKit::PrivateClickMeasurementManager::storeUnattributed): 18 (WebKit::PrivateClickMeasurementManager::getSignedSecretToken): 19 (WebKit::PrivateClickMeasurementManager::setFraudPreventionValuesForTesting): 20 * NetworkProcess/PrivateClickMeasurementManager.h: 21 * UIProcess/API/C/WKPage.cpp: 22 (WKPageSetFraudPreventionValuesForTesting): 23 * UIProcess/API/C/WKPagePrivate.h: 24 * UIProcess/WebPageProxy.cpp: 25 (WebKit::WebPageProxy::markPrivateClickMeasurementsAsExpiredForTesting): 26 (WebKit::WebPageProxy::setFraudPreventionValuesForTesting): 27 * UIProcess/WebPageProxy.h: 28 Adds infrastructure to mock the crypto operations such that layout tests can be 29 conducted without the server side crypto support. 30 31 * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp: 32 (WebKit::ResourceLoadStatisticsDatabaseStore::buildPrivateClickMeasurementFromDatabase): 33 (WebKit::ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement): 34 * NetworkProcess/PrivateClickMeasurementManager.cpp: 35 (WebKit::PrivateClickMeasurementManager::storeUnattributed): 36 (WebKit::PrivateClickMeasurementManager::getTokenPublicKey): 37 (WebKit::PrivateClickMeasurementManager::getSignedSecretToken): 38 (WebKit::PrivateClickMeasurementManager::fireConversionRequest): 39 (WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl): 40 * NetworkProcess/PrivateClickMeasurementManager.h: 41 Connects the fraud prevention feature in PCM to generate, store, and report the unlinkable token. 42 1 43 2021-02-20 Kimmo Kinnunen <kkinnunen@apple.com> 2 44 -
trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp
r273144 r273209 2969 2969 } 2970 2970 2971 // FIXME(<rdar://problem/73582032>): Store these in the attribution object once PCM fraud prevention is in place. 2972 UNUSED_PARAM(token); 2973 UNUSED_PARAM(signature); 2974 UNUSED_PARAM(keyID); 2971 attribution.setSourceUnlinkableToken({ token, signature, keyID }); 2975 2972 2976 2973 return attribution; … … 3020 3017 return; 3021 3018 3022 // FIXME(<rdar://problem/73582032>): Use real values from the attribution object once PCM fraud prevention is in place. 3023 String token; 3024 String signature; 3025 String keyID; 3026 3019 auto& sourceUnlinkableToken = attribution.sourceUnlinkableToken(); 3027 3020 if (attributionType == PrivateClickMeasurementAttributionType::Attributed) { 3028 3021 auto attributionTriggerData = attribution.attributionTriggerData() ? attribution.attributionTriggerData().value().data : -1; … … 3039 3032 || statement.bindDouble(6, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK 3040 3033 || statement.bindDouble(7, earliestTimeToSend) != SQLITE_OK 3041 || statement.bindText(8, token) != SQLITE_OK3042 || statement.bindText(9, s ignature) != SQLITE_OK3043 || statement.bindText(10, keyID) != SQLITE_OK3034 || statement.bindText(8, sourceUnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK 3035 || statement.bindText(9, sourceUnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK 3036 || statement.bindText(10, sourceUnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK 3044 3037 || statement.step() != SQLITE_DONE) { 3045 3038 RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement insertAttributedPrivateClickMeasurementQuery, error message: %{private}s", this, m_database.lastErrorMsg()); … … 3055 3048 || statement.bindInt(3, attribution.sourceID().id) != SQLITE_OK 3056 3049 || statement.bindDouble(4, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK 3057 || statement.bindText(5, token) != SQLITE_OK3058 || statement.bindText(6, s ignature) != SQLITE_OK3059 || statement.bindText(7, keyID) != SQLITE_OK3050 || statement.bindText(5, sourceUnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK 3051 || statement.bindText(6, sourceUnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK 3052 || statement.bindText(7, sourceUnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK 3060 3053 || statement.step() != SQLITE_DONE) { 3061 3054 RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement insertUnattributedPrivateClickMeasurementQuery, error message: %{private}s", this, m_database.lastErrorMsg()); -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r273183 r273209 2641 2641 } 2642 2642 2643 void NetworkProcess::setFraudPreventionValuesForTesting(PAL::SessionID sessionID, String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID, CompletionHandler<void()>&& completionHandler) 2644 { 2645 if (auto* session = networkSession(sessionID)) 2646 session->setFraudPreventionValuesForTesting(WTFMove(secretToken), WTFMove(unlinkableToken), WTFMove(signature), WTFMove(keyID)); 2647 2648 completionHandler(); 2649 } 2650 2643 2651 void NetworkProcess::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader) 2644 2652 { -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.h
r273133 r273209 347 347 void setPrivateClickMeasurementAttributionReportURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&); 348 348 void markPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID, CompletionHandler<void()>&&); 349 void setFraudPreventionValuesForTesting(PAL::SessionID, String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID, CompletionHandler<void()>&&); 349 350 350 351 RefPtr<WebCore::StorageQuotaManager> storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&); -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
r273133 r273209 172 172 SetPrivateClickMeasurementAttributionReportURLForTesting(PAL::SessionID sessionID, URL url) -> () Async 173 173 MarkPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async 174 SetFraudPreventionValuesForTesting(PAL::SessionID sessionID, String secretToken, String unlinkableToken, String signature, String keyID) -> () Async 174 175 GetLocalStorageOriginDetails(PAL::SessionID sessionID) -> (Vector<WebKit::LocalStorageDatabaseTracker::OriginDetails> details) Async 175 176 -
trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp
r273133 r273209 359 359 } 360 360 361 // FIXME: Switch to non-mocked test data once the right cryptography library is available in open source. 362 void NetworkSession::setFraudPreventionValuesForTesting(String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID) 363 { 364 privateClickMeasurement().setFraudPreventionValuesForTesting(WTFMove(secretToken), WTFMove(unlinkableToken), WTFMove(signature), WTFMove(keyID)); 365 } 366 361 367 void NetworkSession::firePrivateClickMeasurementTimerImmediately() 362 368 { -
trunk/Source/WebKit/NetworkProcess/NetworkSession.h
r273133 r273209 128 128 void setPrivateClickMeasurementAttributionReportURLForTesting(URL&&); 129 129 void markPrivateClickMeasurementsAsExpiredForTesting(); 130 void setFraudPreventionValuesForTesting(String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID); 130 131 void firePrivateClickMeasurementTimerImmediately(); 131 132 -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp
r273180 r273209 38 38 #include <WebCore/RuntimeApplicationChecks.h> 39 39 #include <WebCore/RuntimeEnabledFeatures.h> 40 #include <pal/crypto/CryptoDigest.h> 40 41 #include <wtf/CryptographicallyRandomNumber.h> 41 42 #include <wtf/text/StringBuilder.h> … … 77 78 if (attribution.ephemeralSourceNonce()) { 78 79 auto attributionCopy = attribution; 79 getTokenPublicKey(WTFMove(attributionCopy)); 80 getTokenPublicKey(WTFMove(attributionCopy), [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL) { 81 if (!weakThis) 82 return; 83 84 if (publicKeyBase64URL.isEmpty()) 85 return; 86 87 if (m_fraudPreventionValuesForTesting) 88 attribution.setSourceSecretTokenValue(m_fraudPreventionValuesForTesting->secretToken); 89 #if PLATFORM(COCOA) 90 else { 91 if (!attribution.calculateAndUpdateSourceSecretToken(publicKeyBase64URL)) 92 return; 93 } 94 #endif 95 96 getSignedSecretToken(WTFMove(attribution)); 97 }); 80 98 } 81 99 … … 127 145 } 128 146 129 void PrivateClickMeasurementManager::getTokenPublicKey(PrivateClickMeasurement&& attribution )147 void PrivateClickMeasurementManager::getTokenPublicKey(PrivateClickMeasurement&& attribution, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&& callback) 130 148 { 131 149 if (!featureEnabled()) … … 148 166 m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token public key request."_s); 149 167 150 m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), attribution = WTFMove(attribution), this] (const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) mutable {168 m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, attribution = WTFMove(attribution), callback = WTFMove(callback)] (const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) mutable { 151 169 if (!weakThis) 152 170 return; … … 157 175 } 158 176 159 // FIXME : Receive and extra the server public key, rdar://73582032.160 getSignedSecretToken(WTFMove(attribution), emptyString());177 // FIXME(222217): Retrieve the public key from the content instead of the header. 178 callback(WTFMove(attribution), response.httpHeaderFields().get("unlinkable_token_public_key"_s)); 161 179 }); 162 180 163 181 } 164 182 165 void PrivateClickMeasurementManager::getSignedSecretToken(PrivateClickMeasurement&& attribution , const String& tokenPublicKeyBase64URL)183 void PrivateClickMeasurementManager::getSignedSecretToken(PrivateClickMeasurement&& attribution) 166 184 { 167 185 if (!featureEnabled()) … … 179 197 return; 180 198 181 auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON( tokenPublicKeyBase64URL), pcmDataCarried);199 auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(), pcmDataCarried); 182 200 183 201 RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a secret token signing request."); 184 202 m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a secret token signing request."_s); 185 203 186 m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this) ](const WebCore::ResourceError& error, const WebCore::ResourceResponse& response){204 m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, attribution = WTFMove(attribution)] (const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) mutable { 187 205 if (!weakThis) 188 206 return; 189 207 190 208 if (!error.isNull()) { 191 weakThis->m_networkProcess->broadcastConsoleMessage(weakThis->m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for secret token signing request."_s));209 m_networkProcess->broadcastConsoleMessage(weakThis->m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for secret token signing request."_s)); 192 210 return; 193 211 } 194 195 // FIXME: Receive and store the signed secret token, rdar://73582032. 212 213 // FIXME(222217): Retrieve the signature from the content instead of the header. 214 auto signatureBase64URL = response.httpHeaderFields().get("secret_token_signature"_s); 215 if (signatureBase64URL.isEmpty()) 216 return; 217 218 if (m_fraudPreventionValuesForTesting) 219 attribution.setSourceUnlinkableToken({ m_fraudPreventionValuesForTesting->unlinkableToken, m_fraudPreventionValuesForTesting->signature, m_fraudPreventionValuesForTesting->keyID }); 220 #if PLATFORM(COCOA) 221 else { 222 if (!attribution.calculateAndUpdateSourceUnlinkableToken(signatureBase64URL)) 223 return; 224 } 225 #endif 226 227 m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] Storing an unlinkable token."_s); 228 229 #if ENABLE(RESOURCE_LOAD_STATISTICS) 230 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 231 resourceLoadStatistics->insertPrivateClickMeasurement(WTFMove(attribution), PrivateClickMeasurementAttributionType::Unattributed); 232 #endif 196 233 }); 197 234 … … 257 294 return; 258 295 296 if (!attribution.sourceUnlinkableToken()) { 297 fireConversionRequestImpl(attribution); 298 return; 299 } 300 301 auto attributionCopy = attribution; 302 getTokenPublicKey(WTFMove(attributionCopy), [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL) { 303 if (!weakThis) 304 return; 305 306 Vector<uint8_t> publicKeyData; 307 WTF::base64URLDecode(publicKeyBase64URL, publicKeyData); 308 309 auto crypto = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256); 310 crypto->addBytes(publicKeyData.data(), publicKeyData.size()); 311 auto publicKeyDataHash = crypto->computeHash(); 312 313 static const size_t keyIDSize = 4; 314 auto keyID = WTF::base64URLEncode(publicKeyDataHash.data(), keyIDSize); 315 if (keyID != attribution.sourceUnlinkableToken()->keyIDBase64URL) 316 return; 317 318 fireConversionRequestImpl(attribution); 319 }); 320 } 321 322 void PrivateClickMeasurementManager::fireConversionRequestImpl(const PrivateClickMeasurement& attribution) 323 { 259 324 auto attributionURL = m_attributionReportBaseURLForTesting ? *m_attributionReportBaseURLForTesting : attribution.attributionReportURL(); 260 325 if (attributionURL.isEmpty() || !attributionURL.isValid()) … … 426 491 } 427 492 493 void PrivateClickMeasurementManager::setFraudPreventionValuesForTesting(String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID) 494 { 495 if (secretToken.isEmpty() || unlinkableToken.isEmpty() || signature.isEmpty() || keyID.isEmpty()) 496 return; 497 m_fraudPreventionValuesForTesting = TestingFraudPreventionValues { WTFMove(secretToken), WTFMove(unlinkableToken), WTFMove(signature), WTFMove(keyID) }; 498 } 499 428 500 bool PrivateClickMeasurementManager::featureEnabled() const 429 501 { -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h
r273167 r273209 67 67 void markAllUnattributedAsExpiredForTesting(); 68 68 void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&); 69 void setFraudPreventionValuesForTesting(String&& secretToken, String&& unlinkableToken, String&& signature, String&& keyID); 69 70 void startTimer(Seconds); 70 71 71 72 private: 72 void getTokenPublicKey(PrivateClickMeasurement&& );73 void getSignedSecretToken(PrivateClickMeasurement&& , const String& tokenPublicKeyBase64URL);73 void getTokenPublicKey(PrivateClickMeasurement&&, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&&); 74 void getSignedSecretToken(PrivateClickMeasurement&&); 74 75 void clearSentAttribution(PrivateClickMeasurement&&); 75 76 void attribute(const SourceSite&, const AttributeOnSite&, AttributionTriggerData&&); 76 77 void fireConversionRequest(const PrivateClickMeasurement&); 78 void fireConversionRequestImpl(const PrivateClickMeasurement&); 77 79 void firePendingAttributionRequests(); 78 80 void clearExpired(); … … 89 91 PAL::SessionID m_sessionID; 90 92 Function<void(NetworkResourceLoadParameters&&, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&&)> m_pingLoadFunction; 93 94 struct TestingFraudPreventionValues { 95 String secretToken; 96 String unlinkableToken; 97 String signature; 98 String keyID; 99 }; 100 101 Optional<TestingFraudPreventionValues> m_fraudPreventionValuesForTesting; 91 102 }; 92 103 -
trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp
r273133 r273209 2974 2974 } 2975 2975 2976 void WKPageSetFraudPreventionValuesForTesting(WKPageRef page, WKStringRef secretToken, WKStringRef unlinkableToken, WKStringRef signature, WKStringRef keyID, WKPageSetFraudPreventionValuesForTestingFunction callback, void* callbackContext) 2977 { 2978 toImpl(page)->setFraudPreventionValuesForTesting(toWTFString(secretToken), toWTFString(unlinkableToken), toWTFString(signature), toWTFString(keyID), [callbackContext, callback] () { 2979 callback(callbackContext); 2980 }); 2981 } 2982 2976 2983 void WKPageSetMockCameraOrientation(WKPageRef page, uint64_t orientation) 2977 2984 { -
trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h
r273133 r273209 188 188 typedef void (*WKPageMarkPrivateClickMeasurementsAsExpiredForTestingFunction)(void* functionContext); 189 189 WK_EXPORT void WKPageMarkPrivateClickMeasurementsAsExpiredForTesting(WKPageRef page, WKPageMarkPrivateClickMeasurementsAsExpiredForTestingFunction callback, void* callbackContext); 190 typedef void (*WKPageSetFraudPreventionValuesForTestingFunction)(void* functionContext); 191 WK_EXPORT void WKPageSetFraudPreventionValuesForTesting(WKPageRef page, WKStringRef secretToken, WKStringRef unlinkableToken, WKStringRef signature, WKStringRef keyID, WKPageSetFraudPreventionValuesForTestingFunction callback, void* callbackContext); 190 192 191 193 WK_EXPORT void WKPageSetMockCameraOrientation(WKPageRef page, uint64_t orientation); -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r273184 r273209 10053 10053 } 10054 10054 10055 void WebPageProxy::setFraudPreventionValuesForTesting(const String& secretToken, const String& unlinkableToken, const String& signature, const String& keyID, CompletionHandler<void()>&& completionHandler) 10056 { 10057 websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SetFraudPreventionValuesForTesting(m_websiteDataStore->sessionID(), secretToken, unlinkableToken, signature, keyID), WTFMove(completionHandler)); 10058 } 10059 10055 10060 #if ENABLE(SPEECH_SYNTHESIS) 10056 10061 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r273184 r273209 1705 1705 void setPrivateClickMeasurementAttributionReportURLForTesting(const URL&, CompletionHandler<void()>&&); 1706 1706 void markPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&); 1707 void setFraudPreventionValuesForTesting(const String& secretToken, const String& unlinkableToken, const String& signature, const String& keyID, CompletionHandler<void()>&&); 1707 1708 1708 1709 #if ENABLE(SPEECH_SYNTHESIS) -
trunk/Tools/ChangeLog
r273204 r273209 1 2021-02-20 Jiewen Tan <jiewen_tan@apple.com> 2 3 PCM: Store and report source unlinkable tokens 4 https://bugs.webkit.org/show_bug.cgi?id=222208 5 <rdar://problem/73582032> 6 7 Reviewed by John Wilander. 8 9 * TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp: 10 (TestWebKitAPI::TEST): 11 * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: 12 * WebKitTestRunner/InjectedBundle/TestRunner.cpp: 13 (WTR::TestRunner::setFraudPreventionValuesForTesting): 14 * WebKitTestRunner/InjectedBundle/TestRunner.h: 15 * WebKitTestRunner/TestController.cpp: 16 (WTR::TestController::setFraudPreventionValuesForTesting): 17 * WebKitTestRunner/TestController.h: 18 * WebKitTestRunner/TestInvocation.cpp: 19 (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): 20 Rebases some test cases. 21 1 22 2021-02-20 Kimmo Kinnunen <kkinnunen@apple.com> 2 23 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp
r273167 r273209 52 52 ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/"); 53 53 54 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":0,\"attributed_on_site\":\"example.com\",\"trigger_data\":0,\"version\": 1}");54 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":0,\"attributed_on_site\":\"example.com\",\"trigger_data\":0,\"version\":2}"); 55 55 } 56 56 … … 64 64 ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/"); 65 65 66 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":192,\"attributed_on_site\":\"example.com\",\"trigger_data\":9,\"version\": 1}");66 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":192,\"attributed_on_site\":\"example.com\",\"trigger_data\":9,\"version\":2}"); 67 67 } 68 68 … … 76 76 ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/"); 77 77 78 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":255,\"attributed_on_site\":\"example.com\",\"trigger_data\":15,\"version\": 1}");78 ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":255,\"attributed_on_site\":\"example.com\",\"trigger_data\":15,\"version\":2}"); 79 79 } 80 80 … … 308 308 309 309 PrivateClickMeasurement pcm; 310 auto sourceSecretToken = pcm.tokenSignatureJSON( serverPublicKeyBase64URL);310 auto sourceSecretToken = pcm.tokenSignatureJSON(); 311 311 EXPECT_EQ(sourceSecretToken->asObject()->size(), 0ul); 312 312 … … 315 315 pcm.setEphemeralSourceNonce(WTFMove(ephemeralNonce)); 316 316 317 sourceSecretToken = pcm.tokenSignatureJSON(serverPublicKeyBase64URL); 317 EXPECT_TRUE(pcm.calculateAndUpdateSourceSecretToken(serverPublicKeyBase64URL)); 318 sourceSecretToken = pcm.tokenSignatureJSON(); 318 319 EXPECT_EQ(sourceSecretToken->asObject()->size(), 4ul); 319 320 320 auto persistentToken = pcm.calculateSourceUnlinkableToken(emptyString()); 321 EXPECT_FALSE(persistentToken); 321 EXPECT_FALSE(pcm.calculateAndUpdateSourceUnlinkableToken(emptyString())); 322 322 } 323 323 #endif -
trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm
r273167 r273209 82 82 83 83 // Continue the test. 84 auto sourceSecretToken = pcm.tokenSignatureJSON(WTF::base64URLEncode(nsSpkiData.bytes, nsSpkiData.length)); 84 EXPECT_TRUE(pcm.calculateAndUpdateSourceSecretToken(WTF::base64URLEncode(nsSpkiData.bytes, nsSpkiData.length))); 85 auto sourceSecretToken = pcm.tokenSignatureJSON(); 85 86 EXPECT_EQ(sourceSecretToken->asObject()->size(), 4ul); 86 87 EXPECT_STREQ(sourceSecretToken->getString("source_engagement_type"_s).utf8().data(), "click"); … … 97 98 98 99 // Continue the test. 99 auto persistentToken = pcm.calculateSourceUnlinkableToken(WTF::base64URLEncode([blindedSignature bytes], [blindedSignature length])); 100 EXPECT_TRUE(pcm.calculateAndUpdateSourceUnlinkableToken(WTF::base64URLEncode([blindedSignature bytes], [blindedSignature length]))); 101 auto& persistentToken = pcm.sourceUnlinkableToken(); 100 102 EXPECT_TRUE(persistentToken); 101 103 EXPECT_FALSE(persistentToken->tokenBase64URL.isEmpty()); -
trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
r273133 r273209 408 408 undefined setPrivateClickMeasurementAttributionReportURLForTesting(DOMString url); 409 409 undefined markPrivateClickMeasurementsAsExpiredForTesting(); 410 undefined setFraudPreventionValuesForTesting(DOMString secretToken, DOMString unlinkableToken, DOMString signature, DOMString keyID); 410 411 411 412 // SpeechRecognition -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
r273133 r273209 2049 2049 } 2050 2050 2051 void TestRunner::setFraudPreventionValuesForTesting(JSStringRef secretToken, JSStringRef unlinkableToken, JSStringRef signature, JSStringRef keyID) 2052 { 2053 postSynchronousMessage("SetFraudPreventionValuesForTesting", createWKDictionary({ 2054 { "SecretToken", toWK(secretToken) }, 2055 { "UnlinkableToken", toWK(unlinkableToken) }, 2056 { "Signature", toWK(signature) }, 2057 { "KeyID", toWK(keyID) }, 2058 })); 2059 } 2060 2051 2061 bool TestRunner::hasAppBoundSession() 2052 2062 { -
trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
r273133 r273209 518 518 void markPrivateClickMeasurementsAsExpiredForTesting(); 519 519 void markAttributedPrivateClickMeasurementsAsExpiredForTesting(); 520 void setFraudPreventionValuesForTesting(JSStringRef secretToken, JSStringRef unlinkableToken, JSStringRef signature, JSStringRef keyID); 520 521 void simulateResourceLoadStatisticsSessionRestart(); 521 522 -
trunk/Tools/WebKitTestRunner/TestController.cpp
r273133 r273209 3659 3659 } 3660 3660 3661 void TestController::setFraudPreventionValuesForTesting(WKStringRef secretToken, WKStringRef unlinkableToken, WKStringRef signature, WKStringRef keyID) 3662 { 3663 PrivateClickMeasurementVoidCallbackContext callbackContext(*this); 3664 WKPageSetFraudPreventionValuesForTesting(m_mainWebView->page(), secretToken, unlinkableToken, signature, keyID, privateClickMeasurementVoidCallback, &callbackContext); 3665 runUntil(callbackContext.done, noTimeout); 3666 } 3667 3661 3668 WKURLRef TestController::currentTestURL() const 3662 3669 { -
trunk/Tools/WebKitTestRunner/TestController.h
r273133 r273209 351 351 void setPrivateClickMeasurementAttributionReportURLForTesting(WKURLRef); 352 352 void markPrivateClickMeasurementsAsExpiredForTesting(); 353 void setFraudPreventionValuesForTesting(WKStringRef secretToken, WKStringRef unlinkableToken, WKStringRef signature, WKStringRef keyID); 353 354 354 355 void didSetAppBoundDomains() const; -
trunk/Tools/WebKitTestRunner/TestInvocation.cpp
r273133 r273209 1363 1363 } 1364 1364 1365 if (WKStringIsEqualToUTF8CString(messageName, "SetFraudPreventionValuesForTesting")) { 1366 auto testDictionary = dictionaryValue(messageBody); 1367 auto secretToken = stringValue(testDictionary, "SecretToken"); 1368 auto unlinkableToken = stringValue(testDictionary, "UnlinkableToken"); 1369 auto signature = stringValue(testDictionary, "Signature"); 1370 auto keyID = stringValue(testDictionary, "KeyID"); 1371 1372 TestController::singleton().setFraudPreventionValuesForTesting(secretToken, unlinkableToken, signature, keyID); 1373 return nullptr; 1374 } 1375 1365 1376 if (WKStringIsEqualToUTF8CString(messageName, "SyncLocalStorage")) { 1366 1377 TestController::singleton().syncLocalStorage();
Note: See TracChangeset
for help on using the changeset viewer.