FIrst pass at GnuTLS support.

This commit is contained in:
Jim Hague 2019-10-30 14:02:32 +00:00
parent f34218d812
commit 74d9404759
4 changed files with 244 additions and 4 deletions

View File

@ -116,6 +116,7 @@ option(USE_LIBEVENT2 "Use libevent2 if available." ON)
option(USE_LIBUV "Use libuv if available." ON)
option(USE_LIBIDN "Use libidn if available." ON)
option(USE_LIBIDN2 "Use libidn2 if available." ON)
option(USE_GNUTLS "Use GnuTLS for TLS connections." OFF)
# Above names chosen for user consistency. Now define substituted names.
set(REQ_DEBUG ${ENABLE_DEBUG_REQ})
@ -270,6 +271,7 @@ check_type_size(_sigset_t _SIGSET_T)
find_package(OpenSSL "1.0.2" REQUIRED)
set(HAVE_SSL 1)
set(tlsdir "openssl")
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ssl.h HAVE_OPENSSL_SSL_H)
@ -318,6 +320,8 @@ check_symbol_exists(TLS_client_method "openssl/ssl.h" HAVE_TLS_CLIENT_METHOD)
check_symbol_exists(X509_get_notAfter "openssl/x509.h" HAVE_X509_GET_NOTAFTER)
check_symbol_exists(X509_get0_notAfter "openssl/x509.h" HAVE_X509_GET0_NOTAFTER)
check_symbol_exists(NID_ED25519 "openssl/obj_mac.h" HAVE_SSL_ED25519)
check_symbol_exists(NID_ED448 "openssl/obj_mac.h" HAVE_SSL_ED448)
# Threading library
set(THREADS_PREFER_PTHREAD_FLAG ON)
@ -347,6 +351,43 @@ if (USE_LIBIDN2)
endif()
endif()
# GnuTLS and Nettle. If using GnuTLS, we need the Nettle dev stuff to
# handle digital signature algorithms. GnuTLS uses Nettle internally.
if (USE_GNUTLS)
find_package(GnuTLS "3.5.0" REQUIRED)
find_package(Nettle REQUIRED)
set(tlsdir "gnutls")
set(HAVE_NETTLE 1)
set(CMAKE_REQUIRED_INCLUDES ${NETTLE_INCLUDE_DIR})
check_include_file(nettle/dsa-compat.h HAVE_NETTLE_DSA_COMPAT_H)
check_include_file(nettle/eddsa.h HAVE_NETTLE_EDDSA_H)
endif()
# Sort out what signature algorithms can be used.
if (USE_ED25519)
if (USE_GNUTLS)
if (NOT HAVE_NETTLE_EDDSA_H)
message(WARNING "ED25519 enabled and Nettle does not support it. Disabled.")
unset(USE_ED25519)
endif ()
elseif (NOT HAVE_SSL_ED25519)
message(WARNING "ED25519 enabled and OpenSSL does not support it. Disabled.")
unset(USE_ED25519)
endif ()
endif ()
if (USE_ED448)
if (USE_GNUTLS)
message(WARNING "ED448 enabled and Nettle does not support it. Disabled.")
unset(USE_ED448)
elseif (NOT HAVE_SSL_ED448)
message(WARNING "ED448 enabled and OpenSSL does not support it. Disabled.")
unset(USE_ED448)
endif ()
endif ()
# Stuff that might be in a BSD library
check_symbol_exists(strlcpy string.h HAVE_DECL_STRLCPY)
check_symbol_exists(arc4random stdlib.h HAVE_DECL_ARC4RANDOM)
@ -477,9 +518,9 @@ add_library(getdns_objects OBJECT
src/tls/val_secalgo.c
src/tls/anchor-internal.c
src/openssl/tls.c
src/openssl/pubkey-pinning-internal.c
src/openssl/keyraw-internal.c
src/${tlsdir}/tls.c
src/${tlsdir}/pubkey-pinning-internal.c
src/${tlsdir}/keyraw-internal.c
${CMAKE_CURRENT_BINARY_DIR}/version.c
)
@ -527,7 +568,7 @@ target_include_directories(getdns_objects
PRIVATE
src/util/auxiliary
src/openssl
src/${tlsdir}
src/tls
src/yxml
@ -551,6 +592,9 @@ endif ()
if (Libunbound_FOUND)
target_include_directories(getdns_objects PRIVATE ${LIBUNBOUND_INCLUDE_DIR})
endif ()
if (GnuTLS_FOUND)
target_include_directories(getdns_objects PRIVATE ${GNUTLS_INCLUDE_DIR})
endif ()
# Don't compile separate objects for shared and static libraries.
# Yes, -fPIC is slightly suboptimal for static libraries, but it looks
@ -580,6 +624,12 @@ if (ENABLE_STATIC)
if (Libidn2_FOUND)
target_link_libraries(getdns PUBLIC Libidn2::Libidn2)
endif ()
if (GnuTLS_FOUND)
target_link_libraries(getdns PUBLIC GnuTLS::GnuTLS GnuTLS::Dane)
endif ()
if (Nettle_FOUND)
target_link_libraries(getdns PUBLIC Nettle::Nettle Nettle::Hogweed)
endif ()
set_target_properties(getdns PROPERTIES OUTPUT_NAME getdns${static_lib_suffix})
endif ()
@ -605,6 +655,12 @@ if (ENABLE_SHARED)
if (Libidn2_FOUND)
target_link_libraries(getdns_shared PUBLIC Libidn2::Libidn2)
endif ()
if (GnuTLS_FOUND)
target_link_libraries(getdns_shared PUBLIC GnuTLS::GnuTLS GnuTLS::Dane)
endif ()
if (Nettle_FOUND)
target_link_libraries(getdns_shared PUBLIC Nettle::Nettle Nettle::Hogweed)
endif ()
set_target_properties(getdns_shared PROPERTIES OUTPUT_NAME getdns)
target_shared_library_version(getdns_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})

