• 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_ssa_pss_verifier.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include "absl/status/status.h"
24 #include "absl/status/statusor.h"
25 #include "absl/strings/string_view.h"
26 #include "anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h"
27 #include "anonymous_tokens/cpp/crypto/constants.h"
28 #include "anonymous_tokens/cpp/crypto/crypto_utils.h"
29 #include "anonymous_tokens/cpp/testing/proto_utils.h"
30 #include "anonymous_tokens/cpp/testing/utils.h"
31 #include "anonymous_tokens/proto/anonymous_tokens.pb.h"
32 #include <openssl/rsa.h>
33 
34 
35 namespace anonymous_tokens {
36 namespace {
37 
TEST(RsaSsaPssVerifier,SuccessfulVerification)38 TEST(RsaSsaPssVerifier, SuccessfulVerification) {
39   const IetfStandardRsaBlindSignatureTestVector test_vec =
40       GetIetfStandardRsaBlindSignatureTestVector();
41   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_keys,
42                                    GetIetfStandardRsaBlindSignatureTestKeys());
43   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
44   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
45   const int salt_length = kSaltLengthInBytes48;
46   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
47       const auto verifier,
48       RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_keys.first,
49                              /*use_rsa_public_exponent=*/true));
50   EXPECT_TRUE(verifier->Verify(test_vec.signature, test_vec.message).ok());
51 }
52 
TEST(RsaSsaPssVerifier,InvalidSignature)53 TEST(RsaSsaPssVerifier, InvalidSignature) {
54   const IetfStandardRsaBlindSignatureTestVector test_vec =
55       GetIetfStandardRsaBlindSignatureTestVector();
56   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_keys,
57                                    GetIetfStandardRsaBlindSignatureTestKeys());
58   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
59   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
60   const int salt_length = kSaltLengthInBytes48;
61   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
62       const auto verifier,
63       RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_keys.first,
64                              /*use_rsa_public_exponent=*/true));
65   // corrupt signature
66   std::string wrong_sig = test_vec.signature;
67   wrong_sig.replace(10, 1, "x");
68 
69   absl::Status verification_result =
70       verifier->Verify(wrong_sig, test_vec.message);
71   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
72   EXPECT_THAT(verification_result.message(),
73               testing::HasSubstr("verification failed"));
74 }
75 
TEST(RsaSsaPssVerifier,InvalidVerificationKey)76 TEST(RsaSsaPssVerifier, InvalidVerificationKey) {
77   const IetfStandardRsaBlindSignatureTestVector test_vec =
78       GetIetfStandardRsaBlindSignatureTestVector();
79   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
80   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
81   const int salt_length = kSaltLengthInBytes48;
82   // wrong key
83   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto new_keys_pair, GetStandardRsaKeyPair());
84   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
85       const auto verifier,
86       RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash,
87                              new_keys_pair.first,
88                              /*use_rsa_public_exponent=*/true));
89 
90   absl::Status verification_result =
91       verifier->Verify(test_vec.signature, test_vec.message);
92   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
93   EXPECT_THAT(verification_result.message(),
94               testing::HasSubstr("verification failed"));
95 }
96 
TEST(RsaSsaPssVerifierTestWithPublicMetadata,EmptyMessageStandardVerificationSuccess)97 TEST(RsaSsaPssVerifierTestWithPublicMetadata,
98      EmptyMessageStandardVerificationSuccess) {
99   absl::string_view message = "";
100   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
101   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
102   const int salt_length = kSaltLengthInBytes48;
103   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(const auto test_key,
104                                    GetStandardRsaKeyPair());
105   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
106       auto private_key, AnonymousTokensRSAPrivateKeyToRSA(test_key.second));
107   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
108       std::string encoded_message,
109       EncodeMessageForTests(message, test_key.first, sig_hash, mgf1_hash,
110                             salt_length));
111   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
112       std::string potentially_insecure_signature,
113       TestSign(encoded_message, private_key.get()));
114   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
115       auto verifier,
116       RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first,
117                              /*use_rsa_public_exponent=*/true));
118   EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok());
119 }
120 
TEST(RsaSsaPssVerifierTestWithPublicMetadata,IetfRsaBlindSignaturesWithPublicMetadataTestVectorsSuccess)121 TEST(RsaSsaPssVerifierTestWithPublicMetadata,
122      IetfRsaBlindSignaturesWithPublicMetadataTestVectorsSuccess) {
123   auto test_vectors = GetIetfRsaBlindSignatureWithPublicMetadataTestVectors();
124   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
125   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
126   const int salt_length = kSaltLengthInBytes48;
127   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
128       const auto test_key,
129       GetIetfRsaBlindSignatureWithPublicMetadataTestKeys());
130   for (const auto &test_vector : test_vectors) {
131     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
132         auto verifier,
133         RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first,
134                                /*use_rsa_public_exponent=*/true,
135                                test_vector.public_metadata));
136     EXPECT_TRUE(verifier
137                     ->Verify(test_vector.signature,
138                              MaskMessageConcat(test_vector.message_mask,
139                                                test_vector.message))
140                     .ok());
141   }
142 }
143 
TEST(RsaSsaPssVerifierTestWithPublicMetadata,IetfRsaBlindSignaturesWithPublicMetadataNoPublicExponentSuccess)144 TEST(RsaSsaPssVerifierTestWithPublicMetadata,
145      IetfRsaBlindSignaturesWithPublicMetadataNoPublicExponentSuccess) {
146   auto test_vectors =
147       GetIetfPartiallyBlindRSASignatureNoPublicExponentTestVectors();
148   const EVP_MD *sig_hash = EVP_sha384();   // Owned by BoringSSL
149   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
150   const int salt_length = kSaltLengthInBytes48;
151   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
152       const auto test_key,
153       GetIetfRsaBlindSignatureWithPublicMetadataTestKeys());
154   for (const auto &test_vector : test_vectors) {
155     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
156         auto verifier,
157         RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash, test_key.first,
158                                /*use_rsa_public_exponent=*/false,
159                                test_vector.public_metadata));
160     EXPECT_TRUE(
161         verifier->Verify(test_vector.signature, test_vector.message).ok());
162   }
163 }
164 
165 using RsaSsaPssVerifierPublicMetadataTestParams =
166     std::tuple<absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>,
167                /*use_rsa_public_exponent*/ bool>;
168 
169 class RsaSsaPssVerifierTestWithPublicMetadata
170     : public ::testing::TestWithParam<
171           RsaSsaPssVerifierPublicMetadataTestParams> {
172  protected:
SetUp()173   void SetUp() override {
174     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, std::get<0>(GetParam()));
175     use_rsa_public_exponent_ = std::get<1>(GetParam());
176     public_key_ = std::move(keys_pair.first);
177     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
178         private_key_, AnonymousTokensRSAPrivateKeyToRSA(keys_pair.second));
179     // NOTE: using recommended RsaSsaPssParams
180     sig_hash_ = EVP_sha384();
181     mgf1_hash_ = EVP_sha384();
182     salt_length_ = kSaltLengthInBytes48;
183   }
184 
185   RSAPublicKey public_key_;
186   bssl::UniquePtr<RSA> private_key_;
187   const EVP_MD *sig_hash_;   // Owned by BoringSSL.
188   const EVP_MD *mgf1_hash_;  // Owned by BoringSSL.
189   int salt_length_;
190   bool use_rsa_public_exponent_;
191 };
192 
193 // This test only tests whether the implemented verfier 'verifies' properly
194 // under some public metadata. The outline of method calls in this test should
195 // not be assumed a secure signature scheme (and used in other places) as the
196 // security has not been proven/analyzed.
TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,VerifierWorksWithPublicMetadata)197 TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,
198        VerifierWorksWithPublicMetadata) {
199   absl::string_view message = "Hello World!";
200   absl::string_view public_metadata = "pubmd!";
201   std::string augmented_message =
202       EncodeMessagePublicMetadata(message, public_metadata);
203   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
204       std::string encoded_message,
205       EncodeMessageForTests(augmented_message, public_key_, sig_hash_,
206                             mgf1_hash_, salt_length_));
207   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
208       std::string potentially_insecure_signature,
209       TestSignWithPublicMetadata(encoded_message, public_metadata,
210                                  *private_key_, use_rsa_public_exponent_));
211   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
212       auto verifier,
213       RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_,
214                              use_rsa_public_exponent_, public_metadata));
215   EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok());
216 }
217 
TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,VerifierFailsToVerifyWithWrongPublicMetadata)218 TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,
219        VerifierFailsToVerifyWithWrongPublicMetadata) {
220   absl::string_view message = "Hello World!";
221   absl::string_view public_metadata = "pubmd!";
222   absl::string_view public_metadata_2 = "pubmd2";
223   std::string augmented_message =
224       EncodeMessagePublicMetadata(message, public_metadata);
225   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
226       std::string encoded_message,
227       EncodeMessageForTests(augmented_message, public_key_, sig_hash_,
228                             mgf1_hash_, salt_length_));
229   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
230       std::string potentially_insecure_signature,
231       TestSignWithPublicMetadata(encoded_message, public_metadata,
232                                  *private_key_, use_rsa_public_exponent_));
233   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
234       auto verifier,
235       RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_,
236                              use_rsa_public_exponent_, public_metadata_2));
237   absl::Status verification_result =
238       verifier->Verify(potentially_insecure_signature, message);
239   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
240   EXPECT_THAT(verification_result.message(),
241               testing::HasSubstr("verification failed"));
242 }
243 
TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,VerifierFailsToVerifyWithEmptyPublicMetadata)244 TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,
245        VerifierFailsToVerifyWithEmptyPublicMetadata) {
246   absl::string_view message = "Hello World!";
247   absl::string_view public_metadata = "pubmd!";
248   absl::string_view empty_public_metadata = "";
249   std::string augmented_message =
250       EncodeMessagePublicMetadata(message, public_metadata);
251   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
252       std::string encoded_message,
253       EncodeMessageForTests(augmented_message, public_key_, sig_hash_,
254                             mgf1_hash_, salt_length_));
255   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
256       std::string potentially_insecure_signature,
257       TestSignWithPublicMetadata(encoded_message, public_metadata,
258                                  *private_key_, use_rsa_public_exponent_));
259   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
260       auto verifier,
261       RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_,
262                              use_rsa_public_exponent_, empty_public_metadata));
263   absl::Status verification_result =
264       verifier->Verify(potentially_insecure_signature, message);
265   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
266   EXPECT_THAT(verification_result.message(),
267               testing::HasSubstr("verification failed"));
268 }
269 
TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,VerifierFailsToVerifyWithoutPublicMetadataSupport)270 TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,
271        VerifierFailsToVerifyWithoutPublicMetadataSupport) {
272   absl::string_view message = "Hello World!";
273   absl::string_view public_metadata = "pubmd!";
274   std::string augmented_message =
275       EncodeMessagePublicMetadata(message, public_metadata);
276   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
277       std::string encoded_message,
278       EncodeMessageForTests(augmented_message, public_key_, sig_hash_,
279                             mgf1_hash_, salt_length_));
280   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
281       std::string potentially_insecure_signature,
282       TestSignWithPublicMetadata(encoded_message, public_metadata,
283                                  *private_key_, use_rsa_public_exponent_));
284   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
285       auto verifier,
286       RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_,
287                              use_rsa_public_exponent_));
288   absl::Status verification_result =
289       verifier->Verify(potentially_insecure_signature, message);
290   EXPECT_EQ(verification_result.code(), absl::StatusCode::kInvalidArgument);
291   EXPECT_THAT(verification_result.message(),
292               testing::HasSubstr("verification failed"));
293 }
294 
TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,EmptyMessageEmptyPublicMetadataVerificationSuccess)295 TEST_P(RsaSsaPssVerifierTestWithPublicMetadata,
296        EmptyMessageEmptyPublicMetadataVerificationSuccess) {
297   absl::string_view message = "";
298   absl::string_view public_metadata = "";
299   std::string augmented_message =
300       EncodeMessagePublicMetadata(message, public_metadata);
301   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
302       std::string encoded_message,
303       EncodeMessageForTests(augmented_message, public_key_, sig_hash_,
304                             mgf1_hash_, salt_length_));
305   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
306       std::string potentially_insecure_signature,
307       TestSignWithPublicMetadata(encoded_message, public_metadata,
308                                  *private_key_.get(),
309                                  use_rsa_public_exponent_));
310   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
311       auto verifier,
312       RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_,
313                              use_rsa_public_exponent_, public_metadata));
314   EXPECT_TRUE(verifier->Verify(potentially_insecure_signature, message).ok());
315 }
316 
317 INSTANTIATE_TEST_SUITE_P(
318     RsaSsaPssVerifierTestWithPublicMetadata,
319     RsaSsaPssVerifierTestWithPublicMetadata,
320     ::testing::Combine(
321         ::testing::Values(GetStrongRsaKeys2048(), GetAnotherStrongRsaKeys2048(),
322                           GetStrongRsaKeys3072(), GetStrongRsaKeys4096()),
323         /*use_rsa_public_exponent*/ ::testing::Values(true, false)));
324 
325 }  // namespace
326 }  // namespace anonymous_tokens
327 
328