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