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