Test lookup and creation by RSA parameters in evp_test
In preparation for when we add RSA-PSS and want to test that those also
import properly.
Change-Id: I50d35d0bbd0d2240a7609d9efa828578360969d4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81649
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc
index 1088869..2df9cc4 100644
--- a/crypto/evp/evp_test.cc
+++ b/crypto/evp/evp_test.cc
@@ -109,6 +109,28 @@
enum class KeyRole { kPublic, kPrivate };
+static void CheckRSAParam(FileTest *t, std::string_view attr_name,
+ const EVP_PKEY *pkey,
+ const BIGNUM *(*rsa_getter)(const RSA *)) {
+ SCOPED_TRACE(attr_name);
+ if (t->HasAttribute(attr_name)) {
+ bssl::UniquePtr<BIGNUM> want =
+ HexToBIGNUM(t->GetAttributeOrDie(attr_name).c_str());
+ ASSERT_TRUE(want);
+
+ const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ ASSERT_TRUE(rsa);
+ const BIGNUM *got = rsa_getter(rsa);
+ ASSERT_TRUE(got);
+ EXPECT_EQ(BN_cmp(want.get(), got), 0)
+ << "wanted: " << BIGNUMToHex(want.get())
+ << "\ngot: " << BIGNUMToHex(got);
+ }
+ // We have many test RSA keys so, for now, don't require that all RSA keys
+ // list out these parameters. That is, the absence of an RSA parameter does
+ // not currently assert that we omit them.
+}
+
static bool ImportKey(FileTest *t, KeyMap *key_map, KeyRole key_role) {
auto format_name = key_role == KeyRole::kPublic ? "spki" : "pkcs8";
auto parse_func = key_role == KeyRole::kPublic ? &EVP_parse_public_key
@@ -165,6 +187,61 @@
keys.emplace_back("raw private", std::move(new_key));
}
+ // Import RSA key from parameters.
+ if (key_type == EVP_PKEY_RSA) {
+ if (key_role == KeyRole::kPublic && t->HasAttribute("RSAParamN") &&
+ t->HasAttribute("RSAParamE")) {
+ bssl::UniquePtr<BIGNUM> n =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamN").c_str());
+ bssl::UniquePtr<BIGNUM> e =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamE").c_str());
+ if (n == nullptr || e == nullptr) {
+ return false;
+ }
+ bssl::UniquePtr<RSA> rsa(RSA_new_public_key(n.get(), e.get()));
+ new_key.reset(EVP_PKEY_new());
+ if (rsa == nullptr || new_key == nullptr ||
+ !EVP_PKEY_set1_RSA(new_key.get(), rsa.get())) {
+ return false;
+ }
+ keys.emplace_back("RSA public params", std::move(new_key));
+ }
+ if (key_role == KeyRole::kPrivate && t->HasAttribute("RSAParamN") &&
+ t->HasAttribute("RSAParamE") && t->HasAttribute("RSAParamD") &&
+ t->HasAttribute("RSAParamP") && t->HasAttribute("RSAParamQ") &&
+ t->HasAttribute("RSAParamDMP1") && t->HasAttribute("RSAParamDMQ1") &&
+ t->HasAttribute("RSAParamIQMP")) {
+ bssl::UniquePtr<BIGNUM> n =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamN").c_str());
+ bssl::UniquePtr<BIGNUM> e =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamE").c_str());
+ bssl::UniquePtr<BIGNUM> d =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamD").c_str());
+ bssl::UniquePtr<BIGNUM> p =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamP").c_str());
+ bssl::UniquePtr<BIGNUM> q =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamQ").c_str());
+ bssl::UniquePtr<BIGNUM> dmp1 =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamDMP1").c_str());
+ bssl::UniquePtr<BIGNUM> dmq1 =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamDMQ1").c_str());
+ bssl::UniquePtr<BIGNUM> iqmp =
+ HexToBIGNUM(t->GetAttributeOrDie("RSAParamIQMP").c_str());
+ if (n == nullptr || e == nullptr) {
+ return false;
+ }
+ bssl::UniquePtr<RSA> rsa(RSA_new_private_key(n.get(), e.get(), d.get(),
+ p.get(), q.get(), dmp1.get(),
+ dmq1.get(), iqmp.get()));
+ new_key.reset(EVP_PKEY_new());
+ if (rsa == nullptr || new_key == nullptr ||
+ !EVP_PKEY_set1_RSA(new_key.get(), rsa.get())) {
+ return false;
+ }
+ keys.emplace_back("RSA private params", std::move(new_key));
+ }
+ }
+
// Check properties of the keys.
for (const auto &[name, pkey] : keys) {
SCOPED_TRACE(name);
@@ -183,6 +260,15 @@
EXPECT_EQ(EVP_PKEY_get_ec_curve_nid(pkey.get()), NID_undef);
}
+ CheckRSAParam(t, "RSAParamN", pkey.get(), RSA_get0_n);
+ CheckRSAParam(t, "RSAParamE", pkey.get(), RSA_get0_e);
+ CheckRSAParam(t, "RSAParamD", pkey.get(), RSA_get0_d);
+ CheckRSAParam(t, "RSAParamP", pkey.get(), RSA_get0_p);
+ CheckRSAParam(t, "RSAParamQ", pkey.get(), RSA_get0_q);
+ CheckRSAParam(t, "RSAParamDMP1", pkey.get(), RSA_get0_dmp1);
+ CheckRSAParam(t, "RSAParamDMQ1", pkey.get(), RSA_get0_dmq1);
+ CheckRSAParam(t, "RSAParamIQMP", pkey.get(), RSA_get0_iqmp);
+
// All keys must compare equal.
EXPECT_EQ(EVP_PKEY_cmp(pkey.get(), keys.front().second.get()), 1);
diff --git a/crypto/evp/test/rsa_tests.txt b/crypto/evp/test/rsa_tests.txt
index d12ce21..4e28c86 100644
--- a/crypto/evp/test/rsa_tests.txt
+++ b/crypto/evp/test/rsa_tests.txt
@@ -5,12 +5,22 @@
Type = RSA
Bits = 2048
Input = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5
+RSAParamN = cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f
+RSAParamE = 010001
+RSAParamD = 60297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd1870531
+RSAParamP = f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be3
+RSAParamQ = d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a5
+RSAParamDMP1 = 21f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec432061
+RSAParamDMQ1 = 1f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd59
+RSAParamIQMP = 4d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5
# The public half of the same key encoded as a SubjectPublicKeyInfo.
PublicKey = RSA-2048-SPKI
Type = RSA
Bits = 2048
Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
+RSAParamN = cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f
+RSAParamE = 010001
# The same key but with a negative RSA modulus.
PublicKey = RSA-2048-SPKI-Negative
diff --git a/crypto/test/test_util.cc b/crypto/test/test_util.cc
index 265de03..28ab074 100644
--- a/crypto/test/test_util.cc
+++ b/crypto/test/test_util.cc
@@ -89,3 +89,11 @@
BN_hex2bn(&bn, hex);
return bssl::UniquePtr<BIGNUM>(bn);
}
+
+std::string BIGNUMToHex(const BIGNUM *bn) {
+ bssl::UniquePtr<char> hex(BN_bn2hex(bn));
+ if (hex == nullptr) {
+ return "error";
+ }
+ return hex.get();
+}
diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h
index bdd3fcf..4433cc3 100644
--- a/crypto/test/test_util.h
+++ b/crypto/test/test_util.h
@@ -80,5 +80,8 @@
// returns it as a |BIGNUM|, or nullptr on error.
bssl::UniquePtr<BIGNUM> HexToBIGNUM(const char *hex);
+// BIGNUMToHex returns |bn| as a hexadecimal, big-endian, unsigned integer.
+std::string BIGNUMToHex(const BIGNUM *bn);
+
#endif // OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H