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 #include "anonymous_tokens/cpp/testing/proto_utils.h"
15
16 #include <cstdint>
17 #include <fstream>
18 #include <ios>
19 #include <sstream>
20 #include <string>
21 #include <utility>
22 #include <vector>
23
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/str_cat.h"
27 #include "absl/strings/string_view.h"
28 #include "anonymous_tokens/cpp/crypto/constants.h"
29 #include "anonymous_tokens/cpp/crypto/crypto_utils.h"
30 #include "anonymous_tokens/cpp/shared/status_utils.h"
31 #include "anonymous_tokens/cpp/testing/testdata_utils.h"
32 #include "anonymous_tokens/cpp/testing/utils.h"
33 #include "anonymous_tokens/proto/anonymous_tokens.pb.h"
34 #include <openssl/base.h>
35 #include <openssl/bn.h>
36 #include <openssl/rsa.h>
37
38
39 namespace anonymous_tokens {
40
41 namespace {
42
ReadFileToString(absl::string_view path)43 absl::StatusOr<std::string> ReadFileToString(absl::string_view path) {
44 std::ifstream file(std::string(path), std::ios::binary);
45 if (!file.is_open()) {
46 return absl::InternalError("Reading file failed.");
47 }
48 std::ostringstream ss(std::ios::binary);
49 ss << file.rdbuf();
50 return ss.str();
51 }
52
ParseRsaKeysFromFile(absl::string_view path)53 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> ParseRsaKeysFromFile(
54 absl::string_view path) {
55 ANON_TOKENS_ASSIGN_OR_RETURN(std::string binary_proto,
56 ReadFileToString(path));
57 RSAPrivateKey private_key;
58 if (!private_key.ParseFromString(binary_proto)) {
59 return absl::InternalError("Parsing binary proto failed.");
60 }
61 RSAPublicKey public_key;
62 public_key.set_n(private_key.n());
63 public_key.set_e(private_key.e());
64 return std::make_pair(std::move(public_key), std::move(private_key));
65 }
66
GenerateRSAKey(int modulus_bit_size,const BIGNUM & e)67 absl::StatusOr<bssl::UniquePtr<RSA>> GenerateRSAKey(int modulus_bit_size,
68 const BIGNUM& e) {
69 bssl::UniquePtr<RSA> rsa(RSA_new());
70 if (!rsa.get()) {
71 return absl::InternalError(
72 absl::StrCat("RSA_new failed: ", GetSslErrors()));
73 }
74 if (RSA_generate_key_ex(rsa.get(), modulus_bit_size, &e,
75 /*cb=*/nullptr) != kBsslSuccess) {
76 return absl::InternalError(
77 absl::StrCat("Error generating private key: ", GetSslErrors()));
78 }
79 return rsa;
80 }
81
PopulateTestVectorKeys(const std::string & n,const std::string & e,const std::string & d,const std::string & p,const std::string & q)82 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> PopulateTestVectorKeys(
83 const std::string& n, const std::string& e, const std::string& d,
84 const std::string& p, const std::string& q) {
85 RSAPublicKey public_key;
86 RSAPrivateKey private_key;
87
88 public_key.set_n(n);
89 public_key.set_e(e);
90
91 private_key.set_n(n);
92 private_key.set_e(e);
93 private_key.set_d(d);
94 private_key.set_p(p);
95 private_key.set_q(q);
96
97 // Computing CRT parameters
98 ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx());
99 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dp_bn, NewBigNum());
100 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> dq_bn, NewBigNum());
101 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> crt_bn, NewBigNum());
102
103 // p - 1
104 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> pm1, StringToBignum(p));
105 BN_sub_word(pm1.get(), 1);
106 // q - 1
107 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> qm1, StringToBignum(q));
108 BN_sub_word(qm1.get(), 1);
109 // d mod p-1
110 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> d_bn, StringToBignum(d));
111 BN_mod(dp_bn.get(), d_bn.get(), pm1.get(), bn_ctx.get());
112 // d mod q-1
113 BN_mod(dq_bn.get(), d_bn.get(), qm1.get(), bn_ctx.get());
114 // crt q^(-1) mod p
115 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> q_bn, StringToBignum(q));
116 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> p_bn, StringToBignum(p));
117 BN_mod_inverse(crt_bn.get(), q_bn.get(), p_bn.get(), bn_ctx.get());
118
119 // Populating crt params in private key
120 ANON_TOKENS_ASSIGN_OR_RETURN(
121 std::string dp_str, BignumToString(*dp_bn, BN_num_bytes(dp_bn.get())));
122 ANON_TOKENS_ASSIGN_OR_RETURN(
123 std::string dq_str, BignumToString(*dq_bn, BN_num_bytes(dq_bn.get())));
124 ANON_TOKENS_ASSIGN_OR_RETURN(
125 std::string crt_str, BignumToString(*crt_bn, BN_num_bytes(crt_bn.get())));
126 private_key.set_dp(dp_str);
127 private_key.set_dq(dq_str);
128 private_key.set_crt(crt_str);
129
130 return std::make_pair(std::move(public_key), std::move(private_key));
131 }
132
133 } // namespace
134
135 absl::StatusOr<std::pair<bssl::UniquePtr<RSA>, RSABlindSignaturePublicKey>>
CreateTestKey(int key_size,HashType sig_hash,MaskGenFunction mfg1_hash,int salt_length,MessageMaskType message_mask_type,int message_mask_size)136 CreateTestKey(int key_size, HashType sig_hash, MaskGenFunction mfg1_hash,
137 int salt_length, MessageMaskType message_mask_type,
138 int message_mask_size) {
139 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_f4, NewBigNum());
140 BN_set_u64(rsa_f4.get(), RSA_F4);
141
142 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<RSA> rsa_key,
143 GenerateRSAKey(key_size * 8, *rsa_f4));
144
145 RSAPublicKey rsa_public_key;
146 ANON_TOKENS_ASSIGN_OR_RETURN(
147 *rsa_public_key.mutable_n(),
148 BignumToString(*RSA_get0_n(rsa_key.get()), key_size));
149 ANON_TOKENS_ASSIGN_OR_RETURN(
150 *rsa_public_key.mutable_e(),
151 BignumToString(*RSA_get0_e(rsa_key.get()), key_size));
152
153 RSABlindSignaturePublicKey public_key;
154 public_key.set_serialized_public_key(rsa_public_key.SerializeAsString());
155 public_key.set_sig_hash_type(sig_hash);
156 public_key.set_mask_gen_function(mfg1_hash);
157 public_key.set_salt_length(salt_length);
158 public_key.set_key_size(key_size);
159 public_key.set_message_mask_type(message_mask_type);
160 public_key.set_message_mask_size(message_mask_size);
161
162 return std::make_pair(std::move(rsa_key), std::move(public_key));
163 }
164
EncodeMessageForTests(absl::string_view message,RSAPublicKey public_key,const EVP_MD * sig_hasher,const EVP_MD * mgf1_hasher,int32_t salt_length)165 absl::StatusOr<std::string> EncodeMessageForTests(absl::string_view message,
166 RSAPublicKey public_key,
167 const EVP_MD* sig_hasher,
168 const EVP_MD* mgf1_hasher,
169 int32_t salt_length) {
170 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus,
171 StringToBignum(public_key.n()));
172 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> e,
173 StringToBignum(public_key.e()));
174 // Convert to OpenSSL RSA.
175 bssl::UniquePtr<RSA> rsa_public_key(RSA_new());
176 if (!rsa_public_key.get()) {
177 return absl::InternalError(
178 absl::StrCat("RSA_new failed: ", GetSslErrors()));
179 } else if (RSA_set0_key(rsa_public_key.get(), rsa_modulus.release(),
180 e.release(), nullptr) != kBsslSuccess) {
181 return absl::InternalError(
182 absl::StrCat("RSA_set0_key failed: ", GetSslErrors()));
183 }
184
185 const int padded_len = RSA_size(rsa_public_key.get());
186 std::vector<uint8_t> padded(padded_len);
187 ANON_TOKENS_ASSIGN_OR_RETURN(std::string digest,
188 ComputeHash(message, *sig_hasher));
189 if (RSA_padding_add_PKCS1_PSS_mgf1(
190 /*rsa=*/rsa_public_key.get(), /*EM=*/padded.data(),
191 /*mHash=*/reinterpret_cast<uint8_t*>(&digest[0]), /*Hash=*/sig_hasher,
192 /*mgf1Hash=*/mgf1_hasher,
193 /*sLen=*/salt_length) != kBsslSuccess) {
194 return absl::InternalError(
195 "RSA_padding_add_PKCS1_PSS_mgf1 failed when called from "
196 "testing_utils");
197 }
198 std::string encoded_message(padded.begin(), padded.end());
199 return encoded_message;
200 }
201
GetStandardRsaKeyPair(int modulus_size_in_bytes)202 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStandardRsaKeyPair(
203 int modulus_size_in_bytes) {
204 ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_f4, NewBigNum());
205 BN_set_u64(rsa_f4.get(), RSA_F4);
206 ANON_TOKENS_ASSIGN_OR_RETURN(
207 bssl::UniquePtr<RSA> rsa_key,
208 GenerateRSAKey(modulus_size_in_bytes * 8, *rsa_f4));
209
210 RSAPublicKey rsa_public_key;
211 ANON_TOKENS_ASSIGN_OR_RETURN(
212 *rsa_public_key.mutable_n(),
213 BignumToString(*RSA_get0_n(rsa_key.get()), modulus_size_in_bytes));
214 ANON_TOKENS_ASSIGN_OR_RETURN(
215 *rsa_public_key.mutable_e(),
216 BignumToString(*RSA_get0_e(rsa_key.get()), modulus_size_in_bytes));
217
218 RSAPrivateKey rsa_private_key;
219 ANON_TOKENS_ASSIGN_OR_RETURN(
220 *rsa_private_key.mutable_n(),
221 BignumToString(*RSA_get0_n(rsa_key.get()), modulus_size_in_bytes));
222 ANON_TOKENS_ASSIGN_OR_RETURN(
223 *rsa_private_key.mutable_e(),
224 BignumToString(*RSA_get0_e(rsa_key.get()), modulus_size_in_bytes));
225 ANON_TOKENS_ASSIGN_OR_RETURN(
226 *rsa_private_key.mutable_d(),
227 BignumToString(*RSA_get0_d(rsa_key.get()), modulus_size_in_bytes));
228 ANON_TOKENS_ASSIGN_OR_RETURN(
229 *rsa_private_key.mutable_p(),
230 BignumToString(*RSA_get0_p(rsa_key.get()), modulus_size_in_bytes));
231 ANON_TOKENS_ASSIGN_OR_RETURN(
232 *rsa_private_key.mutable_q(),
233 BignumToString(*RSA_get0_q(rsa_key.get()), modulus_size_in_bytes));
234 ANON_TOKENS_ASSIGN_OR_RETURN(
235 *rsa_private_key.mutable_dp(),
236 BignumToString(*RSA_get0_dmp1(rsa_key.get()), modulus_size_in_bytes));
237 ANON_TOKENS_ASSIGN_OR_RETURN(
238 *rsa_private_key.mutable_dq(),
239 BignumToString(*RSA_get0_dmq1(rsa_key.get()), modulus_size_in_bytes));
240 ANON_TOKENS_ASSIGN_OR_RETURN(
241 *rsa_private_key.mutable_crt(),
242 BignumToString(*RSA_get0_iqmp(rsa_key.get()), modulus_size_in_bytes));
243
244 return std::make_pair(std::move(rsa_public_key), std::move(rsa_private_key));
245 }
246
GetStrongRsaKeys2048()247 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys2048() {
248 std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(),
249 "strong_rsa_modulus2048_example.binarypb");
250 ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path));
251 return std::make_pair(std::move(key_pair.first), std::move(key_pair.second));
252 }
253
254 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>
GetAnotherStrongRsaKeys2048()255 GetAnotherStrongRsaKeys2048() {
256 std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(),
257 "strong_rsa_modulus2048_example_2.binarypb");
258 ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path));
259 return std::make_pair(std::move(key_pair.first), std::move(key_pair.second));
260 }
261
GetStrongRsaKeys3072()262 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys3072() {
263 std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(),
264 "strong_rsa_modulus3072_example.binarypb");
265 ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path));
266 return std::make_pair(std::move(key_pair.first), std::move(key_pair.second));
267 }
268
GetStrongRsaKeys4096()269 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>> GetStrongRsaKeys4096() {
270 std::string path = absl::StrCat(::anonymous_tokens::GetTestdataPath(),
271 "strong_rsa_modulus4096_example.binarypb");
272 ANON_TOKENS_ASSIGN_OR_RETURN(auto key_pair, ParseRsaKeysFromFile(path));
273 return std::make_pair(std::move(key_pair.first), std::move(key_pair.second));
274 }
275
276 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>
GetIetfStandardRsaBlindSignatureTestKeys()277 GetIetfStandardRsaBlindSignatureTestKeys() {
278 IetfStandardRsaBlindSignatureTestVector test_vector =
279 GetIetfStandardRsaBlindSignatureTestVector();
280 return PopulateTestVectorKeys(test_vector.n, test_vector.e, test_vector.d,
281 test_vector.p, test_vector.q);
282 }
283
284 absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>
GetIetfRsaBlindSignatureWithPublicMetadataTestKeys()285 GetIetfRsaBlindSignatureWithPublicMetadataTestKeys() {
286 auto test_vectors = GetIetfRsaBlindSignatureWithPublicMetadataTestVectors();
287 return PopulateTestVectorKeys(test_vectors[0].n, test_vectors[0].e,
288 test_vectors[0].d, test_vectors[0].p,
289 test_vectors[0].q);
290 }
291
292 } // namespace anonymous_tokens
293
294