From 87765bace9be7d8105b3d148dd389a612299275b Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 3 Sep 2023 09:35:28 -0400 Subject: Move random number device check to runtime (fixes #1022) Having it at compile time breaks cross-compilation and isn't really right anyway. --- libqpdf/SecureRandomDataProvider.cc | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'libqpdf/SecureRandomDataProvider.cc') diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc index 64199903..e5007d62 100644 --- a/libqpdf/SecureRandomDataProvider.cc +++ b/libqpdf/SecureRandomDataProvider.cc @@ -87,24 +87,27 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len) throw std::runtime_error("unable to generate secure random data"); } -# elif defined(RANDOM_DEVICE) - - // Optimization: wrap the file open and close in a class so that the file is closed in a - // destructor, then make this static to keep the file handle open. Only do this if it can be - // done in a thread-safe fashion. - FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb"); - size_t fr = fread(data, 1, len, f); - fclose(f); +# else + static std::unique_ptr random_device = []() { + FILE* f = fopen("/dev/urandom", "rb"); + if (f == nullptr) { + f = fopen("/dev/arandom", "rb"); + } + if (f == nullptr) { + f = fopen("/dev/random", "rb"); + } + if (f == nullptr) { + throw std::runtime_error("unable to find device in /dev for generating random numbers"); + } + return std::make_unique(f); + }(); + + size_t fr = fread(data, 1, len, random_device->f); if (fr != len) { throw std::runtime_error( - "unable to read " + std::to_string(len) + " bytes from " + std::string(RANDOM_DEVICE)); + "unable to read " + std::to_string(len) + " bytes from random number device"); } -# else - -# error \ - "Don't know how to generate secure random numbers on this platform. See random number generation in the top-level README.md" - # endif } -- cgit v1.2.3-54-g00ecf