Add `GeoHint` to `BlindSignToken`. As a part of the impl of Token caching by Geo, it is required that the `BlindSideToken` contains the geo. More details about the implementation can be found in the [design](https://docs.google.com/document/d/1mQHfJvhDItCXk5LdkMxn1DQ0pQvNiItzIWTXSbcv9pU/edit?usp=sharing). PiperOrigin-RevId: 642286269
diff --git a/quiche/blind_sign_auth/blind_sign_auth.cc b/quiche/blind_sign_auth/blind_sign_auth.cc index b52367e..9142276 100644 --- a/quiche/blind_sign_auth/blind_sign_auth.cc +++ b/quiche/blind_sign_auth/blind_sign_auth.cc
@@ -148,6 +148,9 @@ std::vector<uint16_t> kExpectedExtensionTypes = { /*ExpirationTimestamp=*/0x0001, /*GeoHint=*/0x0002, /*ServiceType=*/0xF001, /*DebugMode=*/0xF002, /*ProxyLayer=*/0xF003}; + // TODO(b/345801768): Improve the API of + // `anonymous_tokens::ValidateExtensionsOrderAndValues` to + // avoid any possible TOCTOU problems. absl::Status result = anonymous_tokens::ValidateExtensionsOrderAndValues( *extensions, absl::MakeSpan(kExpectedExtensionTypes), absl::Now()); @@ -168,6 +171,11 @@ absl::Time public_metadata_expiry_time = absl::FromUnixSeconds(expiration_timestamp->timestamp); + absl::StatusOr<anonymous_tokens::GeoHint> geo_hint = + anonymous_tokens::GeoHint::FromExtension( + extensions->extensions.at(1)); + QUICHE_CHECK(geo_hint.ok()); + // Create token challenge. anonymous_tokens::TokenChallenge challenge; challenge.issuer_name = kIssuerHostname; @@ -248,7 +256,7 @@ absl::bind_front(&BlindSignAuth::PrivacyPassAuthAndSignCallback, this, std::move(initial_data_response.privacy_pass_data() .public_metadata_extensions()), - public_metadata_expiry_time, *use_case, + public_metadata_expiry_time, *geo_hint, *use_case, std::move(privacy_pass_clients), std::move(callback)); // TODO(b/304811277): remove other usages of string.data() fetcher_->DoRequest(BlindSignMessageRequestType::kAuthAndSign, oauth_token, @@ -258,6 +266,7 @@ void BlindSignAuth::PrivacyPassAuthAndSignCallback( std::string encoded_extensions, absl::Time public_key_expiry_time, + anonymous_tokens::GeoHint geo_hint, anonymous_tokens::AnonymousTokensUseCase use_case, std::vector<std::unique_ptr<anonymous_tokens:: PrivacyPassRsaBssaPublicMetadataClient>> @@ -331,8 +340,9 @@ privacy_pass_token_data.mutable_encoded_extensions()->assign( absl::WebSafeBase64Escape(encoded_extensions)); privacy_pass_token_data.set_use_case_override(use_case); - tokens_vec.push_back(BlindSignToken{ - privacy_pass_token_data.SerializeAsString(), public_key_expiry_time}); + tokens_vec.push_back( + BlindSignToken{privacy_pass_token_data.SerializeAsString(), + public_key_expiry_time, geo_hint}); } std::move(callback)(absl::Span<BlindSignToken>(tokens_vec));
diff --git a/quiche/blind_sign_auth/blind_sign_auth.h b/quiche/blind_sign_auth/blind_sign_auth.h index 552f2c1..39d8fa6 100644 --- a/quiche/blind_sign_auth/blind_sign_auth.h +++ b/quiche/blind_sign_auth/blind_sign_auth.h
@@ -12,6 +12,7 @@ #include "absl/status/statusor.h" #include "absl/time/time.h" #include "anonymous_tokens/cpp/privacy_pass/rsa_bssa_public_metadata_client.h" +#include "anonymous_tokens/cpp/privacy_pass/token_encodings.h" #include "quiche/blind_sign_auth/blind_sign_auth_interface.h" #include "quiche/blind_sign_auth/blind_sign_auth_protos.h" #include "quiche/blind_sign_auth/blind_sign_message_interface.h" @@ -27,7 +28,8 @@ privacy::ppn::BlindSignAuthOptions auth_options) : fetcher_(fetcher), auth_options_(std::move(auth_options)) {} - // Returns signed unblinded tokens and their expiration time in a callback. + // Returns signed unblinded tokens, their expiration time, and their geo in a + // callback. // Tokens are single-use. // The GetTokens callback will run on the same thread as the // BlindSignMessageInterface callbacks. @@ -49,6 +51,7 @@ SignedTokenCallback callback); void PrivacyPassAuthAndSignCallback( std::string encoded_extensions, absl::Time public_key_expiry_time, + anonymous_tokens::GeoHint geo_hint, anonymous_tokens::AnonymousTokensUseCase use_case, std::vector<std::unique_ptr<anonymous_tokens:: PrivacyPassRsaBssaPublicMetadataClient>>
diff --git a/quiche/blind_sign_auth/blind_sign_auth_interface.h b/quiche/blind_sign_auth/blind_sign_auth_interface.h index c46df3e..12b6204 100644 --- a/quiche/blind_sign_auth/blind_sign_auth_interface.h +++ b/quiche/blind_sign_auth/blind_sign_auth_interface.h
@@ -11,11 +11,14 @@ #include "absl/status/statusor.h" #include "absl/time/time.h" #include "absl/types/span.h" +#include "anonymous_tokens/cpp/privacy_pass/token_encodings.h" #include "quiche/common/platform/api/quiche_export.h" #include "quiche/common/quiche_callbacks.h" namespace quiche { +using ::anonymous_tokens::GeoHint; + // ProxyLayer indicates which proxy layer that tokens will be used with. enum class ProxyLayer : int { kProxyA, @@ -36,6 +39,7 @@ struct QUICHE_EXPORT BlindSignToken { std::string token; absl::Time expiration; + GeoHint geo_hint; }; using SignedTokenCallback =
diff --git a/quiche/blind_sign_auth/blind_sign_auth_test.cc b/quiche/blind_sign_auth/blind_sign_auth_test.cc index 6e01b5c..f293bca 100644 --- a/quiche/blind_sign_auth/blind_sign_auth_test.cc +++ b/quiche/blind_sign_auth/blind_sign_auth_test.cc
@@ -13,7 +13,9 @@ #include "absl/status/statusor.h" #include "absl/strings/escaping.h" #include "absl/strings/string_view.h" +#include "absl/time/clock.h" #include "absl/time/time.h" +#include "absl/types/span.h" #include "anonymous_tokens/cpp/crypto/crypto_utils.h" #include "anonymous_tokens/cpp/privacy_pass/token_encodings.h" #include "anonymous_tokens/cpp/testing/utils.h" @@ -243,6 +245,11 @@ std::string decoded_extensions; ASSERT_TRUE(absl::WebSafeBase64Unescape( privacy_pass_token_data.encoded_extensions(), &decoded_extensions)); + // Validate GeoHint in BlindSignToken. + EXPECT_EQ(token.geo_hint.geo_hint, "US,US-AL,ALABASTER"); + EXPECT_EQ(token.geo_hint.country_code, "US"); + EXPECT_EQ(token.geo_hint.region, "US-AL"); + EXPECT_EQ(token.geo_hint.city, "ALABASTER"); } }