1*e7b1675dSTing-Kang Chang // Copyright 2021 Google LLC
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang #include "tink/internal/rsa_util.h"
17*e7b1675dSTing-Kang Chang
18*e7b1675dSTing-Kang Chang #include <stddef.h>
19*e7b1675dSTing-Kang Chang #include <stdint.h>
20*e7b1675dSTing-Kang Chang
21*e7b1675dSTing-Kang Chang #include <algorithm>
22*e7b1675dSTing-Kang Chang #include <iterator>
23*e7b1675dSTing-Kang Chang #include <memory>
24*e7b1675dSTing-Kang Chang #include <string>
25*e7b1675dSTing-Kang Chang #include <utility>
26*e7b1675dSTing-Kang Chang #include <vector>
27*e7b1675dSTing-Kang Chang
28*e7b1675dSTing-Kang Chang #include "gmock/gmock.h"
29*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
30*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
31*e7b1675dSTing-Kang Chang #include "absl/strings/escaping.h"
32*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
33*e7b1675dSTing-Kang Chang #include "openssl/bn.h"
34*e7b1675dSTing-Kang Chang #include "openssl/rsa.h"
35*e7b1675dSTing-Kang Chang #include "tink/internal/bn_util.h"
36*e7b1675dSTing-Kang Chang #include "tink/internal/ssl_unique_ptr.h"
37*e7b1675dSTing-Kang Chang #include "tink/subtle/random.h"
38*e7b1675dSTing-Kang Chang #include "tink/util/secret_data.h"
39*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
40*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
41*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
42*e7b1675dSTing-Kang Chang
43*e7b1675dSTing-Kang Chang namespace crypto {
44*e7b1675dSTing-Kang Chang namespace tink {
45*e7b1675dSTing-Kang Chang namespace internal {
46*e7b1675dSTing-Kang Chang namespace {
47*e7b1675dSTing-Kang Chang
48*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
49*e7b1675dSTing-Kang Chang using ::crypto::tink::test::StatusIs;
50*e7b1675dSTing-Kang Chang using ::testing::IsEmpty;
51*e7b1675dSTing-Kang Chang using ::testing::Not;
52*e7b1675dSTing-Kang Chang
53*e7b1675dSTing-Kang Chang constexpr int kSslSuccess = 1;
54*e7b1675dSTing-Kang Chang // 2048 bits modulus.
55*e7b1675dSTing-Kang Chang constexpr absl::string_view k2048BitRsaModulus =
56*e7b1675dSTing-Kang Chang "b5a5651bc2e15ce31d789f0984053a2ea0cf8f964a78068c45acfdf078c57fd62d5a287c32"
57*e7b1675dSTing-Kang Chang "f3baa879f5dfea27d7a3077c9d3a2a728368c3d90164690c3d82f660ffebc7f13fed454eb5"
58*e7b1675dSTing-Kang Chang "103df943c10dc32ec60b0d9b6e307bfd7f9b943e0dc3901e42501765365f7286eff2f1f728"
59*e7b1675dSTing-Kang Chang "774aa6a371e108a3a7dd00d7bcd4c1a186c2865d4b370ea38cc89c0b23b318dbcafbd872b4"
60*e7b1675dSTing-Kang Chang "f9b833dfb2a4ca7fcc23298020044e8130bfe930adfb3e5cab8d324547adf4b2ce34d7cea4"
61*e7b1675dSTing-Kang Chang "298f0b613d85f2bf1df03da44aee0784a1a20a15ee0c38a0f8e84962f1f61b18bd43781c73"
62*e7b1675dSTing-Kang Chang "85f3c2b8e2aebd3c560b4faad208ad3938bad27ddda9ed9e933dba0880212dd9e28d";
63*e7b1675dSTing-Kang Chang
64*e7b1675dSTing-Kang Chang // Utility function to create an RSA key pair.
GetKeyPair(size_t modulus_size_in_bits)65*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> GetKeyPair(
66*e7b1675dSTing-Kang Chang size_t modulus_size_in_bits) {
67*e7b1675dSTing-Kang Chang RsaPublicKey public_key;
68*e7b1675dSTing-Kang Chang RsaPrivateKey private_key;
69*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> e(BN_new());
70*e7b1675dSTing-Kang Chang BN_set_word(e.get(), RSA_F4);
71*e7b1675dSTing-Kang Chang util::Status res =
72*e7b1675dSTing-Kang Chang NewRsaKeyPair(modulus_size_in_bits, e.get(), &private_key, &public_key);
73*e7b1675dSTing-Kang Chang if (!res.ok()) {
74*e7b1675dSTing-Kang Chang return res;
75*e7b1675dSTing-Kang Chang }
76*e7b1675dSTing-Kang Chang return {{public_key, private_key}};
77*e7b1675dSTing-Kang Chang }
78*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,BasicSanityChecks)79*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, BasicSanityChecks) {
80*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
81*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
82*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
83*e7b1675dSTing-Kang Chang const RsaPublicKey& public_key = keys->first;
84*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
85*e7b1675dSTing-Kang Chang
86*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.n, Not(IsEmpty()));
87*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.e, Not(IsEmpty()));
88*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.d, Not(IsEmpty()));
89*e7b1675dSTing-Kang Chang
90*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.p, Not(IsEmpty()));
91*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.q, Not(IsEmpty()));
92*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.dp, Not(IsEmpty()));
93*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.dq, Not(IsEmpty()));
94*e7b1675dSTing-Kang Chang EXPECT_THAT(private_key.crt, Not(IsEmpty()));
95*e7b1675dSTing-Kang Chang
96*e7b1675dSTing-Kang Chang EXPECT_THAT(public_key.n, Not(IsEmpty()));
97*e7b1675dSTing-Kang Chang EXPECT_THAT(public_key.e, Not(IsEmpty()));
98*e7b1675dSTing-Kang Chang
99*e7b1675dSTing-Kang Chang EXPECT_EQ(public_key.n, private_key.n);
100*e7b1675dSTing-Kang Chang EXPECT_EQ(public_key.e, private_key.e);
101*e7b1675dSTing-Kang Chang }
102*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,FailsOnLargeE)103*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, FailsOnLargeE) {
104*e7b1675dSTing-Kang Chang // OpenSSL requires the "e" value to be at most 32 bits.
105*e7b1675dSTing-Kang Chang RsaPublicKey public_key;
106*e7b1675dSTing-Kang Chang RsaPrivateKey private_key;
107*e7b1675dSTing-Kang Chang
108*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> e(BN_new());
109*e7b1675dSTing-Kang Chang BN_set_word(e.get(), 1L << 33);
110*e7b1675dSTing-Kang Chang EXPECT_THAT(NewRsaKeyPair(/*modulus_size_in_bits=*/2048, e.get(),
111*e7b1675dSTing-Kang Chang &private_key, &public_key),
112*e7b1675dSTing-Kang Chang StatusIs(absl::StatusCode::kInvalidArgument));
113*e7b1675dSTing-Kang Chang }
114*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,KeyIsWellFormed)115*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, KeyIsWellFormed) {
116*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
117*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
118*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
119*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
120*e7b1675dSTing-Kang Chang
121*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> n =
122*e7b1675dSTing-Kang Chang internal::StringToBignum(private_key.n);
123*e7b1675dSTing-Kang Chang ASSERT_THAT(n, IsOk());
124*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> d =
125*e7b1675dSTing-Kang Chang internal::StringToBignum(util::SecretDataAsStringView(private_key.d));
126*e7b1675dSTing-Kang Chang ASSERT_THAT(d, IsOk());
127*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> p =
128*e7b1675dSTing-Kang Chang internal::StringToBignum(util::SecretDataAsStringView(private_key.p));
129*e7b1675dSTing-Kang Chang ASSERT_THAT(p, IsOk());
130*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> q =
131*e7b1675dSTing-Kang Chang internal::StringToBignum(util::SecretDataAsStringView(private_key.q));
132*e7b1675dSTing-Kang Chang ASSERT_THAT(q, IsOk());
133*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> dp =
134*e7b1675dSTing-Kang Chang internal::StringToBignum(util::SecretDataAsStringView(private_key.dp));
135*e7b1675dSTing-Kang Chang ASSERT_THAT(dp, IsOk());
136*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> dq =
137*e7b1675dSTing-Kang Chang internal::StringToBignum(util::SecretDataAsStringView(private_key.dq));
138*e7b1675dSTing-Kang Chang ASSERT_THAT(dq, IsOk());
139*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BN_CTX> ctx(BN_CTX_new());
140*e7b1675dSTing-Kang Chang
141*e7b1675dSTing-Kang Chang // Check n = p * q.
142*e7b1675dSTing-Kang Chang {
143*e7b1675dSTing-Kang Chang auto n_calc = internal::SslUniquePtr<BIGNUM>(BN_new());
144*e7b1675dSTing-Kang Chang ASSERT_EQ(BN_mul(n_calc.get(), p->get(), q->get(), ctx.get()), kSslSuccess);
145*e7b1675dSTing-Kang Chang EXPECT_EQ(BN_cmp(n_calc.get(), n->get()), 0);
146*e7b1675dSTing-Kang Chang }
147*e7b1675dSTing-Kang Chang
148*e7b1675dSTing-Kang Chang // Check n size >= 2048 bit.
149*e7b1675dSTing-Kang Chang EXPECT_GE(BN_num_bits(n->get()), 2048);
150*e7b1675dSTing-Kang Chang
151*e7b1675dSTing-Kang Chang // dp = d mod (p - 1)
152*e7b1675dSTing-Kang Chang {
153*e7b1675dSTing-Kang Chang auto pm1 = internal::SslUniquePtr<BIGNUM>(BN_dup(p->get()));
154*e7b1675dSTing-Kang Chang ASSERT_EQ(BN_sub_word(pm1.get(), /*w=*/1), kSslSuccess);
155*e7b1675dSTing-Kang Chang auto dp_calc = internal::SslUniquePtr<BIGNUM>(BN_new());
156*e7b1675dSTing-Kang Chang ASSERT_EQ(BN_mod(dp_calc.get(), d->get(), pm1.get(), ctx.get()),
157*e7b1675dSTing-Kang Chang kSslSuccess);
158*e7b1675dSTing-Kang Chang EXPECT_EQ(BN_cmp(dp_calc.get(), dp->get()), 0);
159*e7b1675dSTing-Kang Chang }
160*e7b1675dSTing-Kang Chang
161*e7b1675dSTing-Kang Chang // dq = d mod (q - 1)
162*e7b1675dSTing-Kang Chang {
163*e7b1675dSTing-Kang Chang auto qm1 = internal::SslUniquePtr<BIGNUM>(BN_dup(q->get()));
164*e7b1675dSTing-Kang Chang ASSERT_EQ(BN_sub_word(qm1.get(), /*w=*/1), kSslSuccess);
165*e7b1675dSTing-Kang Chang auto dq_calc = internal::SslUniquePtr<BIGNUM>(BN_new());
166*e7b1675dSTing-Kang Chang ASSERT_EQ(BN_mod(dq_calc.get(), d->get(), qm1.get(), ctx.get()),
167*e7b1675dSTing-Kang Chang kSslSuccess);
168*e7b1675dSTing-Kang Chang EXPECT_EQ(BN_cmp(dq_calc.get(), dq->get()), 0);
169*e7b1675dSTing-Kang Chang }
170*e7b1675dSTing-Kang Chang }
171*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,GeneratesDifferentPrivateKeys)172*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, GeneratesDifferentPrivateKeys) {
173*e7b1675dSTing-Kang Chang RsaPublicKey public_key;
174*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> e(BN_new());
175*e7b1675dSTing-Kang Chang BN_set_word(e.get(), RSA_F4);
176*e7b1675dSTing-Kang Chang
177*e7b1675dSTing-Kang Chang std::vector<RsaPrivateKey> private_keys;
178*e7b1675dSTing-Kang Chang std::generate_n(std::back_inserter(private_keys), 4, [&]() {
179*e7b1675dSTing-Kang Chang RsaPrivateKey private_key;
180*e7b1675dSTing-Kang Chang EXPECT_THAT(NewRsaKeyPair(/*modulus_size_in_bits=*/2048, e.get(),
181*e7b1675dSTing-Kang Chang &private_key, &public_key),
182*e7b1675dSTing-Kang Chang IsOk());
183*e7b1675dSTing-Kang Chang return private_key;
184*e7b1675dSTing-Kang Chang });
185*e7b1675dSTing-Kang Chang
186*e7b1675dSTing-Kang Chang for (int i = 0; i < private_keys.size() - 1; i++) {
187*e7b1675dSTing-Kang Chang for (int j = i + 1; j < private_keys.size(); j++) {
188*e7b1675dSTing-Kang Chang // The only field that should be equal.
189*e7b1675dSTing-Kang Chang EXPECT_EQ(private_keys[i].e, private_keys[j].e);
190*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].n, private_keys[j].n);
191*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].d, private_keys[j].d);
192*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].p, private_keys[j].p);
193*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].q, private_keys[j].q);
194*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].dp, private_keys[j].dp);
195*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].dq, private_keys[j].dq);
196*e7b1675dSTing-Kang Chang EXPECT_NE(private_keys[i].crt, private_keys[j].crt);
197*e7b1675dSTing-Kang Chang }
198*e7b1675dSTing-Kang Chang }
199*e7b1675dSTing-Kang Chang }
200*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,ValidateRsaModulusSize)201*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, ValidateRsaModulusSize) {
202*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
203*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
204*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
205*e7b1675dSTing-Kang Chang {
206*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
207*e7b1675dSTing-Kang Chang
208*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> n =
209*e7b1675dSTing-Kang Chang internal::StringToBignum(private_key.n);
210*e7b1675dSTing-Kang Chang EXPECT_THAT(ValidateRsaModulusSize(BN_num_bits(n->get())), IsOk());
211*e7b1675dSTing-Kang Chang }
212*e7b1675dSTing-Kang Chang keys = GetKeyPair(/*modulus_size_in_bits=*/1024);
213*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
214*e7b1675dSTing-Kang Chang {
215*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
216*e7b1675dSTing-Kang Chang
217*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> n =
218*e7b1675dSTing-Kang Chang internal::StringToBignum(private_key.n);
219*e7b1675dSTing-Kang Chang EXPECT_THAT(ValidateRsaModulusSize(BN_num_bits(n->get())), Not(IsOk()));
220*e7b1675dSTing-Kang Chang }
221*e7b1675dSTing-Kang Chang }
222*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,ValidateRsaPublicExponent)223*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, ValidateRsaPublicExponent) {
224*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> e_bn(BN_new());
225*e7b1675dSTing-Kang Chang
226*e7b1675dSTing-Kang Chang // Failure scenario.
227*e7b1675dSTing-Kang Chang const std::vector<BN_ULONG> invalid_exponents = {2, 3, 4, 65536, 65538};
228*e7b1675dSTing-Kang Chang for (const BN_ULONG exponent : invalid_exponents) {
229*e7b1675dSTing-Kang Chang BN_set_word(e_bn.get(), exponent);
230*e7b1675dSTing-Kang Chang util::StatusOr<std::string> e_str =
231*e7b1675dSTing-Kang Chang internal::BignumToString(e_bn.get(), BN_num_bytes(e_bn.get()));
232*e7b1675dSTing-Kang Chang ASSERT_THAT(e_str, IsOk());
233*e7b1675dSTing-Kang Chang EXPECT_THAT(ValidateRsaPublicExponent(*e_str), Not(IsOk()));
234*e7b1675dSTing-Kang Chang }
235*e7b1675dSTing-Kang Chang
236*e7b1675dSTing-Kang Chang // Successful case.
237*e7b1675dSTing-Kang Chang BN_set_word(e_bn.get(), RSA_F4);
238*e7b1675dSTing-Kang Chang util::StatusOr<std::string> e_str =
239*e7b1675dSTing-Kang Chang internal::BignumToString(e_bn.get(), BN_num_bytes(e_bn.get()));
240*e7b1675dSTing-Kang Chang ASSERT_THAT(e_str, IsOk());
241*e7b1675dSTing-Kang Chang EXPECT_THAT(ValidateRsaPublicExponent(*e_str), IsOk());
242*e7b1675dSTing-Kang Chang }
243*e7b1675dSTing-Kang Chang
244*e7b1675dSTing-Kang Chang // Checks if a BIGNUM is equal to a string value.
ExpectBignumEquals(const BIGNUM * bn,absl::string_view data)245*e7b1675dSTing-Kang Chang void ExpectBignumEquals(const BIGNUM* bn, absl::string_view data) {
246*e7b1675dSTing-Kang Chang util::StatusOr<std::string> converted =
247*e7b1675dSTing-Kang Chang internal::BignumToString(bn, BN_num_bytes(bn));
248*e7b1675dSTing-Kang Chang ASSERT_THAT(converted, IsOk());
249*e7b1675dSTing-Kang Chang EXPECT_EQ(*converted, data);
250*e7b1675dSTing-Kang Chang }
251*e7b1675dSTing-Kang Chang
252*e7b1675dSTing-Kang Chang // Checks if a BIGNUM is equal to a SecretData value.
ExpectBignumEquals(const BIGNUM * bn,const util::SecretData & data)253*e7b1675dSTing-Kang Chang void ExpectBignumEquals(const BIGNUM* bn, const util::SecretData& data) {
254*e7b1675dSTing-Kang Chang internal::ExpectBignumEquals(bn, util::SecretDataAsStringView(data));
255*e7b1675dSTing-Kang Chang }
256*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,GetRsaModAndExponents)257*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, GetRsaModAndExponents) {
258*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
259*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
260*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
261*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
262*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> rsa(RSA_new());
263*e7b1675dSTing-Kang Chang util::Status result = GetRsaModAndExponents(private_key, rsa.get());
264*e7b1675dSTing-Kang Chang ASSERT_THAT(result, IsOk());
265*e7b1675dSTing-Kang Chang const BIGNUM* n = nullptr;
266*e7b1675dSTing-Kang Chang const BIGNUM* e = nullptr;
267*e7b1675dSTing-Kang Chang const BIGNUM* d = nullptr;
268*e7b1675dSTing-Kang Chang RSA_get0_key(rsa.get(), &n, &e, &d);
269*e7b1675dSTing-Kang Chang ExpectBignumEquals(n, private_key.n);
270*e7b1675dSTing-Kang Chang ExpectBignumEquals(e, private_key.e);
271*e7b1675dSTing-Kang Chang ExpectBignumEquals(d, private_key.d);
272*e7b1675dSTing-Kang Chang }
273*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,GetRsaPrimeFactors)274*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, GetRsaPrimeFactors) {
275*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
276*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
277*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
278*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
279*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> rsa(RSA_new());
280*e7b1675dSTing-Kang Chang util::Status result = GetRsaPrimeFactors(private_key, rsa.get());
281*e7b1675dSTing-Kang Chang ASSERT_THAT(result, IsOk());
282*e7b1675dSTing-Kang Chang const BIGNUM* p = nullptr;
283*e7b1675dSTing-Kang Chang const BIGNUM* q = nullptr;
284*e7b1675dSTing-Kang Chang RSA_get0_factors(rsa.get(), &p, &q);
285*e7b1675dSTing-Kang Chang ExpectBignumEquals(p, private_key.p);
286*e7b1675dSTing-Kang Chang ExpectBignumEquals(q, private_key.q);
287*e7b1675dSTing-Kang Chang }
288*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,GetRsaCrtParams)289*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, GetRsaCrtParams) {
290*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
291*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
292*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
293*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
294*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> rsa(RSA_new());
295*e7b1675dSTing-Kang Chang const BIGNUM* dp = nullptr;
296*e7b1675dSTing-Kang Chang const BIGNUM* dq = nullptr;
297*e7b1675dSTing-Kang Chang const BIGNUM* crt = nullptr;
298*e7b1675dSTing-Kang Chang util::Status result = GetRsaCrtParams(private_key, rsa.get());
299*e7b1675dSTing-Kang Chang ASSERT_THAT(result, IsOk());
300*e7b1675dSTing-Kang Chang RSA_get0_crt_params(rsa.get(), &dp, &dq, &crt);
301*e7b1675dSTing-Kang Chang ExpectBignumEquals(dp, private_key.dp);
302*e7b1675dSTing-Kang Chang ExpectBignumEquals(dq, private_key.dq);
303*e7b1675dSTing-Kang Chang ExpectBignumEquals(crt, private_key.crt);
304*e7b1675dSTing-Kang Chang }
305*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,CopiesRsaPrivateKey)306*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, CopiesRsaPrivateKey) {
307*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
308*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
309*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
310*e7b1675dSTing-Kang Chang const RsaPrivateKey& private_key = keys->second;
311*e7b1675dSTing-Kang Chang
312*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> rsa_result =
313*e7b1675dSTing-Kang Chang RsaPrivateKeyToRsa(private_key);
314*e7b1675dSTing-Kang Chang EXPECT_TRUE(rsa_result.ok());
315*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> rsa = std::move(rsa_result).value();
316*e7b1675dSTing-Kang Chang const BIGNUM* n = nullptr;
317*e7b1675dSTing-Kang Chang const BIGNUM* e = nullptr;
318*e7b1675dSTing-Kang Chang const BIGNUM* d = nullptr;
319*e7b1675dSTing-Kang Chang RSA_get0_key(rsa.get(), &n, &e, &d);
320*e7b1675dSTing-Kang Chang const BIGNUM* p = nullptr;
321*e7b1675dSTing-Kang Chang const BIGNUM* q = nullptr;
322*e7b1675dSTing-Kang Chang RSA_get0_factors(rsa.get(), &p, &q);
323*e7b1675dSTing-Kang Chang ExpectBignumEquals(n, private_key.n);
324*e7b1675dSTing-Kang Chang ExpectBignumEquals(e, private_key.e);
325*e7b1675dSTing-Kang Chang ExpectBignumEquals(d, private_key.d);
326*e7b1675dSTing-Kang Chang ExpectBignumEquals(p, private_key.p);
327*e7b1675dSTing-Kang Chang ExpectBignumEquals(q, private_key.q);
328*e7b1675dSTing-Kang Chang }
329*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,CopiesRsaPublicKey)330*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, CopiesRsaPublicKey) {
331*e7b1675dSTing-Kang Chang util::StatusOr<std::pair<RsaPublicKey, RsaPrivateKey>> keys =
332*e7b1675dSTing-Kang Chang GetKeyPair(/*modulus_size_in_bits=*/2048);
333*e7b1675dSTing-Kang Chang ASSERT_THAT(keys, IsOk());
334*e7b1675dSTing-Kang Chang const RsaPublicKey& public_key = keys->first;
335*e7b1675dSTing-Kang Chang
336*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> rsa_result =
337*e7b1675dSTing-Kang Chang RsaPublicKeyToRsa(public_key);
338*e7b1675dSTing-Kang Chang EXPECT_TRUE(rsa_result.ok());
339*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> rsa = std::move(rsa_result).value();
340*e7b1675dSTing-Kang Chang
341*e7b1675dSTing-Kang Chang const BIGNUM* n = nullptr;
342*e7b1675dSTing-Kang Chang const BIGNUM* e = nullptr;
343*e7b1675dSTing-Kang Chang RSA_get0_key(rsa.get(), &n, &e, /*d=*/nullptr);
344*e7b1675dSTing-Kang Chang ExpectBignumEquals(n, public_key.n);
345*e7b1675dSTing-Kang Chang ExpectBignumEquals(e, public_key.e);
346*e7b1675dSTing-Kang Chang }
347*e7b1675dSTing-Kang Chang
348*e7b1675dSTing-Kang Chang // Utility function that creates an RSA public key with the given modulus
349*e7b1675dSTing-Kang Chang // `n_hex` and exponent `exp`.
NewRsaPublicKey(absl::string_view n_hex,uint64_t exp)350*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> NewRsaPublicKey(
351*e7b1675dSTing-Kang Chang absl::string_view n_hex, uint64_t exp) {
352*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> key(RSA_new());
353*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<BIGNUM>> n_bn =
354*e7b1675dSTing-Kang Chang internal::StringToBignum(absl::HexStringToBytes(n_hex));
355*e7b1675dSTing-Kang Chang if (!n_bn.ok()) {
356*e7b1675dSTing-Kang Chang return n_bn.status();
357*e7b1675dSTing-Kang Chang }
358*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> n = *std::move(n_bn);
359*e7b1675dSTing-Kang Chang internal::SslUniquePtr<BIGNUM> e(BN_new());
360*e7b1675dSTing-Kang Chang BN_set_word(e.get(), exp);
361*e7b1675dSTing-Kang Chang if (RSA_set0_key(key.get(), n.get(), e.get(), /*d=*/nullptr) != 1) {
362*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInternal, "RSA_set0_key failed");
363*e7b1675dSTing-Kang Chang }
364*e7b1675dSTing-Kang Chang // RSA_set0_key takes ownership of the arguments.
365*e7b1675dSTing-Kang Chang n.release();
366*e7b1675dSTing-Kang Chang e.release();
367*e7b1675dSTing-Kang Chang return std::move(key);
368*e7b1675dSTing-Kang Chang }
369*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyNullKey)370*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyNullKey) {
371*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(nullptr), Not(IsOk()));
372*e7b1675dSTing-Kang Chang }
373*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyMissingExponentAndModule)374*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyMissingExponentAndModule) {
375*e7b1675dSTing-Kang Chang internal::SslUniquePtr<RSA> key(RSA_new());
376*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key.get()), Not(IsOk()));
377*e7b1675dSTing-Kang Chang }
378*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyValid)379*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyValid) {
380*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
381*e7b1675dSTing-Kang Chang NewRsaPublicKey(k2048BitRsaModulus, RSA_F4);
382*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
383*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), IsOk());
384*e7b1675dSTing-Kang Chang }
385*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyExponentTooLarge)386*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyExponentTooLarge) {
387*e7b1675dSTing-Kang Chang // Invalid exponent of 34 bits.
388*e7b1675dSTing-Kang Chang constexpr uint64_t kExponentTooLarge = 0x200000000;
389*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
390*e7b1675dSTing-Kang Chang NewRsaPublicKey(k2048BitRsaModulus, kExponentTooLarge);
391*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
392*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), Not(IsOk()));
393*e7b1675dSTing-Kang Chang }
394*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyExponentTooSmall)395*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyExponentTooSmall) {
396*e7b1675dSTing-Kang Chang constexpr uint64_t kExponentEqualsToOne = 0x1;
397*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
398*e7b1675dSTing-Kang Chang NewRsaPublicKey(k2048BitRsaModulus, kExponentEqualsToOne);
399*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
400*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), Not(IsOk()));
401*e7b1675dSTing-Kang Chang }
402*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyExponentNotOdd)403*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyExponentNotOdd) {
404*e7b1675dSTing-Kang Chang constexpr uint64_t kExponentNotOdd = 0x20000000;
405*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
406*e7b1675dSTing-Kang Chang NewRsaPublicKey(k2048BitRsaModulus, kExponentNotOdd);
407*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
408*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), Not(IsOk()));
409*e7b1675dSTing-Kang Chang }
410*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyModulusTooLarge)411*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyModulusTooLarge) {
412*e7b1675dSTing-Kang Chang // Get 1 byte more than 16384 bits (2048 bytes).
413*e7b1675dSTing-Kang Chang std::string too_large_modulus = subtle::Random::GetRandomBytes(2049);
414*e7b1675dSTing-Kang Chang if (too_large_modulus[0] == '\0') {
415*e7b1675dSTing-Kang Chang too_large_modulus[0] = 0x01;
416*e7b1675dSTing-Kang Chang }
417*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
418*e7b1675dSTing-Kang Chang NewRsaPublicKey(absl::BytesToHexString(too_large_modulus), RSA_F4);
419*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
420*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), Not(IsOk()));
421*e7b1675dSTing-Kang Chang }
422*e7b1675dSTing-Kang Chang
TEST(RsaUtilTest,RsaCheckPublicKeyModulusSmallerThanExp)423*e7b1675dSTing-Kang Chang TEST(RsaUtilTest, RsaCheckPublicKeyModulusSmallerThanExp) {
424*e7b1675dSTing-Kang Chang constexpr absl::string_view kModulusSmallerThanExp = "1001";
425*e7b1675dSTing-Kang Chang util::StatusOr<internal::SslUniquePtr<RSA>> key =
426*e7b1675dSTing-Kang Chang NewRsaPublicKey(kModulusSmallerThanExp, RSA_F4);
427*e7b1675dSTing-Kang Chang ASSERT_THAT(key, IsOk());
428*e7b1675dSTing-Kang Chang EXPECT_THAT(RsaCheckPublicKey(key->get()), Not(IsOk()));
429*e7b1675dSTing-Kang Chang }
430*e7b1675dSTing-Kang Chang
431*e7b1675dSTing-Kang Chang } // namespace
432*e7b1675dSTing-Kang Chang } // namespace internal
433*e7b1675dSTing-Kang Chang } // namespace tink
434*e7b1675dSTing-Kang Chang } // namespace crypto
435