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/crypto/rsa_blinder.h"
16 
17 #include <memory>
18 #include <string>
19 #include <tuple>
20 #include <utility>
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/string_view.h"
27 #include "anonymous_tokens/cpp/crypto/constants.h"
28 #include "anonymous_tokens/cpp/testing/utils.h"
29 #include <openssl/base.h>
30 #include <openssl/digest.h>
31 #include <openssl/rsa.h>
32 
33 namespace anonymous_tokens {
34 namespace {
35 
36 
37 struct RsaBlinderTestParameters {
38   TestRsaPublicKey public_key;
39   TestRsaPrivateKey private_key;
40   const EVP_MD* sig_hash;
41   const EVP_MD* mgf1_hash;
42   int salt_length;
43 };
44 
CreateDefaultTestKeyParameters()45 RsaBlinderTestParameters CreateDefaultTestKeyParameters() {
46   const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096();
47   return {public_key, private_key, EVP_sha384(), EVP_sha384(),
48           kSaltLengthInBytes48};
49 }
50 
CreateShorterTestKeyParameters()51 RsaBlinderTestParameters CreateShorterTestKeyParameters() {
52   const auto [public_key, private_key] = GetStrongTestRsaKeyPair3072();
53   return {public_key, private_key, EVP_sha384(), EVP_sha384(),
54           kSaltLengthInBytes48};
55 }
56 
CreateShortestTestKeyParameters()57 RsaBlinderTestParameters CreateShortestTestKeyParameters() {
58   const auto [public_key, private_key] = GetStrongTestRsaKeyPair2048();
59   return {public_key, private_key, EVP_sha384(), EVP_sha384(),
60           kSaltLengthInBytes48};
61 }
62 
CreateSHA256TestKeyParameters()63 RsaBlinderTestParameters CreateSHA256TestKeyParameters() {
64   const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096();
65   return {public_key, private_key, EVP_sha256(), EVP_sha256(), 32};
66 }
67 
CreateLongerSaltTestKeyParameters()68 RsaBlinderTestParameters CreateLongerSaltTestKeyParameters() {
69   const auto [public_key, private_key] = GetStrongTestRsaKeyPair4096();
70   return {public_key, private_key, EVP_sha384(), EVP_sha384(), 64};
71 }
72 
73 class RsaBlinderTest : public testing::TestWithParam<RsaBlinderTestParameters> {
74  protected:
SetUp()75   void SetUp() override {
76     rsa_blinder_test_params_ = GetParam();
77     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
78         rsa_key_,
79         CreatePrivateKeyRSA(rsa_blinder_test_params_.private_key.n,
80                             rsa_blinder_test_params_.private_key.e,
81                             rsa_blinder_test_params_.private_key.d,
82                             rsa_blinder_test_params_.private_key.p,
83                             rsa_blinder_test_params_.private_key.q,
84                             rsa_blinder_test_params_.private_key.dp,
85                             rsa_blinder_test_params_.private_key.dq,
86                             rsa_blinder_test_params_.private_key.crt));
87   }
88 
89   RsaBlinderTestParameters rsa_blinder_test_params_;
90   bssl::UniquePtr<RSA> rsa_key_;
91 };
92 
TEST_P(RsaBlinderTest,BlindSignUnblindEnd2EndTest)93 TEST_P(RsaBlinderTest, BlindSignUnblindEnd2EndTest) {
94   const absl::string_view message = "Hello World!";
95 
96   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
97       std::unique_ptr<RsaBlinder> blinder,
98       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
99                       rsa_blinder_test_params_.public_key.e,
100                       rsa_blinder_test_params_.sig_hash,
101                       rsa_blinder_test_params_.mgf1_hash,
102                       rsa_blinder_test_params_.salt_length,
103                       /*use_rsa_public_exponent=*/true));
104   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
105                                    blinder->Blind(message));
106   EXPECT_NE(blinded_message, message);
107 
108   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_signature,
109                                    TestSign(blinded_message, rsa_key_.get()));
110   EXPECT_NE(blinded_signature, blinded_message);
111   EXPECT_NE(blinded_signature, message);
112 
113   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
114                                    blinder->Unblind(blinded_signature));
115   EXPECT_NE(signature, blinded_signature);
116   EXPECT_NE(signature, blinded_message);
117   EXPECT_NE(signature, message);
118 
119   EXPECT_TRUE(blinder->Verify(signature, message).ok());
120 }
121 
TEST_P(RsaBlinderTest,DoubleBlindingFailure)122 TEST_P(RsaBlinderTest, DoubleBlindingFailure) {
123   const absl::string_view message = "Hello World2!";
124   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
125       std::unique_ptr<RsaBlinder> blinder,
126       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
127                       rsa_blinder_test_params_.public_key.e,
128                       rsa_blinder_test_params_.sig_hash,
129                       rsa_blinder_test_params_.mgf1_hash,
130                       rsa_blinder_test_params_.salt_length,
131                       /*use_rsa_public_exponent=*/true));
132   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message,
133                                    blinder->Blind(message));
134   // Blind the blinded_message
135   absl::StatusOr<std::string> result = blinder->Blind(blinded_message);
136   EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition);
137   EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state"));
138   // Blind a new message
139   const absl::string_view new_message = "Hello World3!";
140   result = blinder->Blind(new_message);
141   EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition);
142   EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state"));
143 }
144 
TEST_P(RsaBlinderTest,DoubleUnblindingFailure)145 TEST_P(RsaBlinderTest, DoubleUnblindingFailure) {
146   const absl::string_view message = "Hello World2!";
147   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
148       std::unique_ptr<RsaBlinder> blinder,
149       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
150                       rsa_blinder_test_params_.public_key.e,
151                       rsa_blinder_test_params_.sig_hash,
152                       rsa_blinder_test_params_.mgf1_hash,
153                       rsa_blinder_test_params_.salt_length,
154                       /*use_rsa_public_exponent=*/true));
155   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message,
156                                    blinder->Blind(message));
157   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature,
158                                    TestSign(blinded_message, rsa_key_.get()));
159   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
160                                    blinder->Unblind(blinded_signature));
161   // Unblind the unblinded signature
162   absl::StatusOr<std::string> result = blinder->Unblind(signature);
163   EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition);
164   EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state"));
165   // Unblind the blinded_signature again
166   result = blinder->Unblind(signature);
167   EXPECT_EQ(result.status().code(), absl::StatusCode::kFailedPrecondition);
168   EXPECT_THAT(result.status().message(), testing::HasSubstr("wrong state"));
169 }
170 
TEST_P(RsaBlinderTest,InvalidSignature)171 TEST_P(RsaBlinderTest, InvalidSignature) {
172   const absl::string_view message = "Hello World2!";
173   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
174       std::unique_ptr<RsaBlinder> blinder,
175       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
176                       rsa_blinder_test_params_.public_key.e,
177                       rsa_blinder_test_params_.sig_hash,
178                       rsa_blinder_test_params_.mgf1_hash,
179                       rsa_blinder_test_params_.salt_length,
180                       /*use_rsa_public_exponent=*/true));
181   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message,
182                                    blinder->Blind(message));
183   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature,
184                                    TestSign(blinded_message, rsa_key_.get()));
185   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
186                                    blinder->Unblind(blinded_signature));
187   EXPECT_TRUE(blinder->Verify(signature, message).ok());
188 
189   // Invalidate the signature by replacing the last 10 characters by 10 '0's
190   for (int i = 0; i < 10; i++) {
191     signature.pop_back();
192   }
193   for (int i = 0; i < 10; i++) {
194     signature.push_back('0');
195   }
196 
197   absl::Status result = blinder->Verify(signature, message);
198   EXPECT_EQ(result.code(), absl::StatusCode::kInvalidArgument);
199   EXPECT_THAT(result.message(), testing::HasSubstr("verification failed"));
200 }
201 
TEST_P(RsaBlinderTest,InvalidVerificationKey)202 TEST_P(RsaBlinderTest, InvalidVerificationKey) {
203   const absl::string_view message = "Hello World4!";
204   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
205       std::unique_ptr<RsaBlinder> blinder,
206       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
207                       rsa_blinder_test_params_.public_key.e,
208                       rsa_blinder_test_params_.sig_hash,
209                       rsa_blinder_test_params_.mgf1_hash,
210                       rsa_blinder_test_params_.salt_length,
211                       /*use_rsa_public_exponent=*/true));
212   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_message,
213                                    blinder->Blind(message));
214   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const std::string blinded_signature,
215                                    TestSign(blinded_message, rsa_key_.get()));
216   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
217                                    blinder->Unblind(blinded_signature));
218 
219   const auto [bad_key, _] = GetAnotherStrongTestRsaKeyPair2048();
220   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
221       std::unique_ptr<RsaBlinder> bad_blinder,
222       RsaBlinder::New(bad_key.n, bad_key.e, rsa_blinder_test_params_.sig_hash,
223                       rsa_blinder_test_params_.mgf1_hash,
224                       rsa_blinder_test_params_.salt_length,
225                       /*use_rsa_public_exponent=*/true));
226   EXPECT_THAT(bad_blinder->Verify(signature, message).code(),
227               absl::StatusCode::kInvalidArgument);
228 }
229 
230 INSTANTIATE_TEST_SUITE_P(RsaBlinderTest, RsaBlinderTest,
231                          testing::Values(CreateDefaultTestKeyParameters(),
232                                          CreateShorterTestKeyParameters(),
233                                          CreateShortestTestKeyParameters(),
234                                          CreateSHA256TestKeyParameters(),
235                                          CreateLongerSaltTestKeyParameters()));
236 
237 using RsaBlinderPublicMetadataTestParams =
238     std::tuple<std::pair<TestRsaPublicKey, TestRsaPrivateKey>,
239                /*use_rsa_public_exponent*/ bool>;
240 
241 class RsaBlinderWithPublicMetadataTest
242     : public testing::TestWithParam<RsaBlinderPublicMetadataTestParams> {
243  protected:
SetUp()244   void SetUp() override {
245     std::pair<TestRsaPublicKey, TestRsaPrivateKey> key_pair;
246     std::tie(key_pair, use_rsa_public_exponent_) = GetParam();
247     const auto [public_key, private_key] = key_pair;
248     rsa_blinder_test_params_ = {public_key, private_key, EVP_sha384(),
249                                 EVP_sha384(), kSaltLengthInBytes48};
250     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
251         rsa_key_,
252         CreatePrivateKeyRSA(rsa_blinder_test_params_.private_key.n,
253                             rsa_blinder_test_params_.private_key.e,
254                             rsa_blinder_test_params_.private_key.d,
255                             rsa_blinder_test_params_.private_key.p,
256                             rsa_blinder_test_params_.private_key.q,
257                             rsa_blinder_test_params_.private_key.dp,
258                             rsa_blinder_test_params_.private_key.dq,
259                             rsa_blinder_test_params_.private_key.crt));
260   }
261 
262   RsaBlinderTestParameters rsa_blinder_test_params_;
263   bssl::UniquePtr<RSA> rsa_key_;
264   bool use_rsa_public_exponent_;
265 };
266 
TEST_P(RsaBlinderWithPublicMetadataTest,BlindSignUnblindWithPublicMetadataEnd2EndTest)267 TEST_P(RsaBlinderWithPublicMetadataTest,
268        BlindSignUnblindWithPublicMetadataEnd2EndTest) {
269   const absl::string_view message = "Hello World!";
270   const absl::string_view public_metadata = "pubmd!";
271 
272   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
273       std::unique_ptr<RsaBlinder> blinder,
274       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
275                       rsa_blinder_test_params_.public_key.e,
276                       rsa_blinder_test_params_.sig_hash,
277                       rsa_blinder_test_params_.mgf1_hash,
278                       rsa_blinder_test_params_.salt_length,
279                       use_rsa_public_exponent_, public_metadata));
280   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
281                                    blinder->Blind(message));
282   EXPECT_NE(blinded_message, message);
283 
284   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
285       std::string blinded_signature,
286       TestSignWithPublicMetadata(blinded_message, public_metadata, *rsa_key_,
287                                  use_rsa_public_exponent_));
288   EXPECT_NE(blinded_signature, blinded_message);
289   EXPECT_NE(blinded_signature, message);
290 
291   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
292                                    blinder->Unblind(blinded_signature));
293   EXPECT_NE(signature, blinded_signature);
294   EXPECT_NE(signature, blinded_message);
295   EXPECT_NE(signature, message);
296 
297   EXPECT_TRUE(blinder->Verify(signature, message).ok());
298 }
299 
TEST_P(RsaBlinderWithPublicMetadataTest,BlindSignUnblindWithEmptyPublicMetadataEnd2EndTest)300 TEST_P(RsaBlinderWithPublicMetadataTest,
301        BlindSignUnblindWithEmptyPublicMetadataEnd2EndTest) {
302   const absl::string_view message = "Hello World!";
303   const absl::string_view empty_public_metadata = "";
304 
305   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
306       std::unique_ptr<RsaBlinder> blinder,
307       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
308                       rsa_blinder_test_params_.public_key.e,
309                       rsa_blinder_test_params_.sig_hash,
310                       rsa_blinder_test_params_.mgf1_hash,
311                       rsa_blinder_test_params_.salt_length,
312                       use_rsa_public_exponent_, empty_public_metadata));
313   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
314                                    blinder->Blind(message));
315   EXPECT_NE(blinded_message, message);
316 
317   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
318       std::string blinded_signature,
319       TestSignWithPublicMetadata(blinded_message, empty_public_metadata,
320                                  *rsa_key_, use_rsa_public_exponent_));
321   EXPECT_NE(blinded_signature, blinded_message);
322   EXPECT_NE(blinded_signature, message);
323 
324   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
325                                    blinder->Unblind(blinded_signature));
326   EXPECT_NE(signature, blinded_signature);
327   EXPECT_NE(signature, blinded_message);
328   EXPECT_NE(signature, message);
329 
330   EXPECT_TRUE(blinder->Verify(signature, message).ok());
331 }
332 
TEST_P(RsaBlinderWithPublicMetadataTest,WrongPublicMetadata)333 TEST_P(RsaBlinderWithPublicMetadataTest, WrongPublicMetadata) {
334   const absl::string_view message = "Hello World!";
335   const absl::string_view public_metadata = "pubmd!";
336   const absl::string_view public_metadata_2 = "pubmd2";
337 
338   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
339       std::unique_ptr<RsaBlinder> blinder,
340       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
341                       rsa_blinder_test_params_.public_key.e,
342                       rsa_blinder_test_params_.sig_hash,
343                       rsa_blinder_test_params_.mgf1_hash,
344                       rsa_blinder_test_params_.salt_length,
345                       use_rsa_public_exponent_, public_metadata));
346   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
347                                    blinder->Blind(message));
348   EXPECT_NE(blinded_message, message);
349 
350   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
351       std::string blinded_signature,
352       TestSignWithPublicMetadata(blinded_message, public_metadata_2, *rsa_key_,
353                                  use_rsa_public_exponent_));
354   EXPECT_NE(blinded_signature, blinded_message);
355   EXPECT_NE(blinded_signature, message);
356 
357   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
358                                    blinder->Unblind(blinded_signature));
359   EXPECT_NE(signature, blinded_signature);
360   EXPECT_NE(signature, blinded_message);
361   EXPECT_NE(signature, message);
362   absl::Status verification_result = blinder->Verify(signature, message);
363   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
364   EXPECT_THAT(verification_result.message(),
365               ::testing::HasSubstr("verification failed"));
366 }
367 
TEST_P(RsaBlinderWithPublicMetadataTest,NoPublicMetadataForSigning)368 TEST_P(RsaBlinderWithPublicMetadataTest, NoPublicMetadataForSigning) {
369   const absl::string_view message = "Hello World!";
370   const absl::string_view public_metadata = "pubmd!";
371 
372   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
373       std::unique_ptr<RsaBlinder> blinder,
374       RsaBlinder::New(rsa_blinder_test_params_.public_key.n,
375                       rsa_blinder_test_params_.public_key.e,
376                       rsa_blinder_test_params_.sig_hash,
377                       rsa_blinder_test_params_.mgf1_hash,
378                       rsa_blinder_test_params_.salt_length,
379                       use_rsa_public_exponent_, public_metadata));
380   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
381                                    blinder->Blind(message));
382   EXPECT_NE(blinded_message, message);
383 
384   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_signature,
385                                    TestSign(blinded_message, rsa_key_.get()));
386   EXPECT_NE(blinded_signature, blinded_message);
387   EXPECT_NE(blinded_signature, message);
388 
389   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
390                                    blinder->Unblind(blinded_signature));
391   EXPECT_NE(signature, blinded_signature);
392   EXPECT_NE(signature, blinded_message);
393   EXPECT_NE(signature, message);
394   absl::Status verification_result = blinder->Verify(signature, message);
395   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
396   EXPECT_THAT(verification_result.message(),
397               ::testing::HasSubstr("verification failed"));
398 }
399 
TEST_P(RsaBlinderWithPublicMetadataTest,NoPublicMetadataInBlinding)400 TEST_P(RsaBlinderWithPublicMetadataTest, NoPublicMetadataInBlinding) {
401   const absl::string_view message = "Hello World!";
402   const absl::string_view public_metadata = "pubmd!";
403 
404   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
405       std::unique_ptr<RsaBlinder> blinder,
406       RsaBlinder::New(
407           rsa_blinder_test_params_.public_key.n,
408           rsa_blinder_test_params_.public_key.e,
409           rsa_blinder_test_params_.sig_hash, rsa_blinder_test_params_.mgf1_hash,
410           rsa_blinder_test_params_.salt_length, use_rsa_public_exponent_));
411   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string blinded_message,
412                                    blinder->Blind(message));
413   EXPECT_NE(blinded_message, message);
414 
415   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
416       std::string blinded_signature,
417       TestSignWithPublicMetadata(blinded_message, public_metadata, *rsa_key_,
418                                  use_rsa_public_exponent_));
419   EXPECT_NE(blinded_signature, blinded_message);
420   EXPECT_NE(blinded_signature, message);
421 
422   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string signature,
423                                    blinder->Unblind(blinded_signature));
424   EXPECT_NE(signature, blinded_signature);
425   EXPECT_NE(signature, blinded_message);
426   EXPECT_NE(signature, message);
427   absl::Status verification_result = blinder->Verify(signature, message);
428   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
429   EXPECT_THAT(verification_result.message(),
430               ::testing::HasSubstr("verification failed"));
431 }
432 
433 INSTANTIATE_TEST_SUITE_P(
434     RsaBlinderWithPublicMetadataTest, RsaBlinderWithPublicMetadataTest,
435     testing::Combine(testing::Values(GetStrongTestRsaKeyPair2048(),
436                                      GetAnotherStrongTestRsaKeyPair2048(),
437                                      GetStrongTestRsaKeyPair3072(),
438                                      GetStrongTestRsaKeyPair4096()),
439                      /*use_rsa_public_exponent*/ testing::Values(true, false)));
440 
441 }  // namespace
442 }  // namespace anonymous_tokens
443