Commit 30287d2d655e1a9fe476477b6c74b62f816f37d6

Authored by Jay Berkenbilt
1 parent 5e3bad2f

Allow OS-provided secure random to be disabled

ChangeLog
... ... @@ -9,6 +9,13 @@
9 9 OS-provided or insecure random number generation. See
10 10 documentation for 5.1.0 for details.
11 11  
  12 + * Add configure option --enable-os-secure-random (enabled by
  13 + default). Pass --disable-os-secure-random or define
  14 + SKIP_OS_SECURE_RANDOM to avoid attempts to use the operating
  15 + system-provided secure random number generation. This can be
  16 + especially useful on Windows if you wish to avoid any dependency
  17 + on Microsoft's cryptography system.
  18 +
12 19 2013-11-29 Jay Berkenbilt <ejb@ql.org>
13 20  
14 21 * If NO_GET_ENVIRONMENT is #defined, for Windows only,
... ...
... ... @@ -196,17 +196,41 @@ packages for qpdf enable this option, for example.
196 196 Random Number Generation
197 197 ========================
198 198  
199   -When the qpdf detects either the Windows cryptography API or the
200   -existence of /dev/urandom, /dev/arandom, or /dev/random, it uses them
201   -to generate cryptography secure random numbers. If none of these
202   -conditions are true, the build will fail with an error. It is
203   -possible to configure qpdf with the --enable-insecure-random option,
204   -in which case it will generate random numbers with stdlib's random()
205   -or rand() calls instead. These random numbers are not cryptography
206   -secure, but the qpdf library is fully functional using them. Using
207   -non-secure random numbers means that it's easier in some cases to
208   -guess encryption keys. If you're not generating encrypted files,
209   -there's no advantage to using secure random numbers.
  199 +By default, when the qpdf detects either the Windows cryptography API
  200 +or the existence of /dev/urandom, /dev/arandom, or /dev/random, it
  201 +uses them to generate cryptography secure random numbers. If none of
  202 +these conditions are true, the build will fail with an error. This
  203 +behavior can be modified in several ways:
  204 +
  205 + * If you configure with --disable-os-secure-random or define
  206 + SKIP_OS_SECURE_RANDOM, qpdf will not attempt to use Windows
  207 + cryptography or the random device. You must either supply your own
  208 + random data provider or allow use of insecure random numbers.
  209 +
  210 + * If you configure qpdf with the --enable-insecure-random option or
  211 + define USE_INSECURE_RANDOM, qpdf will try insecure random numbers
  212 + if OS-provided secure random numbers are disabled. This is not a
  213 + fallback. In order for insecure random numbers to be used, you
  214 + must also disable OS secure random numbers since, otherwise,
  215 + failure to find OS secure random numbers is a compile error. The
  216 + insecure random number source is stdlib's random() or rand() calls.
  217 + These random numbers are not cryptography secure, but the qpdf
  218 + library is fully functional using them. Using non-secure random
  219 + numbers means that it's easier in some cases to guess encryption
  220 + keys. If you're not generating encrypted files, there's no
  221 + advantage to using secure random numbers.
  222 +
  223 + * In all cases, you may supply your own random data provider. To do
  224 + this, derive a class from qpdf/RandomDataProvider (since 5.1.0) and
  225 + call QUtil::setRandomDataProvider before you create any QPDF
  226 + objects. If you supply your own random data provider, it will
  227 + always be used even if support for one of the other random data
  228 + providers is compiled in. If you wish to avoid any possibility of
  229 + your build of qpdf from using anything but a user-supplied random
  230 + data provider, you can define SKIP_OS_SECURE_RANDOM and not
  231 + USE_INSECURE_RANDOM. In this case, qpdf will throw a runtime error
  232 + if any attempt is made to generate random numbers and no random
  233 + data provider has been supplied.
210 234  
211 235 If you are building qpdf on a platform that qpdf doesn't know how to
212 236 generate secure random numbers on, a patch would be welcome.
... ...
configure.ac
... ... @@ -26,11 +26,26 @@ AC_ARG_ENABLE(insecure-random,
26 26 fi], [qpdf_INSECURE_RANDOM=0])
27 27 if test "$qpdf_INSECURE_RANDOM" = "1"; then
28 28 AC_MSG_RESULT(yes)
29   - AC_DEFINE([USE_INSECURE_RANDOM], [1], [Whether to use inscure random numbers])
  29 + AC_DEFINE([USE_INSECURE_RANDOM], [1], [Whether to use insecure random numbers])
30 30 else
31 31 AC_MSG_RESULT(no)
32 32 fi
33 33  
  34 +AC_ARG_ENABLE(os-secure-random,
  35 + AS_HELP_STRING([--enable-os-secure-random],
  36 + [whether to try to use OS-provided secure random numbers (default is yes)]),
  37 + [if test "$enableval" = "yes"; then
  38 + qpdf_OS_SECURE_RANDOM=1;
  39 + else
  40 + qpdf_OS_SECURE_RANDOM=0;
  41 + fi], [qpdf_OS_SECURE_RANDOM=1])
  42 +if test "$qpdf_OS_SECURE_RANDOM" = "1"; then
  43 + AC_MSG_RESULT(yes)
  44 +else
  45 + AC_MSG_RESULT(no)
  46 + AC_DEFINE([SKIP_OS_SECURE_RANDOM], [1], [Whether to suppres use of OS-provided secure random numbers])
  47 +fi
  48 +