View File

@ -168,6 +168,10 @@
#cmakedefine HAVE_LIBIDN 1
#cmakedefine HAVE_LIBIDN2 1
#cmakedefine HAVE_NETTLE 1
#cmakedefine HAVE_NETTLE_DSA_COMPAT_H 1
#cmakedefine HAVE_NETTLE_EDDSA_H 1
#cmakedefine HAVE_EVENT2_EVENT_H 1
#cmakedefine HAVE_EVENT_BASE_NEW 1
#cmakedefine HAVE_EVENT_BASE_FREE 1

View File

@ -0,0 +1,85 @@
#[=======================================================================[.rst:
FindGnuTLS
----------
Find the GnuTLS library.
Imported targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` targets:
``GnuTLS::GnuTLS``
The GnuTLS library, if found.
``GnuTLS::Dane``
The GnuTLS DANE library, if found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``GnuTLS_FOUND``
If false, do not try to use GnuTLS.
``GNUTLS_INCLUDE_DIR``
where to find GnuTLS headers.
``GNUTLS_LIBRARIES``
the libraries needed to use GnuTLS.
``GNUTLS_VERSION``
the version of the GnuTLS library found
#]=======================================================================]
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
HINTS
"${GNUTLS_DIR}"
"${GNUTLS_DIR}/include"
)
find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls
HINTS
"${GNUTLS_DIR}"
"${GNUTLS_DIR}/lib"
)
find_library(GNUTLS_DANE_LIBRARY NAMES gnutls-dane libgnutls-dane
HINTS
"${GNUTLS_DIR}"
"${GNUTLS_DIR}/lib"
)
set(GNUTLS_LIBRARIES "")
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
if (NOT TARGET GnuTLS::GnuTLS)
add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED)
set_target_properties(GnuTLS::GnuTLS PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GNUTLS_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${GNUTLS_LIBRARY}"
)
endif ()
if (NOT TARGET GnuTLS::Dane)
add_library(GnuTLS::Dane UNKNOWN IMPORTED)
set_target_properties(GnuTLS::Dane PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GNUTLS_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${GNUTLS_DANE_LIBRARY}"
)
endif ()
if (NOT GNUTLS_VERSION AND GNUTLS_INCLUDE_DIR)
file(STRINGS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" GNUTLS_VER_H REGEX "^#define GNUTLS_VERSION_(MAJOR|MINOR|PATCH) ")
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*_PATCH ([0-9]+).*$" "\\1.\\2.\\3c" GNUTLS_VERSION "${GNUTLS_VER_H}")
endif ()
endif()
list(APPEND GNUTLS_LIBRARIES "${GNUTLS_LIBRARY}" "${GNUTLS_DANE_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GnuTLS
REQUIRED_VARS GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR
VERSION_VAR GNUTLS_VERSION
)
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARIES GNUTLS_LIBRARY GNUTLS_DANE_LIBRARY)

View File

@ -0,0 +1,95 @@
#[=======================================================================[.rst:
FindNettle
----------
Find the Nettle library.
Imported targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` targets:
``Nettle::Nettle``
The Nettle library, if found.
``Nettle::Hogweed``
The Hogweed library, if found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``Nettle_FOUND``
If false, do not try to use Nettle.
``NETTLE_INCLUDE_DIR``
where to find Nettle headers.
``NETTLE_LIBRARIES``
the libraries needed to use Nettle.
``NETTLE_VERSION``
the version of the Nettle library found
#]=======================================================================]
find_path(NETTLE_INCLUDE_DIR nettle/version.h
HINTS
"${NETTLE_DIR}"
"${NETTLE_DIR}/include"
)
find_library(NETTLE_LIBRARY NAMES nettle libnettle
HINTS
"${NETTLE_DIR}"
"${NETTLE_DIR}/lib"
)
find_library(HOGWEED_LIBRARY NAMES hogweed libhogweed
HINTS
"${NETTLE_DIR}"
"${NETTLE_DIR}/lib"
)
set(NETTLE_LIBRARIES "")
# May need gmp library on Unix.
if (UNIX)
find_library(NETTLE_GMP_LIBRARY gmp)
if (NETTLE_GMP_LIBRARY)
list(APPEND NETTLE_LIBRARIES "${NETTLE_GMP_LIBRARY}")
endif ()
endif ()
if (NETTLE_INCLUDE_DIR AND NETTLE_LIBRARY AND HOGWEED_LIBRARY)
if (NOT TARGET Nettle::Nettle)
add_library(Nettle::Nettle UNKNOWN IMPORTED)
set_target_properties(Nettle::Nettle PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${NETTLE_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${NETTLE_LIBRARIES}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${NETTLE_LIBRARY}"
)
endif ()
if (NOT TARGET Nettle::Hogweed)
add_library(Nettle::Hogweed UNKNOWN IMPORTED)
set_target_properties(Nettle::Hogweed PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${NETTLE_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${HOGWEED_LIBRARY}"
)
endif ()
if (NOT NETTLE_VERSION AND NETTLE_INCLUDE_DIR)
file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h" NETTLE_VER_H REGEX "^#define NETTLE_VERSION_(MAJOR|MINOR) ")
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*$" "\\1.\\2" NETTLE_VERSION "${NETTLE_VER_H}")
endif ()
endif()
list(APPEND NETTLE_LIBRARIES "${NETTLE_LIBRARY}" "${HOGWEED_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Nettle
REQUIRED_VARS NETTLE_LIBRARIES NETTLE_INCLUDE_DIR
VERSION_VAR NETTLE_VERSION
)
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARIES NETTLE_LIBRARY HOGWEED_LIBRARY)