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