Diff
Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt (273166 => 273167)
--- trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt 2021-02-19 23:15:22 UTC (rev 273167)
@@ -18,7 +18,7 @@
REQUEST_URI: /privateClickMeasurement/resources/signToken.php
No cookies in token signing request.
Request body:
-{"source_engagement_type":"click","source_nonce":"ABCDEFabcdef0123456789","unlinkable_token":"TODO","version":2}
+{}
Unattributed Private Click Measurements:
WebCore::PrivateClickMeasurement 1
Modified: trunk/Source/WTF/ChangeLog (273166 => 273167)
--- trunk/Source/WTF/ChangeLog 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WTF/ChangeLog 2021-02-19 23:15:22 UTC (rev 273167)
@@ -1,3 +1,14 @@
+2021-02-16 Jiewen Tan <[email protected]>
+
+ PCM: Generate secret token and corresponding unlinkable token
+ https://bugs.webkit.org/show_bug.cgi?id=222019
+ <rdar://problem/73581412>
+
+ Reviewed by John Wilander.
+
+ * wtf/PlatformHave.h:
+ Adds a compile time flag for RSABSSA.
+
2021-02-19 Jer Noble <[email protected]>
[Cocoa] Enable Opus decode support by default
Modified: trunk/Source/WTF/wtf/PlatformHave.h (273166 => 273167)
--- trunk/Source/WTF/wtf/PlatformHave.h 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WTF/wtf/PlatformHave.h 2021-02-19 23:15:22 UTC (rev 273167)
@@ -888,3 +888,8 @@
#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
#define HAVE_STATIC_FONT_REGISTRY 1
#endif
+
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000) \
+ || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150000)
+#define HAVE_RSA_BSSA 1
+#endif
Modified: trunk/Source/WebCore/ChangeLog (273166 => 273167)
--- trunk/Source/WebCore/ChangeLog 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/ChangeLog 2021-02-19 23:15:22 UTC (rev 273167)
@@ -1,3 +1,37 @@
+2021-02-16 Jiewen Tan <[email protected]>
+
+ PCM: Generate secret token and corresponding unlinkable token
+ https://bugs.webkit.org/show_bug.cgi?id=222019
+ <rdar://problem/73581412>
+
+ Reviewed by John Wilander.
+
+ Covered by API tests.
+
+ This patch utilizes RSABSSA to generate secret token for PCM fraud prevention.
+
+ * Configurations/WebCore.xcconfig:
+ * SourcesCocoa.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ Paperwork to link CryptoKitCBridging.
+
+ * loader/PrivateClickMeasurement.cpp:
+ (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::isValid const):
+ (WebCore::PrivateClickMeasurement::setEphemeralSourceNonce):
+ * loader/PrivateClickMeasurement.h:
+ (WebCore::PrivateClickMeasurement::attributeOnSite const):
+ (WebCore::PrivateClickMeasurement::ephemeralSourceNonce const):
+ (WebCore::PrivateClickMeasurement::clearEphemeralSourceNonce):
+ (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::EphemeralSourceNonce): Deleted.
+ (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::isValid const): Deleted.
+ (WebCore::PrivateClickMeasurement::setEphemeralSourceNonce): Deleted.
+ Groups functionalities behind HAVE_RSA_BSSA.
+
+ * loader/cocoa/PrivateClickMeasurementCocoa.mm: Added.
+ (WebCore::PrivateClickMeasurement::blindedSecretJson):
+ (WebCore::PrivateClickMeasurement::calculatePersistentBlindedToken):
+ Introduces new methods to generate the blinded secrets and unlinkable tokens.
+
2021-02-19 Devin Rousso <[email protected]>
[Payment Request] add support for Apple Pay payment method mode
Modified: trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj (273166 => 273167)
--- trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj 2021-02-19 23:15:22 UTC (rev 273167)
@@ -138,6 +138,8 @@
570AB8F920AF6E3D00B8BE87 /* NSXPCConnectionSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 570AB8F820AF6E3D00B8BE87 /* NSXPCConnectionSPI.h */; };
572A107822B456F500F410C8 /* AuthKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 572A107722B456F500F410C8 /* AuthKitSPI.h */; };
576CA9D622B854AB0030143C /* AppSSOSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 576CA9D522B854AB0030143C /* AppSSOSPI.h */; };
+ 57F1C90925DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */; };
+ 57F1C90A25DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */; };
57FD318A22B3593E008D0E8B /* AppSSOSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */; };
57FD318B22B35989008D0E8B /* AppSSOSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 57FD318822B3592F008D0E8B /* AppSSOSoftLink.h */; };
5C7C787323AC3E770065F47E /* ManagedConfigurationSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C7C787123AC3E770065F47E /* ManagedConfigurationSoftLink.h */; };
@@ -341,6 +343,8 @@
570AB8F820AF6E3D00B8BE87 /* NSXPCConnectionSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSXPCConnectionSPI.h; sourceTree = "<group>"; };
572A107722B456F500F410C8 /* AuthKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthKitSPI.h; sourceTree = "<group>"; };
576CA9D522B854AB0030143C /* AppSSOSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSSOSPI.h; sourceTree = "<group>"; };
+ 57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoKitCBridgingSoftLink.h; sourceTree = "<group>"; };
+ 57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CryptoKitCBridgingSoftLink.mm; sourceTree = "<group>"; };
57FD318822B3592F008D0E8B /* AppSSOSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppSSOSoftLink.h; sourceTree = "<group>"; };
57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppSSOSoftLink.mm; sourceTree = "<group>"; };
5C7C787123AC3E770065F47E /* ManagedConfigurationSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManagedConfigurationSoftLink.h; sourceTree = "<group>"; };
@@ -691,6 +695,8 @@
57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */,
077E87B0226A460200A2AFF0 /* AVFoundationSoftLink.h */,
077E87AF226A460200A2AFF0 /* AVFoundationSoftLink.mm */,
+ 57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */,
+ 57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */,
F44291661FA52705002CC93E /* FileSizeFormatterCocoa.mm */,
1C022EFC22CFE8E0006DF01B /* Gunzip.cpp */,
CDACB35E23873E480018D7CE /* MediaToolboxSoftLink.cpp */,
@@ -828,6 +834,7 @@
1CCEE4F520D871930047B097 /* CoreUISPI.h in Headers */,
0C5AF9191F43A4C7002EAC02 /* CoreUISPI.h in Headers */,
1C09D0531E31C44100725F18 /* CryptoDigest.h in Headers */,
+ 57F1C90925DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h in Headers */,
0C2DA1411F3BEB4900DBC317 /* DataDetectorsCoreSPI.h in Headers */,
0C77858A1F45130F00F4EBB6 /* DataDetectorsSPI.h in Headers */,
0C5AF91A1F43A4C7002EAC02 /* DataDetectorsUISPI.h in Headers */,
@@ -1037,6 +1044,7 @@
0CF99CA81F738437007EE793 /* CoreMediaSoftLink.cpp in Sources */,
1C77C8C925D7972000635E0C /* CoreTextSoftLink.cpp in Sources */,
1C09D0561E31C46500725F18 /* CryptoDigestCommonCrypto.cpp in Sources */,
+ 57F1C90A25DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm in Sources */,
A1175B581F6B470500C4B9F0 /* DefaultSearchProvider.cpp in Sources */,
F44291641FA52670002CC93E /* FileSizeFormatter.cpp in Sources */,
F44291681FA52705002CC93E /* FileSizeFormatterCocoa.mm in Sources */,
Added: trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.h (0 => 273167)
--- trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.h (rev 0)
+++ trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.h 2021-02-19 23:15:22 UTC (rev 273167)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if HAVE(RSA_BSSA)
+
+#import <CryptoKitCBridging/RSABSSA.h>
+#import <wtf/SoftLinking.h>
+
+SOFT_LINK_FRAMEWORK_FOR_HEADER(PAL, CryptoKitCBridging);
+
+SOFT_LINK_CLASS_FOR_HEADER(PAL, RSABSSATokenBlinder);
+
+#endif
Added: trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.mm (0 => 273167)
--- trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.mm (rev 0)
+++ trunk/Source/WebCore/PAL/pal/cocoa/CryptoKitCBridgingSoftLink.mm 2021-02-19 23:15:22 UTC (rev 273167)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if HAVE(RSA_BSSA)
+
+#import <wtf/SoftLinking.h>
+
+SOFT_LINK_PRIVATE_FRAMEWORK_FOR_SOURCE_WITH_EXPORT(PAL, CryptoKitCBridging, PAL_EXPORT);
+
+SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, CryptoKitCBridging, RSABSSATokenBlinder, PAL_EXPORT);
+
+#endif
Modified: trunk/Source/WebCore/SourcesCocoa.txt (273166 => 273167)
--- trunk/Source/WebCore/SourcesCocoa.txt 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2021-02-19 23:15:22 UTC (rev 273167)
@@ -169,6 +169,7 @@
loader/archive/cf/LegacyWebArchive.cpp
loader/archive/cf/LegacyWebArchiveMac.mm
loader/cocoa/DiskCacheMonitorCocoa.mm
+loader/cocoa/PrivateClickMeasurementCocoa.mm
loader/cocoa/SubresourceLoaderCocoa.mm
loader/ios/LegacyPreviewLoader.mm
loader/mac/DocumentLoaderMac.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (273166 => 273167)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-02-19 23:15:22 UTC (rev 273167)
@@ -9421,6 +9421,7 @@
57EEAA571EA0AFBB00701124 /* CommonCryptoDERUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommonCryptoDERUtilities.cpp; sourceTree = "<group>"; };
57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecReplacement.h; sourceTree = "<group>"; };
57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecReplacement.cpp; sourceTree = "<group>"; };
+ 57F1C8E325DC6EE700E8F6EA /* PrivateClickMeasurementCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementCocoa.mm; sourceTree = "<group>"; };
57F827391DB72C22009D2BF4 /* RsaHashedKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaHashedKeyGenParams.idl; sourceTree = "<group>"; };
57FEDD3D1DB6D47F00EB96F5 /* RsaKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaKeyGenParams.idl; sourceTree = "<group>"; };
57FEDD3E1DB6D59200EB96F5 /* CryptoAlgorithmRsaKeyGenParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRsaKeyGenParams.h; sourceTree = "<group>"; };
@@ -9736,7 +9737,7 @@
6A22E8721F1042C400F546C3 /* InspectorCanvas.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorCanvas.cpp; sourceTree = "<group>"; };
6A7279881F16C29B003F39B8 /* InspectorShaderProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorShaderProgram.h; sourceTree = "<group>"; };
6A7279891F16C29B003F39B8 /* InspectorShaderProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorShaderProgram.cpp; sourceTree = "<group>"; };
- 6B0A07F021FA4B5C00D57391 /* PrivateClickMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurement.h; sourceTree = "<group>"; };
+ 6B0A07F021FA4B5C00D57391 /* PrivateClickMeasurement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurement.h; sourceTree = "<group>"; };
6B0A07F121FA4B5C00D57391 /* PrivateClickMeasurement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurement.cpp; sourceTree = "<group>"; };
6B1F480F22989EC400DE8B82 /* CrossSiteNavigationDataTransfer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrossSiteNavigationDataTransfer.h; sourceTree = "<group>"; };
6B4D412B23983F88002494C2 /* LoggedInStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoggedInStatus.h; sourceTree = "<group>"; };
@@ -22973,6 +22974,7 @@
children = (
7EDAAFC819A2CBD10034DFD1 /* DiskCacheMonitorCocoa.h */,
7E4DE10C198B10B60051CB02 /* DiskCacheMonitorCocoa.mm */,
+ 57F1C8E325DC6EE700E8F6EA /* PrivateClickMeasurementCocoa.mm */,
7E8FADC3199A95B100714968 /* SubresourceLoaderCocoa.mm */,
);
path = cocoa;
Modified: trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp (273166 => 273167)
--- trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp 2021-02-19 23:15:22 UTC (rev 273167)
@@ -37,7 +37,7 @@
namespace WebCore {
static const char privateClickMeasurementTriggerAttributionPath[] = "/.well-known/private-click-measurement/trigger-attribution/";
-static const char privateClickMeasurementTokenSignaturePath[] = "/.well-known/private-click-measurement/sign-unlinkable-token/";
+static const char privateClickMeasurementTokenSignaturePath[] = "/.well-known/private-click-measurement/sign-secret-token/";
static const char privateClickMeasurementTokenPublicKeyPath[] = "/.well-known/private-click-measurement/get-unlinkable-token-public-key/";
static const char privateClickMeasurementReportAttributionPath[] = "/.well-known/private-click-measurement/report-attribution/";
const size_t privateClickMeasurementAttributionTriggerDataPathSegmentSize = 2;
@@ -116,15 +116,15 @@
return m_attributionTriggerData->priority > other.m_attributionTriggerData->priority;
}
-URL PrivateClickMeasurement::tokenSignatureURL() const
+URL PrivateClickMeasurement::attributionReportURL() const
{
- if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
+ if (!isValid())
return URL();
StringBuilder builder;
builder.appendLiteral("https://");
builder.append(m_sourceSite.registrableDomain.string());
- builder.appendLiteral(privateClickMeasurementTokenSignaturePath);
+ builder.appendLiteral(privateClickMeasurementReportAttributionPath);
URL url { URL(), builder.toString() };
if (url.isValid())
@@ -133,12 +133,51 @@
return URL();
}
-URL PrivateClickMeasurement::tokenPublicKeyURL() const
+Ref<JSON::Object> PrivateClickMeasurement::attributionReportJSON() const
{
+ auto reportDetails = JSON::Object::create();
+ if (!m_attributionTriggerData || !isValid())
+ return reportDetails;
+
+ reportDetails->setString("source_engagement_type"_s, "click"_s);
+ reportDetails->setString("source_site"_s, m_sourceSite.registrableDomain.string());
+ reportDetails->setInteger("source_id"_s, m_sourceID.id);
+ reportDetails->setString("attributed_on_site"_s, m_attributeOnSite.registrableDomain.string());
+ reportDetails->setInteger("trigger_data"_s, m_attributionTriggerData->data);
+ reportDetails->setInteger("version"_s, 1);
+ return reportDetails;
+}
+
+// MARK: - Fraud Prevention
+
+static constexpr uint32_t EphemeralSourceNonceRequiredNumberOfBytes = 16;
+
+bool PrivateClickMeasurement::EphemeralSourceNonce::isValid() const
+{
+ // FIXME: Investigate if we can do with a simple length check instead of decoding.
+ // https://bugs.webkit.org/show_bug.cgi?id=221945
+ Vector<uint8_t> digest;
+ if (!base64URLDecode(nonce, digest))
+ return false;
+ return digest.size() == EphemeralSourceNonceRequiredNumberOfBytes;
+}
+
+void PrivateClickMeasurement::setEphemeralSourceNonce(EphemeralSourceNonce&& nonce)
+{
+ if (!nonce.isValid())
+ return;
+ m_ephemeralSourceNonce = WTFMove(nonce);
+}
+
+URL PrivateClickMeasurement::tokenSignatureURL() const
+{
+ if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
+ return URL();
+
StringBuilder builder;
builder.appendLiteral("https://");
builder.append(m_sourceSite.registrableDomain.string());
- builder.appendLiteral(privateClickMeasurementTokenPublicKeyPath);
+ builder.appendLiteral(privateClickMeasurementTokenSignaturePath);
URL url { URL(), builder.toString() };
if (url.isValid())
@@ -147,28 +186,12 @@
return URL();
}
-Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON() const
+URL PrivateClickMeasurement::tokenPublicKeyURL() const
{
- auto reportDetails = JSON::Object::create();
- if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
- return reportDetails;
-
- reportDetails->setString("source_engagement_type"_s, "click"_s);
- reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce);
- reportDetails->setString("unlinkable_token"_s, "TODO"_s);
- reportDetails->setInteger("version"_s, 2);
- return reportDetails;
-}
-
-URL PrivateClickMeasurement::attributionReportURL() const
-{
- if (!isValid())
- return URL();
-
StringBuilder builder;
builder.appendLiteral("https://");
builder.append(m_sourceSite.registrableDomain.string());
- builder.appendLiteral(privateClickMeasurementReportAttributionPath);
+ builder.appendLiteral(privateClickMeasurementTokenPublicKeyPath);
URL url { URL(), builder.toString() };
if (url.isValid())
@@ -177,19 +200,24 @@
return URL();
}
-Ref<JSON::Object> PrivateClickMeasurement::attributionReportJSON() const
+Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON(const String& serverPublicKeyBase64URL)
{
auto reportDetails = JSON::Object::create();
- if (!m_attributionTriggerData || !isValid())
+ if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
return reportDetails;
+ String token;
+#if PLATFORM(COCOA)
+ token = sourceSecretToken(serverPublicKeyBase64URL);
+#endif
+ if (token.isEmpty())
+ return reportDetails;
+
reportDetails->setString("source_engagement_type"_s, "click"_s);
- reportDetails->setString("source_site"_s, m_sourceSite.registrableDomain.string());
- reportDetails->setInteger("source_id"_s, m_sourceID.id);
- reportDetails->setString("attributed_on_site"_s, m_attributeOnSite.registrableDomain.string());
- reportDetails->setInteger("trigger_data"_s, m_attributionTriggerData->data);
- reportDetails->setInteger("version"_s, 1);
+ reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce);
+ reportDetails->setString("source_secret_token"_s, token);
+ reportDetails->setInteger("version"_s, 2);
return reportDetails;
}
-}
+} // namespace WebCore
Modified: trunk/Source/WebCore/loader/PrivateClickMeasurement.h (273166 => 273167)
--- trunk/Source/WebCore/loader/PrivateClickMeasurement.h 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebCore/loader/PrivateClickMeasurement.h 2021-02-19 23:15:22 UTC (rev 273167)
@@ -36,6 +36,16 @@
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
+#if PLATFORM(COCOA)
+#include <wtf/RetainPtr.h>
+#endif
+
+#if PLATFORM(COCOA)
+OBJC_CLASS RSABSSATokenReady;
+OBJC_CLASS RSABSSATokenWaitingActivation;
+OBJC_CLASS RSABSSATokenBlinder;
+#endif
+
namespace WebCore {
class PrivateClickMeasurement {
@@ -201,31 +211,6 @@
static const bool safeToCompareToEmptyOrDeleted = false;
};
- struct EphemeralSourceNonce {
- static constexpr uint32_t RequiredNumberOfBytes = 16;
-
- EphemeralSourceNonce() = default;
- explicit EphemeralSourceNonce(const String& nonceString)
- : nonce { nonceString }
- {
- }
-
- // FIXME: Investigate if we can do with a simple length check instead of decoding.
- // https://bugs.webkit.org/show_bug.cgi?id=221945
- bool isValid() const
- {
- Vector<uint8_t> digest;
- if (!base64URLDecode(nonce, digest))
- return false;
- return digest.size() == RequiredNumberOfBytes;
- }
-
- String nonce;
-
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<EphemeralSourceNonce> decode(Decoder&);
- };
-
struct Priority {
static constexpr uint32_t MaxEntropy = 63;
@@ -277,16 +262,10 @@
WEBCORE_EXPORT static Expected<AttributionTriggerData, String> parseAttributionRequest(const URL& redirectURL);
WEBCORE_EXPORT Optional<Seconds> attributeAndGetEarliestTimeToSend(AttributionTriggerData&&);
WEBCORE_EXPORT bool hasHigherPriorityThan(const PrivateClickMeasurement&) const;
- WEBCORE_EXPORT URL tokenPublicKeyURL() const;
- WEBCORE_EXPORT URL tokenSignatureURL() const;
- WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON() const;
WEBCORE_EXPORT URL attributionReportURL() const;
WEBCORE_EXPORT Ref<JSON::Object> attributionReportJSON() const;
const SourceSite& sourceSite() const { return m_sourceSite; };
const AttributeOnSite& attributeOnSite() const { return m_attributeOnSite; };
- void setEphemeralSourceNonce(EphemeralSourceNonce&& nonce) { m_ephemeralSourceNonce = WTFMove(nonce); };
- Optional<EphemeralSourceNonce> ephemeralSourceNonce() const { return !m_ephemeralSourceNonce ? WTF::nullopt : m_ephemeralSourceNonce->isValid() ? m_ephemeralSourceNonce : WTF::nullopt; };
- void clearEphemeralSourceNonce() { m_ephemeralSourceNonce = WTF::nullopt; };
WallTime timeOfAdClick() const { return m_timeOfAdClick; }
Optional<WallTime> earliestTimeToSend() const { return m_earliestTimeToSend; };
void setEarliestTimeToSend(WallTime time) { m_earliestTimeToSend = time; }
@@ -297,11 +276,40 @@
const String& sourceDescription() const { return m_sourceDescription; }
const String& purchaser() const { return m_purchaser; }
+ // MARK: - Fraud Prevention
+ struct EphemeralSourceNonce {
+ String nonce;
+
+ WEBCORE_EXPORT bool isValid() const;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<EphemeralSourceNonce> decode(Decoder&);
+ };
+
+ WEBCORE_EXPORT void setEphemeralSourceNonce(EphemeralSourceNonce&&);
+ Optional<EphemeralSourceNonce> ephemeralSourceNonce() const { return m_ephemeralSourceNonce; };
+ void clearEphemeralSourceNonce() { m_ephemeralSourceNonce.reset(); };
+
+ struct SourceUnlinkableToken {
+ String tokenBase64URL;
+ String keyIDBase64URL;
+ String signatureBase64URL;
+ };
+
+ WEBCORE_EXPORT URL tokenPublicKeyURL() const;
+ WEBCORE_EXPORT URL tokenSignatureURL() const;
+
+ WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON(const String& serverPublicKeyBase64URL);
+ WEBCORE_EXPORT Optional<SourceUnlinkableToken> calculateSourceUnlinkableToken(const String& serverResponseBase64URL);
+
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static Optional<PrivateClickMeasurement> decode(Decoder&);
private:
bool isValid() const;
+#if PLATFORM(COCOA)
+ String sourceSecretToken(const String& serverPublicKeyBase64URL);
+#endif
SourceID m_sourceID;
SourceSite m_sourceSite;
@@ -310,9 +318,19 @@
String m_purchaser;
WallTime m_timeOfAdClick;
- Optional<EphemeralSourceNonce> m_ephemeralSourceNonce;
Optional<AttributionTriggerData> m_attributionTriggerData;
Optional<WallTime> m_earliestTimeToSend;
+
+ struct SourceSecretToken {
+#if PLATFORM(COCOA)
+ RetainPtr<RSABSSATokenBlinder> blinder;
+ RetainPtr<RSABSSATokenWaitingActivation> waitingToken;
+ RetainPtr<RSABSSATokenReady> readyToken;
+#endif
+ };
+
+ Optional<EphemeralSourceNonce> m_ephemeralSourceNonce;
+ SourceSecretToken m_sourceSecretToken;
};
template<class Encoder>
Added: trunk/Source/WebCore/loader/cocoa/PrivateClickMeasurementCocoa.mm (0 => 273167)
--- trunk/Source/WebCore/loader/cocoa/PrivateClickMeasurementCocoa.mm (rev 0)
+++ trunk/Source/WebCore/loader/cocoa/PrivateClickMeasurementCocoa.mm 2021-02-19 23:15:22 UTC (rev 273167)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PrivateClickMeasurement.h"
+
+#import <pal/cocoa/CryptoKitCBridgingSoftLink.h>
+
+namespace WebCore {
+
+String PrivateClickMeasurement::sourceSecretToken(const String& serverPublicKeyBase64URL)
+{
+#if HAVE(RSA_BSSA)
+ {
+ Vector<uint8_t> serverPublicKeyData;
+ if (!base64URLDecode(serverPublicKeyBase64URL, serverPublicKeyData))
+ return emptyString();
+ auto serverPublicKey = adoptNS([[NSData alloc] initWithBytes:serverPublicKeyData.data() length:serverPublicKeyData.size()]);
+
+ // FIXME(222018): Check error.
+ m_sourceSecretToken.blinder = adoptNS([PAL::allocRSABSSATokenBlinderInstance() initWithPublicKey:serverPublicKey.get() error:nullptr]);
+ if (!m_sourceSecretToken.blinder)
+ return emptyString();
+ }
+
+ // FIXME(222018): Check error.
+ m_sourceSecretToken.waitingToken = [m_sourceSecretToken.blinder tokenWaitingActivationWithContent:nullptr error:nullptr];
+ if (!m_sourceSecretToken.waitingToken)
+ return emptyString();
+
+ return WTF::base64URLEncode([m_sourceSecretToken.waitingToken blindedMessage].bytes, [m_sourceSecretToken.waitingToken blindedMessage].length);
+#else
+ UNUSED_PARAM(serverPublicKeyBase64URL);
+ return emptyString();
+#endif // HAVE(RSA_BSSA)
+}
+
+auto PrivateClickMeasurement::calculateSourceUnlinkableToken(const String& serverResponseBase64URL) -> Optional<SourceUnlinkableToken>
+{
+#if HAVE(RSA_BSSA)
+ if (!m_sourceSecretToken.waitingToken)
+ return WTF::nullopt;
+
+ {
+ Vector<uint8_t> serverResponseData;
+ if (!base64URLDecode(serverResponseBase64URL, serverResponseData))
+ return WTF::nullopt;
+ auto serverResponse = adoptNS([[NSData alloc] initWithBytes:serverResponseData.data() length:serverResponseData.size()]);
+
+ // FIXME(222018): Check error.
+ m_sourceSecretToken.readyToken = [m_sourceSecretToken.waitingToken activateTokenWithServerResponse:serverResponse.get() error:nullptr];
+ if (!m_sourceSecretToken.readyToken)
+ return WTF::nullopt;
+ }
+
+ SourceUnlinkableToken token;
+ token.tokenBase64URL = WTF::base64URLEncode([m_sourceSecretToken.readyToken tokenContent].bytes, [m_sourceSecretToken.readyToken tokenContent].length);
+ token.keyIDBase64URL = WTF::base64URLEncode([m_sourceSecretToken.readyToken keyId].bytes, [m_sourceSecretToken.readyToken keyId].length);
+ token.signatureBase64URL = WTF::base64URLEncode([m_sourceSecretToken.readyToken signature].bytes, [m_sourceSecretToken.readyToken signature].length);
+
+ return token;
+#else
+ UNUSED_PARAM(serverResponseBase64URL);
+ return WTF::nullopt;
+#endif // HAVE(RSA_BSSA)
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (273166 => 273167)
--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp 2021-02-19 23:15:22 UTC (rev 273167)
@@ -157,12 +157,12 @@
}
// FIXME: Receive and extra the server public key, rdar://73582032.
- getSignedUnlinkableToken(WTFMove(attribution));
+ getSignedSecretToken(WTFMove(attribution), emptyString());
});
}
-void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& attribution)
+void PrivateClickMeasurementManager::getSignedSecretToken(PrivateClickMeasurement&& attribution, const String& tokenPublicKeyBase64URL)
{
if (!featureEnabled())
return;
@@ -178,10 +178,10 @@
if (tokenSignatureURL.isEmpty() || !tokenSignatureURL.isValid())
return;
- auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(), pcmDataCarried);
+ auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(tokenPublicKeyBase64URL), pcmDataCarried);
- RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
- m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
+ RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a secret token signing request.");
+ m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a secret token signing request."_s);
m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this)](const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) {
if (!weakThis)
@@ -188,11 +188,11 @@
return;
if (!error.isNull()) {
- weakThis->m_networkProcess->broadcastConsoleMessage(weakThis->m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for unlinkable token signing request."_s));
+ 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));
return;
}
- // FIXME: Receive and store the signed unlinkable token, rdar://73582032.
+ // FIXME: Receive and store the signed secret token, rdar://73582032.
});
}
Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (273166 => 273167)
--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h 2021-02-19 23:15:22 UTC (rev 273167)
@@ -70,7 +70,7 @@
private:
void getTokenPublicKey(PrivateClickMeasurement&&);
- void getSignedUnlinkableToken(PrivateClickMeasurement&&);
+ void getSignedSecretToken(PrivateClickMeasurement&&, const String& tokenPublicKeyBase64URL);
void clearSentAttribution(PrivateClickMeasurement&&);
void attribute(const SourceSite&, const AttributeOnSite&, AttributionTriggerData&&);
void fireConversionRequest(const PrivateClickMeasurement&);
Modified: trunk/Tools/ChangeLog (273166 => 273167)
--- trunk/Tools/ChangeLog 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Tools/ChangeLog 2021-02-19 23:15:22 UTC (rev 273167)
@@ -1,3 +1,15 @@
+2021-02-16 Jiewen Tan <[email protected]>
+
+ PCM: Generate secret token and corresponding unlinkable token
+ https://bugs.webkit.org/show_bug.cgi?id=222019
+ <rdar://problem/73581412>
+
+ Reviewed by John Wilander.
+
+ * TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
+ (TestWebKitAPI::TEST):
+ Add tests.
+
2021-02-19 Aditya Keerthi <[email protected]>
[iOS][FCR] Enable the new appearance by default
Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig (273166 => 273167)
--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig 2021-02-19 23:15:22 UTC (rev 273167)
@@ -55,6 +55,12 @@
WK_PDFKIT_LDFLAGS_iphoneos = -framework PDFKit;
WK_PDFKIT_LDFLAGS_iphonesimulator = -framework PDFKit;
+WK_SYSTEM_LDFLAGS = $(WK_SYSTEM_LDFLAGS_$(WK_PLATFORM_NAME));
+WK_SYSTEM_LDFLAGS_macosx = -framework System;
+WK_SYSTEM_LDFLAGS_iphoneos = $(WK_SYSTEM_LDFLAGS_$(WK_IOS_15));
+WK_SYSTEM_LDFLAGS_iphonesimulator = $(WK_SYSTEM_LDFLAGS_$(WK_IOS_15));
+WK_SYSTEM_LDFLAGS_IOS_SINCE_15 = -framework System;
+
WK_HID_LDFLAGS = $(WK_HID_LDFLAGS_$(WK_PLATFORM_NAME));
WK_HID_LDFLAGS_macosx = $(WK_HID_LDFLAGS$(WK_MACOS_1015));
WK_HID_LDFLAGS_MACOS_SINCE_1015 = -framework HID;
@@ -71,7 +77,7 @@
WK_OPENGL_LDFLAGS_appletvsimulator = $(WK_OPENGL_LDFLAGS_iphonesimulator);
WK_OPENGL_LDFLAGS_macosx = -framework OpenGL;
-OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework _javascript_Core -framework WebKit -lWebCoreTestSupport $(WK_AUTHKIT_LDFLAGS) -framework Network $(WK_PDFKIT_LDFLAGS) $(WK_HID_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH));
+OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework _javascript_Core -framework WebKit -lWebCoreTestSupport $(WK_AUTHKIT_LDFLAGS) -framework Network $(WK_SYSTEM_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_HID_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH));
OTHER_LDFLAGS_PLATFORM_ = -framework Cocoa -framework Carbon;
// FIXME: This should not be built on iOS. Instead we should create and use a TestWebKitAPI application.
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (273166 => 273167)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-02-19 23:15:22 UTC (rev 273167)
@@ -441,6 +441,7 @@
57C624502346C21E00383FE7 /* web-authentication-get-assertion.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57C6244F2346C1EC00383FE7 /* web-authentication-get-assertion.html */; };
57EDFC5C245A1A3F00959521 /* web-authentication-make-credential-la-no-mock.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57EDFC5B245A18F500959521 /* web-authentication-make-credential-la-no-mock.html */; };
57EDFC60245A299C00959521 /* web-authentication-get-assertion-la-no-mock.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57EDFC5F245A279900959521 /* web-authentication-get-assertion-la-no-mock.html */; };
+ 57F1C91125DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */; };
57F4AAA0208FAEF000A68E9E /* SSLKeyGenerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */; };
57F56A5C1C7F8CC100F31D7E /* IsNavigationActionTrusted.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */; };
5C0160C121A132460077FA32 /* JITEnabled.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C0160C021A132320077FA32 /* JITEnabled.mm */; };
@@ -2233,6 +2234,7 @@
57EDFC5B245A18F500959521 /* web-authentication-make-credential-la-no-mock.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-la-no-mock.html"; sourceTree = "<group>"; };
57EDFC5F245A279900959521 /* web-authentication-get-assertion-la-no-mock.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-la-no-mock.html"; sourceTree = "<group>"; };
57F10D921C7E7B3800ECDF30 /* IsNavigationActionTrusted.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IsNavigationActionTrusted.mm; sourceTree = "<group>"; };
+ 57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementCocoa.mm; sourceTree = "<group>"; };
57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SSLKeyGenerator.mm; sourceTree = "<group>"; };
57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IsNavigationActionTrusted.html; sourceTree = "<group>"; };
5C0160C021A132320077FA32 /* JITEnabled.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JITEnabled.mm; sourceTree = "<group>"; };
@@ -4711,6 +4713,7 @@
children = (
0711DF51226A95FB003DD2F7 /* AVFoundationSoftLinkTest.mm */,
751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */,
+ 57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */,
5769C50A1D9B0001000847FB /* SerializedCryptoKeyWrap.mm */,
A17991861E1C994E00A505ED /* SharedBuffer.mm */,
CD89D0381C4EDB2A00040A04 /* WebCoreNSURLSession.mm */,
@@ -5486,6 +5489,7 @@
A1EC11881F42541200D0146E /* PreviewConverter.cpp in Sources */,
7CCE7F0C1A411AE600447C4C /* PrivateBrowsingPushStateNoHistoryCallback.cpp in Sources */,
6B0A07F721FA9C2B00D57391 /* PrivateClickMeasurement.cpp in Sources */,
+ 57F1C91125DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm in Sources */,
4647B1261EBA3B850041D7EF /* ProcessDidTerminate.cpp in Sources */,
41882F0321010C0D002FF288 /* ProcessPreWarming.mm in Sources */,
CDA4438E21F7A47700379489 /* ProcessSuspendMediaBuffering.mm in Sources */,
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp (273166 => 273167)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp 2021-02-19 23:01:20 UTC (rev 273166)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp 2021-02-19 23:15:22 UTC (rev 273167)
@@ -24,6 +24,7 @@
*/
#include "config.h"
+#include "Test.h"
#include <WebCore/PrivateClickMeasurement.h>
#include <wtf/URL.h>
@@ -300,4 +301,25 @@
ASSERT_FALSE(ephemeralNonce.isValid());
}
+#if HAVE(RSA_BSSA)
+TEST(PrivateClickMeasurement, InvalidBlindedSecret)
+{
+ const char serverPublicKeyBase64URL[] = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzb1dThrtYwVh46SjInegKhAqpbJwm1XnTBCvybSK8zk53R0Am1hG33AVF5J1lqYf36wp663GasclHtqzvxFZIvDA1DUSH4aZz_fDHCTTxEeJVPORS3zNN2UjWwbtnwsh4BmDTi-z_cDn0LAz2JuZyKlyFt5GgVLAQvL9H3VLHU9_XHNK-uboyXfcHRTtrDnpu3c6wvX5dd-AJoLmIQTZBEJfVkxBGznk1qKHjc6nASAirKF_wJCnuwAK8C6BAcjNcwUWCeKp0YECzCXU--JXd2OEU-QhxPC67faiDOh3V0vlfqZLtrlbnanUCKrvhw7GaGOGYotIrnZtuNfxC14d_XNVd1FS8nHjRTHnEgw_jnlSssfgStz0uJtcmkfgoJBvOE4mIRpi7iSlRfXNkKsWX1J-gwcnCVo5u0uJEW6X6NyvEGYJ8w5BPfwsQuK9y-4Z7ikt9IOucEHY7ThDmi9TNNhHBVj0Gu4wGoSjq3a6vL5N10ZSHXoq1XgfGPrmHhhL90cjvWonoyOXsUqlXEzTjD2W9897Q-Mx9BUNrGQPqmIx8F5MwxWcOrye8WRp4Q88n2YSUnV7C8ayld3v1Fh7N5jeSqeVmtDVRYTn2sVfNqgXrzgdigJcQR8vFENu6nzFPwsrXPMaCiLUnZNUmQ1ZSLQeQyhYXxHqRJrnuCDWXLkCAwEAAQ";
+
+ PrivateClickMeasurement pcm;
+ auto sourceSecretToken = pcm.tokenSignatureJSON(serverPublicKeyBase64URL);
+ EXPECT_EQ(sourceSecretToken->asObject()->size(), 0ul);
+
+ auto ephemeralNonce = PrivateClickMeasurement::EphemeralSourceNonce { "ABCDEFabcdef0123456789"_s };
+ EXPECT_TRUE(ephemeralNonce.isValid());
+ pcm.setEphemeralSourceNonce(WTFMove(ephemeralNonce));
+
+ sourceSecretToken = pcm.tokenSignatureJSON(serverPublicKeyBase64URL);
+ EXPECT_EQ(sourceSecretToken->asObject()->size(), 4ul);
+
+ auto persistentToken = pcm.calculateSourceUnlinkableToken(emptyString());
+ EXPECT_FALSE(persistentToken);
+}
+#endif
+
} // namespace TestWebKitAPI
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm (0 => 273167)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm 2021-02-19 23:15:22 UTC (rev 273167)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Test.h"
+
+#if HAVE(RSA_BSSA)
+
+#include <Security/SecKeyPriv.h>
+#include <WebCore/PrivateClickMeasurement.h>
+
+extern "C" {
+#include <corecrypto/cc_priv.h>
+#include <corecrypto/ccrng.h>
+#include <corecrypto/ccrsa.h>
+#include <corecrypto/ccrsabssa.h>
+}
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+TEST(PrivateClickMeasurement, ValidBlindedSecret)
+{
+ auto ephemeralNonce = PrivateClickMeasurement::EphemeralSourceNonce { "ABCDEFabcdef0123456789"_s };
+ EXPECT_TRUE(ephemeralNonce.isValid());
+
+ PrivateClickMeasurement pcm;
+ pcm.setEphemeralSourceNonce(WTFMove(ephemeralNonce));
+
+ // Generate the server key pair.
+ size_t modulusNBits = 4096;
+ int error = 0;
+
+ struct ccrng_state* rng = ccrng(&error);
+ EXPECT_EQ(error, CCERR_OK);
+
+ const uint8_t e[] = { 0x1, 0x00, 0x01 };
+ ccrsa_full_ctx_decl(ccn_sizeof(modulusNBits), rsaPrivateKey);
+ error = ccrsa_generate_key(modulusNBits, rsaPrivateKey, sizeof(e), e, rng);
+ EXPECT_EQ(error, CCERR_OK);
+
+ ccrsa_pub_ctx_t rsaPublicKey = ccrsa_ctx_public(rsaPrivateKey);
+ size_t modulusNBytes = cc_ceiling(ccrsa_pubkeylength(rsaPublicKey), 8);
+
+ const struct ccrsabssa_ciphersuite *ciphersuite = &ccrsabssa_ciphersuite_rsa4096_sha384;
+
+ size_t exportSize = ccder_encode_rsa_pub_size(rsaPublicKey);
+ auto publicKey = adoptNS([[NSMutableData alloc] initWithLength:exportSize]);
+ ccder_encode_rsa_pub(rsaPublicKey, static_cast<uint8_t*>([publicKey mutableBytes]), static_cast<uint8_t*>([publicKey mutableBytes]) + [publicKey length]);
+
+ auto secKey = adoptCF(SecKeyCreateWithData((__bridge CFDataRef)publicKey.get(), (__bridge CFDictionaryRef)@{
+ (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
+ (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPublic
+ }, nil));
+ EXPECT_NOT_NULL(secKey);
+
+ auto spkiData = adoptCF(SecKeyCopySubjectPublicKeyInfo(secKey.get()));
+ auto *nsSpkiData = (__bridge NSData *)spkiData.get();
+
+ // Continue the test.
+ auto sourceSecretToken = pcm.tokenSignatureJSON(WTF::base64URLEncode(nsSpkiData.bytes, nsSpkiData.length));
+ EXPECT_EQ(sourceSecretToken->asObject()->size(), 4ul);
+ EXPECT_STREQ(sourceSecretToken->getString("source_engagement_type"_s).utf8().data(), "click");
+ EXPECT_STREQ(sourceSecretToken->getString("source_nonce"_s).utf8().data(), "ABCDEFabcdef0123456789");
+ EXPECT_FALSE(sourceSecretToken->getString("source_secret_token"_s).isEmpty());
+ EXPECT_EQ(sourceSecretToken->getInteger("version"_s), 2);
+
+ // Generate the signature.
+ Vector<uint8_t> blindedMessage;
+ base64URLDecode(sourceSecretToken->getString("source_secret_token"_s), blindedMessage);
+
+ auto blindedSignature = adoptNS([[NSMutableData alloc] initWithLength: modulusNBytes]);
+ ccrsabssa_sign_blinded_message(ciphersuite, rsaPrivateKey, blindedMessage.data(), blindedMessage.size(), static_cast<uint8_t *>([blindedSignature mutableBytes]), [blindedSignature length], rng);
+
+ // Continue the test.
+ auto persistentToken = pcm.calculateSourceUnlinkableToken(WTF::base64URLEncode([blindedSignature bytes], [blindedSignature length]));
+ EXPECT_TRUE(persistentToken);
+ EXPECT_FALSE(persistentToken->tokenBase64URL.isEmpty());
+ EXPECT_FALSE(persistentToken->keyIDBase64URL.isEmpty());
+ EXPECT_FALSE(persistentToken->signatureBase64URL.isEmpty());
+}
+
+} // namespace TestWebKitAPI
+
+#endif // EHAVE(RSA_BSSA)