summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2013-11-30 18:25:01 +0100
committerJay Berkenbilt <ejb@ql.org>2013-12-14 21:17:36 +0100
commit30287d2d655e1a9fe476477b6c74b62f816f37d6 (patch)
tree54b8088e9945e634d91060a413011e62ba35bb96
parent5e3bad2f86665b35155095b91a2d672fc7335870 (diff)
downloadqpdf-30287d2d655e1a9fe476477b6c74b62f816f37d6.tar.zst
Allow OS-provided secure random to be disabled
-rw-r--r--ChangeLog7
-rw-r--r--README46
-rw-r--r--configure.ac19
-rw-r--r--libqpdf/SecureRandomDataProvider.cc18
-rw-r--r--libtests/random.cc3
-rw-r--r--manual/qpdf-manual.xml25
6 files changed, 105 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 84b8297c..fc880375 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,13 @@
OS-provided or insecure random number generation. See
documentation for 5.1.0 for details.
+ * Add configure option --enable-os-secure-random (enabled by
+ default). Pass --disable-os-secure-random or define
+ SKIP_OS_SECURE_RANDOM to avoid attempts to use the operating
+ system-provided secure random number generation. This can be
+ especially useful on Windows if you wish to avoid any dependency
+ on Microsoft's cryptography system.
+
2013-11-29 Jay Berkenbilt <ejb@ql.org>
* If NO_GET_ENVIRONMENT is #defined, for Windows only,
diff --git a/README b/README
index 5373a61e..8f394a1c 100644
--- a/README
+++ b/README
@@ -196,17 +196,41 @@ packages for qpdf enable this option, for example.
Random Number Generation
========================
-When the qpdf detects either the Windows cryptography API or the
-existence of /dev/urandom, /dev/arandom, or /dev/random, it uses them
-to generate cryptography secure random numbers. If none of these
-conditions are true, the build will fail with an error. It is
-possible to configure qpdf with the --enable-insecure-random option,
-in which case it will generate random numbers with stdlib's random()
-or rand() calls instead. These random numbers are not cryptography
-secure, but the qpdf library is fully functional using them. Using
-non-secure random numbers means that it's easier in some cases to
-guess encryption keys. If you're not generating encrypted files,
-there's no advantage to using secure random numbers.
+By default, when the qpdf detects either the Windows cryptography API
+or the existence of /dev/urandom, /dev/arandom, or /dev/random, it
+uses them to generate cryptography secure random numbers. If none of
+these conditions are true, the build will fail with an error. This
+behavior can be modified in several ways:
+
+ * If you configure with --disable-os-secure-random or define
+ SKIP_OS_SECURE_RANDOM, qpdf will not attempt to use Windows
+ cryptography or the random device. You must either supply your own
+ random data provider or allow use of insecure random numbers.
+
+ * If you configure qpdf with the --enable-insecure-random option or
+ define USE_INSECURE_RANDOM, qpdf will try insecure random numbers
+ if OS-provided secure random numbers are disabled. This is not a
+ fallback. In order for insecure random numbers to be used, you
+ must also disable OS secure random numbers since, otherwise,
+ failure to find OS secure random numbers is a compile error. The
+ insecure random number source is stdlib's random() or rand() calls.
+ These random numbers are not cryptography secure, but the qpdf
+ library is fully functional using them. Using non-secure random
+ numbers means that it's easier in some cases to guess encryption
+ keys. If you're not generating encrypted files, there's no
+ advantage to using secure random numbers.
+
+ * In all cases, you may supply your own random data provider. To do
+ this, derive a class from qpdf/RandomDataProvider (since 5.1.0) and
+ call QUtil::setRandomDataProvider before you create any QPDF
+ objects. If you supply your own random data provider, it will
+ always be used even if support for one of the other random data
+ providers is compiled in. If you wish to avoid any possibility of
+ your build of qpdf from using anything but a user-supplied random
+ data provider, you can define SKIP_OS_SECURE_RANDOM and not
+ USE_INSECURE_RANDOM. In this case, qpdf will throw a runtime error
+ if any attempt is made to generate random numbers and no random
+ data provider has been supplied.
If you are building qpdf on a platform that qpdf doesn't know how to
generate secure random numbers on, a patch would be welcome.
diff --git a/configure.ac b/configure.ac
index 683b239f..9b53403b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,11 +26,26 @@ AC_ARG_ENABLE(insecure-random,
fi], [qpdf_INSECURE_RANDOM=0])
if test "$qpdf_INSECURE_RANDOM" = "1"; then
AC_MSG_RESULT(yes)
- AC_DEFINE([USE_INSECURE_RANDOM], [1], [Whether to use inscure random numbers])
+ AC_DEFINE([USE_INSECURE_RANDOM], [1], [Whether to use insecure random numbers])
else
AC_MSG_RESULT(no)
fi
+AC_ARG_ENABLE(os-secure-random,
+ AS_HELP_STRING([--enable-os-secure-random],
+ [whether to try to use OS-provided secure random numbers (default is yes)]),
+ [if test "$enableval" = "yes"; then
+ qpdf_OS_SECURE_RANDOM=1;
+ else
+ qpdf_OS_SECURE_RANDOM=0;
+ fi], [qpdf_OS_SECURE_RANDOM=1])
+if test "$qpdf_OS_SECURE_RANDOM" = "1"; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+ AC_DEFINE([SKIP_OS_SECURE_RANDOM], [1], [Whether to suppres use of OS-provided secure random numbers])
+fi
+
AX_RANDOM_DEVICE
USE_EXTERNAL_LIBS=0
@@ -71,7 +86,7 @@ if test "$BUILD_INTERNAL_LIBS" = "0"; then
AC_SEARCH_LIBS(pcre_compile,pcre,,[MISSING_PCRE=1; MISSING_ANY=1])
fi
-if test "x$qpdf_INSECURE_RANDOM" != "x1"; then
+if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then
OLIBS=$LIBS
LIBS="$LIBS Advapi32.lib"
AC_MSG_CHECKING(for Advapi32 library)
diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc
index 14ef55a7..2870ab98 100644
--- a/libqpdf/SecureRandomDataProvider.cc
+++ b/libqpdf/SecureRandomDataProvider.cc
@@ -19,6 +19,22 @@ SecureRandomDataProvider::~SecureRandomDataProvider()
{
}
+#ifdef SKIP_OS_SECURE_RANDOM
+
+void
+SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len)
+{
+ throw std::logic_error("SecureRandomDataProvider::provideRandomData called when support was not compiled in");
+}
+
+RandomDataProvider*
+SecureRandomDataProvider::getInstance()
+{
+ return 0;
+}
+
+#else
+
#ifdef _WIN32
class WindowsCryptProvider
@@ -84,3 +100,5 @@ SecureRandomDataProvider::getInstance()
static SecureRandomDataProvider instance;
return &instance;
}
+
+#endif
diff --git a/libtests/random.cc b/libtests/random.cc
index 644fdd91..0099844b 100644
--- a/libtests/random.cc
+++ b/libtests/random.cc
@@ -1,4 +1,5 @@
#include <qpdf/QUtil.hh>
+#include <qpdf/qpdf-config.h>
#include <qpdf/InsecureRandomDataProvider.hh>
#include <qpdf/SecureRandomDataProvider.hh>
#include <iostream>
@@ -36,6 +37,7 @@ int main()
{
std::cout << "fail: two insecure randoms were the same\n";
}
+#ifndef SKIP_OS_SECURE_RANDOM
SecureRandomDataProvider srdp;
srdp.provideRandomData(reinterpret_cast<unsigned char*>(&r1), 4);
srdp.provideRandomData(reinterpret_cast<unsigned char*>(&r2), 4);
@@ -43,6 +45,7 @@ int main()
{
std::cout << "fail: two secure randoms were the same\n";
}
+#endif
BogusRandomDataProvider brdp;
QUtil::setRandomDataProvider(&brdp);
r1 = QUtil::random();
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index 8d68db9d..2cb6be5d 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -1851,6 +1851,31 @@ outfile.pdf</option>
preserved as clear-text if it is that way in the original file.
</para>
</sect1>
+ <sect1 id="ref.random-numbers">
+ <title>Random Number Generation</title>
+ <para>
+ QPDF generates random numbers to support generation of encrypted
+ data. Versions prior to 5.0.1 used <function>random</function> or
+ <function>rand</function> from <filename>stdlib</filename> to
+ generate random numbers. Version 5.0.1, if available, used
+ operating system-provided secure random number generation instead,
+ enabling use of <filename>stdlib</filename> random number
+ generation only if enabled by a compile-time option. Starting in
+ version 5.1.0, use of insecure random numbers was disabled unless
+ enabled at compile time. Starting in version 5.1.0, it is also
+ possible for you to disable use of OS-provided secure random
+ numbers. This is especially useful on Windows if you want to
+ avoid a dependency on Microsoft's cryptography API. In this case,
+ you must provide your own random data provider. Regardless of how
+ you compile qpdf, starting in version 5.1.0, it is possible for
+ you to provide your own random data provider at runtime. This
+ would enable you to use some software-based secure pseudorandom
+ number generator and to avoid use of whatever the operating system
+ provides. For details on how to do this, please refer to the
+ top-level README file in the source distribution and to comments
+ in <filename>QUtil.hh</filename>.
+ </para>
+ </sect1>
<sect1 id="ref.adding-and-remove-pages">
<title>Adding and Removing Pages</title>
<para>