Add OpenSSL/BoringSSL crypto provider

Fixes qpdf/qpdf#417
This commit is contained in:
Dean Scarff 2020-04-06 13:19:56 +10:00 committed by Jay Berkenbilt
parent 0837932164
commit 0f2507234f
10 changed files with 518 additions and 6 deletions

View File

@ -30,9 +30,7 @@ QPDF requires a C++ compiler that supports C++-11.
QPDF depends on the external libraries [zlib](https://www.zlib.net/) and [jpeg](https://www.ijg.org/files/). The [libjpeg-turbo](https://libjpeg-turbo.org/) library is also known to work since it is compatible with the regular jpeg library, and QPDF doesn't use any interfaces that aren't present in the straight jpeg8 API. These are part of every Linux distribution and are readily available. Download information appears in the documentation. For Windows, you can download pre-built binary versions of these libraries for some compilers; see [README-windows.md](README-windows.md) for additional details.
If the optional GnuTLS crypto provider is enabled,
then [GnuTLS](https://www.gnutls.org/) is also required. This is
discussed more in `Crypto providers` below.
Depending on which crypto providers are enabled, then [GnuTLS](https://www.gnutls.org/) and [OpenSSL](https://openssl.org) may also be required. This is discussed more in `Crypto providers` below.
# Licensing terms of embedded software
@ -46,6 +44,7 @@ As of version 9.1.0, qpdf can use different crypto implementations. These can be
Initially, the following providers are available:
* `native`: a native implementation where all the source is embedded in qpdf and no external dependencies are required
* `openssl`: an implementation that can use the OpenSSL (or BoringSSL) libraries to provide crypto; causes libqpdf to link with the OpenSSL library
* `gnutls`: an implementation that uses the GnuTLS library to provide crypto; causes libqpdf to link with the GnuTLS library
The default behavior is for ./configure to discover which other crypto providers can be supported based on available external libraries, to build all available crypto providers, and to use an external provider as the default over the native one. This behavior can be changed with the following flags to ./configure:

View File

@ -31,6 +31,7 @@ OBJDUMP=@OBJDUMP@
GENDEPS=@GENDEPS@
LIBTOOL=@LIBTOOL@
USE_CRYPTO_NATIVE=@USE_CRYPTO_NATIVE@
USE_CRYPTO_OPENSSL=@USE_CRYPTO_OPENSSL@
USE_CRYPTO_GNUTLS=@USE_CRYPTO_GNUTLS@
DOCBOOKX_DTD=@DOCBOOKX_DTD@
FOP=@FOP@

View File

@ -1,11 +1,11 @@
4db55494bcfbd5053f956d435416f30591a59bc24b1c4f4431d0b3da27a54ef7 configure.ac
3fa4ba7aa1286928e542cd2dd221ce43775e03c9689d82edd1cafc80bf51b0a5 configure.ac
d3f9ee6f6f0846888d9a10fd3dad2e4b1258be84205426cf04d7cef02d61dad7 aclocal.m4
2e4cd495837be1b8454a4d8aef541b000988634be89d9c05a9cf5de67dffef5e libqpdf/qpdf/qpdf-config.h.in
b0ce6d1dba8effa47d25154b2bb56eddafc997254a0f3f903cf9b6abffc03616 libqpdf/qpdf/qpdf-config.h.in
5297971a0ef90bcd5563eb3f7127a032bb76d3ae2af7258bf13479caf8983a60 m4/ax_cxx_compile_stdcxx.m4
35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4
6a1e4f8aa2902d7993300660c43e6ee479b4b6781ed7d5ef9c9f9f1cc46623b7 m4/libtool.m4
26fa3285c35dd6ab00ed1e466ba92a17e4655e01897731ec18a587a4cf5e4f8d m4/lt~obsolete.m4
e77ebba8361b36f14b4d0927173a034b98c5d05049697a9ded84d85eb99a7990 m4/ltoptions.m4
5a6735cda60e0ba0d1b706c0ef648f5d096298da46daefd9cdecdb6a0f4584d3 m4/ltsugar.m4
a27b754709de61575197bf5a980696c98ae49da3f92f0de8ee7f42dd543b7465 m4/ltversion.m4
26fa3285c35dd6ab00ed1e466ba92a17e4655e01897731ec18a587a4cf5e4f8d m4/lt~obsolete.m4
9fab676fae13feb97d5183a8ed86ae9398c76d21927c28bc59460d230f3e0884 m4/pkg.m4

201
configure vendored
View File

@ -646,6 +646,9 @@ DEFAULT_CRYPTO
USE_CRYPTO_GNUTLS
pc_gnutls_LIBS
pc_gnutls_CFLAGS
USE_CRYPTO_OPENSSL
pc_openssl_LIBS
pc_openssl_CFLAGS
USE_CRYPTO_NATIVE
WINDOWS_MAIN_XLINK_FLAGS
WINDOWS_WMAIN_XLINK_FLAGS
@ -785,6 +788,7 @@ enable_werror
enable_int_warnings
enable_implicit_crypto
enable_crypto_native
enable_crypto_openssl
enable_crypto_gnutls
with_default_crypto
enable_test_compare_images
@ -818,6 +822,8 @@ pc_zlib_CFLAGS
pc_zlib_LIBS
pc_libjpeg_CFLAGS
pc_libjpeg_LIBS
pc_openssl_CFLAGS
pc_openssl_LIBS
pc_gnutls_CFLAGS
pc_gnutls_LIBS'
@ -1474,6 +1480,8 @@ Optional Features:
are not explicitly requested; true by default
--enable-crypto-native whether to include support for native crypto
provider
--enable-crypto-openssl whether to include support for the BoringSSL crypto
provider
--enable-crypto-gnutls whether to include support for gnutls crypto
provider
--enable-test-compare-images
@ -1545,6 +1553,10 @@ Some influential environment variables:
C compiler flags for pc_libjpeg, overriding pkg-config
pc_libjpeg_LIBS
linker flags for pc_libjpeg, overriding pkg-config
pc_openssl_CFLAGS
C compiler flags for pc_openssl, overriding pkg-config
pc_openssl_LIBS
linker flags for pc_openssl, overriding pkg-config
pc_gnutls_CFLAGS
C compiler flags for pc_gnutls, overriding pkg-config
pc_gnutls_LIBS
@ -17650,6 +17662,190 @@ fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_openssl" >&5
$as_echo_n "checking for pc_openssl... " >&6; }
if test -n "$pc_openssl_CFLAGS"; then
pkg_cv_pc_openssl_CFLAGS="$pc_openssl_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
($PKG_CONFIG --exists --print-errors "openssl") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_pc_openssl_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$pc_openssl_LIBS"; then
pkg_cv_pc_openssl_LIBS="$pc_openssl_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
($PKG_CONFIG --exists --print-errors "openssl") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_pc_openssl_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
pc_openssl_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1`
else
pc_openssl_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$pc_openssl_PKG_ERRORS" >&5
OPENSSL_FOUND=0
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
OPENSSL_FOUND=0
else
pc_openssl_CFLAGS=$pkg_cv_pc_openssl_CFLAGS
pc_openssl_LIBS=$pkg_cv_pc_openssl_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
OPENSSL_FOUND=1
fi
if test "$OPENSSL_FOUND" = "0"; then
ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default"
if test "x$ac_cv_header_openssl_evp_h" = xyes; then :
OPENSSL_FOUND=1
else
OPENSSL_FOUND=0
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_DigestInit_ex" >&5
$as_echo_n "checking for library containing EVP_DigestInit_ex... " >&6; }
if ${ac_cv_search_EVP_DigestInit_ex+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char EVP_DigestInit_ex ();
int
main ()
{
return EVP_DigestInit_ex ();
;
return 0;
}
_ACEOF
for ac_lib in '' openssl; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_EVP_DigestInit_ex=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_EVP_DigestInit_ex+:} false; then :
break
fi
done
if ${ac_cv_search_EVP_DigestInit_ex+:} false; then :
else
ac_cv_search_EVP_DigestInit_ex=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_DigestInit_ex" >&5
$as_echo "$ac_cv_search_EVP_DigestInit_ex" >&6; }
ac_res=$ac_cv_search_EVP_DigestInit_ex
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
OPENSSL_FOUND=1
else
OPENSSL_FOUND=0
fi
fi
IMPLICIT_OPENSSL=0
USE_CRYPTO_OPENSSL=0
# Check whether --enable-crypto-openssl was given.
if test "${enable_crypto_openssl+set}" = set; then :
enableval=$enable_crypto_openssl; if test "$enableval" = "yes"; then
USE_CRYPTO_OPENSSL=1
else
USE_CRYPTO_OPENSSL=0
fi
else
IMPLICIT_OPENSSL=$IMPLICIT_CRYPTO
fi
if test "$IMPLICIT_OPENSSL" = "1"; then
USE_CRYPTO_OPENSSL=$OPENSSL_FOUND
if test "$USE_CRYPTO_OPENSSL" = "1"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: enabling openssl crypto provider since openssl is available" >&5
$as_echo "$as_me: enabling openssl crypto provider since openssl is available" >&6;}
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not enabling openssl crypto provider since openssl was not found" >&5
$as_echo "$as_me: not enabling openssl crypto provider since openssl was not found" >&6;}
fi
fi
if test "$USE_CRYPTO_OPENSSL" = "1" -a "$OPENSSL_FOUND" = "0"; then
as_fn_error $? "unable to use requested openssl crypto provider without openssl" "$LINENO" 5
fi
if test "$USE_CRYPTO_OPENSSL" = "1"; then
CFLAGS="$CFLAGS $pc_openssl_CFLAGS"
CXXFLAGS="$CXXFLAGS $pc_openssl_CXXFLAGS"
LIBS="$LIBS $pc_openssl_LIBS"
$as_echo "#define USE_CRYPTO_OPENSSL 1" >>confdefs.h
DEFAULT_CRYPTO=openssl
elif test "$OPENSSL_FOUND" = "1"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: not linking with openssl even though it is available" >&5
$as_echo "$as_me: not linking with openssl even though it is available" >&6;}
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_gnutls" >&5
$as_echo_n "checking for pc_gnutls... " >&6; }
@ -17858,6 +18054,11 @@ case "$DEFAULT_CRYPTO" in
bad_crypto=1
fi
;;
"openssl")
if test "$USE_CRYPTO_OPENSSL" != "1"; then
bad_crypto=1
fi
;;
"gnutls")
if test "$USE_CRYPTO_GNUTLS" != "1"; then
bad_crypto=1

View File

@ -513,6 +513,53 @@ if test "$USE_CRYPTO_NATIVE" = "1"; then
DEFAULT_CRYPTO=native
fi
dnl If the openssl/BoringSSL provider is explicitly requested, require openssl
dnl If the openssl provider is not explicitly disabled, enable it if
dnl openssl is available. If the openssl provider is explicitly
dnl disabled, do not link with openssl even if present.
PKG_CHECK_MODULES([pc_openssl], [openssl], [OPENSSL_FOUND=1], [OPENSSL_FOUND=0])
if test "$OPENSSL_FOUND" = "0"; then
AC_CHECK_HEADER([openssl/evp.h],[OPENSSL_FOUND=1],[OPENSSL_FOUND=0])
AC_SEARCH_LIBS(EVP_DigestInit_ex,openssl,[OPENSSL_FOUND=1],[OPENSSL_FOUND=0])
fi
IMPLICIT_OPENSSL=0
USE_CRYPTO_OPENSSL=0
AC_SUBST(USE_CRYPTO_OPENSSL)
AC_ARG_ENABLE(crypto-openssl,
AS_HELP_STRING([--enable-crypto-openssl],
[whether to include support for the BoringSSL crypto provider]),
[if test "$enableval" = "yes"; then
USE_CRYPTO_OPENSSL=1
else
USE_CRYPTO_OPENSSL=0
fi],
[IMPLICIT_OPENSSL=$IMPLICIT_CRYPTO])
if test "$IMPLICIT_OPENSSL" = "1"; then
USE_CRYPTO_OPENSSL=$OPENSSL_FOUND
if test "$USE_CRYPTO_OPENSSL" = "1"; then
AC_MSG_NOTICE(enabling openssl crypto provider since openssl is available)
else
AC_MSG_NOTICE(not enabling openssl crypto provider since openssl was not found)
fi
fi
if test "$USE_CRYPTO_OPENSSL" = "1" -a "$OPENSSL_FOUND" = "0"; then
AC_MSG_ERROR(unable to use requested openssl crypto provider without openssl)
fi
if test "$USE_CRYPTO_OPENSSL" = "1"; then
CFLAGS="$CFLAGS $pc_openssl_CFLAGS"
CXXFLAGS="$CXXFLAGS $pc_openssl_CXXFLAGS"
LIBS="$LIBS $pc_openssl_LIBS"
AC_DEFINE([USE_CRYPTO_OPENSSL], 1, [Whether to use the openssl crypto provider])
DEFAULT_CRYPTO=openssl
elif test "$OPENSSL_FOUND" = "1"; then
AC_MSG_NOTICE(not linking with openssl even though it is available)
fi
dnl If the gnutls provider is explicitly requested, require gnutls. If
dnl the gnutls provider is not explicitly disabled, enable it if
dnl gnutls is available. If the gnutls provider is explicitly
@ -581,6 +628,11 @@ case "$DEFAULT_CRYPTO" in
bad_crypto=1
fi
;;
"openssl")
if test "$USE_CRYPTO_OPENSSL" != "1"; then
bad_crypto=1
fi
;;
"gnutls")
if test "$USE_CRYPTO_GNUTLS" != "1"; then
bad_crypto=1

View File

@ -9,6 +9,9 @@
#ifdef USE_CRYPTO_GNUTLS
# include <qpdf/QPDFCrypto_gnutls.hh>
#endif
#ifdef USE_CRYPTO_OPENSSL
# include <qpdf/QPDFCrypto_openssl.hh>
#endif
std::shared_ptr<QPDFCryptoImpl>
QPDFCryptoProvider::getImpl()
@ -49,6 +52,9 @@ QPDFCryptoProvider::QPDFCryptoProvider() :
#endif
#ifdef USE_CRYPTO_GNUTLS
registerImpl_internal<QPDFCrypto_gnutls>("gnutls");
#endif
#ifdef USE_CRYPTO_OPENSSL
registerImpl_internal<QPDFCrypto_openssl>("openssl");
#endif
std::string default_crypto;
if (! QUtil::get_env("QPDF_CRYPTO_PROVIDER", &default_crypto))

View File

@ -0,0 +1,193 @@
#include <qpdf/QPDFCrypto_openssl.hh>
#include <cstring>
#include <stdexcept>
#include <qpdf/QIntC.hh>
static void
bad_bits(int bits)
{
throw std::logic_error(
std::string("unsupported key length: ") + std::to_string(bits));
}
static void
check_openssl(int status)
{
if (status != 1)
{
throw std::runtime_error("openssl error");
}
}
QPDFCrypto_openssl::QPDFCrypto_openssl() :
md_ctx(EVP_MD_CTX_new()), cipher_ctx(EVP_CIPHER_CTX_new())
{
memset(md_out, 0, sizeof(md_out));
EVP_MD_CTX_init(md_ctx);
EVP_CIPHER_CTX_init(cipher_ctx);
}
QPDFCrypto_openssl::~QPDFCrypto_openssl()
{
EVP_MD_CTX_reset(md_ctx);
EVP_CIPHER_CTX_reset(cipher_ctx);
EVP_CIPHER_CTX_free(cipher_ctx);
EVP_MD_CTX_free(md_ctx);
}
void
QPDFCrypto_openssl::MD5_init()
{
check_openssl(EVP_MD_CTX_reset(md_ctx));
check_openssl(EVP_DigestInit_ex(md_ctx, EVP_md5(), nullptr));
}
void
QPDFCrypto_openssl::SHA2_init(int bits)
{
const EVP_MD* md = EVP_sha512();
switch (bits)
{
case 256:
md = EVP_sha256();
break;
case 384:
md = EVP_sha384();
break;
case 512:
md = EVP_sha512();
break;
default:
bad_bits(bits);
return;
}
sha2_bits = static_cast<size_t>(bits);
check_openssl(EVP_MD_CTX_reset(md_ctx));
check_openssl(EVP_DigestInit_ex(md_ctx, md, nullptr));
}
void
QPDFCrypto_openssl::MD5_update(unsigned char const* data, size_t len)
{
check_openssl(EVP_DigestUpdate(md_ctx, data, len));
}
void
QPDFCrypto_openssl::SHA2_update(unsigned char const* data, size_t len)
{
check_openssl(EVP_DigestUpdate(md_ctx, data, len));
}
void
QPDFCrypto_openssl::MD5_finalize()
{
if (EVP_MD_CTX_md(md_ctx))
{
check_openssl(EVP_DigestFinal(md_ctx, md_out + 0, nullptr));
}
}
void
QPDFCrypto_openssl::SHA2_finalize()
{
if (EVP_MD_CTX_md(md_ctx))
{
check_openssl(EVP_DigestFinal(md_ctx, md_out + 0, nullptr));
}
}
void
QPDFCrypto_openssl::MD5_digest(MD5_Digest d)
{
memcpy(d, md_out, sizeof(QPDFCryptoImpl::MD5_Digest));
}
std::string
QPDFCrypto_openssl::SHA2_digest()
{
return std::string(reinterpret_cast<char*>(md_out), sha2_bits / 8);
}
void
QPDFCrypto_openssl::RC4_init(unsigned char const* key_data, int key_len)
{
check_openssl(EVP_CIPHER_CTX_reset(cipher_ctx));
if (key_len == -1)
{
key_len = QIntC::to_int(
strlen(reinterpret_cast<const char*>(key_data)));
}
check_openssl(
EVP_EncryptInit_ex(cipher_ctx, EVP_rc4(), nullptr, nullptr, nullptr));
check_openssl(EVP_CIPHER_CTX_set_key_length(cipher_ctx, key_len));
check_openssl(
EVP_EncryptInit_ex(cipher_ctx, nullptr, nullptr, key_data, nullptr));
}
void
QPDFCrypto_openssl::rijndael_init(
bool encrypt, unsigned char const* key_data, size_t key_len,
bool cbc_mode, unsigned char* cbc_block)
{
const EVP_CIPHER* cipher = nullptr;
switch (key_len)
{
case 32:
cipher = cbc_mode ? EVP_aes_256_cbc() : EVP_aes_256_ecb();
break;
case 24:
cipher = cbc_mode ? EVP_aes_192_cbc() : EVP_aes_192_ecb();
break;
default:
cipher = cbc_mode ? EVP_aes_128_cbc() : EVP_aes_128_ecb();
break;
}
check_openssl(EVP_CIPHER_CTX_reset(cipher_ctx));
check_openssl(
EVP_CipherInit_ex(cipher_ctx, cipher, nullptr,
key_data, cbc_block, encrypt));
check_openssl(EVP_CIPHER_CTX_set_padding(cipher_ctx, 0));
}
void
QPDFCrypto_openssl::RC4_process(
unsigned char* in_data, size_t len, unsigned char* out_data)
{
if (nullptr == out_data)
{
out_data = in_data;
}
int out_len = static_cast<int>(len);
check_openssl(
EVP_EncryptUpdate(cipher_ctx, out_data, &out_len, in_data, out_len));
}
void
QPDFCrypto_openssl::rijndael_process(
unsigned char* in_data, unsigned char* out_data)
{
int len = QPDFCryptoImpl::rijndael_buf_size;
check_openssl(EVP_CipherUpdate(cipher_ctx, out_data, &len, in_data, len));
}
void
QPDFCrypto_openssl::RC4_finalize()
{
if (EVP_CIPHER_CTX_cipher(cipher_ctx))
{
check_openssl(EVP_CIPHER_CTX_reset(cipher_ctx));
}
}
void
QPDFCrypto_openssl::rijndael_finalize()
{
if (EVP_CIPHER_CTX_cipher(cipher_ctx))
{
check_openssl(EVP_CIPHER_CTX_reset(cipher_ctx));
}
}

View File

@ -14,6 +14,9 @@ CRYPTO_NATIVE = \
libqpdf/sha2.c \
libqpdf/sha2big.c
CRYPTO_OPENSSL = \
libqpdf/QPDFCrypto_openssl.cc
CRYPTO_GNUTLS = \
libqpdf/QPDFCrypto_gnutls.cc
@ -97,6 +100,10 @@ ifeq ($(USE_CRYPTO_NATIVE), 1)
SRCS_libqpdf += $(CRYPTO_NATIVE)
endif
ifeq ($(USE_CRYPTO_OPENSSL), 1)
SRCS_libqpdf += $(CRYPTO_OPENSSL)
endif
ifeq ($(USE_CRYPTO_GNUTLS), 1)
SRCS_libqpdf += $(CRYPTO_GNUTLS)
endif

View File

@ -0,0 +1,50 @@
#ifndef QPDFCRYPTO_openssl_HH
#define QPDFCRYPTO_openssl_HH
#include <qpdf/QPDFCryptoImpl.hh>
#include <string>
#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/cipher.h>
#include <openssl/digest.h>
#else
#include <openssl/evp.h>
#endif
class QPDFCrypto_openssl: public QPDFCryptoImpl
{
public:
QPDFCrypto_openssl();
QPDF_DLL
~QPDFCrypto_openssl() override;
void MD5_init() override;
void MD5_update(unsigned char const* data, size_t len) override;
void MD5_finalize() override;
void MD5_digest(MD5_Digest) override;
void RC4_init(unsigned char const* key_data, int key_len = -1) override;
void RC4_process(unsigned char* in_data, size_t len,
unsigned char* out_data = 0) override;
void RC4_finalize() override;
void SHA2_init(int bits) override;
void SHA2_update(unsigned char const* data, size_t len) override;
void SHA2_finalize() override;
std::string SHA2_digest() override;
void rijndael_init(
bool encrypt, unsigned char const* key_data, size_t key_len,
bool cbc_mode, unsigned char* cbc_block) override;
void rijndael_process(
unsigned char* in_data, unsigned char* out_data) override;
void rijndael_finalize() override;
private:
EVP_MD_CTX* const md_ctx;
EVP_CIPHER_CTX* const cipher_ctx;
uint8_t md_out[EVP_MAX_MD_SIZE];
size_t sha2_bits;
};
#endif // QPDFCRYPTO_openssl_HH

View File

@ -90,6 +90,9 @@
/* Whether to use the native crypto provider */
#undef USE_CRYPTO_NATIVE
/* Whether to use the openssl crypto provider */
#undef USE_CRYPTO_OPENSSL
/* Whether to use insecure random numbers */
#undef USE_INSECURE_RANDOM