aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/SecureRandomDataProvider.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2023-09-03 15:35:28 +0200
committerJay Berkenbilt <ejb@ql.org>2023-09-03 15:36:13 +0200
commit87765bace9be7d8105b3d148dd389a612299275b (patch)
tree8eab43ac1c2d19e59afa642731d03936b224f039 /libqpdf/SecureRandomDataProvider.cc
parent2b4dcb33aa3cc130241894df78e2b67bbe5c99b8 (diff)
downloadqpdf-87765bace9be7d8105b3d148dd389a612299275b.tar.zst
Move random number device check to runtime (fixes #1022)
Having it at compile time breaks cross-compilation and isn't really right anyway.
Diffstat (limited to 'libqpdf/SecureRandomDataProvider.cc')
-rw-r--r--libqpdf/SecureRandomDataProvider.cc31
1 files changed, 17 insertions, 14 deletions
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<QUtil::FileCloser> 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<QUtil::FileCloser>(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
}