Changeset 273167 in webkit


Ignore:
Timestamp:
Feb 19, 2021 3:15:22 PM (3 years ago)
Author:
jiewen_tan@apple.com
Message:

PCM: Generate secret token and corresponding unlinkable token
https://bugs.webkit.org/show_bug.cgi?id=222019
<rdar://problem/73581412>

Reviewed by John Wilander.

Source/WebCore:

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.

Source/WTF:

  • wtf/PlatformHave.h:

Adds a compile time flag for RSABSSA.

Tools:

  • TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:

(TestWebKitAPI::TEST):
Add tests.

Location:
trunk
Files:
4 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt

    r273133 r273167  
    1919No cookies in token signing request.
    2020Request body:
    21 {"source_engagement_type":"click","source_nonce":"ABCDEFabcdef0123456789","unlinkable_token":"TODO","version":2}
     21{}
    2222
    2323Unattributed Private Click Measurements:
  • trunk/Source/WTF/ChangeLog

    r273165 r273167  
     12021-02-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        PCM: Generate secret token and corresponding unlinkable token
     4        https://bugs.webkit.org/show_bug.cgi?id=222019
     5        <rdar://problem/73581412>
     6
     7        Reviewed by John Wilander.
     8
     9        * wtf/PlatformHave.h:
     10        Adds a compile time flag for RSABSSA.
     11
    1122021-02-19  Jer Noble  <jer.noble@apple.com>
    213
  • trunk/Source/WTF/wtf/PlatformHave.h

    r272999 r273167  
    889889#define HAVE_STATIC_FONT_REGISTRY 1
    890890#endif
     891
     892#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000) \
     893    || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150000)
     894#define HAVE_RSA_BSSA 1
     895#endif
  • trunk/Source/WebCore/ChangeLog

    r273159 r273167  
     12021-02-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        PCM: Generate secret token and corresponding unlinkable token
     4        https://bugs.webkit.org/show_bug.cgi?id=222019
     5        <rdar://problem/73581412>
     6
     7        Reviewed by John Wilander.
     8
     9        Covered by API tests.
     10
     11        This patch utilizes RSABSSA to generate secret token for PCM fraud prevention.
     12
     13        * Configurations/WebCore.xcconfig:
     14        * SourcesCocoa.txt:
     15        * WebCore.xcodeproj/project.pbxproj:
     16        Paperwork to link CryptoKitCBridging.
     17
     18        * loader/PrivateClickMeasurement.cpp:
     19        (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::isValid const):
     20        (WebCore::PrivateClickMeasurement::setEphemeralSourceNonce):
     21        * loader/PrivateClickMeasurement.h:
     22        (WebCore::PrivateClickMeasurement::attributeOnSite const):
     23        (WebCore::PrivateClickMeasurement::ephemeralSourceNonce const):
     24        (WebCore::PrivateClickMeasurement::clearEphemeralSourceNonce):
     25        (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::EphemeralSourceNonce): Deleted.
     26        (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::isValid const): Deleted.
     27        (WebCore::PrivateClickMeasurement::setEphemeralSourceNonce): Deleted.
     28        Groups functionalities behind HAVE_RSA_BSSA.
     29
     30        * loader/cocoa/PrivateClickMeasurementCocoa.mm: Added.
     31        (WebCore::PrivateClickMeasurement::blindedSecretJson):
     32        (WebCore::PrivateClickMeasurement::calculatePersistentBlindedToken):
     33        Introduces new methods to generate the blinded secrets and unlinkable tokens.
     34
    1352021-02-19  Devin Rousso  <drousso@apple.com>
    236
  • trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj

    r273121 r273167  
    139139                572A107822B456F500F410C8 /* AuthKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 572A107722B456F500F410C8 /* AuthKitSPI.h */; };
    140140                576CA9D622B854AB0030143C /* AppSSOSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 576CA9D522B854AB0030143C /* AppSSOSPI.h */; };
     141                57F1C90925DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */; };
     142                57F1C90A25DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */; };
    141143                57FD318A22B3593E008D0E8B /* AppSSOSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */; };
    142144                57FD318B22B35989008D0E8B /* AppSSOSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 57FD318822B3592F008D0E8B /* AppSSOSoftLink.h */; };
     
    342344                572A107722B456F500F410C8 /* AuthKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthKitSPI.h; sourceTree = "<group>"; };
    343345                576CA9D522B854AB0030143C /* AppSSOSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSSOSPI.h; sourceTree = "<group>"; };
     346                57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoKitCBridgingSoftLink.h; sourceTree = "<group>"; };
     347                57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CryptoKitCBridgingSoftLink.mm; sourceTree = "<group>"; };
    344348                57FD318822B3592F008D0E8B /* AppSSOSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppSSOSoftLink.h; sourceTree = "<group>"; };
    345349                57FD318922B3593E008D0E8B /* AppSSOSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppSSOSoftLink.mm; sourceTree = "<group>"; };
     
    692696                                077E87B0226A460200A2AFF0 /* AVFoundationSoftLink.h */,
    693697                                077E87AF226A460200A2AFF0 /* AVFoundationSoftLink.mm */,
     698                                57F1C90725DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h */,
     699                                57F1C90825DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm */,
    694700                                F44291661FA52705002CC93E /* FileSizeFormatterCocoa.mm */,
    695701                                1C022EFC22CFE8E0006DF01B /* Gunzip.cpp */,
     
    829835                                0C5AF9191F43A4C7002EAC02 /* CoreUISPI.h in Headers */,
    830836                                1C09D0531E31C44100725F18 /* CryptoDigest.h in Headers */,
     837                                57F1C90925DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.h in Headers */,
    831838                                0C2DA1411F3BEB4900DBC317 /* DataDetectorsCoreSPI.h in Headers */,
    832839                                0C77858A1F45130F00F4EBB6 /* DataDetectorsSPI.h in Headers */,
     
    10381045                                1C77C8C925D7972000635E0C /* CoreTextSoftLink.cpp in Sources */,
    10391046                                1C09D0561E31C46500725F18 /* CryptoDigestCommonCrypto.cpp in Sources */,
     1047                                57F1C90A25DCF0CF00E8F6EA /* CryptoKitCBridgingSoftLink.mm in Sources */,
    10401048                                A1175B581F6B470500C4B9F0 /* DefaultSearchProvider.cpp in Sources */,
    10411049                                F44291641FA52670002CC93E /* FileSizeFormatter.cpp in Sources */,
  • trunk/Source/WebCore/SourcesCocoa.txt

    r273159 r273167  
    170170loader/archive/cf/LegacyWebArchiveMac.mm
    171171loader/cocoa/DiskCacheMonitorCocoa.mm
     172loader/cocoa/PrivateClickMeasurementCocoa.mm
    172173loader/cocoa/SubresourceLoaderCocoa.mm
    173174loader/ios/LegacyPreviewLoader.mm
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r273159 r273167  
    94229422                57EF5E5F1D20C83900171E60 /* TextCodecReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextCodecReplacement.h; sourceTree = "<group>"; };
    94239423                57EF5E611D20D28700171E60 /* TextCodecReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecReplacement.cpp; sourceTree = "<group>"; };
     9424                57F1C8E325DC6EE700E8F6EA /* PrivateClickMeasurementCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementCocoa.mm; sourceTree = "<group>"; };
    94249425                57F827391DB72C22009D2BF4 /* RsaHashedKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaHashedKeyGenParams.idl; sourceTree = "<group>"; };
    94259426                57FEDD3D1DB6D47F00EB96F5 /* RsaKeyGenParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaKeyGenParams.idl; sourceTree = "<group>"; };
     
    97379738                6A7279881F16C29B003F39B8 /* InspectorShaderProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorShaderProgram.h; sourceTree = "<group>"; };
    97389739                6A7279891F16C29B003F39B8 /* InspectorShaderProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorShaderProgram.cpp; sourceTree = "<group>"; };
    9739                 6B0A07F021FA4B5C00D57391 /* PrivateClickMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurement.h; sourceTree = "<group>"; };
     9740                6B0A07F021FA4B5C00D57391 /* PrivateClickMeasurement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurement.h; sourceTree = "<group>"; };
    97409741                6B0A07F121FA4B5C00D57391 /* PrivateClickMeasurement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurement.cpp; sourceTree = "<group>"; };
    97419742                6B1F480F22989EC400DE8B82 /* CrossSiteNavigationDataTransfer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrossSiteNavigationDataTransfer.h; sourceTree = "<group>"; };
     
    2297422975                                7EDAAFC819A2CBD10034DFD1 /* DiskCacheMonitorCocoa.h */,
    2297522976                                7E4DE10C198B10B60051CB02 /* DiskCacheMonitorCocoa.mm */,
     22977                                57F1C8E325DC6EE700E8F6EA /* PrivateClickMeasurementCocoa.mm */,
    2297622978                                7E8FADC3199A95B100714968 /* SubresourceLoaderCocoa.mm */,
    2297722979                        );
  • trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp

    r273133 r273167  
    3838
    3939static const char privateClickMeasurementTriggerAttributionPath[] = "/.well-known/private-click-measurement/trigger-attribution/";
    40 static const char privateClickMeasurementTokenSignaturePath[] = "/.well-known/private-click-measurement/sign-unlinkable-token/";
     40static const char privateClickMeasurementTokenSignaturePath[] = "/.well-known/private-click-measurement/sign-secret-token/";
    4141static const char privateClickMeasurementTokenPublicKeyPath[] = "/.well-known/private-click-measurement/get-unlinkable-token-public-key/";
    4242static const char privateClickMeasurementReportAttributionPath[] = "/.well-known/private-click-measurement/report-attribution/";
     
    117117}
    118118
    119 URL PrivateClickMeasurement::tokenSignatureURL() const
    120 {
    121     if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
    122         return URL();
    123 
    124     StringBuilder builder;
    125     builder.appendLiteral("https://");
    126     builder.append(m_sourceSite.registrableDomain.string());
    127     builder.appendLiteral(privateClickMeasurementTokenSignaturePath);
    128 
    129     URL url { URL(), builder.toString() };
    130     if (url.isValid())
    131         return url;
    132 
    133     return URL();
    134 }
    135 
    136 URL PrivateClickMeasurement::tokenPublicKeyURL() const
    137 {
    138     StringBuilder builder;
    139     builder.appendLiteral("https://");
    140     builder.append(m_sourceSite.registrableDomain.string());
    141     builder.appendLiteral(privateClickMeasurementTokenPublicKeyPath);
    142 
    143     URL url { URL(), builder.toString() };
    144     if (url.isValid())
    145         return url;
    146 
    147     return URL();
    148 }
    149 
    150 Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON() const
    151 {
    152     auto reportDetails = JSON::Object::create();
    153     if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
    154         return reportDetails;
    155 
    156     reportDetails->setString("source_engagement_type"_s, "click"_s);
    157     reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce);
    158     reportDetails->setString("unlinkable_token"_s, "TODO"_s);
    159     reportDetails->setInteger("version"_s, 2);
    160     return reportDetails;
    161 }
    162 
    163119URL PrivateClickMeasurement::attributionReportURL() const
    164120{
     
    193149}
    194150
    195 }
     151// MARK: - Fraud Prevention
     152
     153static constexpr uint32_t EphemeralSourceNonceRequiredNumberOfBytes = 16;
     154
     155bool PrivateClickMeasurement::EphemeralSourceNonce::isValid() const
     156{
     157    // FIXME: Investigate if we can do with a simple length check instead of decoding.
     158    // https://bugs.webkit.org/show_bug.cgi?id=221945
     159    Vector<uint8_t> digest;
     160    if (!base64URLDecode(nonce, digest))
     161        return false;
     162    return digest.size() == EphemeralSourceNonceRequiredNumberOfBytes;
     163}
     164
     165void PrivateClickMeasurement::setEphemeralSourceNonce(EphemeralSourceNonce&& nonce)
     166{
     167    if (!nonce.isValid())
     168        return;
     169    m_ephemeralSourceNonce = WTFMove(nonce);
     170}
     171
     172URL PrivateClickMeasurement::tokenSignatureURL() const
     173{
     174    if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
     175        return URL();
     176
     177    StringBuilder builder;
     178    builder.appendLiteral("https://");
     179    builder.append(m_sourceSite.registrableDomain.string());
     180    builder.appendLiteral(privateClickMeasurementTokenSignaturePath);
     181
     182    URL url { URL(), builder.toString() };
     183    if (url.isValid())
     184        return url;
     185
     186    return URL();
     187}
     188
     189URL PrivateClickMeasurement::tokenPublicKeyURL() const
     190{
     191    StringBuilder builder;
     192    builder.appendLiteral("https://");
     193    builder.append(m_sourceSite.registrableDomain.string());
     194    builder.appendLiteral(privateClickMeasurementTokenPublicKeyPath);
     195
     196    URL url { URL(), builder.toString() };
     197    if (url.isValid())
     198        return url;
     199
     200    return URL();
     201}
     202
     203Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON(const String& serverPublicKeyBase64URL)
     204{
     205    auto reportDetails = JSON::Object::create();
     206    if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
     207        return reportDetails;
     208
     209    String token;
     210#if PLATFORM(COCOA)
     211    token = sourceSecretToken(serverPublicKeyBase64URL);
     212#endif
     213    if (token.isEmpty())
     214        return reportDetails;
     215
     216    reportDetails->setString("source_engagement_type"_s, "click"_s);
     217    reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce);
     218    reportDetails->setString("source_secret_token"_s, token);
     219    reportDetails->setInteger("version"_s, 2);
     220    return reportDetails;
     221}
     222
     223} // namespace WebCore
  • trunk/Source/WebCore/loader/PrivateClickMeasurement.h

    r273133 r273167  
    3737#include <wtf/text/WTFString.h>
    3838
     39#if PLATFORM(COCOA)
     40#include <wtf/RetainPtr.h>
     41#endif
     42
     43#if PLATFORM(COCOA)
     44OBJC_CLASS RSABSSATokenReady;
     45OBJC_CLASS RSABSSATokenWaitingActivation;
     46OBJC_CLASS RSABSSATokenBlinder;
     47#endif
     48
    3949namespace WebCore {
    4050
     
    200210
    201211        static const bool safeToCompareToEmptyOrDeleted = false;
    202     };
    203 
    204     struct EphemeralSourceNonce {
    205         static constexpr uint32_t RequiredNumberOfBytes = 16;
    206 
    207         EphemeralSourceNonce() = default;
    208         explicit EphemeralSourceNonce(const String& nonceString)
    209             : nonce { nonceString }
    210         {
    211         }
    212 
    213         // FIXME: Investigate if we can do with a simple length check instead of decoding.
    214         // https://bugs.webkit.org/show_bug.cgi?id=221945
    215         bool isValid() const
    216         {
    217             Vector<uint8_t> digest;
    218             if (!base64URLDecode(nonce, digest))
    219                 return false;
    220             return digest.size() == RequiredNumberOfBytes;
    221         }
    222 
    223         String nonce;
    224 
    225         template<class Encoder> void encode(Encoder&) const;
    226         template<class Decoder> static Optional<EphemeralSourceNonce> decode(Decoder&);
    227212    };
    228213
     
    278263    WEBCORE_EXPORT Optional<Seconds> attributeAndGetEarliestTimeToSend(AttributionTriggerData&&);
    279264    WEBCORE_EXPORT bool hasHigherPriorityThan(const PrivateClickMeasurement&) const;
    280     WEBCORE_EXPORT URL tokenPublicKeyURL() const;
    281     WEBCORE_EXPORT URL tokenSignatureURL() const;
    282     WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON() const;
    283265    WEBCORE_EXPORT URL attributionReportURL() const;
    284266    WEBCORE_EXPORT Ref<JSON::Object> attributionReportJSON() const;
    285267    const SourceSite& sourceSite() const { return m_sourceSite; };
    286268    const AttributeOnSite& attributeOnSite() const { return m_attributeOnSite; };
    287     void setEphemeralSourceNonce(EphemeralSourceNonce&& nonce) { m_ephemeralSourceNonce = WTFMove(nonce); };
    288     Optional<EphemeralSourceNonce> ephemeralSourceNonce() const { return !m_ephemeralSourceNonce ? WTF::nullopt : m_ephemeralSourceNonce->isValid() ? m_ephemeralSourceNonce : WTF::nullopt; };
    289     void clearEphemeralSourceNonce() { m_ephemeralSourceNonce  = WTF::nullopt; };
    290269    WallTime timeOfAdClick() const { return m_timeOfAdClick; }
    291270    Optional<WallTime> earliestTimeToSend() const { return m_earliestTimeToSend; };
     
    298277    const String& purchaser() const { return m_purchaser; }
    299278
     279    // MARK: - Fraud Prevention
     280    struct EphemeralSourceNonce {
     281        String nonce;
     282
     283        WEBCORE_EXPORT bool isValid() const;
     284
     285        template<class Encoder> void encode(Encoder&) const;
     286        template<class Decoder> static Optional<EphemeralSourceNonce> decode(Decoder&);
     287    };
     288
     289    WEBCORE_EXPORT void setEphemeralSourceNonce(EphemeralSourceNonce&&);
     290    Optional<EphemeralSourceNonce> ephemeralSourceNonce() const { return m_ephemeralSourceNonce; };
     291    void clearEphemeralSourceNonce() { m_ephemeralSourceNonce.reset(); };
     292
     293    struct SourceUnlinkableToken {
     294        String tokenBase64URL;
     295        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);
     304
    300305    template<class Encoder> void encode(Encoder&) const;
    301306    template<class Decoder> static Optional<PrivateClickMeasurement> decode(Decoder&);
     
    303308private:
    304309    bool isValid() const;
     310#if PLATFORM(COCOA)
     311    String sourceSecretToken(const String& serverPublicKeyBase64URL);
     312#endif
    305313
    306314    SourceID m_sourceID;
     
    311319    WallTime m_timeOfAdClick;
    312320
    313     Optional<EphemeralSourceNonce> m_ephemeralSourceNonce;
    314321    Optional<AttributionTriggerData> m_attributionTriggerData;
    315322    Optional<WallTime> m_earliestTimeToSend;
     323
     324    struct SourceSecretToken {
     325#if PLATFORM(COCOA)
     326        RetainPtr<RSABSSATokenBlinder> blinder;
     327        RetainPtr<RSABSSATokenWaitingActivation> waitingToken;
     328        RetainPtr<RSABSSATokenReady> readyToken;
     329#endif
     330    };
     331
     332    Optional<EphemeralSourceNonce> m_ephemeralSourceNonce;
     333    SourceSecretToken m_sourceSecretToken;
    316334};
    317335
  • trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp

    r273133 r273167  
    158158
    159159        // FIXME: Receive and extra the server public key, rdar://73582032.
    160         getSignedUnlinkableToken(WTFMove(attribution));
     160        getSignedSecretToken(WTFMove(attribution), emptyString());
    161161    });
    162162
    163163}
    164164
    165 void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& attribution)
     165void PrivateClickMeasurementManager::getSignedSecretToken(PrivateClickMeasurement&& attribution, const String& tokenPublicKeyBase64URL)
    166166{
    167167    if (!featureEnabled())
     
    179179        return;
    180180
    181     auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(), pcmDataCarried);
    182 
    183     RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
    184     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
     181    auto loadParameters = generateNetworkResourceLoadParametersForHttpPost(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(tokenPublicKeyBase64URL), pcmDataCarried);
     182
     183    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a secret token signing request.");
     184    m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a secret token signing request."_s);
    185185
    186186    m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this)](const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) {
     
    189189
    190190        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 unlinkable token signing request."_s));
     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));
    192192            return;
    193193        }
    194194       
    195         // FIXME: Receive and store the signed unlinkable token, rdar://73582032.
     195        // FIXME: Receive and store the signed secret token, rdar://73582032.
    196196    });
    197197
  • trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h

    r273133 r273167  
    7171private:
    7272    void getTokenPublicKey(PrivateClickMeasurement&&);
    73     void getSignedUnlinkableToken(PrivateClickMeasurement&&);
     73    void getSignedSecretToken(PrivateClickMeasurement&&, const String& tokenPublicKeyBase64URL);
    7474    void clearSentAttribution(PrivateClickMeasurement&&);
    7575    void attribute(const SourceSite&, const AttributeOnSite&, AttributionTriggerData&&);
  • trunk/Tools/ChangeLog

    r273154 r273167  
     12021-02-16  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        PCM: Generate secret token and corresponding unlinkable token
     4        https://bugs.webkit.org/show_bug.cgi?id=222019
     5        <rdar://problem/73581412>
     6
     7        Reviewed by John Wilander.
     8
     9        * TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
     10        (TestWebKitAPI::TEST):
     11        Add tests.
     12
    1132021-02-19  Aditya Keerthi  <akeerthi@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig

    r267869 r273167  
    5656WK_PDFKIT_LDFLAGS_iphonesimulator = -framework PDFKit;
    5757
     58WK_SYSTEM_LDFLAGS = $(WK_SYSTEM_LDFLAGS_$(WK_PLATFORM_NAME));
     59WK_SYSTEM_LDFLAGS_macosx = -framework System;
     60WK_SYSTEM_LDFLAGS_iphoneos = $(WK_SYSTEM_LDFLAGS_$(WK_IOS_15));
     61WK_SYSTEM_LDFLAGS_iphonesimulator = $(WK_SYSTEM_LDFLAGS_$(WK_IOS_15));
     62WK_SYSTEM_LDFLAGS_IOS_SINCE_15 = -framework System;
     63
    5864WK_HID_LDFLAGS = $(WK_HID_LDFLAGS_$(WK_PLATFORM_NAME));
    5965WK_HID_LDFLAGS_macosx = $(WK_HID_LDFLAGS$(WK_MACOS_1015));
     
    7278WK_OPENGL_LDFLAGS_macosx = -framework OpenGL;
    7379
    74 OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework JavaScriptCore -framework WebKit -lWebCoreTestSupport $(WK_AUTHKIT_LDFLAGS) -framework Network $(WK_PDFKIT_LDFLAGS) $(WK_HID_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH));
     80OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework JavaScriptCore -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));
    7581OTHER_LDFLAGS_PLATFORM_ = -framework Cocoa -framework Carbon;
    7682
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r273130 r273167  
    442442                57EDFC5C245A1A3F00959521 /* web-authentication-make-credential-la-no-mock.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57EDFC5B245A18F500959521 /* web-authentication-make-credential-la-no-mock.html */; };
    443443                57EDFC60245A299C00959521 /* web-authentication-get-assertion-la-no-mock.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57EDFC5F245A279900959521 /* web-authentication-get-assertion-la-no-mock.html */; };
     444                57F1C91125DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */; };
    444445                57F4AAA0208FAEF000A68E9E /* SSLKeyGenerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */; };
    445446                57F56A5C1C7F8CC100F31D7E /* IsNavigationActionTrusted.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */; };
     
    22342235                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>"; };
    22352236                57F10D921C7E7B3800ECDF30 /* IsNavigationActionTrusted.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IsNavigationActionTrusted.mm; sourceTree = "<group>"; };
     2237                57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementCocoa.mm; sourceTree = "<group>"; };
    22362238                57F4AA9F208FA83D00A68E9E /* SSLKeyGenerator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SSLKeyGenerator.mm; sourceTree = "<group>"; };
    22372239                57F56A5B1C7F8A4000F31D7E /* IsNavigationActionTrusted.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IsNavigationActionTrusted.html; sourceTree = "<group>"; };
     
    47124714                                0711DF51226A95FB003DD2F7 /* AVFoundationSoftLinkTest.mm */,
    47134715                                751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */,
     4716                                57F1C91025DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm */,
    47144717                                5769C50A1D9B0001000847FB /* SerializedCryptoKeyWrap.mm */,
    47154718                                A17991861E1C994E00A505ED /* SharedBuffer.mm */,
     
    54875490                                7CCE7F0C1A411AE600447C4C /* PrivateBrowsingPushStateNoHistoryCallback.cpp in Sources */,
    54885491                                6B0A07F721FA9C2B00D57391 /* PrivateClickMeasurement.cpp in Sources */,
     5492                                57F1C91125DDD51900E8F6EA /* PrivateClickMeasurementCocoa.mm in Sources */,
    54895493                                4647B1261EBA3B850041D7EF /* ProcessDidTerminate.cpp in Sources */,
    54905494                                41882F0321010C0D002FF288 /* ProcessPreWarming.mm in Sources */,
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp

    r273088 r273167  
    2525
    2626#include "config.h"
     27#include "Test.h"
    2728
    2829#include <WebCore/PrivateClickMeasurement.h>
     
    301302}
    302303
     304#if HAVE(RSA_BSSA)
     305TEST(PrivateClickMeasurement, InvalidBlindedSecret)
     306{
     307    const char serverPublicKeyBase64URL[] = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzb1dThrtYwVh46SjInegKhAqpbJwm1XnTBCvybSK8zk53R0Am1hG33AVF5J1lqYf36wp663GasclHtqzvxFZIvDA1DUSH4aZz_fDHCTTxEeJVPORS3zNN2UjWwbtnwsh4BmDTi-z_cDn0LAz2JuZyKlyFt5GgVLAQvL9H3VLHU9_XHNK-uboyXfcHRTtrDnpu3c6wvX5dd-AJoLmIQTZBEJfVkxBGznk1qKHjc6nASAirKF_wJCnuwAK8C6BAcjNcwUWCeKp0YECzCXU--JXd2OEU-QhxPC67faiDOh3V0vlfqZLtrlbnanUCKrvhw7GaGOGYotIrnZtuNfxC14d_XNVd1FS8nHjRTHnEgw_jnlSssfgStz0uJtcmkfgoJBvOE4mIRpi7iSlRfXNkKsWX1J-gwcnCVo5u0uJEW6X6NyvEGYJ8w5BPfwsQuK9y-4Z7ikt9IOucEHY7ThDmi9TNNhHBVj0Gu4wGoSjq3a6vL5N10ZSHXoq1XgfGPrmHhhL90cjvWonoyOXsUqlXEzTjD2W9897Q-Mx9BUNrGQPqmIx8F5MwxWcOrye8WRp4Q88n2YSUnV7C8ayld3v1Fh7N5jeSqeVmtDVRYTn2sVfNqgXrzgdigJcQR8vFENu6nzFPwsrXPMaCiLUnZNUmQ1ZSLQeQyhYXxHqRJrnuCDWXLkCAwEAAQ";
     308
     309    PrivateClickMeasurement pcm;
     310    auto sourceSecretToken = pcm.tokenSignatureJSON(serverPublicKeyBase64URL);
     311    EXPECT_EQ(sourceSecretToken->asObject()->size(), 0ul);
     312
     313    auto ephemeralNonce = PrivateClickMeasurement::EphemeralSourceNonce { "ABCDEFabcdef0123456789"_s };
     314    EXPECT_TRUE(ephemeralNonce.isValid());
     315    pcm.setEphemeralSourceNonce(WTFMove(ephemeralNonce));
     316
     317    sourceSecretToken = pcm.tokenSignatureJSON(serverPublicKeyBase64URL);
     318    EXPECT_EQ(sourceSecretToken->asObject()->size(), 4ul);
     319
     320    auto persistentToken = pcm.calculateSourceUnlinkableToken(emptyString());
     321    EXPECT_FALSE(persistentToken);
     322}
     323#endif
     324
    303325} // namespace TestWebKitAPI
Note: See TracChangeset for help on using the changeset viewer.