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");
}
}