Commit 30287d2d655e1a9fe476477b6c74b62f816f37d6
1 parent
5e3bad2f
Allow OS-provided secure random to be disabled
Showing
6 changed files
with
105 additions
and
13 deletions
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, | ... | ... |
README
| ... | ... | @@ -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 "$BUILD_INTERNAL_LIBS" = "0"; 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</option> |
| 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> | ... | ... |