From e55b32ddff4e1d4f580f196485944bcbb5218b70 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 22 Jun 2017 10:53:25 -0400 Subject: [PATCH] Don't crash when decrypting with public keys. Public and private RSA keys have the same type in OpenSSL, so it's probably prudent for us to catch this case with an error rather than crash. (As we do if you, say, configure RSA-PSS parameters on an Ed25519 EVP_PKEY.) Bindings libraries, in particular, tend to hit this sort of then when their callers do silly things. Change-Id: I2555e9bfe716a9f15273abd887a8459c682432dd Reviewed-on: https://boringssl-review.googlesource.com/17325 Commit-Queue: Adam Langley Reviewed-by: Adam Langley CQ-Verified: CQ bot account: commit-bot@chromium.org --- crypto/fipsmodule/rsa/rsa_impl.c | 5 +++++ crypto/rsa_extra/rsa_test.cc | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index 342f1c2c..c79f8649 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -533,6 +533,11 @@ err: int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { + if (rsa->n == NULL || rsa->d == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + BIGNUM *f, *result; BN_CTX *ctx = NULL; unsigned blinding_index = 0; diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc index 162ac055..1cc71eab 100644 --- a/crypto/rsa_extra/rsa_test.cc +++ b/crypto/rsa_extra/rsa_test.cc @@ -697,6 +697,22 @@ TEST(RSATest, BlindingDisabled) { RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig, sig_len, rsa.get())); } +// Test that decrypting with a public key fails gracefully rather than crashing. +TEST(RSATest, DecryptPublic) { + bssl::UniquePtr pub( + RSA_public_key_from_bytes(kFIPSPublicKey, sizeof(kFIPSPublicKey) - 1)); + ASSERT_TRUE(pub); + ASSERT_EQ(1024u / 8u, RSA_size(pub.get())); + + size_t len; + uint8_t in[1024 / 8] = {0}, out[1024 / 8]; + EXPECT_FALSE(RSA_decrypt(pub.get(), &len, out, sizeof(out), in, sizeof(in), + RSA_PKCS1_PADDING)); + uint32_t err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); +} + #if !defined(BORINGSSL_SHARED_LIBRARY) TEST(RSATest, SqrtTwo) { bssl::UniquePtr sqrt(BN_new()), pow2(BN_new());