Commit 87765bace9be7d8105b3d148dd389a612299275b

Authored by Jay Berkenbilt
1 parent 2b4dcb33

Move random number device check to runtime (fixes #1022)

Having it at compile time breaks cross-compilation and isn't really
right anyway.
ChangeLog
  1 +2023-09-03 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Move check for random number device to runtime instead of
  4 + compile time. Since, by default, the crypto provider provides
  5 + random numbers, runtime determinination of a random number device
  6 + is usually not needed. Fixes #1022.
  7 +
1 8 2023-09-02 Jay Berkenbilt <ejb@ql.org>
2 9  
3 10 * Bug fix from M. Holger: allow fix-qdf to read from pipe. Fixes #1010.
... ...
libqpdf/CMakeLists.txt
... ... @@ -320,8 +320,6 @@ check_symbol_exists(fseeko &quot;stdio.h&quot; HAVE_FSEEKO)
320 320 check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64)
321 321 check_symbol_exists(localtime_r "time.h" HAVE_LOCALTIME_R)
322 322 check_symbol_exists(random "stdlib.h" HAVE_RANDOM)
323   -find_file(RANDOM_DEVICE
324   - "urandom" "arandom" "arandom" PATHS "/dev" NO_DEFAULT_PATH)
325 323  
326 324 check_c_source_compiles(
327 325 "#include <time.h>
... ...
libqpdf/SecureRandomDataProvider.cc
... ... @@ -87,24 +87,27 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len)
87 87 throw std::runtime_error("unable to generate secure random data");
88 88 }
89 89  
90   -# elif defined(RANDOM_DEVICE)
91   -
92   - // Optimization: wrap the file open and close in a class so that the file is closed in a
93   - // destructor, then make this static to keep the file handle open. Only do this if it can be
94   - // done in a thread-safe fashion.
95   - FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb");
96   - size_t fr = fread(data, 1, len, f);
97   - fclose(f);
  90 +# else
  91 + static std::unique_ptr<QUtil::FileCloser> random_device = []() {
  92 + FILE* f = fopen("/dev/urandom", "rb");
  93 + if (f == nullptr) {
  94 + f = fopen("/dev/arandom", "rb");
  95 + }
  96 + if (f == nullptr) {
  97 + f = fopen("/dev/random", "rb");
  98 + }
  99 + if (f == nullptr) {
  100 + throw std::runtime_error("unable to find device in /dev for generating random numbers");
  101 + }
  102 + return std::make_unique<QUtil::FileCloser>(f);
  103 + }();
  104 +
  105 + size_t fr = fread(data, 1, len, random_device->f);
98 106 if (fr != len) {
99 107 throw std::runtime_error(
100   - "unable to read " + std::to_string(len) + " bytes from " + std::string(RANDOM_DEVICE));
  108 + "unable to read " + std::to_string(len) + " bytes from random number device");
101 109 }
102 110  
103   -# else
104   -
105   -# error \
106   - "Don't know how to generate secure random numbers on this platform. See random number generation in the top-level README.md"
107   -
108 111 # endif
109 112 }
110 113  
... ...
libqpdf/qpdf/qpdf-config.h.in
... ... @@ -24,8 +24,5 @@
24 24 #cmakedefine HAVE_MALLOC_INFO 1
25 25 #cmakedefine HAVE_OPEN_MEMSTREAM 1
26 26  
27   -/* system random device (e.g. /dev/random) if any */
28   -#cmakedefine RANDOM_DEVICE "${RANDOM_DEVICE}"
29   -
30 27 /* bytes in the size_t type */
31 28 #cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T}
... ...