34 49 AX_RANDOM_DEVICE
35 50  
36 51 USE_EXTERNAL_LIBS=0
... ... @@ -71,7 +86,7 @@ if test &quot;$BUILD_INTERNAL_LIBS&quot; = &quot;0&quot;; then
71 86 AC_SEARCH_LIBS(pcre_compile,pcre,,[MISSING_PCRE=1; MISSING_ANY=1])
72 87 fi
73 88  
74   -if test "x$qpdf_INSECURE_RANDOM" != "x1"; then
  89 +if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then
75 90 OLIBS=$LIBS
76 91 LIBS="$LIBS Advapi32.lib"
77 92 AC_MSG_CHECKING(for Advapi32 library)
... ...
libqpdf/SecureRandomDataProvider.cc
... ... @@ -19,6 +19,22 @@ SecureRandomDataProvider::~SecureRandomDataProvider()
19 19 {
20 20 }
21 21  
  22 +#ifdef SKIP_OS_SECURE_RANDOM
  23 +
  24 +void
  25 +SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len)
  26 +{
  27 + throw std::logic_error("SecureRandomDataProvider::provideRandomData called when support was not compiled in");
  28 +}
  29 +
  30 +RandomDataProvider*
  31 +SecureRandomDataProvider::getInstance()
  32 +{
  33 + return 0;
  34 +}
  35 +
  36 +#else
  37 +
22 38 #ifdef _WIN32
23 39  
24 40 class WindowsCryptProvider
... ... @@ -84,3 +100,5 @@ SecureRandomDataProvider::getInstance()
84 100 static SecureRandomDataProvider instance;
85 101 return &instance;
86 102 }
  103 +
  104 +#endif
... ...
libtests/random.cc
1 1 #include <qpdf/QUtil.hh>
  2 +#include <qpdf/qpdf-config.h>
2 3 #include <qpdf/InsecureRandomDataProvider.hh>
3 4 #include <qpdf/SecureRandomDataProvider.hh>
4 5 #include <iostream>
... ... @@ -36,6 +37,7 @@ int main()
36 37 {
37 38 std::cout << "fail: two insecure randoms were the same\n";
38 39 }
  40 +#ifndef SKIP_OS_SECURE_RANDOM
39 41 SecureRandomDataProvider srdp;
40 42 srdp.provideRandomData(reinterpret_cast<unsigned char*>(&r1), 4);
41 43 srdp.provideRandomData(reinterpret_cast<unsigned char*>(&r2), 4);
... ... @@ -43,6 +45,7 @@ int main()
43 45 {
44 46 std::cout << "fail: two secure randoms were the same\n";
45 47 }
  48 +#endif
46 49 BogusRandomDataProvider brdp;
47 50 QUtil::setRandomDataProvider(&brdp);
48 51 r1 = QUtil::random();
... ...
manual/qpdf-manual.xml
... ... @@ -1851,6 +1851,31 @@ outfile.pdf&lt;/option&gt;
1851 1851 preserved as clear-text if it is that way in the original file.
1852 1852 </para>
1853 1853 </sect1>
  1854 + <sect1 id="ref.random-numbers">
  1855 + <title>Random Number Generation</title>
  1856 + <para>
  1857 + QPDF generates random numbers to support generation of encrypted
  1858 + data. Versions prior to 5.0.1 used <function>random</function> or
  1859 + <function>rand</function> from <filename>stdlib</filename> to
  1860 + generate random numbers. Version 5.0.1, if available, used
  1861 + operating system-provided secure random number generation instead,
  1862 + enabling use of <filename>stdlib</filename> random number
  1863 + generation only if enabled by a compile-time option. Starting in
  1864 + version 5.1.0, use of insecure random numbers was disabled unless
  1865 + enabled at compile time. Starting in version 5.1.0, it is also
  1866 + possible for you to disable use of OS-provided secure random
  1867 + numbers. This is especially useful on Windows if you want to
  1868 + avoid a dependency on Microsoft's cryptography API. In this case,
  1869 + you must provide your own random data provider. Regardless of how
  1870 + you compile qpdf, starting in version 5.1.0, it is possible for
  1871 + you to provide your own random data provider at runtime. This
  1872 + would enable you to use some software-based secure pseudorandom
  1873 + number generator and to avoid use of whatever the operating system
  1874 + provides. For details on how to do this, please refer to the
  1875 + top-level README file in the source distribution and to comments
  1876 + in <filename>QUtil.hh</filename>.
  1877 + </para>
  1878 + </sect1>
1854 1879 <sect1 id="ref.adding-and-remove-pages">
1855 1880 <title>Adding and Removing Pages</title>
1856 1881 <para>
... ...