1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h"
16
17 #include <memory>
18 #include <string>
19 #include <tuple>
20 #include <utility>
21 #include <vector>
22
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include "absl/status/status.h"
26 #include "absl/status/statusor.h"
27 #include "absl/time/time.h"
28 #include "anonymous_tokens/cpp/crypto/constants.h"
29 #include "anonymous_tokens/cpp/crypto/rsa_blind_signer.h"
30 #include "anonymous_tokens/cpp/shared/proto_utils.h"
31 #include "anonymous_tokens/cpp/shared/status_utils.h"
32 #include "anonymous_tokens/cpp/testing/proto_utils.h"
33 #include "anonymous_tokens/cpp/testing/utils.h"
34 #include "anonymous_tokens/proto/anonymous_tokens.pb.h"
35 #include <openssl/base.h>
36 #include <openssl/rsa.h>
37
38 namespace anonymous_tokens {
39 namespace {
40
41 using ::testing::SizeIs;
42
43 // Returns a fixed public private key pair by calling GetStrongRsaKeys4096().
44 absl::StatusOr<std::pair<RSABlindSignaturePublicKey, RSAPrivateKey>>
CreateClientTestKey(absl::string_view use_case="TEST_USE_CASE",int key_version=1,MessageMaskType mask_type=AT_MESSAGE_MASK_CONCAT,int message_mask_size=32,bool enable_public_metadata=false)45 CreateClientTestKey(absl::string_view use_case = "TEST_USE_CASE",
46 int key_version = 1,
47 MessageMaskType mask_type = AT_MESSAGE_MASK_CONCAT,
48 int message_mask_size = 32,
49 bool enable_public_metadata = false) {
50 ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, GetStrongRsaKeys4096());
51 RSABlindSignaturePublicKey public_key;
52 public_key.set_use_case(std::string(use_case));
53 public_key.set_key_version(key_version);
54 public_key.set_serialized_public_key(key_pair.first.SerializeAsString());
55 absl::Time start_time = absl::Now() - absl::Minutes(100);
56 ANON_TOKENS_ASSIGN_OR_RETURN(*public_key.mutable_key_validity_start_time(),
57 TimeToProto(start_time));
58 public_key.set_sig_hash_type(AT_HASH_TYPE_SHA384);
59 public_key.set_mask_gen_function(AT_MGF_SHA384);
60 public_key.set_salt_length(kSaltLengthInBytes48);
61 public_key.set_key_size(kRsaModulusSizeInBytes512);
62 public_key.set_message_mask_type(mask_type);
63 public_key.set_message_mask_size(message_mask_size);
64 public_key.set_public_metadata_support(enable_public_metadata);
65
66 return std::make_pair(std::move(public_key), std::move(key_pair.second));
67 }
68
69 // Creates the input consisting on plaintext messages and public metadata that
70 // can be passed to the AnonymousTokensRsaBssaClient.
CreateInput(absl::Span<const std::string> messages,absl::Span<const std::string> public_metadata={})71 absl::StatusOr<std::vector<PlaintextMessageWithPublicMetadata>> CreateInput(
72 absl::Span<const std::string> messages,
73 absl::Span<const std::string> public_metadata = {}) {
74 // Check input parameter sizes.
75 if (!public_metadata.empty() && messages.size() != public_metadata.size()) {
76 return absl::InvalidArgumentError(
77 "Input vectors should be of the same size.");
78 }
79
80 std::vector<PlaintextMessageWithPublicMetadata> anonymmous_tokens_input_proto;
81 anonymmous_tokens_input_proto.reserve(messages.size());
82 for (size_t i = 0; i < messages.size(); ++i) {
83 PlaintextMessageWithPublicMetadata input_message_and_metadata;
84 input_message_and_metadata.set_plaintext_message(messages[i]);
85 if (!public_metadata.empty()) {
86 input_message_and_metadata.set_public_metadata(public_metadata[i]);
87 }
88 anonymmous_tokens_input_proto.push_back(input_message_and_metadata);
89 }
90 return anonymmous_tokens_input_proto;
91 }
92
93 // Creates the server response for anonymous tokens request by using
94 // RsaBlindSigner.
CreateResponse(const AnonymousTokensSignRequest & request,const RSAPrivateKey & private_key,bool enable_public_metadata=false)95 absl::StatusOr<AnonymousTokensSignResponse> CreateResponse(
96 const AnonymousTokensSignRequest& request, const RSAPrivateKey& private_key,
97 bool enable_public_metadata = false) {
98 AnonymousTokensSignResponse response;
99 const bool use_rsa_public_exponent = false;
100 for (const auto& request_token : request.blinded_tokens()) {
101 auto* response_token = response.add_anonymous_tokens();
102 response_token->set_use_case(request_token.use_case());
103 response_token->set_key_version(request_token.key_version());
104 response_token->set_public_metadata(request_token.public_metadata());
105 response_token->set_serialized_blinded_message(
106 request_token.serialized_token());
107 response_token->set_do_not_use_rsa_public_exponent(
108 !use_rsa_public_exponent);
109 std::optional<std::string> public_metadata = std::nullopt;
110 if (enable_public_metadata) {
111 public_metadata = request_token.public_metadata();
112 }
113 ANON_TOKENS_ASSIGN_OR_RETURN(
114 std::unique_ptr<RsaBlindSigner> blind_signer,
115 RsaBlindSigner::New(private_key, use_rsa_public_exponent,
116 public_metadata));
117 ANON_TOKENS_ASSIGN_OR_RETURN(
118 *response_token->mutable_serialized_token(),
119 blind_signer->Sign(request_token.serialized_token()));
120 }
121 return response;
122 }
123
TEST(CreateAnonymousTokensRsaBssaClientTest,Success)124 TEST(CreateAnonymousTokensRsaBssaClientTest, Success) {
125 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key, CreateClientTestKey());
126 EXPECT_TRUE(AnonymousTokensRsaBssaClient::Create(rsa_key.first).ok());
127 }
128
TEST(CreateAnonymousTokensRsaBssaClientTest,InvalidUseCase)129 TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidUseCase) {
130 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key,
131 CreateClientTestKey("INVALID_USE_CASE"));
132 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
133 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
134 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
135 EXPECT_THAT(client.status().message(),
136 testing::HasSubstr("Invalid use case for public key"));
137 }
138
TEST(CreateAnonymousTokensRsaBssaClientTest,NotAUseCase)139 TEST(CreateAnonymousTokensRsaBssaClientTest, NotAUseCase) {
140 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key,
141 CreateClientTestKey("NOT_A_USE_CASE"));
142 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
143 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
144 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
145 EXPECT_THAT(client.status().message(),
146 testing::HasSubstr("Invalid use case for public key"));
147 }
148
TEST(CreateAnonymousTokensRsaBssaClientTest,InvalidKeyVersion)149 TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidKeyVersion) {
150 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_key,
151 CreateClientTestKey("TEST_USE_CASE", 0));
152 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
153 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
154 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
155 EXPECT_THAT(client.status().message(),
156 testing::HasSubstr("Key version cannot be zero or negative"));
157 }
158
TEST(CreateAnonymousTokensRsaBssaClientTest,InvalidMessageMaskType)159 TEST(CreateAnonymousTokensRsaBssaClientTest, InvalidMessageMaskType) {
160 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
161 auto rsa_key,
162 CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_TYPE_UNDEFINED));
163 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
164 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
165 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
166 EXPECT_THAT(client.status().message(),
167 testing::HasSubstr("Message mask type must be defined"));
168 }
169
TEST(CreateAnonymousTokensRsaBssaClientTest,MessageMaskConcatInvalidMessageMaskSize)170 TEST(CreateAnonymousTokensRsaBssaClientTest,
171 MessageMaskConcatInvalidMessageMaskSize) {
172 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
173 auto rsa_key,
174 CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_CONCAT, 0));
175 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
176 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
177 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
178 EXPECT_THAT(
179 client.status().message(),
180 testing::HasSubstr(
181 "Message mask concat type must have a size of at least 32 bytes"));
182 }
183
TEST(CreateAnonymousTokensRsaBssaClientTest,MessageMaskNoMaskInvalidMessageMaskSize)184 TEST(CreateAnonymousTokensRsaBssaClientTest,
185 MessageMaskNoMaskInvalidMessageMaskSize) {
186 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
187 auto rsa_key,
188 CreateClientTestKey("TEST_USE_CASE", 1, AT_MESSAGE_MASK_NO_MASK, 32));
189 absl::StatusOr<std::unique_ptr<AnonymousTokensRsaBssaClient>> client =
190 AnonymousTokensRsaBssaClient::Create(rsa_key.first);
191 EXPECT_EQ(client.status().code(), absl::StatusCode::kInvalidArgument);
192 EXPECT_THAT(client.status().message(),
193 testing::HasSubstr(
194 "Message mask no mask type must be set to size 0 bytes."));
195 }
196
197 class AnonymousTokensRsaBssaClientTest : public testing::Test {
198 protected:
SetUp()199 void SetUp() override {
200 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::tie(public_key_, private_key_),
201 CreateClientTestKey());
202 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
203 client_, AnonymousTokensRsaBssaClient::Create(public_key_));
204 }
205
206 RSAPrivateKey private_key_;
207 RSABlindSignaturePublicKey public_key_;
208 std::unique_ptr<AnonymousTokensRsaBssaClient> client_;
209 };
210
TEST_F(AnonymousTokensRsaBssaClientTest,SuccessOneMessage)211 TEST_F(AnonymousTokensRsaBssaClientTest, SuccessOneMessage) {
212 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
213 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
214 CreateInput({"message"}));
215 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
216 client_->CreateRequest(input_messages));
217 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
218 CreateResponse(request, private_key_));
219 EXPECT_THAT(response.anonymous_tokens(), SizeIs(1));
220 EXPECT_TRUE(client_->ProcessResponse(response).ok());
221 }
222
TEST_F(AnonymousTokensRsaBssaClientTest,SuccessMultipleMessages)223 TEST_F(AnonymousTokensRsaBssaClientTest, SuccessMultipleMessages) {
224 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
225 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
226 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}));
227 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
228 client_->CreateRequest(input_messages));
229 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
230 CreateResponse(request, private_key_));
231 EXPECT_THAT(response.anonymous_tokens(), SizeIs(4));
232 EXPECT_TRUE(client_->ProcessResponse(response).ok());
233 }
234
TEST_F(AnonymousTokensRsaBssaClientTest,SuccessMultipleMessagesNoMessageMask)235 TEST_F(AnonymousTokensRsaBssaClientTest, SuccessMultipleMessagesNoMessageMask) {
236 RSABlindSignaturePublicKey public_key;
237 RSAPrivateKey private_key;
238 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
239 std::tie(public_key, private_key),
240 CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1,
241 AT_MESSAGE_MASK_NO_MASK, /*message_mask_size=*/0));
242 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
243 std::unique_ptr<AnonymousTokensRsaBssaClient> client,
244 AnonymousTokensRsaBssaClient::Create(public_key));
245 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
246 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
247 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"}));
248 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
249 client->CreateRequest(input_messages));
250 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
251 CreateResponse(request, private_key));
252 ASSERT_EQ(response.anonymous_tokens().size(), 4);
253 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
254 std::vector<RSABlindSignatureTokenWithInput> finalized_tokens_with_inputs,
255 client->ProcessResponse(response));
256
257 for (const RSABlindSignatureTokenWithInput& token_with_input :
258 finalized_tokens_with_inputs) {
259 EXPECT_TRUE(token_with_input.token().message_mask().empty());
260 }
261 }
262
TEST_F(AnonymousTokensRsaBssaClientTest,EnsureRandomTokens)263 TEST_F(AnonymousTokensRsaBssaClientTest, EnsureRandomTokens) {
264 std::string message = "test_same_message";
265 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
266 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
267 CreateInput({message, message}));
268 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
269 client_->CreateRequest(input_messages));
270 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
271 CreateResponse(request, private_key_));
272 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
273 std::vector<RSABlindSignatureTokenWithInput> tokens,
274 client_->ProcessResponse(response));
275 ASSERT_EQ(tokens.size(), 2u);
276 for (const RSABlindSignatureTokenWithInput& token : tokens) {
277 EXPECT_EQ(token.input().plaintext_message(), message);
278 }
279 EXPECT_NE(tokens[0].token().message_mask(), tokens[1].token().message_mask());
280 EXPECT_NE(tokens[0].token().token(), tokens[1].token().token());
281 }
282
TEST_F(AnonymousTokensRsaBssaClientTest,EmptyInput)283 TEST_F(AnonymousTokensRsaBssaClientTest, EmptyInput) {
284 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
285 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
286 CreateInput({}));
287 absl::StatusOr<AnonymousTokensSignRequest> request =
288 client_->CreateRequest(input_messages);
289 EXPECT_EQ(request.status().code(), absl::StatusCode::kInvalidArgument);
290 EXPECT_THAT(request.status().message(),
291 testing::HasSubstr("Cannot create an empty request"));
292 }
293
TEST_F(AnonymousTokensRsaBssaClientTest,CreateRequestTwice)294 TEST_F(AnonymousTokensRsaBssaClientTest, CreateRequestTwice) {
295 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
296 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
297 CreateInput({"message"}));
298 EXPECT_TRUE(client_->CreateRequest(input_messages).ok());
299 absl::StatusOr<AnonymousTokensSignRequest> request =
300 client_->CreateRequest(input_messages);
301 EXPECT_EQ(request.status().code(), absl::StatusCode::kFailedPrecondition);
302 EXPECT_THAT(request.status().message(),
303 testing::HasSubstr("Blind signature request already created"));
304 }
305
TEST_F(AnonymousTokensRsaBssaClientTest,ProcessResponseWithoutCreateRequest)306 TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithoutCreateRequest) {
307 AnonymousTokensSignResponse response;
308 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
309 processed_response = client_->ProcessResponse(response);
310 EXPECT_EQ(processed_response.status().code(),
311 absl::StatusCode::kFailedPrecondition);
312 EXPECT_THAT(
313 processed_response.status().message(),
314 testing::HasSubstr("A valid Blind signature request was not created"));
315 }
316
TEST_F(AnonymousTokensRsaBssaClientTest,ProcessEmptyResponse)317 TEST_F(AnonymousTokensRsaBssaClientTest, ProcessEmptyResponse) {
318 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
319 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
320 CreateInput({"message"}));
321 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
322 client_->CreateRequest(input_messages));
323 AnonymousTokensSignResponse response;
324 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
325 processed_response = client_->ProcessResponse(response);
326 EXPECT_EQ(processed_response.status().code(),
327 absl::StatusCode::kInvalidArgument);
328 EXPECT_THAT(processed_response.status().message(),
329 testing::HasSubstr("Cannot process an empty response"));
330 }
331
TEST_F(AnonymousTokensRsaBssaClientTest,ProcessResponseWithBadUseCase)332 TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithBadUseCase) {
333 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
334 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
335 CreateInput({"message"}));
336 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
337 client_->CreateRequest(input_messages));
338 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
339 CreateResponse(request, private_key_));
340 response.mutable_anonymous_tokens(0)->set_use_case("TEST_USE_CASE_2");
341 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
342 processed_response = client_->ProcessResponse(response);
343 EXPECT_EQ(processed_response.status().code(),
344 absl::StatusCode::kInvalidArgument);
345 EXPECT_THAT(processed_response.status().message(),
346 testing::HasSubstr("Use case does not match public key"));
347 }
348
TEST_F(AnonymousTokensRsaBssaClientTest,ProcessResponseWithBadKeyVersion)349 TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseWithBadKeyVersion) {
350 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
351 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
352 CreateInput({"message"}));
353 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request,
354 client_->CreateRequest(input_messages));
355 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response,
356 CreateResponse(request, private_key_));
357 response.mutable_anonymous_tokens(0)->set_key_version(2);
358 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
359 processed_response = client_->ProcessResponse(response);
360 EXPECT_EQ(processed_response.status().code(),
361 absl::StatusCode::kInvalidArgument);
362 EXPECT_THAT(processed_response.status().message(),
363 testing::HasSubstr("Key version does not match public key"));
364 }
365
TEST_F(AnonymousTokensRsaBssaClientTest,ProcessResponseFromDifferentClient)366 TEST_F(AnonymousTokensRsaBssaClientTest, ProcessResponseFromDifferentClient) {
367 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
368 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
369 CreateInput({"message"}));
370 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
371 std::unique_ptr<AnonymousTokensRsaBssaClient> client2,
372 AnonymousTokensRsaBssaClient::Create(public_key_));
373 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request1,
374 client_->CreateRequest(input_messages));
375 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignRequest request2,
376 client2->CreateRequest(input_messages));
377 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response1,
378 CreateResponse(request1, private_key_));
379 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(AnonymousTokensSignResponse response2,
380 CreateResponse(request2, private_key_));
381 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
382 processed_response2 = client_->ProcessResponse(response2);
383 EXPECT_EQ(processed_response2.status().code(),
384 absl::StatusCode::kInvalidArgument);
385 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
386 processed_response1 = client2->ProcessResponse(response1);
387 EXPECT_EQ(processed_response1.status().code(),
388 absl::StatusCode::kInvalidArgument);
389 }
390
391 class AnonymousTokensRsaBssaClientWithPublicMetadataTest
392 : public testing::Test {
393 protected:
SetUp()394 void SetUp() override {
395 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
396 std::tie(public_key_, private_key_),
397 CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1,
398 AT_MESSAGE_MASK_CONCAT,
399 kRsaMessageMaskSizeInBytes32,
400 /*enable_public_metadata=*/true));
401 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
402 public_metadata_client_,
403 AnonymousTokensRsaBssaClient::Create(public_key_));
404 }
405
406 RSAPrivateKey private_key_;
407 RSABlindSignaturePublicKey public_key_;
408 std::unique_ptr<AnonymousTokensRsaBssaClient> public_metadata_client_;
409 };
410
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,SuccessOneMessageWithPublicMetadata)411 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
412 SuccessOneMessageWithPublicMetadata) {
413 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
414 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
415 CreateInput({"message"}, {"md1"}));
416 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
417 AnonymousTokensSignRequest request,
418 public_metadata_client_->CreateRequest(input_messages));
419 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
420 AnonymousTokensSignResponse response,
421 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
422 EXPECT_THAT(response.anonymous_tokens(), SizeIs(1));
423 EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok());
424 }
425
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,FailureWithEmptyPublicMetadata)426 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
427 FailureWithEmptyPublicMetadata) {
428 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
429 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
430 CreateInput({"message"}, {"md1"}));
431 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
432 AnonymousTokensSignRequest request,
433 public_metadata_client_->CreateRequest(input_messages));
434 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
435 AnonymousTokensSignResponse response,
436 CreateResponse(request, private_key_, /*enable_public_metadata=*/false));
437 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
438 processed_response = public_metadata_client_->ProcessResponse(response);
439 EXPECT_EQ(processed_response.status().code(),
440 absl::StatusCode::kInvalidArgument);
441 }
442
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,FailureWithWrongPublicMetadata)443 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
444 FailureWithWrongPublicMetadata) {
445 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
446 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
447 CreateInput({"message"}, {"md1"}));
448 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
449 AnonymousTokensSignRequest request,
450 public_metadata_client_->CreateRequest(input_messages));
451 request.mutable_blinded_tokens(0)->set_public_metadata(
452 "wrong_public_metadata");
453 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
454 AnonymousTokensSignResponse response,
455 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
456 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
457 processed_response = public_metadata_client_->ProcessResponse(response);
458 EXPECT_EQ(processed_response.status().code(),
459 absl::StatusCode::kInvalidArgument);
460 }
461
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,FailureWithPublicMetadataSupportOff)462 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
463 FailureWithPublicMetadataSupportOff) {
464 // Create a client with public metadata support disabled.
465 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto key_pair, CreateClientTestKey());
466 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
467 std::unique_ptr<AnonymousTokensRsaBssaClient> non_public_metadata_client,
468 AnonymousTokensRsaBssaClient::Create(key_pair.first));
469
470 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
471 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
472 CreateInput({"message"}, {"md1"}));
473 // Use client_ that does not support public metadata.
474 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
475 AnonymousTokensSignRequest request,
476 non_public_metadata_client->CreateRequest(input_messages));
477 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
478 AnonymousTokensSignResponse response,
479 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
480 absl::StatusOr<std::vector<RSABlindSignatureTokenWithInput>>
481 processed_response =
482 non_public_metadata_client->ProcessResponse(response);
483 EXPECT_EQ(processed_response.status().code(),
484 absl::StatusCode::kInvalidArgument);
485 }
486
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,SuccessMultipleMessagesWithDistinctPublicMetadata)487 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
488 SuccessMultipleMessagesWithDistinctPublicMetadata) {
489 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
490 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
491 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"},
492 {"md1", "md2", "md3", "md4"}));
493 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
494 AnonymousTokensSignRequest request,
495 public_metadata_client_->CreateRequest(input_messages));
496 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
497 AnonymousTokensSignResponse response,
498 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
499 EXPECT_THAT(response.anonymous_tokens(), SizeIs(4));
500 EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok());
501 }
502
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,SuccessMultipleMessagesWithRepeatedPublicMetadata)503 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
504 SuccessMultipleMessagesWithRepeatedPublicMetadata) {
505 // Create input with repeated public metadata
506 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
507 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
508 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"},
509 {"md1", "md2", "md2", "md1"}));
510 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
511 AnonymousTokensSignRequest request,
512 public_metadata_client_->CreateRequest(input_messages));
513 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
514 AnonymousTokensSignResponse response,
515 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
516 EXPECT_THAT(response.anonymous_tokens(), SizeIs(4));
517 EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok());
518 }
519
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,SuccessMultipleMessagesWithEmptyStringPublicMetadata)520 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
521 SuccessMultipleMessagesWithEmptyStringPublicMetadata) {
522 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
523 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
524 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"},
525 {"md1", "", "", "md4"}));
526 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
527 AnonymousTokensSignRequest request,
528 public_metadata_client_->CreateRequest(input_messages));
529 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
530 AnonymousTokensSignResponse response,
531 CreateResponse(request, private_key_, /*enable_public_metadata=*/true));
532 EXPECT_THAT(response.anonymous_tokens(), SizeIs(4));
533 EXPECT_TRUE(public_metadata_client_->ProcessResponse(response).ok());
534 }
535
TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,SuccessMultipleMessagesNoMessageMask)536 TEST_F(AnonymousTokensRsaBssaClientWithPublicMetadataTest,
537 SuccessMultipleMessagesNoMessageMask) {
538 RSABlindSignaturePublicKey public_key;
539 RSAPrivateKey private_key;
540 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
541 std::tie(public_key, private_key),
542 CreateClientTestKey("TEST_USE_CASE", /*key_version=*/1,
543 AT_MESSAGE_MASK_NO_MASK, /*message_mask_size=*/0,
544 /*enable_public_metadata=*/true));
545 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
546 std::unique_ptr<AnonymousTokensRsaBssaClient> public_metadata_client,
547 AnonymousTokensRsaBssaClient::Create(public_key));
548 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
549 std::vector<PlaintextMessageWithPublicMetadata> input_messages,
550 CreateInput({"message1", "msg2", "anotherMessage", "one_more_message"},
551 {"md1", "md2", "md3", "md4"}));
552 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
553 AnonymousTokensSignRequest request,
554 public_metadata_client->CreateRequest(input_messages));
555 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
556 AnonymousTokensSignResponse response,
557 CreateResponse(request, private_key, /*enable_public_metadata=*/true));
558 ASSERT_EQ(response.anonymous_tokens().size(), 4);
559 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
560 std::vector<RSABlindSignatureTokenWithInput> finalized_tokens_with_inputs,
561 public_metadata_client->ProcessResponse(response));
562
563 for (const RSABlindSignatureTokenWithInput& token_with_input :
564 finalized_tokens_with_inputs) {
565 EXPECT_TRUE(token_with_input.token().message_mask().empty());
566 }
567 }
568
569 } // namespace
570 } // namespace anonymous_tokens
571