Export BlindSignAuth to GoB, packaging in PPN protos and Anonymous Tokens client crypto library.
PiperOrigin-RevId: 518092689
diff --git a/build/source_list.bzl b/build/source_list.bzl
index 3d8f341..d592628 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -1587,12 +1587,14 @@
]
protobuf_blind_sign_auth = [
"blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto",
+ "blind_sign_auth/proto/any.proto",
"blind_sign_auth/proto/attestation.proto",
"blind_sign_auth/proto/auth_and_sign.proto",
"blind_sign_auth/proto/get_initial_data.proto",
"blind_sign_auth/proto/key_services.proto",
"blind_sign_auth/proto/public_metadata.proto",
"blind_sign_auth/proto/spend_token_data.proto",
+ "blind_sign_auth/proto/timestamp.proto",
]
libevent_hdrs = [
"quic/bindings/quic_libevent.h",
diff --git a/build/source_list.gni b/build/source_list.gni
index 5e70945..cd27eea 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -1587,12 +1587,14 @@
]
protobuf_blind_sign_auth = [
"src/quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto",
+ "src/quiche/blind_sign_auth/proto/any.proto",
"src/quiche/blind_sign_auth/proto/attestation.proto",
"src/quiche/blind_sign_auth/proto/auth_and_sign.proto",
"src/quiche/blind_sign_auth/proto/get_initial_data.proto",
"src/quiche/blind_sign_auth/proto/key_services.proto",
"src/quiche/blind_sign_auth/proto/public_metadata.proto",
"src/quiche/blind_sign_auth/proto/spend_token_data.proto",
+ "src/quiche/blind_sign_auth/proto/timestamp.proto",
]
libevent_hdrs = [
"src/quiche/quic/bindings/quic_libevent.h",
diff --git a/build/source_list.json b/build/source_list.json
index 22a67dc..7f8511c 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -1586,12 +1586,14 @@
],
"protobuf_blind_sign_auth": [
"quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto",
+ "quiche/blind_sign_auth/proto/any.proto",
"quiche/blind_sign_auth/proto/attestation.proto",
"quiche/blind_sign_auth/proto/auth_and_sign.proto",
"quiche/blind_sign_auth/proto/get_initial_data.proto",
"quiche/blind_sign_auth/proto/key_services.proto",
"quiche/blind_sign_auth/proto/public_metadata.proto",
- "quiche/blind_sign_auth/proto/spend_token_data.proto"
+ "quiche/blind_sign_auth/proto/spend_token_data.proto",
+ "quiche/blind_sign_auth/proto/timestamp.proto"
],
"libevent_hdrs": [
"quiche/quic/bindings/quic_libevent.h"
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
index 15584e1..6bd2209 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
@@ -263,7 +263,7 @@
absl::Status AnonymousTokensRsaBssaClient::Verify(
const RSABlindSignatureToken& /*token*/, absl::string_view /*message*/,
- std::optional<absl::string_view> /*public_metadata*/) {
+ absl::optional<absl::string_view> /*public_metadata*/) {
return absl::UnimplementedError("Verify not implemented yet.");
}
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc
index 909096d..9a317f4 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc
@@ -41,7 +41,7 @@
MessageMaskType mask_type = AT_MESSAGE_MASK_CONCAT,
int message_mask_size = 32) {
ANON_TOKENS_ASSIGN_OR_RETURN(auto key, CreateTestKey());
- key.second.set_use_case(use_case);
+ key.second.set_use_case(std::string(use_case));
key.second.set_key_version(key_version);
key.second.set_message_mask_type(mask_type);
key.second.set_message_mask_size(message_mask_size);
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
index da712dc..2e0005f 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
@@ -136,7 +136,8 @@
std::string data = absl::HexStringToBytes(params.input_hex);
std::string expected_digest =
absl::HexStringToBytes(params.expected_digest_hex);
- QUICHE_EXPECT_OK_AND_ASSIGN(auto computed_hash, ComputeHash(data, *params.hasher));
+ ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(auto computed_hash,
+ ComputeHash(data, *params.hasher));
EXPECT_EQ(computed_hash, expected_digest);
}
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/proto_utils_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/proto_utils_test.cc
index a6ff0a2..45dfe9c 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/proto_utils_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/proto_utils_test.cc
@@ -27,8 +27,6 @@
namespace anonymous_tokens {
namespace {
-using ::testing::EqualsProto;
-
TEST(ProtoUtilsTest, EmptyUseCase) {
EXPECT_THAT(ParseUseCase("").status().code(),
absl::StatusCode::kInvalidArgument);
@@ -75,15 +73,13 @@
quiche::protobuf::Timestamp proto;
ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
proto, TimeToProto(absl::FromUnixSeconds(1596762373)));
- EXPECT_THAT(proto, EqualsProto(R"pb(
- seconds: 1596762373 nanos: 0
- )pb"));
+ EXPECT_EQ(proto.seconds(), 1596762373);
+ EXPECT_EQ(proto.nanos(), 0);
ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
proto, TimeToProto(absl::FromUnixMillis(1596762373123L)));
- EXPECT_THAT(proto, EqualsProto(R"pb(
- seconds: 1596762373 nanos: 123000000
- )pb"));
+ EXPECT_EQ(proto.seconds(), 1596762373);
+ EXPECT_EQ(proto.nanos(), 123000000);
}
TEST(ProtoUtilsTest, TimeToProtoBad) {
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/status_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/status_utils.h
index e698702..e0bd70d 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/status_utils.h
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/status_utils.h
@@ -35,7 +35,7 @@
if (ABSL_PREDICT_FALSE(!statusor.ok())) { \
return statusor.status(); \
} \
- lhs = std::move(statusor.value())
+ lhs = *std::move(statusor)
#define ANON_TOKENS_RETURN_IF_ERROR(expr) \
do { \
diff --git a/quiche/blind_sign_auth/blind_sign_auth.cc b/quiche/blind_sign_auth/blind_sign_auth.cc
index f09e6df..413eb64 100644
--- a/quiche/blind_sign_auth/blind_sign_auth.cc
+++ b/quiche/blind_sign_auth/blind_sign_auth.cc
@@ -10,7 +10,6 @@
#include <string>
#include <vector>
-#include "privacy/net/common/cpp/public_metadata/fingerprint.h"
#include "quiche/blind_sign_auth/proto/auth_and_sign.pb.h"
#include "quiche/blind_sign_auth/proto/get_initial_data.pb.h"
#include "quiche/blind_sign_auth/proto/key_services.pb.h"
@@ -28,6 +27,14 @@
#include "quiche/common/quiche_random.h"
namespace quiche {
+namespace {
+
+template <typename T>
+std::string OmitDefault(T value) {
+ return value == 0 ? "" : absl::StrCat(value);
+}
+
+} // namespace
void BlindSignAuth::GetTokens(
absl::string_view oauth_token, int num_tokens,
@@ -101,7 +108,7 @@
random->RandBytes(rand_bytes.data(), rand_bytes.size());
plaintext_message.set_plaintext_message(absl::StrCat("blind:", rand_bytes));
uint64_t fingerprint = 0;
- absl::Status fingerprint_status = privacy::ppn::FingerprintPublicMetadata(
+ absl::Status fingerprint_status = FingerprintPublicMetadata(
initial_data_response.public_metadata_info().public_metadata(),
&fingerprint);
if (!fingerprint_status.ok()) {
@@ -126,7 +133,7 @@
// Create AuthAndSign RPC.
privacy::ppn::AuthAndSignRequest sign_request;
- sign_request.set_oauth_token(oauth_token);
+ sign_request.set_oauth_token(std::string(oauth_token));
sign_request.set_service_type("chromeipblinding");
sign_request.set_key_type(privacy::ppn::AT_PUBLIC_METADATA_KEY_TYPE);
sign_request.set_key_version(
@@ -252,10 +259,38 @@
return;
}
spend_token_data.set_use_case(*use_case);
+ spend_token_data.set_message_mask(
+ signed_tokens->at(i).token().message_mask());
tokens_vec.push_back(spend_token_data.SerializeAsString());
}
callback(absl::Span<std::string>(tokens_vec));
}
+absl::Status BlindSignAuth::FingerprintPublicMetadata(
+ const privacy::ppn::PublicMetadata& metadata, uint64_t* fingerprint) {
+ const EVP_MD* hasher = EVP_sha256();
+ std::string digest;
+ digest.resize(EVP_MAX_MD_SIZE);
+
+ uint32_t digest_length = 0;
+ // Concatenate fields in tag number order, omitting fields whose values match
+ // the default. This enables new fields to be added without changing the
+ // resulting encoding.
+ const std::string input = absl::StrCat( //
+ metadata.exit_location().country(), //
+ metadata.exit_location().city_geo_id(), //
+ metadata.service_type(), //
+ OmitDefault(metadata.expiration().seconds()), //
+ OmitDefault(metadata.expiration().nanos()));
+ if (EVP_Digest(input.data(), input.length(),
+ reinterpret_cast<uint8_t*>(&digest[0]), &digest_length, hasher,
+ nullptr) != 1) {
+ return absl::InternalError("EVP_Digest failed");
+ }
+ // Return the first uint64_t of the SHA-256 hash.
+ memcpy(fingerprint, digest.data(), sizeof(*fingerprint));
+ return absl::OkStatus();
+}
+
} // namespace quiche
diff --git a/quiche/blind_sign_auth/blind_sign_auth.h b/quiche/blind_sign_auth/blind_sign_auth.h
index 5a85dea..5a9384b 100644
--- a/quiche/blind_sign_auth/blind_sign_auth.h
+++ b/quiche/blind_sign_auth/blind_sign_auth.h
@@ -53,6 +53,8 @@
private_membership::anonymous_tokens::AnonymousTokensRsaBssaClient*
bssa_client,
std::function<void(absl::StatusOr<absl::Span<std::string>>)> callback);
+ absl::Status FingerprintPublicMetadata(
+ const privacy::ppn::PublicMetadata& metadata, uint64_t* fingerprint);
BlindSignHttpInterface* http_fetcher_ = nullptr;
};
diff --git a/quiche/blind_sign_auth/blind_sign_auth_test.cc b/quiche/blind_sign_auth/blind_sign_auth_test.cc
index 39bf880..d7e677a 100644
--- a/quiche/blind_sign_auth/blind_sign_auth_test.cc
+++ b/quiche/blind_sign_auth/blind_sign_auth_test.cc
@@ -8,8 +8,8 @@
#include <memory>
#include <string>
#include <utility>
-#include <vector>
+#include "quiche/blind_sign_auth/proto/timestamp.pb.h"
#include "quiche/blind_sign_auth/proto/auth_and_sign.pb.h"
#include "quiche/blind_sign_auth/proto/get_initial_data.pb.h"
#include "quiche/blind_sign_auth/proto/key_services.pb.h"
@@ -22,7 +22,6 @@
#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/testing_utils.h"
#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
#include "openssl/base.h"
-
#include "quiche/blind_sign_auth/blind_sign_http_response.h"
#include "quiche/blind_sign_auth/test_tools/mock_blind_sign_http_interface.h"
#include "quiche/common/platform/api/quiche_mutex.h"
@@ -35,13 +34,11 @@
using ::testing::_;
using ::testing::Eq;
-using ::testing::EqualsProto;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeArgument;
using ::testing::StartsWith;
using ::testing::Unused;
-using ::testing::proto::WhenDeserializedAs;
class BlindSignAuthTest : public QuicheTest {
protected:
@@ -53,7 +50,13 @@
}
keypair_ = *std::move(keypair);
keypair_.second.set_key_version(1);
- keypair_.second.set_use_case("CHROME_IP_BLINDING");
+ keypair_.second.set_use_case("TEST_USE_CASE");
+
+ // Create fake GetInitialDataRequest.
+ expected_get_initial_data_request_.set_use_attestation(false);
+ expected_get_initial_data_request_.set_service_type("chromeipblinding");
+ expected_get_initial_data_request_.set_location_granularity(
+ privacy::ppn::GetInitialDataRequest_LocationGranularity_UNKNOWN);
// Create fake public key response.
privacy::ppn::GetInitialDataResponse fake_get_initial_data_response;
@@ -72,11 +75,18 @@
}
validation_version: 1
)pb";
- privacy::ppn::PublicMetadataInfo public_metadata_info;
- ASSERT_TRUE(proto2::TextFormat::ParseFromString(public_metadata_str,
- &public_metadata_info));
+ privacy::ppn::PublicMetadata::Location location;
+ location.set_country("US");
+ quiche::protobuf::Timestamp expiration;
+ expiration.set_seconds(3600);
+ privacy::ppn::PublicMetadata public_metadata;
+ *public_metadata.mutable_exit_location() = location;
+ public_metadata.set_service_type("chromeipblinding");
+ *public_metadata.mutable_expiration() = expiration;
+ public_metadata_info_.set_validation_version(1);
+ *public_metadata_info_.mutable_public_metadata() = public_metadata;
*fake_get_initial_data_response.mutable_public_metadata_info() =
- public_metadata_info;
+ public_metadata_info_;
fake_get_initial_data_response_ = fake_get_initial_data_response;
blind_sign_auth_ = std::make_unique<BlindSignAuth>(&mock_http_interface_);
@@ -100,14 +110,8 @@
// privacy::ppn::AT_PUBLIC_METADATA_KEY_TYPE.
EXPECT_EQ(request.key_type(), privacy::ppn::AT_PUBLIC_METADATA_KEY_TYPE);
EXPECT_EQ(request.public_key_hash(), "");
- EXPECT_THAT(request.public_metadata_info(), EqualsProto(R"pb(
- public_metadata {
- exit_location { country: "US" }
- service_type: "chromeipblinding"
- expiration { seconds: 3600 }
- }
- validation_version: 1
- )pb"));
+ EXPECT_EQ(request.public_metadata_info().SerializeAsString(),
+ public_metadata_info_.SerializeAsString());
EXPECT_EQ(request.key_version(), keypair_.second.key_version());
// Construct AuthAndSignResponse.
@@ -130,22 +134,17 @@
privacy::ppn::SpendTokenData spend_token_data;
ASSERT_TRUE(spend_token_data.ParseFromString(token));
// Validate token structure.
- EXPECT_THAT(spend_token_data.public_metadata(), EqualsProto(R"pb(
- public_metadata {
- exit_location { country: "US" }
- service_type: "chromeipblinding"
- expiration { seconds: 3600 }
- }
- validation_version: 1
- )pb"));
+ EXPECT_EQ(spend_token_data.public_metadata().SerializeAsString(),
+ public_metadata_info_.SerializeAsString());
EXPECT_THAT(spend_token_data.unblinded_token(), StartsWith("blind:"));
EXPECT_GE(spend_token_data.unblinded_token_signature().size(),
spend_token_data.unblinded_token().size());
EXPECT_EQ(spend_token_data.signing_key_version(),
keypair_.second.key_version());
- EXPECT_THAT(spend_token_data.use_case(),
- private_membership::anonymous_tokens::AnonymousTokensUseCase::
- CHROME_IP_BLINDING);
+ EXPECT_NE(spend_token_data.use_case(),
+ private_membership::anonymous_tokens::AnonymousTokensUseCase::
+ ANONYMOUS_TOKENS_USE_CASE_UNDEFINED);
+ EXPECT_NE(spend_token_data.message_mask(), "");
}
}
@@ -154,14 +153,11 @@
std::pair<bssl::UniquePtr<RSA>,
private_membership::anonymous_tokens::RSABlindSignaturePublicKey>
keypair_;
+ privacy::ppn::PublicMetadataInfo public_metadata_info_;
privacy::ppn::AuthAndSignResponse sign_response_;
privacy::ppn::GetInitialDataResponse fake_get_initial_data_response_;
std::string oauth_token_ = "oauth_token";
- absl::string_view expected_get_initial_data_request_ = R"pb(
- use_attestation: false
- service_type: "chromeipblinding"
- location_granularity: 0
- )pb";
+ privacy::ppn::GetInitialDataRequest expected_get_initial_data_request_;
};
TEST_F(BlindSignAuthTest, TestGetTokensSuccessful) {
@@ -174,8 +170,7 @@
EXPECT_CALL(
mock_http_interface_,
DoRequest(Eq("/v1/getInitialData"), Eq(oauth_token_),
- WhenDeserializedAs<privacy::ppn::GetInitialDataRequest>(
- EqualsProto(expected_get_initial_data_request_)),
+ Eq(expected_get_initial_data_request_.SerializeAsString()),
_))
.Times(1)
.WillOnce(InvokeArgument<3>(fake_public_key_response));
@@ -237,11 +232,10 @@
BlindSignHttpResponse fake_public_key_response(
200, fake_get_initial_data_response_.SerializeAsString());
- EXPECT_CALL(mock_http_interface_,
- DoRequest(Eq("/v1/getInitialData"), Eq(oauth_token_),
- WhenDeserializedAs<privacy::ppn::GetInitialDataRequest>(
- EqualsProto(expected_get_initial_data_request_)),
- _))
+ EXPECT_CALL(
+ mock_http_interface_,
+ DoRequest(Eq("/v1/getInitialData"), Eq(oauth_token_),
+ Eq(expected_get_initial_data_request_.SerializeAsString()), _))
.Times(1)
.WillOnce(InvokeArgument<3>(fake_public_key_response));
@@ -269,8 +263,7 @@
EXPECT_CALL(
mock_http_interface_,
DoRequest(Eq("/v1/getInitialData"), Eq(oauth_token_),
- WhenDeserializedAs<privacy::ppn::GetInitialDataRequest>(
- EqualsProto(expected_get_initial_data_request_)),
+ Eq(expected_get_initial_data_request_.SerializeAsString()),
_))
.Times(1)
.WillOnce(InvokeArgument<3>(fake_public_key_response));
diff --git a/quiche/blind_sign_auth/proto/any.proto b/quiche/blind_sign_auth/proto/any.proto
new file mode 100644
index 0000000..c4fa835
--- /dev/null
+++ b/quiche/blind_sign_auth/proto/any.proto
@@ -0,0 +1,26 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package quiche.protobuf;
+
+// Cloned from
+// https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/any.proto.
+message Any {
+ string type_url = 1;
+
+ // Must be a valid serialized protocol buffer of the above specified type.
+ bytes value = 2;
+}
diff --git a/quiche/blind_sign_auth/proto/attestation.proto b/quiche/blind_sign_auth/proto/attestation.proto
index 1743234..8e658e9 100644
--- a/quiche/blind_sign_auth/proto/attestation.proto
+++ b/quiche/blind_sign_auth/proto/attestation.proto
@@ -1,17 +1,26 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
import "quiche/blind_sign_auth/proto/any.proto";
-import "storage/datapol/annotations/proto/semantic_annotations.proto";
-option go_api_flag = "OPEN_TO_OPAQUE_HYBRID";
-option java_api_version = 2;
option java_multiple_files = true;
option java_outer_classname = "AttestationProto";
option java_package = "com.google.android.libraries.privacy.ppn.proto";
-option cc_api_version = 2;
-option (datapol.file_vetting_status) = "latest";
message NonceRequest {}
diff --git a/quiche/blind_sign_auth/proto/auth_and_sign.proto b/quiche/blind_sign_auth/proto/auth_and_sign.proto
index 64d396d..38f82d1 100644
--- a/quiche/blind_sign_auth/proto/auth_and_sign.proto
+++ b/quiche/blind_sign_auth/proto/auth_and_sign.proto
@@ -1,3 +1,17 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
@@ -5,10 +19,6 @@
import "quiche/blind_sign_auth/proto/attestation.proto";
import "quiche/blind_sign_auth/proto/key_services.proto";
import "quiche/blind_sign_auth/proto/public_metadata.proto";
-import "storage/datapol/annotations/proto/semantic_annotations.proto";
-
-option cc_api_version = 2;
-option (datapol.file_vetting_status) = "latest";
// Client is requesting to auth using the provided auth token.
// Next ID: 9
diff --git a/quiche/blind_sign_auth/proto/get_initial_data.proto b/quiche/blind_sign_auth/proto/get_initial_data.proto
index f05b637..317b356 100644
--- a/quiche/blind_sign_auth/proto/get_initial_data.proto
+++ b/quiche/blind_sign_auth/proto/get_initial_data.proto
@@ -1,15 +1,26 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
import "quiche/blind_sign_auth/proto/attestation.proto";
import "quiche/blind_sign_auth/proto/public_metadata.proto";
-import "storage/datapol/annotations/proto/semantic_annotations.proto";
import "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto";
option java_multiple_files = true;
-option cc_api_version = 2;
-option (datapol.file_vetting_status) = "latest";
// Request data needed to prepare for AuthAndSign.
message GetInitialDataRequest {
@@ -43,4 +54,4 @@
// Data needed to set up attestation, included if use_attestation is true or
// if the service_type input requires it.
privacy.ppn.PrepareAttestationData attestation = 3;
-}
\ No newline at end of file
+}
diff --git a/quiche/blind_sign_auth/proto/key_services.proto b/quiche/blind_sign_auth/proto/key_services.proto
index 271b033..343fea8 100644
--- a/quiche/blind_sign_auth/proto/key_services.proto
+++ b/quiche/blind_sign_auth/proto/key_services.proto
@@ -1,11 +1,22 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
-import "storage/datapol/annotations/proto/semantic_annotations.proto";
-
option java_multiple_files = true;
-option (datapol.file_vetting_status) = "latest";
// Indicates client's desired or capable key support.
enum KeyType {
diff --git a/quiche/blind_sign_auth/proto/public_metadata.proto b/quiche/blind_sign_auth/proto/public_metadata.proto
index c542e0f..5154200 100644
--- a/quiche/blind_sign_auth/proto/public_metadata.proto
+++ b/quiche/blind_sign_auth/proto/public_metadata.proto
@@ -1,13 +1,24 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
import "quiche/blind_sign_auth/proto/timestamp.proto";
-import "storage/datapol/annotations/proto/semantic_annotations.proto";
option java_multiple_files = true;
-option cc_api_version = 2;
-option (datapol.file_vetting_status) = "latest";
// Contains fields which will be cryptographically linked to a blinded token and
// visible to client, signer, and verifier. Clients should validate/set fields
diff --git a/quiche/blind_sign_auth/proto/spend_token_data.proto b/quiche/blind_sign_auth/proto/spend_token_data.proto
index ba2af00..a70bb80 100644
--- a/quiche/blind_sign_auth/proto/spend_token_data.proto
+++ b/quiche/blind_sign_auth/proto/spend_token_data.proto
@@ -1,3 +1,17 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
syntax = "proto3";
package privacy.ppn;
@@ -5,8 +19,6 @@
import "quiche/blind_sign_auth/proto/public_metadata.proto";
import "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.proto";
-option cc_api_version = 2;
-
message SpendTokenData {
// Public metadata associated with the token being spent.
// See go/ppn-token-spend and go/ppn-phosphor-at-service for details.
diff --git a/quiche/blind_sign_auth/proto/timestamp.proto b/quiche/blind_sign_auth/proto/timestamp.proto
new file mode 100644
index 0000000..1d99392
--- /dev/null
+++ b/quiche/blind_sign_auth/proto/timestamp.proto
@@ -0,0 +1,32 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package quiche.protobuf;
+
+// Copied from
+// https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto.
+message Timestamp {
+ // Represents seconds of UTC time since Unix epoch
+ // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+ // 9999-12-31T23:59:59Z inclusive.
+ int64 seconds = 1;
+
+ // Non-negative fractions of a second at nanosecond resolution. Negative
+ // second values with fractions must still have non-negative nanos values
+ // that count forward in time. Must be from 0 to 999,999,999
+ // inclusive.
+ int32 nanos = 2;
+}
diff --git a/quiche/common/test_tools/quiche_test_utils.h b/quiche/common/test_tools/quiche_test_utils.h
index d35ed7f..811611a 100644
--- a/quiche/common/test_tools/quiche_test_utils.h
+++ b/quiche/common/test_tools/quiche_test_utils.h
@@ -57,6 +57,15 @@
return ::testing::ExplainMatchResult(matcher, arg.value(), result_listener);
}
+MATCHER_P(StatusIs, code, "Matcher against only a specific status code") {
+ if (ExtractStatus(arg).code() != code) {
+ *result_listener << "Expected status " << absl::StatusCodeToString(code)
+ << ", got " << ExtractStatus(arg);
+ return false;
+ }
+ return true;
+}
+
MATCHER_P2(StatusIs, code, matcher, "Matcher against a specific status code") {
if (ExtractStatus(arg).code() != code) {
*result_listener << "Expected status " << absl::StatusCodeToString(code)