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