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