| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_ |
| #define CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_ |
| |
| #include <stdint.h> |
| |
| #include <array> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "base/containers/flat_set.h" |
| #include "base/types/expected.h" |
| #include "base/types/optional_ref.h" |
| #include "base/uuid.h" |
| #include "base/values.h" |
| #include "content/browser/interest_group/auction_metrics_recorder.h" |
| #include "content/browser/interest_group/interest_group_auction.h" |
| #include "content/common/content_export.h" |
| #include "third_party/blink/public/common/interest_group/interest_group.h" |
| #include "url/origin.h" |
| |
| namespace content { |
| |
| struct CONTENT_EXPORT AdditionalBidDecodeResult { |
| AdditionalBidDecodeResult(); |
| AdditionalBidDecodeResult(const AdditionalBidDecodeResult& other) = delete; |
| AdditionalBidDecodeResult(AdditionalBidDecodeResult&& other); |
| ~AdditionalBidDecodeResult(); |
| |
| AdditionalBidDecodeResult& operator=(const AdditionalBidDecodeResult&) = |
| delete; |
| AdditionalBidDecodeResult& operator=(AdditionalBidDecodeResult&&); |
| |
| std::unique_ptr<InterestGroupAuction::BidState> bid_state; |
| std::unique_ptr<InterestGroupAuction::Bid> bid; |
| |
| // `negative_target_joining_origin` is required if there is more than one |
| // entry in `negative_target_interest_group_names` (and DecodeAdditionalBid |
| // ensures it's set in that case). |
| std::optional<url::Origin> negative_target_joining_origin; |
| std::vector<std::string> negative_target_interest_group_names; |
| }; |
| |
| // Tries to parse a "bid" object `bid_in` specified as part of "additionalBids", |
| // and to construct corresponding InterestGroupAuction::Bid and BidState. |
| // |
| // `auction` will only be used to populate the `auction` field of the |
| // returned result's `bid`, so may be null for tests. |
| // |
| // `auction_nonce_from_header` is the expected `auctionNonce` for the bid (if |
| // the bid specifies an `auctionNonce`), or an input into the calculation of the |
| // expected `bidNonce` of the bid (if the bid specifies a `bidNonce`). |
| // |
| // `seller_nonce_from_header`, if present, is used as an input into the |
| // calculation of the expected `bidNonce` of the bid. |
| // |
| // `interest_group_buyers` is the set of interest group owners participating in |
| // the auction, from the auction config. |
| // |
| // `seller` is expected seller for the auction the bid is to participate in. |
| // |
| // `top_level_seller` should be set for the component auctions only, and specify |
| // the seller of the enclosing top-level auction. |
| // |
| // On success, returns an AdditionalBidDecodeResult. Note that `*bid` will |
| // have a pointer to `*bid_state`. |
| // |
| // On failure, returns an error message. |
| CONTENT_EXPORT base::expected<AdditionalBidDecodeResult, std::string> |
| DecodeAdditionalBid( |
| InterestGroupAuction* auction, |
| const base::Value& bid_in, |
| const base::Uuid& auction_nonce_from_header, |
| base::optional_ref<const std::string> seller_nonce_from_header, |
| const base::flat_set<url::Origin>& interest_group_buyers, |
| const url::Origin& seller, |
| base::optional_ref<const url::Origin> top_level_seller); |
| |
| struct CONTENT_EXPORT SignedAdditionalBidSignature { |
| blink::InterestGroup::AdditionalBidKey key; |
| std::array<uint8_t, 64> signature; |
| }; |
| |
| struct CONTENT_EXPORT SignedAdditionalBid { |
| SignedAdditionalBid(); |
| SignedAdditionalBid(const SignedAdditionalBid& other) = delete; |
| SignedAdditionalBid(SignedAdditionalBid&& other); |
| ~SignedAdditionalBid(); |
| |
| SignedAdditionalBid& operator=(const SignedAdditionalBid&) = delete; |
| SignedAdditionalBid& operator=(SignedAdditionalBid&&); |
| |
| std::string additional_bid_json; |
| std::vector<SignedAdditionalBidSignature> signatures; |
| |
| // Returns a vector of indices of signatures that succeed in verifying. |
| std::vector<size_t> VerifySignatures(); |
| }; |
| |
| // Tries to decode a signed additional bid JSON represented as |
| // `signed_additional_bid_in`. |
| CONTENT_EXPORT base::expected<SignedAdditionalBid, std::string> |
| DecodeSignedAdditionalBid(base::Value signed_additional_bid_in); |
| |
| // This class keeps the memory index of negative targeting interest groups |
| // and helps decide whether they apply to particular bids. |
| class CONTENT_EXPORT AdAuctionNegativeTargeter { |
| public: |
| AdAuctionNegativeTargeter(); |
| ~AdAuctionNegativeTargeter(); |
| |
| // Register a negative targeting group for buyer `buyer` named `name` |
| // that was joined from `joining_origin` with public key `key`. |
| void AddInterestGroupInfo(const url::Origin& buyer, |
| const std::string& name, |
| const url::Origin& joining_origin, |
| const blink::InterestGroup::AdditionalBidKey& key); |
| |
| // Returns the number of negative interest groups added to this targeter |
| // using AddInterestGroupInfo. |
| size_t GetNumNegativeInterestGroups(); |
| |
| // Returns true if negative targeting applies to a bid. |
| // |
| // `buyer` is the purported origin of the additional bid. |
| // |
| // `negative_target_joining_origin`, `negative_target_interest_group_names` |
| // is the negative targeting info provided by the additional bid. |
| // |
| // `signatures` are the signatures that were included with the signed |
| // additional bid. |
| // |
| // `valid_signatures` are indices into `signatures` specifying which ones |
| // are actually valid signatures for the key. (This does not mean they are |
| // valid signatures done by the `buyer`). |
| // |
| // `seller` is the seller of the auction this is participating in. It's |
| // only used for error messages. |
| // |
| // Any warning messages that may be of interest to developer will be |
| // collected into `errors_out`. |
| bool ShouldDropDueToNegativeTargeting( |
| const url::Origin& buyer, |
| const std::optional<url::Origin>& negative_target_joining_origin, |
| const std::vector<std::string>& negative_target_interest_group_names, |
| const std::vector<SignedAdditionalBidSignature>& signatures, |
| const std::vector<size_t>& valid_signatures, |
| const url::Origin& seller, |
| AuctionMetricsRecorder& auction_metrics_recorder, |
| std::vector<std::string>& errors_out); |
| |
| private: |
| struct NegativeInfo { |
| NegativeInfo(); |
| NegativeInfo(const NegativeInfo& other) = delete; |
| NegativeInfo(NegativeInfo&& other) = delete; |
| ~NegativeInfo(); |
| |
| NegativeInfo& operator=(const NegativeInfo&) = delete; |
| NegativeInfo& operator=(NegativeInfo&&) = delete; |
| |
| url::Origin joining_origin; |
| blink::InterestGroup::AdditionalBidKey key; |
| }; |
| std::map<std::pair<url::Origin, std::string>, NegativeInfo> |
| negative_interest_groups_; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_ |