mirror of https://github.com/getdnsapi/getdns.git
Compare commits
57 Commits
v1.7.0_stu
...
develop
Author | SHA1 | Date |
---|---|---|
|
f8c95b4f15 | |
|
ee534d10bf | |
|
6395fe43cc | |
|
d98d307e64 | |
|
c8df60e67d | |
|
037892739f | |
|
9c076ca34b | |
|
3a71bd350e | |
|
8aa19255b8 | |
|
7eaf8454a2 | |
|
2e04e9f8b6 | |
|
a19177d41e | |
|
a1451df680 | |
|
777e0b245c | |
|
2d48a3bd1b | |
|
9bb533ab57 | |
|
86bd62cb40 | |
|
adcdf20289 | |
|
aca15088e5 | |
|
1ea92a68ad | |
|
142f616693 | |
|
6b65aed443 | |
|
0cb72000f8 | |
|
1748ca4c29 | |
|
b181782e0e | |
|
f97ee14b69 | |
|
1a1e79603c | |
|
875c03176e | |
|
2d7d8a4ea5 | |
|
8e2accfd74 | |
|
861ae30725 | |
|
dc5026f2c8 | |
|
10a000b916 | |
|
893d4720c9 | |
|
2bbac1163b | |
|
9d8eea97a5 | |
|
c0e45395b8 | |
|
ed7bfa107e | |
|
94dbb8e916 | |
|
a5a1256adc | |
|
190dbe1b91 | |
|
c50288f71e | |
|
c2e085ee9e | |
|
01715688d7 | |
|
ecb9de2c29 | |
|
b86f8e904c | |
|
45683d3cfe | |
|
822166d7ad | |
|
e4661f957e | |
|
de2137562d | |
|
6eb1a6790a | |
|
f92f97bf1e | |
|
cf2b805ef7 | |
|
e19e6bd464 | |
|
f9db16a65e | |
|
67b7a8c024 | |
|
215d553c0b |
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
|
||||||
|
|
||||||
if (POLICY CMP0075)
|
if (POLICY CMP0075)
|
||||||
cmake_policy(SET CMP0075 NEW)
|
cmake_policy(SET CMP0075 NEW)
|
||||||
|
@ -6,14 +6,14 @@ endif ()
|
||||||
|
|
||||||
# The following must be set BEFORE doing project() or enable_language().
|
# The following must be set BEFORE doing project() or enable_language().
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
message(STATUS "No build type defined; defaulting to 'Debug'")
|
message(STATUS "No build type defined; defaulting to 'RelWithDebInfo'")
|
||||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
|
||||||
"The type of build. Possible values are: Debug, Release, RelWithDebInfo and MinSizeRel.")
|
"The type of build. Possible values are: Debug, Release, RelWithDebInfo and MinSizeRel.")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(PACKAGE "getdns")
|
set(PACKAGE "getdns")
|
||||||
set(PACKAGE_NAME "getdns")
|
set(PACKAGE_NAME "getdns")
|
||||||
set(PACKAGE_VERSION "1.7.0")
|
set(PACKAGE_VERSION "1.7.3")
|
||||||
set(PACKAGE_BUGREPORT "team@getdnsapi.net")
|
set(PACKAGE_BUGREPORT "team@getdnsapi.net")
|
||||||
set(PACKAGE_URL "https://getdnsapi.net")
|
set(PACKAGE_URL "https://getdnsapi.net")
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
|
||||||
set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
|
set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
|
||||||
|
|
||||||
set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
|
set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
|
||||||
set(GETDNS_NUMERIC_VERSION 0x01070000)
|
set(GETDNS_NUMERIC_VERSION 0x01070200)
|
||||||
set(API_VERSION "December 2015")
|
set(API_VERSION "December 2015")
|
||||||
set(API_NUMERIC_VERSION 0x07df0c00)
|
set(API_NUMERIC_VERSION 0x07df0c00)
|
||||||
|
|
||||||
|
@ -262,6 +262,7 @@ check_include_file(inttypes.h HAVE_INTTYPES_H)
|
||||||
check_include_file(limits.h HAVE_LIMITS_H)
|
check_include_file(limits.h HAVE_LIMITS_H)
|
||||||
check_include_file(sys/limits.h HAVE_SYS_LIMITS_H)
|
check_include_file(sys/limits.h HAVE_SYS_LIMITS_H)
|
||||||
check_include_file(stdarg.h HAVE_STDARG_H)
|
check_include_file(stdarg.h HAVE_STDARG_H)
|
||||||
|
check_include_file(stddef.h HAVE_STDDEF_H)
|
||||||
check_include_file(stdint.h HAVE_STDINT_H)
|
check_include_file(stdint.h HAVE_STDINT_H)
|
||||||
check_include_file(stdio.h HAVE_STDIO_H)
|
check_include_file(stdio.h HAVE_STDIO_H)
|
||||||
check_include_file(stdlib.h HAVE_STDLIB_H)
|
check_include_file(stdlib.h HAVE_STDLIB_H)
|
||||||
|
@ -340,6 +341,7 @@ check_include_file(openssl/engine.h HAVE_OPENSSL_ENGINE_H)
|
||||||
check_include_file(openssl/bn.h HAVE_OPENSSL_BN_H)
|
check_include_file(openssl/bn.h HAVE_OPENSSL_BN_H)
|
||||||
check_include_file(openssl/dsa.h HAVE_OPENSSL_DSA_H)
|
check_include_file(openssl/dsa.h HAVE_OPENSSL_DSA_H)
|
||||||
check_include_file(openssl/rsa.h HAVE_OPENSSL_RSA_H)
|
check_include_file(openssl/rsa.h HAVE_OPENSSL_RSA_H)
|
||||||
|
check_include_file(openssl/param_build.h HAVE_OPENSSL_PARAM_BUILD_H)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES} ${getdns_system_libs})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES} ${getdns_system_libs})
|
||||||
check_function_exists(DSA_SIG_set0 HAVE_DSA_SIG_SET0)
|
check_function_exists(DSA_SIG_set0 HAVE_DSA_SIG_SET0)
|
||||||
|
@ -372,6 +374,8 @@ check_function_exists(SSL_set_ciphersuites HAVE_SSL_SET_CIPHERSUITES)
|
||||||
|
|
||||||
check_function_exists(OPENSSL_init_crypto HAVE_OPENSSL_INIT_CRYPTO)
|
check_function_exists(OPENSSL_init_crypto HAVE_OPENSSL_INIT_CRYPTO)
|
||||||
|
|
||||||
|
check_function_exists(OSSL_PARAM_BLD_new HAVE_OSSL_PARAM_BLD_NEW)
|
||||||
|
|
||||||
check_symbol_exists(SSL_dane_enable "openssl/ssl.h" HAVE_SSL_DANE_ENABLE)
|
check_symbol_exists(SSL_dane_enable "openssl/ssl.h" HAVE_SSL_DANE_ENABLE)
|
||||||
check_symbol_exists(SSL_CTX_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_CTX_SET1_CURVES_LIST)
|
check_symbol_exists(SSL_CTX_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_CTX_SET1_CURVES_LIST)
|
||||||
check_symbol_exists(SSL_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_SET1_CURVES_LIST)
|
check_symbol_exists(SSL_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_SET1_CURVES_LIST)
|
||||||
|
@ -684,9 +688,6 @@ if (NOT HAVE_SSL_DANE_ENABLE)
|
||||||
target_include_directories(getdns_objects PRIVATE src/ssl_dane)
|
target_include_directories(getdns_objects PRIVATE src/ssl_dane)
|
||||||
set(USE_DANESSL 1)
|
set(USE_DANESSL 1)
|
||||||
endif ()
|
endif ()
|
||||||
if (Libidn_FOUND)
|
|
||||||
target_include_directories(getdns_objects PRIVATE ${LIBIDN_INCLUDE_DIR})
|
|
||||||
endif ()
|
|
||||||
if (Libidn2_FOUND)
|
if (Libidn2_FOUND)
|
||||||
target_include_directories(getdns_objects PRIVATE ${LIBIDN2_INCLUDE_DIR})
|
target_include_directories(getdns_objects PRIVATE ${LIBIDN2_INCLUDE_DIR})
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -720,9 +721,6 @@ if (ENABLE_STATIC)
|
||||||
if (Libunbound_FOUND)
|
if (Libunbound_FOUND)
|
||||||
target_link_libraries(getdns PUBLIC Libunbound::Libunbound)
|
target_link_libraries(getdns PUBLIC Libunbound::Libunbound)
|
||||||
endif ()
|
endif ()
|
||||||
if (Libidn_FOUND)
|
|
||||||
target_link_libraries(getdns PUBLIC Libidn::Libidn)
|
|
||||||
endif ()
|
|
||||||
if (Libidn2_FOUND)
|
if (Libidn2_FOUND)
|
||||||
target_link_libraries(getdns PUBLIC Libidn2::Libidn2)
|
target_link_libraries(getdns PUBLIC Libidn2::Libidn2)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -752,9 +750,6 @@ if (ENABLE_SHARED)
|
||||||
if (Libunbound_FOUND)
|
if (Libunbound_FOUND)
|
||||||
target_link_libraries(getdns_shared PUBLIC Libunbound::Libunbound)
|
target_link_libraries(getdns_shared PUBLIC Libunbound::Libunbound)
|
||||||
endif ()
|
endif ()
|
||||||
if (Libidn_FOUND)
|
|
||||||
target_link_libraries(getdns_shared PUBLIC Libidn::Libidn)
|
|
||||||
endif ()
|
|
||||||
if (Libidn2_FOUND)
|
if (Libidn2_FOUND)
|
||||||
target_link_libraries(getdns_shared PUBLIC Libidn2::Libidn2)
|
target_link_libraries(getdns_shared PUBLIC Libidn2::Libidn2)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -1032,6 +1027,8 @@ if (BUILD_TESTING)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Substitutions in files.
|
# Substitutions in files.
|
||||||
|
string(TOUPPER "${CMAKE_BUILD_TYPE}" GETDNS_BUILD_RELTYPE)
|
||||||
|
string(REPLACE "\"" "\\\"" GETDNS_BUILD_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${GETDNS_BUILD_RELTYPE}}")
|
||||||
configure_file(cmake/include/cmakeconfig.h.in config.h)
|
configure_file(cmake/include/cmakeconfig.h.in config.h)
|
||||||
configure_file(src/getdns/getdns.h.in getdns/getdns.h)
|
configure_file(src/getdns/getdns.h.in getdns/getdns.h)
|
||||||
configure_file(src/getdns/getdns_extra.h.in getdns/getdns_extra.h)
|
configure_file(src/getdns/getdns_extra.h.in getdns/getdns_extra.h)
|
||||||
|
@ -1064,6 +1061,8 @@ foreach (man ${mans})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
|
cmake_path(APPEND libdir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
cmake_path(APPEND includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
configure_file(getdns.pc.in getdns.pc @ONLY)
|
configure_file(getdns.pc.in getdns.pc @ONLY)
|
||||||
|
|
||||||
# Installing.
|
# Installing.
|
||||||
|
@ -1099,11 +1098,10 @@ if (BUILD_GETDNS_SERVER_MON)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION share/man)
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION ${CMAKE_INSTALL_MANDIR})
|
||||||
|
|
||||||
set(docdir share/doc/getdns)
|
install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||||
install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${docdir})
|
install(FILES spec/index.html DESTINATION ${CMAKE_INSTALL_DOCDIR}/spec)
|
||||||
install(FILES spec/index.html DESTINATION ${docdir}/spec)
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
|
||||||
install(CODE "message(\"\
|
install(CODE "message(\"\
|
||||||
|
|
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
* 2023-??-??: Version 1.7.4
|
||||||
|
* Issue #536: Broken trust anchor files are silently ignored
|
||||||
|
Thanks Stéphane Bortzmeyer
|
||||||
|
|
||||||
|
* 2022-12-22: Version 1.7.3
|
||||||
|
* PR #532: Increase CMake required version 3.5 -> 3.20, because we
|
||||||
|
need cmake_path for Absolute paths in pkg-config (See Issue #517)
|
||||||
|
Thanks Gabriel Ganne
|
||||||
|
* Updated to Stubby 0.4.3 quickfix release
|
||||||
|
|
||||||
|
* 2022-08-19: Version 1.7.2
|
||||||
|
* Updated to Stubby 0.4.2 quickfix release
|
||||||
|
|
||||||
|
* 2022-08-19: Version 1.7.1
|
||||||
|
* Always send the `dot` ALPN when using DoT
|
||||||
|
* Strengthen version determination for Libidn2 during cmake processing
|
||||||
|
(thanks jpbion).
|
||||||
|
* Fix for issue in UDP stream selection in case of timeouts.
|
||||||
|
Thanks Shikha Sharma
|
||||||
|
* Fix using asterisk in ipstr for any address. Thanks uzlonewolf.
|
||||||
|
* Issue stubby#295: rdata not correctly written for validation for
|
||||||
|
certain RR type. Also, set default built type to RelWithDebInfo and
|
||||||
|
expose CFLAGS via GETDNS_BUILD_CFLAGS define and via
|
||||||
|
getdns_context_get_api_information()
|
||||||
|
* Issue #524: Bug fixes from submodules' upstream?
|
||||||
|
Thanks Johnnyslee
|
||||||
|
* Issue #517: Allow Absolute path CMAKE_INSTALL_{INCLUDE,LIB}DIR in
|
||||||
|
pkg-config files. Thanks Alex Shpilkin
|
||||||
|
* Issue #512: Update README.md to show correct PGP key location.
|
||||||
|
Thanks Katze Prior.
|
||||||
|
|
||||||
* 2021-06-04: Version 1.7.0
|
* 2021-06-04: Version 1.7.0
|
||||||
* Make TLS Handshake timeout max 4/5th of timeout for the query,
|
* Make TLS Handshake timeout max 4/5th of timeout for the query,
|
||||||
just like connection setup timeout was, so fallback transport
|
just like connection setup timeout was, so fallback transport
|
||||||
|
|
|
@ -48,7 +48,7 @@ Once it is built you should take a look at `spec/example` to see how the library
|
||||||
Download the sources from our [github repo](https://github.com/getdnsapi/getdns)
|
Download the sources from our [github repo](https://github.com/getdnsapi/getdns)
|
||||||
or from [getdnsapi.net](https://getdnsapi.net) and verify the download using
|
or from [getdnsapi.net](https://getdnsapi.net) and verify the download using
|
||||||
the checksums (SHA1 or MD5) or using gpg to verify the signature. Our keys are
|
the checksums (SHA1 or MD5) or using gpg to verify the signature. Our keys are
|
||||||
available from the [pgp keyservers](https://keyserver.pgp.com)
|
available from the [openpgp keyserver](https://keys.openpgp.org/)
|
||||||
|
|
||||||
* `willem@nlnetlabs.nl`, key id E5F8F8212F77A498
|
* `willem@nlnetlabs.nl`, key id E5F8F8212F77A498
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#cmakedefine HAVE_LIMITS_H 1
|
#cmakedefine HAVE_LIMITS_H 1
|
||||||
#cmakedefine HAVE_SYS_LIMITS_H 1
|
#cmakedefine HAVE_SYS_LIMITS_H 1
|
||||||
#cmakedefine HAVE_STDARG_H 1
|
#cmakedefine HAVE_STDARG_H 1
|
||||||
|
#cmakedefine HAVE_STDDEF_H 1
|
||||||
#cmakedefine HAVE_STDINT_H 1
|
#cmakedefine HAVE_STDINT_H 1
|
||||||
#cmakedefine HAVE_STDIO_H 1
|
#cmakedefine HAVE_STDIO_H 1
|
||||||
#cmakedefine HAVE_STDLIB_H 1
|
#cmakedefine HAVE_STDLIB_H 1
|
||||||
|
@ -61,6 +62,7 @@
|
||||||
#cmakedefine HAVE_OPENSSL_BN_H 1
|
#cmakedefine HAVE_OPENSSL_BN_H 1
|
||||||
#cmakedefine HAVE_OPENSSL_DSA_H 1
|
#cmakedefine HAVE_OPENSSL_DSA_H 1
|
||||||
#cmakedefine HAVE_OPENSSL_RSA_H 1
|
#cmakedefine HAVE_OPENSSL_RSA_H 1
|
||||||
|
#cmakedefine HAVE_OPENSSL_PARAM_BUILD_H 1
|
||||||
|
|
||||||
#cmakedefine HAVE_DSA_SIG_SET0 1
|
#cmakedefine HAVE_DSA_SIG_SET0 1
|
||||||
#cmakedefine HAVE_DSA_SET0_PQG 1
|
#cmakedefine HAVE_DSA_SET0_PQG 1
|
||||||
|
@ -96,6 +98,8 @@
|
||||||
|
|
||||||
#cmakedefine HAVE_OPENSSL_INIT_CRYPTO 1
|
#cmakedefine HAVE_OPENSSL_INIT_CRYPTO 1
|
||||||
|
|
||||||
|
#cmakedefine HAVE_OSSL_PARAM_BLD_NEW 1
|
||||||
|
|
||||||
#cmakedefine HAVE_SSL_DANE_ENABLE 1
|
#cmakedefine HAVE_SSL_DANE_ENABLE 1
|
||||||
#cmakedefine HAVE_DECL_SSL_CTX_SET1_CURVES_LIST 1
|
#cmakedefine HAVE_DECL_SSL_CTX_SET1_CURVES_LIST 1
|
||||||
#cmakedefine HAVE_DECL_SSL_SET1_CURVES_LIST 1
|
#cmakedefine HAVE_DECL_SSL_SET1_CURVES_LIST 1
|
||||||
|
@ -238,6 +242,10 @@
|
||||||
# define FD_SETSIZE 1024
|
# define FD_SETSIZE 1024
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* the version of the windows API enabled */
|
/* the version of the windows API enabled */
|
||||||
# ifndef WINVER
|
# ifndef WINVER
|
||||||
# define WINVER 0x0600 // 0x0502
|
# define WINVER 0x0600 // 0x0502
|
||||||
|
@ -304,12 +312,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef HAVE_STDLIB_H
|
||||||
extern "C" {
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STDC_HEADERS
|
#ifdef HAVE_STDDEF_H
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -28,48 +28,62 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(CHECK_INCLUDE_DIR check.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgCheck IMPORTED_TARGET GLOBAL check)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgCheck_FOUND)
|
||||||
|
set(CHECK_INCLUDE_DIR ${PkgCheck_INCLUDE_DIRS} CACHE FILEPATH "check include path")
|
||||||
|
set(CHECK_LIBRARIES ${PkgCheck_LIBRARIES} CACHE STRING "check libraries")
|
||||||
|
set(CHECK_VERSION ${PkgCheck_VERSION})
|
||||||
|
add_library(Check::Check ALIAS PkgConfig::PkgCheck)
|
||||||
|
set(Check_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(CHECK_INCLUDE_DIR check.h
|
||||||
HINTS
|
HINTS
|
||||||
"${CHECK_DIR}"
|
"${CHECK_DIR}"
|
||||||
"${CHECK_DIR}/include"
|
"${CHECK_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check for PIC and non-PIC libraries. If PIC present, use that
|
# Check for PIC and non-PIC libraries. If PIC present, use that
|
||||||
# in preference (as per Debian check.pc).
|
# in preference (as per Debian check.pc).
|
||||||
find_library(CHECK_LIBRARY NAMES check_pic libcheck_pic
|
find_library(CHECK_LIBRARY NAMES check_pic libcheck_pic
|
||||||
HINTS
|
HINTS
|
||||||
"${CHECK_DIR}"
|
"${CHECK_DIR}"
|
||||||
"${CHECK_DIR}/lib"
|
"${CHECK_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT CHECK_LIBRARY)
|
if (NOT CHECK_LIBRARY)
|
||||||
find_library(CHECK_LIBRARY NAMES check libcheck
|
find_library(CHECK_LIBRARY NAMES check libcheck
|
||||||
HINTS
|
HINTS
|
||||||
"${CHECK_DIR}"
|
"${CHECK_DIR}"
|
||||||
"${CHECK_DIR}/lib"
|
"${CHECK_DIR}/lib"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(CHECK_LIBRARIES "")
|
set(_CHECK_LIBARIES "")
|
||||||
|
|
||||||
# Check may need the math, subunit and rt libraries on Unix
|
# Check may need the math, subunit and rt libraries on Unix
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
find_library(CHECK_MATH_LIBRARY m)
|
find_library(CHECK_MATH_LIBRARY m)
|
||||||
find_library(CHECK_RT_LIBRARY rt)
|
find_library(CHECK_RT_LIBRARY rt)
|
||||||
find_library(CHECK_SUBUNIT_LIBRARY subunit)
|
find_library(CHECK_SUBUNIT_LIBRARY subunit)
|
||||||
|
|
||||||
if (CHECK_MATH_LIBRARY)
|
if (CHECK_MATH_LIBRARY)
|
||||||
list(APPEND CHECK_LIBRARIES "${CHECK_MATH_LIBRARY}")
|
list(APPEND _CHECK_LIBARIES "${CHECK_MATH_LIBRARY}")
|
||||||
endif ()
|
endif ()
|
||||||
if (CHECK_RT_LIBRARY)
|
if (CHECK_RT_LIBRARY)
|
||||||
list(APPEND CHECK_LIBRARIES "${CHECK_RT_LIBRARY}")
|
list(APPEND _CHECK_LIBARIES "${CHECK_RT_LIBRARY}")
|
||||||
endif ()
|
endif ()
|
||||||
if (CHECK_SUBUNIT_LIBRARY)
|
if (CHECK_SUBUNIT_LIBRARY)
|
||||||
list(APPEND CHECK_LIBRARIES "${CHECK_SUBUNIT_LIBRARY}")
|
list(APPEND _CHECK_LIBARIES "${CHECK_SUBUNIT_LIBRARY}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CHECK_INCLUDE_DIR AND CHECK_LIBRARY)
|
set(CHECK_LIBRARIES ${_CHECK_LIBARIES} ${CHECK_LIBRARY} CACHE STRING "check libraries")
|
||||||
|
|
||||||
|
if (CHECK_INCLUDE_DIR AND CHECK_LIBRARY)
|
||||||
if (NOT TARGET Check::Check)
|
if (NOT TARGET Check::Check)
|
||||||
add_library(Check::Check UNKNOWN IMPORTED)
|
add_library(Check::Check UNKNOWN IMPORTED)
|
||||||
set_target_properties(Check::Check PROPERTIES
|
set_target_properties(Check::Check PROPERTIES
|
||||||
|
@ -84,15 +98,17 @@ if (CHECK_INCLUDE_DIR AND CHECK_LIBRARY)
|
||||||
file(STRINGS "${CHECK_INCLUDE_DIR}/check.h" CHECK_H REGEX "^#define CHECK_M[A-Z]+_VERSION")
|
file(STRINGS "${CHECK_INCLUDE_DIR}/check.h" CHECK_H REGEX "^#define CHECK_M[A-Z]+_VERSION")
|
||||||
string(REGEX REPLACE "^.*\(([0-9]+)\).*\(([0-9]+)\).*\(([0-9]+)\).*$" "\\1.\\2.\\3" CHECK_VERSION "${CHECK_H}")
|
string(REGEX REPLACE "^.*\(([0-9]+)\).*\(([0-9]+)\).*\(([0-9]+)\).*$" "\\1.\\2.\\3" CHECK_VERSION "${CHECK_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND CHECK_LIBRARIES "${CHECK_LIBRARY}")
|
list(APPEND CHECK_LIBRARIES "${CHECK_LIBRARY}")
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(Check
|
find_package_handle_standard_args(Check
|
||||||
REQUIRED_VARS CHECK_LIBRARIES CHECK_INCLUDE_DIR
|
REQUIRED_VARS CHECK_LIBRARIES CHECK_INCLUDE_DIR
|
||||||
VERSION_VAR CHECK_VERSION
|
VERSION_VAR CHECK_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARIES CHECK_LIBRARY
|
mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARIES CHECK_LIBRARY
|
||||||
CHECK_MATH_LIBRARY CHECK_RT_LIBRARY CHECK_SUBUNIT_LIBRARY)
|
CHECK_MATH_LIBRARY CHECK_RT_LIBRARY CHECK_SUBUNIT_LIBRARY)
|
||||||
|
|
|
@ -30,27 +30,41 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgGnuTLS IMPORTED_TARGET GLOBAL QUIET gnutls)
|
||||||
|
pkg_check_modules(PkgGnuTLSDane IMPORTED_TARGET GLOBAL QUIET gnutls-dane)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgGnuTLS_FOUND AND PkgGnuTLSDane_FOUND)
|
||||||
|
set(GNUTLS_INCLUDE_DIR ${PkgGnuTLS_INCLUDE_DIRS} $PkgGnuTLSDane_INCLUDE_DIRS} CACHE FILEPATH "GnuTLS include path")
|
||||||
|
set(NETTLE_LIBRARIES ${PkgGnuTLS_LIBRARIES} ${PkgGnuTLSDane_LIBRARIES} CACHE STRING "GnuTLS libraries")
|
||||||
|
set(NETTLE_VERSION ${PkgGnuTLS_VERSION})
|
||||||
|
add_library(GnuTLS::GnuTLS ALIAS PkgConfig::PkgGnuTLS)
|
||||||
|
add_library(GnuTLS::Dane ALIAS PkgConfig::PkgGnuTLSDane)
|
||||||
|
set(GnuTLS_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
|
||||||
HINTS
|
HINTS
|
||||||
"${GNUTLS_DIR}"
|
"${GNUTLS_DIR}"
|
||||||
"${GNUTLS_DIR}/include"
|
"${GNUTLS_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls
|
find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls
|
||||||
HINTS
|
HINTS
|
||||||
"${GNUTLS_DIR}"
|
"${GNUTLS_DIR}"
|
||||||
"${GNUTLS_DIR}/lib"
|
"${GNUTLS_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(GNUTLS_DANE_LIBRARY NAMES gnutls-dane libgnutls-dane
|
find_library(GNUTLS_DANE_LIBRARY NAMES gnutls-dane libgnutls-dane
|
||||||
HINTS
|
HINTS
|
||||||
"${GNUTLS_DIR}"
|
"${GNUTLS_DIR}"
|
||||||
"${GNUTLS_DIR}/lib"
|
"${GNUTLS_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GNUTLS_LIBRARIES "")
|
set(_GNUTLS_LIBRARIES "")
|
||||||
|
|
||||||
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
|
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
|
||||||
if (NOT TARGET GnuTLS::GnuTLS)
|
if (NOT TARGET GnuTLS::GnuTLS)
|
||||||
add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED)
|
add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED)
|
||||||
set_target_properties(GnuTLS::GnuTLS PROPERTIES
|
set_target_properties(GnuTLS::GnuTLS PROPERTIES
|
||||||
|
@ -72,14 +86,16 @@ if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
|
||||||
file(STRINGS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" GNUTLS_VER_H REGEX "^#define GNUTLS_VERSION_(MAJOR|MINOR|PATCH) ")
|
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}")
|
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*_PATCH ([0-9]+).*$" "\\1.\\2.\\3c" GNUTLS_VERSION "${GNUTLS_VER_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
list(APPEND GNUTLS_LIBRARIES "${GNUTLS_LIBRARY}" "${GNUTLS_DANE_LIBRARY}")
|
list(APPEND _GNUTLS_LIBRARIES "${GNUTLS_LIBRARY}" "${GNUTLS_DANE_LIBRARY}")
|
||||||
|
set(GNUTLS_LIBRARIES ${_GNUTLS_LIBRARIES} CACHE STRING "GnuTLS libraries")
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(GnuTLS
|
find_package_handle_standard_args(GnuTLS
|
||||||
REQUIRED_VARS GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR
|
REQUIRED_VARS GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR
|
||||||
VERSION_VAR GNUTLS_VERSION
|
VERSION_VAR GNUTLS_VERSION
|
||||||
)
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARIES GNUTLS_LIBRARY GNUTLS_DANE_LIBRARY)
|
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARIES GNUTLS_LIBRARY GNUTLS_DANE_LIBRARY)
|
||||||
|
|
|
@ -28,27 +28,37 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(LIBEVENT2_INCLUDE_DIR event2/event.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgLibevent IMPORTED_TARGET GLOBAL QUIET libevent>=2)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgLibevent_FOUND)
|
||||||
|
set(LIBEVENT2_INCLUDE_DIR ${PkgLibevent_INCLUDE_DIRS} CACHE FILEPATH "libevent2 include path")
|
||||||
|
set(LIBEVENT2_LIBRARIES ${PkgLibevent_LIBRARIES} CACHE STRING "libevent2 libraries")
|
||||||
|
set(LIBEVENT2_VERSION ${PkgLibevent_VERSION})
|
||||||
|
add_library(Libevent2::Libevent_core ALIAS PkgConfig::PkgLibevent)
|
||||||
|
set(Libevent2_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(LIBEVENT2_INCLUDE_DIR event2/event.h
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBEVENT2_DIR}"
|
"${LIBEVENT2_DIR}"
|
||||||
"${LIBEVENT2_DIR}/include"
|
"${LIBEVENT2_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(LIBEVENT2_LIBRARY NAMES event_core libevent_core
|
find_library(LIBEVENT2_LIBRARIES NAMES event_core libevent_core
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBEVENT2_DIR}"
|
"${LIBEVENT2_DIR}"
|
||||||
"${LIBEVENT2_DIR}/lib"
|
"${LIBEVENT2_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBEVENT2_LIBRARIES "")
|
if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARIES)
|
||||||
|
|
||||||
if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARY)
|
|
||||||
if (NOT TARGET Libevent2::Libevent_core)
|
if (NOT TARGET Libevent2::Libevent_core)
|
||||||
add_library(Libevent2::Libevent_core UNKNOWN IMPORTED)
|
add_library(Libevent2::Libevent_core UNKNOWN IMPORTED)
|
||||||
set_target_properties(Libevent2::Libevent_core PROPERTIES
|
set_target_properties(Libevent2::Libevent_core PROPERTIES
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBEVENT2_INCLUDE_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${LIBEVENT2_INCLUDE_DIR}"
|
||||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||||
IMPORTED_LOCATION "${LIBEVENT2_LIBRARY}"
|
IMPORTED_LOCATION "${LIBEVENT2_LIBRARIES}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
@ -56,14 +66,13 @@ if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARY)
|
||||||
file(STRINGS "${LIBEVENT2_INCLUDE_DIR}/event2/event-config.h" LIBEVENT2_H REGEX "^#define _?EVENT_+VERSION ")
|
file(STRINGS "${LIBEVENT2_INCLUDE_DIR}/event2/event-config.h" LIBEVENT2_H REGEX "^#define _?EVENT_+VERSION ")
|
||||||
string(REGEX REPLACE "^.*EVENT_+VERSION \"([^\"]+)\".*$" "\\1" LIBEVENT2_VERSION "${LIBEVENT2_H}")
|
string(REGEX REPLACE "^.*EVENT_+VERSION \"([^\"]+)\".*$" "\\1" LIBEVENT2_VERSION "${LIBEVENT2_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
list(APPEND LIBEVENT2_LIBRARIES "${LIBEVENT2_LIBRARY}")
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Libevent2
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Libevent2
|
|
||||||
REQUIRED_VARS LIBEVENT2_LIBRARIES LIBEVENT2_INCLUDE_DIR
|
REQUIRED_VARS LIBEVENT2_LIBRARIES LIBEVENT2_INCLUDE_DIR
|
||||||
VERSION_VAR LIBEVENT2_VERSION
|
VERSION_VAR LIBEVENT2_VERSION
|
||||||
)
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
mark_as_advanced(LIBEVENT2_INCLUDE_DIR LIBEVENT2_LIBRARIES LIBEVENT2_LIBRARY)
|
mark_as_advanced(LIBEVENT2_INCLUDE_DIR LIBEVENT2_LIBRARIES)
|
||||||
|
|
|
@ -28,42 +28,50 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(LIBIDN2_INCLUDE_DIR idn2.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgLibIdn2 IMPORTED_TARGET GLOBAL libidn2)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgLibIdn2_FOUND)
|
||||||
|
set(LIBIDN2_INCLUDE_DIR ${PkgLibIdn2_INCLUDE_DIRS} CACHE FILEPATH "libidn2 include path")
|
||||||
|
set(LIBIDN2_LIBRARIES ${PkgLibIdn2_LIBRARIES} CACHE STRING "libidn2 libraries")
|
||||||
|
set(LIBIDN2_VERSION ${PkgLibIdn2_VERSION})
|
||||||
|
add_library(Libidn2::Libidn2 ALIAS PkgConfig::PkgLibIdn2)
|
||||||
|
set(Libidn2_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(LIBIDN2_INCLUDE_DIR idn2.h
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBIDN2_DIR}"
|
"${LIBIDN2_DIR}"
|
||||||
"${LIBIDN2_DIR}/include"
|
"${LIBIDN2_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(LIBIDN2_LIBRARY NAMES idn2 libidn2
|
find_library(LIBIDN2_LIBRARIES NAMES idn2 libidn2
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBIDN2_DIR}"
|
"${LIBIDN2_DIR}"
|
||||||
"${LIBIDN2_DIR}/lib"
|
"${LIBIDN2_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBIDN2_LIBRARIES "")
|
if (LIBIDN2_INCLUDE_DIR AND LIBIDN2_LIBRARIES)
|
||||||
|
|
||||||
if (LIBIDN2_INCLUDE_DIR AND LIBIDN2_LIBRARY)
|
|
||||||
if (NOT TARGET Libidn2::Libidn2)
|
if (NOT TARGET Libidn2::Libidn2)
|
||||||
add_library(Libidn2::Libidn2 UNKNOWN IMPORTED)
|
add_library(Libidn2::Libidn2 UNKNOWN IMPORTED)
|
||||||
set_target_properties(Libidn2::Libidn2 PROPERTIES
|
set_target_properties(Libidn2::Libidn2 PROPERTIES
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBIDN2_INCLUDE_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${LIBIDN2_INCLUDE_DIR}"
|
||||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||||
IMPORTED_LOCATION "${LIBIDN2_LIBRARY}"
|
IMPORTED_LOCATION "${LIBIDN2_LIBRARIES}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT LIBIDN2_VERSION AND LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/unbound.h")
|
if (NOT LIBIDN2_VERSION AND LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h")
|
||||||
file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" LIBIDN2_H REGEX "^#define IDN2_VERSION ")
|
file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" LIBIDN2_H REGEX "^[ \t]*#[ \t]*define[ \t]+IDN2_VERSION[ \t]")
|
||||||
string(REGEX REPLACE "^.*IDN2_VERSION \"([0-9.]+)\".*$" "\\1" LIBIDN2_VERSION "${LIBIDN2_H}")
|
string(REGEX REPLACE "^.*IDN2_VERSION[ \t]+\"([0-9.]+)\".*$" "\\1" LIBIDN2_VERSION "${LIBIDN2_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
list(APPEND LIBIDN2_LIBRARIES "${LIBIDN2_LIBRARY}")
|
find_package_handle_standard_args(Libidn2
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Libidn2
|
|
||||||
REQUIRED_VARS LIBIDN2_LIBRARIES LIBIDN2_INCLUDE_DIR
|
REQUIRED_VARS LIBIDN2_LIBRARIES LIBIDN2_INCLUDE_DIR
|
||||||
VERSION_VAR LIBIDN2_VERSION
|
VERSION_VAR LIBIDN2_VERSION
|
||||||
)
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARIES LIBIDN2_LIBRARY)
|
mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARIES)
|
||||||
|
|
|
@ -28,29 +28,41 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(LIBUNBOUND_INCLUDE_DIR unbound.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgLibunbound IMPORTED_TARGET GLOBAL QUIET libunbound)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgLibunbound_FOUND)
|
||||||
|
set(LIBUNBOUND_INCLUDE_DIR ${PkgLibunbound_INCLUDE_DIRS} CACHE FILEPATH "libunbound include path")
|
||||||
|
set(LIBUNBOUND_LIBRARIES ${PkgLibunbound_LIBRARIES} CACHE STRING "libunbound libraries")
|
||||||
|
set(LIBUNBOUND_VERSION ${PkgLibunbound_VERSION})
|
||||||
|
add_library(Libunbound::Libunbound ALIAS PkgConfig::PkgLibunbound)
|
||||||
|
set(Libunbound_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(LIBUNBOUND_INCLUDE_DIR unbound.h
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBUNBOUND_DIR}"
|
"${LIBUNBOUND_DIR}"
|
||||||
"${LIBUNBOUND_DIR}/include"
|
"${LIBUNBOUND_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(LIBUNBOUND_LIBRARY NAMES unbound
|
find_library(LIBUNBOUND_LIBRARY NAMES unbound
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBUNBOUND_DIR}"
|
"${LIBUNBOUND_DIR}"
|
||||||
"${LIBUNBOUND_DIR}/lib"
|
"${LIBUNBOUND_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBUNBOUND_LIBRARIES "")
|
set(_LIBUNBOUND_LIBRARIES "")
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
|
|
||||||
list(APPEND LIBUNBOUND_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
list(APPEND _LIBUNBOUND_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
list(APPEND LIBUNBOUND_LIBRARIES "${OPENSSL_LIBRARIES}")
|
list(APPEND _LIBUNBOUND_LIBRARIES "${OPENSSL_LIBRARIES}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LIBUNBOUND_INCLUDE_DIR AND LIBUNBOUND_LIBRARY)
|
if (LIBUNBOUND_INCLUDE_DIR AND LIBUNBOUND_LIBRARY)
|
||||||
if (NOT TARGET Libunbound::Libunbound)
|
if (NOT TARGET Libunbound::Libunbound)
|
||||||
add_library(Libunbound::Libunbound UNKNOWN IMPORTED)
|
add_library(Libunbound::Libunbound UNKNOWN IMPORTED)
|
||||||
set_target_properties(Libunbound::Libunbound PROPERTIES
|
set_target_properties(Libunbound::Libunbound PROPERTIES
|
||||||
|
@ -77,14 +89,16 @@ if (LIBUNBOUND_INCLUDE_DIR AND LIBUNBOUND_LIBRARY)
|
||||||
file(STRINGS "${LIBUNBOUND_INCLUDE_DIR}/unbound.h" LIBUNBOUND_H REGEX "^#define UNBOUND_VERSION_M[A-Z]+")
|
file(STRINGS "${LIBUNBOUND_INCLUDE_DIR}/unbound.h" LIBUNBOUND_H REGEX "^#define UNBOUND_VERSION_M[A-Z]+")
|
||||||
string(REGEX REPLACE "^.*MAJOR ([0-9]+).*MINOR ([0-9]+).*MICRO ([0-9]+).*$" "\\1.\\2.\\3" LIBUNBOUND_VERSION "${LIBUNBOUND_H}")
|
string(REGEX REPLACE "^.*MAJOR ([0-9]+).*MINOR ([0-9]+).*MICRO ([0-9]+).*$" "\\1.\\2.\\3" LIBUNBOUND_VERSION "${LIBUNBOUND_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
list(APPEND LIBUNBOUND_LIBRARIES "${LIBUNBOUND_LIBRARY}")
|
list(APPEND _LIBUNBOUND_LIBRARIES "${LIBUNBOUND_LIBRARY}")
|
||||||
|
set(LIBUNBOUND_LIBRARIES ${_LIBUNBOUND_LIBRARIES} CACHE STRING "libunbound libraries")
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(Libunbound
|
find_package_handle_standard_args(Libunbound
|
||||||
REQUIRED_VARS LIBUNBOUND_LIBRARIES LIBUNBOUND_INCLUDE_DIR
|
REQUIRED_VARS LIBUNBOUND_LIBRARIES LIBUNBOUND_INCLUDE_DIR
|
||||||
VERSION_VAR LIBUNBOUND_VERSION
|
VERSION_VAR LIBUNBOUND_VERSION
|
||||||
)
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
mark_as_advanced(LIBUNBOUND_INCLUDE_DIR LIBUNBOUND_LIBRARIES LIBUNBOUND_LIBRARY)
|
mark_as_advanced(LIBUNBOUND_INCLUDE_DIR LIBUNBOUND_LIBRARIES LIBUNBOUND_LIBRARY)
|
||||||
|
|
|
@ -28,27 +28,37 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(LIBUV_INCLUDE_DIR uv.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgLibuv IMPORTED_TARGET GLOBAL libuv)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PkgLibuv_FOUND)
|
||||||
|
set(LIBUV_INCLUDE_DIR ${PkgLibuv_INCLUDE_DIRS} CACHE FILEPATH "libuv include path")
|
||||||
|
set(LIBUV_LIBRARIES ${PkgLibuv_LIBRARIES} CACHE STRING "libuv libraries")
|
||||||
|
set(LIBUV_VERSION ${PkgLibuv_VERSION})
|
||||||
|
add_library(Libuv::Libuv ALIAS PkgConfig::PkgLibuv)
|
||||||
|
set(Libuv_FOUND ON)
|
||||||
|
else ()
|
||||||
|
find_path(LIBUV_INCLUDE_DIR uv.h
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBUV_DIR}"
|
"${LIBUV_DIR}"
|
||||||
"${LIBUV_DIR}/include"
|
"${LIBUV_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(LIBUV_LIBRARY NAMES uv libuv
|
find_library(LIBUV_LIBRARIES NAMES uv libuv
|
||||||
HINTS
|
HINTS
|
||||||
"${LIBUV_DIR}"
|
"${LIBUV_DIR}"
|
||||||
"${LIBUV_DIR}/lib"
|
"${LIBUV_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBUV_LIBRARIES "")
|
if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARIES)
|
||||||
|
|
||||||
if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARY)
|
|
||||||
if (NOT TARGET Libuv::Libuv)
|
if (NOT TARGET Libuv::Libuv)
|
||||||
add_library(Libuv::Libuv UNKNOWN IMPORTED)
|
add_library(Libuv::Libuv UNKNOWN IMPORTED)
|
||||||
set_target_properties(Libuv::Libuv PROPERTIES
|
set_target_properties(Libuv::Libuv PROPERTIES
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBUV_INCLUDE_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${LIBUV_INCLUDE_DIR}"
|
||||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||||
IMPORTED_LOCATION "${LIBUV_LIBRARY}"
|
IMPORTED_LOCATION "${LIBUV_LIBRARIES}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
@ -60,14 +70,13 @@ if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARY)
|
||||||
endif ()
|
endif ()
|
||||||
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*_PATCH ([0-9]+).*$" "\\1.\\2.\\3" LIBUV_VERSION "${LIBUV_VER_H}")
|
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*_PATCH ([0-9]+).*$" "\\1.\\2.\\3" LIBUV_VERSION "${LIBUV_VER_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
list(APPEND LIBUV_LIBRARIES "${LIBUV_LIBRARY}")
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Libuv
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Libuv
|
|
||||||
REQUIRED_VARS LIBUV_LIBRARIES LIBUV_INCLUDE_DIR
|
REQUIRED_VARS LIBUV_LIBRARIES LIBUV_INCLUDE_DIR
|
||||||
VERSION_VAR LIBUV_VERSION
|
VERSION_VAR LIBUV_VERSION
|
||||||
)
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARIES LIBUV_LIBRARY)
|
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARIES)
|
||||||
|
|
|
@ -30,36 +30,51 @@ This module will set the following variables in your project:
|
||||||
|
|
||||||
#]=======================================================================]
|
#]=======================================================================]
|
||||||
|
|
||||||
find_path(NETTLE_INCLUDE_DIR nettle/version.h
|
find_package(PkgConfig QUIET)
|
||||||
|
if(PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(PkgNettle IMPORTED_TARGET GLOBAL nettle)
|
||||||
|
pkg_check_modules(PkgHogweed IMPORTED_TARGET GLOBAL QUIET hogweed)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(PkgNettle_FOUND AND PkHogweed_FOUND)
|
||||||
|
set(NETTLE_INCLUDE_DIR ${PkgNettle_INCLUDE_DIRS} ${PkgHogweed_INCLUDE_DIRS} CACHE FILEPATH "Nettle include path")
|
||||||
|
set(NETTLE_LIBRARIES ${PkgNettle_LIBRARIES} ${PkgHogweed_LIBRARIES} CACHE STRING "Nettle libraries")
|
||||||
|
set(NETTLE_VERSION ${PkgNettle_VERSION})
|
||||||
|
add_library(Nettle::Nettle ALIAS PkgConfig::PkgNettle)
|
||||||
|
add_library(Nettle::Hogweed ALIAS PkgConfig::PkgHogweed)
|
||||||
|
set(Nettle_FOUND ON)
|
||||||
|
else()
|
||||||
|
find_path(NETTLE_INCLUDE_DIR nettle/version.h
|
||||||
HINTS
|
HINTS
|
||||||
"${NETTLE_DIR}"
|
"${NETTLE_DIR}"
|
||||||
"${NETTLE_DIR}/include"
|
"${NETTLE_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(NETTLE_LIBRARY NAMES nettle libnettle
|
find_library(NETTLE_LIBRARY NAMES nettle libnettle
|
||||||
HINTS
|
HINTS
|
||||||
"${NETTLE_DIR}"
|
"${NETTLE_DIR}"
|
||||||
"${NETTLE_DIR}/lib"
|
"${NETTLE_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(HOGWEED_LIBRARY NAMES hogweed libhogweed
|
find_library(HOGWEED_LIBRARY NAMES hogweed libhogweed
|
||||||
HINTS
|
HINTS
|
||||||
"${NETTLE_DIR}"
|
"${NETTLE_DIR}"
|
||||||
"${NETTLE_DIR}/lib"
|
"${NETTLE_DIR}/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(NETTLE_LIBRARIES "")
|
set(_NETTLE_LIBRARIES ${NETTLE_LIBRARY} ${HOGWEED_LIBRARY})
|
||||||
|
|
||||||
# May need gmp library on Unix.
|
# May need gmp library on Unix.
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
find_library(NETTLE_GMP_LIBRARY gmp)
|
find_library(NETTLE_GMP_LIBRARY gmp)
|
||||||
|
|
||||||
if (NETTLE_GMP_LIBRARY)
|
|
||||||
list(APPEND NETTLE_LIBRARIES "${NETTLE_GMP_LIBRARY}")
|
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
if (NETTLE_GMP_LIBRARY)
|
||||||
|
list(APPEND _NETTLE_LIBRARIES "${NETTLE_GMP_LIBRARY}")
|
||||||
|
endif ()
|
||||||
|
set(NETTLE_LIBRARIES ${_NETTLE_LIBRARIES} CACHE STRING "nettle libraries")
|
||||||
|
|
||||||
if (NETTLE_INCLUDE_DIR AND NETTLE_LIBRARY AND HOGWEED_LIBRARY)
|
|
||||||
|
if (NETTLE_INCLUDE_DIR AND NETTLE_LIBRARY AND HOGWEED_LIBRARY)
|
||||||
if (NOT TARGET Nettle::Nettle)
|
if (NOT TARGET Nettle::Nettle)
|
||||||
add_library(Nettle::Nettle UNKNOWN IMPORTED)
|
add_library(Nettle::Nettle UNKNOWN IMPORTED)
|
||||||
set_target_properties(Nettle::Nettle PROPERTIES
|
set_target_properties(Nettle::Nettle PROPERTIES
|
||||||
|
@ -82,14 +97,15 @@ if (NETTLE_INCLUDE_DIR AND NETTLE_LIBRARY AND HOGWEED_LIBRARY)
|
||||||
file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h" NETTLE_VER_H REGEX "^#define NETTLE_VERSION_(MAJOR|MINOR) ")
|
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}")
|
string(REGEX REPLACE "^.*_MAJOR ([0-9]+).*_MINOR ([0-9]+).*$" "\\1.\\2" NETTLE_VERSION "${NETTLE_VER_H}")
|
||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND NETTLE_LIBRARIES "${NETTLE_LIBRARY}" "${HOGWEED_LIBRARY}")
|
list(APPEND NETTLE_LIBRARIES "${NETTLE_LIBRARY}" "${HOGWEED_LIBRARY}")
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(Nettle
|
find_package_handle_standard_args(Nettle
|
||||||
REQUIRED_VARS NETTLE_LIBRARIES NETTLE_INCLUDE_DIR
|
REQUIRED_VARS NETTLE_LIBRARIES NETTLE_INCLUDE_DIR
|
||||||
VERSION_VAR NETTLE_VERSION
|
VERSION_VAR NETTLE_VERSION
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARIES NETTLE_LIBRARY HOGWEED_LIBRARY)
|
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARIES NETTLE_LIBRARY HOGWEED_LIBRARY NETTLE_GMP_LIBRARY)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
libdir=@libdir_for_pc_file@
|
||||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
includedir=@includedir_for_pc_file@
|
||||||
|
|
||||||
Name: getdns
|
Name: getdns
|
||||||
Version: @GETDNS_VERSION@
|
Version: @GETDNS_VERSION@
|
||||||
|
|
|
@ -1390,6 +1390,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
#endif
|
#endif
|
||||||
result->processing = 0;
|
result->processing = 0;
|
||||||
result->destroying = 0;
|
result->destroying = 0;
|
||||||
|
result->to_destroy = 0;
|
||||||
result->my_mf.mf_arg = userarg;
|
result->my_mf.mf_arg = userarg;
|
||||||
result->my_mf.mf.ext.malloc = malloc;
|
result->my_mf.mf.ext.malloc = malloc;
|
||||||
result->my_mf.mf.ext.realloc = realloc;
|
result->my_mf.mf.ext.realloc = realloc;
|
||||||
|
@ -1642,8 +1643,11 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If being destroyed during getdns callback, fail via assert */
|
|
||||||
assert(context->processing == 0);
|
assert(context->processing == 0);
|
||||||
|
if (context->processing == 1) {
|
||||||
|
context->to_destroy = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (context->destroying)
|
if (context->destroying)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3768,7 +3772,6 @@ getdns_context_get_num_pending_requests(const getdns_context* context,
|
||||||
|
|
||||||
if (context->outbound_requests.count)
|
if (context->outbound_requests.count)
|
||||||
context->extension->vmt->run_once(context->extension, 0);
|
context->extension->vmt->run_once(context->extension, 0);
|
||||||
|
|
||||||
return context->outbound_requests.count;
|
return context->outbound_requests.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,6 +4099,9 @@ getdns_context_get_api_information(const getdns_context* context)
|
||||||
&& ! getdns_dict_util_set_string(
|
&& ! getdns_dict_util_set_string(
|
||||||
result, "compilation_comment", GETDNS_COMPILATION_COMMENT)
|
result, "compilation_comment", GETDNS_COMPILATION_COMMENT)
|
||||||
|
|
||||||
|
&& ! getdns_dict_util_set_string(
|
||||||
|
result, "build_cflags", GETDNS_BUILD_CFLAGS)
|
||||||
|
|
||||||
&& ! getdns_dict_util_set_string(
|
&& ! getdns_dict_util_set_string(
|
||||||
result, "default_trust_anchor_location", TRUST_ANCHOR_FILE)
|
result, "default_trust_anchor_location", TRUST_ANCHOR_FILE)
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,7 @@ struct getdns_context {
|
||||||
|
|
||||||
int processing;
|
int processing;
|
||||||
int destroying;
|
int destroying;
|
||||||
|
int to_destroy;
|
||||||
|
|
||||||
struct mem_funcs mf;
|
struct mem_funcs mf;
|
||||||
struct mem_funcs my_mf;
|
struct mem_funcs my_mf;
|
||||||
|
|
|
@ -529,8 +529,10 @@ _getdns_fp2rr_list(struct mem_funcs *mf,
|
||||||
else while (r == GETDNS_RETURN_GOOD && !feof(in)) {
|
else while (r == GETDNS_RETURN_GOOD && !feof(in)) {
|
||||||
len = GLDNS_RR_BUF_SIZE;
|
len = GLDNS_RR_BUF_SIZE;
|
||||||
dname_len = 0;
|
dname_len = 0;
|
||||||
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
|
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst)) {
|
||||||
|
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
|
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
|
||||||
memcpy(pst.prev_rr, rr, dname_len);
|
memcpy(pst.prev_rr, rr, dname_len);
|
||||||
pst.prev_rr_len = dname_len;
|
pst.prev_rr_len = dname_len;
|
||||||
|
@ -1189,7 +1191,7 @@ _getdns_ipaddr_dict_mf(struct mem_funcs *mf, const char *ipstr)
|
||||||
tsig_name_str = "";
|
tsig_name_str = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*ipstr == '*') {
|
if (*ipstr == '*' && *(ipstr+1) == '\0') {
|
||||||
getdns_dict_util_set_string(r, "address_type", "IPv6");
|
getdns_dict_util_set_string(r, "address_type", "IPv6");
|
||||||
addr.size = 16;
|
addr.size = 16;
|
||||||
(void) memset(buf, 0, 16);
|
(void) memset(buf, 0, 16);
|
||||||
|
|
|
@ -1554,7 +1554,7 @@ static int _getdns_verify_rrsig(const struct mem_funcs *mf,
|
||||||
for ( rdf = _getdns_rdf_iter_init(&rdf_spc, &val_rrset[i])
|
for ( rdf = _getdns_rdf_iter_init(&rdf_spc, &val_rrset[i])
|
||||||
; rdf
|
; rdf
|
||||||
; rdf = _getdns_rdf_iter_next(rdf) ) {
|
; rdf = _getdns_rdf_iter_next(rdf) ) {
|
||||||
if (!(rdf->rdd_pos->type & GETDNS_RDF_N)) {
|
if ((rdf->rdd_pos->type & GETDNS_RDF_N) != GETDNS_RDF_N) {
|
||||||
gldns_buffer_write(
|
gldns_buffer_write(
|
||||||
&valbuf, rdf->pos, rdf->nxt - rdf->pos);
|
&valbuf, rdf->pos, rdf->nxt - rdf->pos);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ getdns_context_set_follow_redirects(getdns_context *context,
|
||||||
* contains at least two names: address_type (whose value is
|
* contains at least two names: address_type (whose value is
|
||||||
* a bindata; it is currently either "IPv4" or "IPv6") and
|
* a bindata; it is currently either "IPv4" or "IPv6") and
|
||||||
* address_data (whose value is a bindata).
|
* address_data (whose value is a bindata).
|
||||||
* This implementation also accepts a list of addressxi
|
* This implementation also accepts a list of address
|
||||||
* bindatas. Or a list of rr_dicts for address records (i.e.
|
* bindatas. Or a list of rr_dicts for address records (i.e.
|
||||||
* the additional section of a NS query for ".", or a with
|
* the additional section of a NS query for ".", or a with
|
||||||
* getdns_fp2rr_list() converted root.hints file).
|
* getdns_fp2rr_list() converted root.hints file).
|
||||||
|
|
|
@ -128,6 +128,7 @@ extern "C" {
|
||||||
#define GETDNS_NUMERIC_VERSION @GETDNS_NUMERIC_VERSION@
|
#define GETDNS_NUMERIC_VERSION @GETDNS_NUMERIC_VERSION@
|
||||||
#define GETDNS_API_VERSION "@API_VERSION@"
|
#define GETDNS_API_VERSION "@API_VERSION@"
|
||||||
#define GETDNS_API_NUMERIC_VERSION @API_NUMERIC_VERSION@
|
#define GETDNS_API_NUMERIC_VERSION @API_NUMERIC_VERSION@
|
||||||
|
#define GETDNS_BUILD_CFLAGS "@GETDNS_BUILD_CFLAGS@"
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "gldns/gbuffer.h"
|
#include "gldns/gbuffer.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <strings.h>
|
||||||
|
|
||||||
gldns_lookup_table gldns_directive_types[] = {
|
gldns_lookup_table gldns_directive_types[] = {
|
||||||
{ GLDNS_DIR_TTL, "$TTL" },
|
{ GLDNS_DIR_TTL, "$TTL" },
|
||||||
|
@ -34,7 +34,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||||
{
|
{
|
||||||
int c, prev_c;
|
int c, prev_c;
|
||||||
int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
|
int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
|
||||||
int com, quoted;
|
int com, quoted, only_blank;
|
||||||
char *t;
|
char *t;
|
||||||
size_t i;
|
size_t i;
|
||||||
const char *d;
|
const char *d;
|
||||||
|
@ -53,6 +53,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||||
com = 0;
|
com = 0;
|
||||||
quoted = 0;
|
quoted = 0;
|
||||||
prev_c = 0;
|
prev_c = 0;
|
||||||
|
only_blank = 1; /* Assume we got only <blank> until now */
|
||||||
t = token;
|
t = token;
|
||||||
if (del[0] == '"') {
|
if (del[0] == '"') {
|
||||||
quoted = 1;
|
quoted = 1;
|
||||||
|
@ -101,6 +102,22 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||||
if (line_nr) {
|
if (line_nr) {
|
||||||
*line_nr = *line_nr + 1;
|
*line_nr = *line_nr + 1;
|
||||||
}
|
}
|
||||||
|
if (only_blank && i > 0) {
|
||||||
|
/* Got only <blank> so far. Reset and try
|
||||||
|
* again with the next line.
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
t = token;
|
||||||
|
}
|
||||||
|
if (p == 0) {
|
||||||
|
/* If p != 0 then the next line is a continuation. So
|
||||||
|
* we assume that the next line starts with a blank only
|
||||||
|
* if it is actually a new line.
|
||||||
|
*/
|
||||||
|
only_blank = 1; /* Assume next line starts with
|
||||||
|
* <blank>.
|
||||||
|
*/
|
||||||
|
}
|
||||||
if (p == 0 && i > 0) {
|
if (p == 0 && i > 0) {
|
||||||
goto tokenread;
|
goto tokenread;
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,12 +148,29 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||||
|
|
||||||
/* check if we hit the delim */
|
/* check if we hit the delim */
|
||||||
for (d = del; *d; d++) {
|
for (d = del; *d; d++) {
|
||||||
|
if (c == *d)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
|
if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
|
||||||
if (c == '\n' && line_nr) {
|
if (c == '\n' && line_nr) {
|
||||||
*line_nr = *line_nr + 1;
|
*line_nr = *line_nr + 1;
|
||||||
}
|
}
|
||||||
|
if (only_blank) {
|
||||||
|
/* Got only <blank> so far. Reset and
|
||||||
|
* try again with the next line.
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
t = token;
|
||||||
|
only_blank = 1;
|
||||||
|
prev_c = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
goto tokenread;
|
goto tokenread;
|
||||||
}
|
}
|
||||||
|
if (c != ' ' && c != '\t') {
|
||||||
|
/* Found something that is not <blank> */
|
||||||
|
only_blank= 0;
|
||||||
}
|
}
|
||||||
if (c != '\0' && c != '\n') {
|
if (c != '\0' && c != '\n') {
|
||||||
i++;
|
i++;
|
||||||
|
@ -149,6 +183,14 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||||
if (c != '\0' && c != '\n') {
|
if (c != '\0' && c != '\n') {
|
||||||
*t++ = c;
|
*t++ = c;
|
||||||
}
|
}
|
||||||
|
if (c == '\n') {
|
||||||
|
if (line_nr) {
|
||||||
|
*line_nr = *line_nr + 1;
|
||||||
|
}
|
||||||
|
only_blank = 1; /* Assume next line starts with
|
||||||
|
* <blank>.
|
||||||
|
*/
|
||||||
|
}
|
||||||
if (c == '\\' && prev_c == '\\')
|
if (c == '\\' && prev_c == '\\')
|
||||||
prev_c = 0;
|
prev_c = 0;
|
||||||
else prev_c = c;
|
else prev_c = c;
|
||||||
|
|
|
@ -14,12 +14,8 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "gldns/parseutil.h"
|
#include "gldns/parseutil.h"
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_TIME_H
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
gldns_lookup_table *
|
gldns_lookup_table *
|
||||||
|
@ -213,11 +209,13 @@ gldns_hexdigit_to_int(char ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
gldns_str2period(const char *nptr, const char **endptr)
|
gldns_str2period(const char *nptr, const char **endptr, int* overflow)
|
||||||
{
|
{
|
||||||
int sign = 0;
|
int sign = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t seconds = 0;
|
uint32_t seconds = 0;
|
||||||
|
const uint32_t maxint = 0xffffffff;
|
||||||
|
*overflow = 0;
|
||||||
|
|
||||||
for(*endptr = nptr; **endptr; (*endptr)++) {
|
for(*endptr = nptr; **endptr; (*endptr)++) {
|
||||||
switch (**endptr) {
|
switch (**endptr) {
|
||||||
|
@ -240,26 +238,46 @@ gldns_str2period(const char *nptr, const char **endptr)
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
|
if(seconds > maxint-i) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i;
|
seconds += i;
|
||||||
i = 0;
|
i = 0;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
|
if(i > maxint/60 || seconds > maxint-(i*60)) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i * 60;
|
seconds += i * 60;
|
||||||
i = 0;
|
i = 0;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
|
if(i > maxint/(60*60) || seconds > maxint-(i*60*60)) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i * 60 * 60;
|
seconds += i * 60 * 60;
|
||||||
i = 0;
|
i = 0;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D':
|
case 'D':
|
||||||
|
if(i > maxint/(60*60*24) || seconds > maxint-(i*60*60*24)) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i * 60 * 60 * 24;
|
seconds += i * 60 * 60 * 24;
|
||||||
i = 0;
|
i = 0;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'W':
|
case 'W':
|
||||||
|
if(i > maxint/(60*60*24*7) || seconds > maxint-(i*60*60*24*7)) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i * 60 * 60 * 24 * 7;
|
seconds += i * 60 * 60 * 24 * 7;
|
||||||
i = 0;
|
i = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -273,15 +291,27 @@ gldns_str2period(const char *nptr, const char **endptr)
|
||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
|
if(i > maxint/10 || i*10 > maxint - (**endptr - '0')) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
i *= 10;
|
i *= 10;
|
||||||
i += (**endptr - '0');
|
i += (**endptr - '0');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if(seconds > maxint-i) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i;
|
seconds += i;
|
||||||
/* disregard signedness */
|
/* disregard signedness */
|
||||||
return seconds;
|
return seconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(seconds > maxint-i) {
|
||||||
|
*overflow = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
seconds += i;
|
seconds += i;
|
||||||
/* disregard signedness */
|
/* disregard signedness */
|
||||||
return seconds;
|
return seconds;
|
||||||
|
@ -794,3 +824,18 @@ int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
|
||||||
}
|
}
|
||||||
return gldns_b64_pton_base(src, srcsize, target, targsize, 1);
|
return gldns_b64_pton_base(src, srcsize, target, targsize, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gldns_b64_contains_nonurl(char const *src, size_t srcsize)
|
||||||
|
{
|
||||||
|
const char* s = src;
|
||||||
|
while(*s && srcsize) {
|
||||||
|
char d = *s++;
|
||||||
|
srcsize--;
|
||||||
|
/* the '+' and the '/' and padding '=' is not allowed in b64
|
||||||
|
* url encoding */
|
||||||
|
if(d == '+' || d == '/' || d == '=') {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ time_t gldns_mktime_from_utc(const struct tm *tm);
|
||||||
* The function interprets time as the number of seconds since epoch
|
* The function interprets time as the number of seconds since epoch
|
||||||
* with respect to now using serial arithmetics (rfc1982).
|
* with respect to now using serial arithmetics (rfc1982).
|
||||||
* That number of seconds is then converted to broken-out time information.
|
* That number of seconds is then converted to broken-out time information.
|
||||||
* This is especially usefull when converting the inception and expiration
|
* This is especially useful when converting the inception and expiration
|
||||||
* fields of RRSIG records.
|
* fields of RRSIG records.
|
||||||
*
|
*
|
||||||
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
|
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
|
||||||
|
@ -74,9 +74,11 @@ struct tm * gldns_serial_arithmetics_gmtime_r(int32_t time, time_t now, struct t
|
||||||
* converts a ttl value (like 5d2h) to a long.
|
* converts a ttl value (like 5d2h) to a long.
|
||||||
* \param[in] nptr the start of the string
|
* \param[in] nptr the start of the string
|
||||||
* \param[out] endptr points to the last char in case of error
|
* \param[out] endptr points to the last char in case of error
|
||||||
|
* \param[out] overflow returns if the string causes integer overflow error,
|
||||||
|
* the number is too big, string of digits too long.
|
||||||
* \return the convert duration value
|
* \return the convert duration value
|
||||||
*/
|
*/
|
||||||
uint32_t gldns_str2period(const char *nptr, const char **endptr);
|
uint32_t gldns_str2period(const char *nptr, const char **endptr, int* overflow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the int value of the given (hex) digit
|
* Returns the int value of the given (hex) digit
|
||||||
|
@ -102,6 +104,7 @@ size_t gldns_b64_pton_calculate_size(size_t srcsize);
|
||||||
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
|
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
|
||||||
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
|
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
|
||||||
size_t targsize);
|
size_t targsize);
|
||||||
|
int gldns_b64_contains_nonurl(char const *src, size_t srcsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculates the size needed to store the result of b32_ntop
|
* calculates the size needed to store the result of b32_ntop
|
||||||
|
|
|
@ -97,18 +97,22 @@ extern "C" {
|
||||||
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
|
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
|
||||||
*/
|
*/
|
||||||
#define GLDNS_QDCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_QDCOUNT_OFF))
|
#define GLDNS_QDCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_QDCOUNT_OFF))
|
||||||
|
#define GLDNS_QDCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_QDCOUNT_OFF, i))
|
||||||
|
|
||||||
/* Counter of the answer section */
|
/* Counter of the answer section */
|
||||||
#define GLDNS_ANCOUNT_OFF 6
|
#define GLDNS_ANCOUNT_OFF 6
|
||||||
#define GLDNS_ANCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ANCOUNT_OFF))
|
#define GLDNS_ANCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ANCOUNT_OFF))
|
||||||
|
#define GLDNS_ANCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_ANCOUNT_OFF, i))
|
||||||
|
|
||||||
/* Counter of the authority section */
|
/* Counter of the authority section */
|
||||||
#define GLDNS_NSCOUNT_OFF 8
|
#define GLDNS_NSCOUNT_OFF 8
|
||||||
#define GLDNS_NSCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_NSCOUNT_OFF))
|
#define GLDNS_NSCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_NSCOUNT_OFF))
|
||||||
|
#define GLDNS_NSCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_NSCOUNT_OFF, i))
|
||||||
|
|
||||||
/* Counter of the additional section */
|
/* Counter of the additional section */
|
||||||
#define GLDNS_ARCOUNT_OFF 10
|
#define GLDNS_ARCOUNT_OFF 10
|
||||||
#define GLDNS_ARCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ARCOUNT_OFF))
|
#define GLDNS_ARCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ARCOUNT_OFF))
|
||||||
|
#define GLDNS_ARCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_ARCOUNT_OFF, i))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sections of a packet
|
* The sections of a packet
|
||||||
|
|
|
@ -155,6 +155,9 @@ static const gldns_rdf_type type_csync_wireformat[] = {
|
||||||
static const gldns_rdf_type type_zonemd_wireformat[] = {
|
static const gldns_rdf_type type_zonemd_wireformat[] = {
|
||||||
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_HEX
|
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_HEX
|
||||||
};
|
};
|
||||||
|
static const gldns_rdf_type type_svcb_wireformat[] = {
|
||||||
|
GLDNS_RDF_TYPE_INT16, GLDNS_RDF_TYPE_DNAME
|
||||||
|
};
|
||||||
/* nsec3 is some vars, followed by same type of data of nsec */
|
/* nsec3 is some vars, followed by same type of data of nsec */
|
||||||
static const gldns_rdf_type type_nsec3_wireformat[] = {
|
static const gldns_rdf_type type_nsec3_wireformat[] = {
|
||||||
/* GLDNS_RDF_TYPE_NSEC3_VARS, GLDNS_RDF_TYPE_NSEC3_NEXT_OWNER, GLDNS_RDF_TYPE_NSEC*/
|
/* GLDNS_RDF_TYPE_NSEC3_VARS, GLDNS_RDF_TYPE_NSEC3_NEXT_OWNER, GLDNS_RDF_TYPE_NSEC*/
|
||||||
|
@ -388,8 +391,10 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
|
||||||
{GLDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{GLDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
/* 63 */
|
/* 63 */
|
||||||
{GLDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{GLDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
{(enum gldns_enum_rr_type)0, "TYPE64", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
/* 64 */
|
||||||
{(enum gldns_enum_rr_type)0, "TYPE65", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{GLDNS_RR_TYPE_SVCB, "SVCB", 2, 2, type_svcb_wireformat, GLDNS_RDF_TYPE_SVCPARAM, GLDNS_RR_NO_COMPRESS, 1 },
|
||||||
|
/* 65 */
|
||||||
|
{GLDNS_RR_TYPE_HTTPS, "HTTPS", 2, 2, type_svcb_wireformat, GLDNS_RDF_TYPE_SVCPARAM, GLDNS_RR_NO_COMPRESS, 1 },
|
||||||
{(enum gldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{(enum gldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
{(enum gldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{(enum gldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
{(enum gldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
{(enum gldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
|
||||||
|
|
|
@ -196,8 +196,8 @@ enum gldns_enum_rr_type
|
||||||
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
|
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
|
||||||
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
|
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
|
||||||
GLDNS_RR_TYPE_ZONEMD = 63, /* RFC8976 */
|
GLDNS_RR_TYPE_ZONEMD = 63, /* RFC8976 */
|
||||||
GLDNS_RR_TYPE_SVCB = 64,
|
GLDNS_RR_TYPE_SVCB = 64, /* draft-ietf-dnsop-svcb-https-04 */
|
||||||
GLDNS_RR_TYPE_HTTPS = 65,
|
GLDNS_RR_TYPE_HTTPS = 65, /* draft-ietf-dnsop-svcb-https-04 */
|
||||||
|
|
||||||
GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
|
GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
|
||||||
|
|
||||||
|
@ -360,8 +360,13 @@ enum gldns_enum_rdf_type
|
||||||
/** TSIG extended 16bit error value */
|
/** TSIG extended 16bit error value */
|
||||||
GLDNS_RDF_TYPE_TSIGERROR,
|
GLDNS_RDF_TYPE_TSIGERROR,
|
||||||
|
|
||||||
|
/* draft-ietf-dnsop-svcb-https-05:
|
||||||
|
* each SvcParam consisting of a SvcParamKey=SvcParamValue pair or
|
||||||
|
* a standalone SvcParamKey */
|
||||||
|
GLDNS_RDF_TYPE_SVCPARAM,
|
||||||
|
|
||||||
/* Aliases */
|
/* Aliases */
|
||||||
GLDNS_RDF_TYPE_BITMAP = GLDNS_RDF_TYPE_NSEC
|
GLDNS_RDF_TYPE_BITMAP = GLDNS_RDF_TYPE_NSEC,
|
||||||
};
|
};
|
||||||
typedef enum gldns_enum_rdf_type gldns_rdf_type;
|
typedef enum gldns_enum_rdf_type gldns_rdf_type;
|
||||||
|
|
||||||
|
@ -435,10 +440,42 @@ enum gldns_enum_edns_option
|
||||||
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||||
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||||
GLDNS_EDNS_PADDING = 12, /* RFC7830 */
|
GLDNS_EDNS_PADDING = 12, /* RFC7830 */
|
||||||
|
GLDNS_EDNS_EDE = 15, /* RFC8914 */
|
||||||
GLDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
|
GLDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
|
||||||
};
|
};
|
||||||
typedef enum gldns_enum_edns_option gldns_edns_option;
|
typedef enum gldns_enum_edns_option gldns_edns_option;
|
||||||
|
|
||||||
|
enum gldns_enum_ede_code
|
||||||
|
{
|
||||||
|
GLDNS_EDE_NONE = -1, /* EDE undefined for internal use */
|
||||||
|
GLDNS_EDE_OTHER = 0,
|
||||||
|
GLDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
|
||||||
|
GLDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
|
||||||
|
GLDNS_EDE_STALE_ANSWER = 3,
|
||||||
|
GLDNS_EDE_FORGED_ANSWER = 4,
|
||||||
|
GLDNS_EDE_DNSSEC_INDETERMINATE = 5,
|
||||||
|
GLDNS_EDE_DNSSEC_BOGUS = 6,
|
||||||
|
GLDNS_EDE_SIGNATURE_EXPIRED = 7,
|
||||||
|
GLDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
|
||||||
|
GLDNS_EDE_DNSKEY_MISSING = 9,
|
||||||
|
GLDNS_EDE_RRSIGS_MISSING = 10,
|
||||||
|
GLDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
|
||||||
|
GLDNS_EDE_NSEC_MISSING = 12,
|
||||||
|
GLDNS_EDE_CACHED_ERROR = 13,
|
||||||
|
GLDNS_EDE_NOT_READY = 14,
|
||||||
|
GLDNS_EDE_BLOCKED = 15,
|
||||||
|
GLDNS_EDE_CENSORED = 16,
|
||||||
|
GLDNS_EDE_FILTERED = 17,
|
||||||
|
GLDNS_EDE_PROHIBITED = 18,
|
||||||
|
GLDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
|
||||||
|
GLDNS_EDE_NOT_AUTHORITATIVE = 20,
|
||||||
|
GLDNS_EDE_NOT_SUPPORTED = 21,
|
||||||
|
GLDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||||
|
GLDNS_EDE_NETWORK_ERROR = 23,
|
||||||
|
GLDNS_EDE_INVALID_DATA = 24,
|
||||||
|
};
|
||||||
|
typedef enum gldns_enum_ede_code gldns_ede_code;
|
||||||
|
|
||||||
#define GLDNS_EDNS_MASK_DO_BIT 0x8000
|
#define GLDNS_EDNS_MASK_DO_BIT 0x8000
|
||||||
|
|
||||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||||
|
|
|
@ -26,11 +26,12 @@
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** bits for the offset */
|
||||||
|
#define RET_OFFSET_MASK (((unsigned)(~GLDNS_WIREPARSE_MASK))>>GLDNS_WIREPARSE_SHIFT)
|
||||||
/** return an error */
|
/** return an error */
|
||||||
#define RET_ERR(e, off) ((int)((e)|((off)<<GLDNS_WIREPARSE_SHIFT)))
|
#define RET_ERR(e, off) ((int)(((e)&GLDNS_WIREPARSE_MASK)|(((off)&RET_OFFSET_MASK)<<GLDNS_WIREPARSE_SHIFT)))
|
||||||
/** Move parse error but keep its ID */
|
/** Move parse error but keep its ID */
|
||||||
#define RET_ERR_SHIFT(e, move) RET_ERR(GLDNS_WIREPARSE_ERROR(e), GLDNS_WIREPARSE_OFFSET(e)+(move));
|
#define RET_ERR_SHIFT(e, move) RET_ERR(GLDNS_WIREPARSE_ERROR(e), GLDNS_WIREPARSE_OFFSET(e)+(move));
|
||||||
#define GLDNS_IP6ADDRLEN (128/8)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No special care is taken, all dots are translated into
|
* No special care is taken, all dots are translated into
|
||||||
|
@ -249,11 +250,16 @@ rrinternal_get_ttl(gldns_buffer* strbuf, char* token, size_t token_len,
|
||||||
int* not_there, uint32_t* ttl, uint32_t default_ttl)
|
int* not_there, uint32_t* ttl, uint32_t default_ttl)
|
||||||
{
|
{
|
||||||
const char* endptr;
|
const char* endptr;
|
||||||
|
int overflow;
|
||||||
if(gldns_bget_token(strbuf, token, "\t\n ", token_len) == -1) {
|
if(gldns_bget_token(strbuf, token, "\t\n ", token_len) == -1) {
|
||||||
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_TTL,
|
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_TTL,
|
||||||
gldns_buffer_position(strbuf));
|
gldns_buffer_position(strbuf));
|
||||||
}
|
}
|
||||||
*ttl = (uint32_t) gldns_str2period(token, &endptr);
|
*ttl = (uint32_t) gldns_str2period(token, &endptr, &overflow);
|
||||||
|
if(overflow) {
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
|
||||||
|
gldns_buffer_position(strbuf));
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
|
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
|
||||||
*not_there = 1;
|
*not_there = 1;
|
||||||
|
@ -373,7 +379,8 @@ rrinternal_get_quoted(gldns_buffer* strbuf, const char** delimiters,
|
||||||
|
|
||||||
/* skip spaces */
|
/* skip spaces */
|
||||||
while(gldns_buffer_remaining(strbuf) > 0 &&
|
while(gldns_buffer_remaining(strbuf) > 0 &&
|
||||||
*(gldns_buffer_current(strbuf)) == ' ') {
|
(*(gldns_buffer_current(strbuf)) == ' ' ||
|
||||||
|
*(gldns_buffer_current(strbuf)) == '\t')) {
|
||||||
gldns_buffer_skip(strbuf, 1);
|
gldns_buffer_skip(strbuf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,9 +552,10 @@ gldns_parse_rdf_token(gldns_buffer* strbuf, char* token, size_t token_len,
|
||||||
{
|
{
|
||||||
size_t slen;
|
size_t slen;
|
||||||
|
|
||||||
/* skip spaces */
|
/* skip spaces and tabs */
|
||||||
while(gldns_buffer_remaining(strbuf) > 0 && !*quoted &&
|
while(gldns_buffer_remaining(strbuf) > 0 && !*quoted &&
|
||||||
*(gldns_buffer_current(strbuf)) == ' ') {
|
(*(gldns_buffer_current(strbuf)) == ' ' ||
|
||||||
|
*(gldns_buffer_current(strbuf)) == '\t')) {
|
||||||
gldns_buffer_skip(strbuf, 1);
|
gldns_buffer_skip(strbuf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +611,10 @@ gldns_affix_token(gldns_buffer* strbuf, char* token, size_t* token_len,
|
||||||
size_t addstrlen = 0;
|
size_t addstrlen = 0;
|
||||||
|
|
||||||
/* add space */
|
/* add space */
|
||||||
if(addlen < 1) return 0;
|
/* when addlen < 2, the token buffer is full considering the NULL byte
|
||||||
|
* from strlen and will lead to buffer overflow with the second
|
||||||
|
* assignment below. */
|
||||||
|
if(addlen < 2) return 0;
|
||||||
token[*token_strlen] = ' ';
|
token[*token_strlen] = ' ';
|
||||||
token[++(*token_strlen)] = 0;
|
token[++(*token_strlen)] = 0;
|
||||||
|
|
||||||
|
@ -616,6 +627,122 @@ gldns_affix_token(gldns_buffer* strbuf, char* token, size_t* token_len,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gldns_str2wire_svcparam_key_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return gldns_read_uint16(*(uint8_t**) a)
|
||||||
|
- gldns_read_uint16(*(uint8_t**) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add constraints to the SVCB RRs which involve the whole set
|
||||||
|
*/
|
||||||
|
static int gldns_str2wire_check_svcbparams(uint8_t* rdata, uint16_t rdata_len)
|
||||||
|
{
|
||||||
|
size_t nparams = 0, i;
|
||||||
|
uint8_t new_rdata[GLDNS_MAX_RDFLEN];
|
||||||
|
uint8_t* new_rdata_ptr = new_rdata;
|
||||||
|
uint8_t* svcparams[MAX_NUMBER_OF_SVCPARAMS];
|
||||||
|
uint8_t* rdata_ptr = rdata;
|
||||||
|
uint16_t rdata_remaining = rdata_len;
|
||||||
|
|
||||||
|
/* find the SvcParams */
|
||||||
|
while (rdata_remaining) {
|
||||||
|
uint16_t svcbparam_len;
|
||||||
|
|
||||||
|
svcparams[nparams] = rdata_ptr;
|
||||||
|
if (rdata_remaining < 4)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
|
||||||
|
svcbparam_len = gldns_read_uint16(rdata_ptr + 2);
|
||||||
|
rdata_remaining -= 4;
|
||||||
|
rdata_ptr += 4;
|
||||||
|
|
||||||
|
if (rdata_remaining < svcbparam_len)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
|
||||||
|
rdata_remaining -= svcbparam_len;
|
||||||
|
rdata_ptr += svcbparam_len;
|
||||||
|
|
||||||
|
nparams += 1;
|
||||||
|
if (nparams >= MAX_NUMBER_OF_SVCPARAMS)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
|
||||||
|
*
|
||||||
|
* In wire format, the keys are represented by their numeric
|
||||||
|
* values in network byte order, concatenated in ascending order.
|
||||||
|
*/
|
||||||
|
qsort((void *)svcparams
|
||||||
|
,nparams
|
||||||
|
,sizeof(uint8_t*)
|
||||||
|
,gldns_str2wire_svcparam_key_cmp);
|
||||||
|
|
||||||
|
|
||||||
|
/* The code below revolves around semantic errors in the SVCParam set.
|
||||||
|
* So long as we do not distinguish between running Unbound as a primary
|
||||||
|
* or as a secondary, we default to secondary behavior and we ignore the
|
||||||
|
* semantic errors. */
|
||||||
|
|
||||||
|
#ifdef SVCB_SEMANTIC_ERRORS
|
||||||
|
{
|
||||||
|
uint8_t* mandatory = NULL;
|
||||||
|
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
|
||||||
|
*
|
||||||
|
* Keys (...) MUST NOT appear more than once.
|
||||||
|
*
|
||||||
|
* If they key has already been seen, we have a duplicate
|
||||||
|
*/
|
||||||
|
for(i=0; i < nparams; i++) {
|
||||||
|
uint16_t key = gldns_read_uint16(svcparams[i]);
|
||||||
|
if(i + 1 < nparams && key == gldns_read_uint16(svcparams[i+1]))
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS;
|
||||||
|
if(key == SVCB_KEY_MANDATORY)
|
||||||
|
mandatory = svcparams[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4. verify that all the SvcParamKeys in mandatory are present */
|
||||||
|
if(mandatory) {
|
||||||
|
/* Divide by sizeof(uint16_t)*/
|
||||||
|
uint16_t mandatory_nkeys = gldns_read_uint16(mandatory + 2) / sizeof(uint16_t);
|
||||||
|
|
||||||
|
/* Guaranteed by gldns_str2wire_svcparam_key_value */
|
||||||
|
assert(mandatory_nkeys > 0);
|
||||||
|
|
||||||
|
for(i=0; i < mandatory_nkeys; i++) {
|
||||||
|
uint16_t mandatory_key = gldns_read_uint16(
|
||||||
|
mandatory
|
||||||
|
+ 2 * sizeof(uint16_t)
|
||||||
|
+ i * sizeof(uint16_t));
|
||||||
|
uint8_t found = 0;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
for(j=0; j < nparams; j++) {
|
||||||
|
if(mandatory_key == gldns_read_uint16(svcparams[j])) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Write rdata in correct order */
|
||||||
|
for (i = 0; i < nparams; i++) {
|
||||||
|
uint16_t svcparam_len = gldns_read_uint16(svcparams[i] + 2)
|
||||||
|
+ 2 * sizeof(uint16_t);
|
||||||
|
|
||||||
|
if ((unsigned)(new_rdata_ptr - new_rdata) + svcparam_len > sizeof(new_rdata))
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
memcpy(new_rdata_ptr, svcparams[i], svcparam_len);
|
||||||
|
new_rdata_ptr += svcparam_len;
|
||||||
|
}
|
||||||
|
memcpy(rdata, new_rdata, rdata_len);
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/** parse rdata from string into rr buffer(-remainder after dname). */
|
/** parse rdata from string into rr buffer(-remainder after dname). */
|
||||||
static int
|
static int
|
||||||
rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
|
rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
|
||||||
|
@ -655,7 +782,8 @@ rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
|
||||||
|
|
||||||
/* unknown RR data */
|
/* unknown RR data */
|
||||||
if(token_strlen>=2 && strncmp(token, "\\#", 2) == 0 &&
|
if(token_strlen>=2 && strncmp(token, "\\#", 2) == 0 &&
|
||||||
!quoted && (token_strlen == 2 || token[2]==' ')) {
|
!quoted && (token_strlen == 2 || token[2]==' ' ||
|
||||||
|
token[2]=='\t')) {
|
||||||
was_unknown_rr_format = 1;
|
was_unknown_rr_format = 1;
|
||||||
if((status=rrinternal_parse_unknown(strbuf, token,
|
if((status=rrinternal_parse_unknown(strbuf, token,
|
||||||
token_len, rr, rr_len, &rr_cur_len,
|
token_len, rr, rr_len, &rr_cur_len,
|
||||||
|
@ -713,6 +841,42 @@ rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
|
||||||
/* write rdata length */
|
/* write rdata length */
|
||||||
gldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10));
|
gldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10));
|
||||||
*rr_len = rr_cur_len;
|
*rr_len = rr_cur_len;
|
||||||
|
/* SVCB/HTTPS handling */
|
||||||
|
if (rr_type == GLDNS_RR_TYPE_SVCB || rr_type == GLDNS_RR_TYPE_HTTPS) {
|
||||||
|
size_t rdata_len = rr_cur_len - dname_len - 10;
|
||||||
|
uint8_t *rdata = rr+dname_len + 10;
|
||||||
|
|
||||||
|
/* skip 1st rdata field SvcPriority (uint16_t) */
|
||||||
|
if (rdata_len < sizeof(uint16_t))
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
|
||||||
|
rdata_len -= sizeof(uint16_t);
|
||||||
|
rdata += sizeof(uint16_t);
|
||||||
|
|
||||||
|
/* skip 2nd rdata field dname */
|
||||||
|
while (rdata_len && *rdata != 0) {
|
||||||
|
uint8_t label_len;
|
||||||
|
|
||||||
|
if (*rdata & 0xC0)
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
|
||||||
|
label_len = *rdata + 1;
|
||||||
|
if (rdata_len < label_len)
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
|
||||||
|
rdata_len -= label_len;
|
||||||
|
rdata += label_len;
|
||||||
|
}
|
||||||
|
/* The root label is one more character, so smaller
|
||||||
|
* than 1 + 1 means no Svcparam Keys */
|
||||||
|
if (rdata_len < 2 || *rdata != 0)
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
|
||||||
|
rdata_len -= 1;
|
||||||
|
rdata += 1;
|
||||||
|
return gldns_str2wire_check_svcbparams(rdata, rdata_len);
|
||||||
|
|
||||||
|
}
|
||||||
return GLDNS_WIREPARSE_ERR_OK;
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +901,7 @@ gldns_str2wire_rr_buf_internal(const char* str, uint8_t* rr, size_t* len,
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int not_there = 0;
|
int not_there = 0;
|
||||||
char token[GLDNS_MAX_RDFLEN+1] = "";
|
char token[GLDNS_MAX_RDFLEN+1];
|
||||||
uint32_t ttl = 0;
|
uint32_t ttl = 0;
|
||||||
uint16_t tp = 0, cl = 0;
|
uint16_t tp = 0, cl = 0;
|
||||||
size_t ddlen = 0;
|
size_t ddlen = 0;
|
||||||
|
@ -899,12 +1063,15 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||||
return s;
|
return s;
|
||||||
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
|
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
|
||||||
const char* end = NULL;
|
const char* end = NULL;
|
||||||
|
int overflow = 0;
|
||||||
strlcpy((char*)rr, line, *len);
|
strlcpy((char*)rr, line, *len);
|
||||||
*len = 0;
|
*len = 0;
|
||||||
*dname_len = 0;
|
*dname_len = 0;
|
||||||
if(!parse_state) return GLDNS_WIREPARSE_ERR_OK;
|
if(!parse_state) return GLDNS_WIREPARSE_ERR_OK;
|
||||||
parse_state->default_ttl = gldns_str2period(
|
parse_state->default_ttl = gldns_str2period(
|
||||||
gldns_strip_ws(line+5), &end);
|
gldns_strip_ws(line+5), &end, &overflow);
|
||||||
|
if(overflow)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW;
|
||||||
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
|
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
|
||||||
strlcpy((char*)rr, line, *len);
|
strlcpy((char*)rr, line, *len);
|
||||||
*len = 0;
|
*len = 0;
|
||||||
|
@ -939,6 +1106,524 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||||
return GLDNS_WIREPARSE_ERR_OK;
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
char *endptr;
|
||||||
|
unsigned long int key_value;
|
||||||
|
|
||||||
|
if (key_len >= 4 && key_len <= 8 && !strncmp(key, "key", 3)) {
|
||||||
|
memcpy(buf, key + 3, key_len - 3);
|
||||||
|
buf[key_len - 3] = 0;
|
||||||
|
key_value = strtoul(buf, &endptr, 10);
|
||||||
|
|
||||||
|
if (endptr > buf /* digits seen */
|
||||||
|
&& *endptr == 0 /* no non-digit chars after digits */
|
||||||
|
&& key_value <= 65535) /* no overflow */
|
||||||
|
return key_value;
|
||||||
|
|
||||||
|
} else switch (key_len) {
|
||||||
|
case sizeof("mandatory")-1:
|
||||||
|
if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
|
||||||
|
return SVCB_KEY_MANDATORY;
|
||||||
|
if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
|
||||||
|
return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof("alpn")-1:
|
||||||
|
if (!strncmp(key, "alpn", sizeof("alpn")-1))
|
||||||
|
return SVCB_KEY_ALPN;
|
||||||
|
if (!strncmp(key, "port", sizeof("port")-1))
|
||||||
|
return SVCB_KEY_PORT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof("no-default-alpn")-1:
|
||||||
|
if (!strncmp( key , "no-default-alpn"
|
||||||
|
, sizeof("no-default-alpn")-1))
|
||||||
|
return SVCB_KEY_NO_DEFAULT_ALPN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof("ipv4hint")-1:
|
||||||
|
if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
|
||||||
|
return SVCB_KEY_IPV4HINT;
|
||||||
|
if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
|
||||||
|
return SVCB_KEY_IPV6HINT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof("ech")-1:
|
||||||
|
if (!strncmp(key, "ech", sizeof("ech")-1))
|
||||||
|
return SVCB_KEY_ECH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Although the returned value might be used by the caller,
|
||||||
|
* the parser has erred, so the zone will not be loaded.
|
||||||
|
*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcparam_port(const char* val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
unsigned long int port;
|
||||||
|
char *endptr;
|
||||||
|
|
||||||
|
if (*rd_len < 6)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
port = strtoul(val, &endptr, 10);
|
||||||
|
|
||||||
|
if (endptr > val /* digits seen */
|
||||||
|
&& *endptr == 0 /* no non-digit chars after digits */
|
||||||
|
&& port <= 65535) { /* no overflow */
|
||||||
|
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_PORT);
|
||||||
|
gldns_write_uint16(rd + 2, sizeof(uint16_t));
|
||||||
|
gldns_write_uint16(rd + 4, port);
|
||||||
|
*rd_len = 6;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcbparam_ipv4hint(const char* val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
size_t count;
|
||||||
|
char ip_str[INET_ADDRSTRLEN+1];
|
||||||
|
char *next_ip_str;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0, count = 1; val[i]; i++) {
|
||||||
|
if (val[i] == ',')
|
||||||
|
count += 1;
|
||||||
|
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*rd_len < (GLDNS_IP4ADDRLEN * count) + 4)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
/* count is number of comma's in val + 1; so the actual number of IPv4
|
||||||
|
* addresses in val
|
||||||
|
*/
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_IPV4HINT);
|
||||||
|
gldns_write_uint16(rd + 2, GLDNS_IP4ADDRLEN * count);
|
||||||
|
*rd_len = 4;
|
||||||
|
|
||||||
|
while (count) {
|
||||||
|
if (!(next_ip_str = strchr(val, ','))) {
|
||||||
|
if (inet_pton(AF_INET, val, rd + *rd_len) != 1)
|
||||||
|
break;
|
||||||
|
*rd_len += GLDNS_IP4ADDRLEN;
|
||||||
|
|
||||||
|
assert(count == 1);
|
||||||
|
|
||||||
|
} else if (next_ip_str - val >= (int)sizeof(ip_str))
|
||||||
|
break;
|
||||||
|
|
||||||
|
else {
|
||||||
|
memcpy(ip_str, val, next_ip_str - val);
|
||||||
|
ip_str[next_ip_str - val] = 0;
|
||||||
|
if (inet_pton(AF_INET, ip_str, rd + *rd_len) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*rd_len += GLDNS_IP4ADDRLEN;
|
||||||
|
|
||||||
|
val = next_ip_str + 1;
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
if (count) /* verify that we parsed all values */
|
||||||
|
return GLDNS_WIREPARSE_ERR_SYNTAX_IP4;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcbparam_ipv6hint(const char* val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
size_t count;
|
||||||
|
char ip_str[INET6_ADDRSTRLEN+1];
|
||||||
|
char *next_ip_str;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0, count = 1; val[i]; i++) {
|
||||||
|
if (val[i] == ',')
|
||||||
|
count += 1;
|
||||||
|
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*rd_len < (GLDNS_IP6ADDRLEN * count) + 4)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
/* count is number of comma's in val + 1; so the actual number of IPv6
|
||||||
|
* addresses in val
|
||||||
|
*/
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_IPV6HINT);
|
||||||
|
gldns_write_uint16(rd + 2, GLDNS_IP6ADDRLEN * count);
|
||||||
|
*rd_len = 4;
|
||||||
|
|
||||||
|
while (count) {
|
||||||
|
if (!(next_ip_str = strchr(val, ','))) {
|
||||||
|
if (inet_pton(AF_INET6, val, rd + *rd_len) != 1)
|
||||||
|
break;
|
||||||
|
*rd_len += GLDNS_IP6ADDRLEN;
|
||||||
|
|
||||||
|
assert(count == 1);
|
||||||
|
|
||||||
|
} else if (next_ip_str - val >= (int)sizeof(ip_str))
|
||||||
|
break;
|
||||||
|
|
||||||
|
else {
|
||||||
|
memcpy(ip_str, val, next_ip_str - val);
|
||||||
|
ip_str[next_ip_str - val] = 0;
|
||||||
|
if (inet_pton(AF_INET6, ip_str, rd + *rd_len) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*rd_len += GLDNS_IP6ADDRLEN;
|
||||||
|
|
||||||
|
val = next_ip_str + 1;
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
if (count) /* verify that we parsed all values */
|
||||||
|
return GLDNS_WIREPARSE_ERR_SYNTAX_IP6;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compare function used for sorting uint16_t's */
|
||||||
|
static int
|
||||||
|
gldns_network_uint16_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return ((int)gldns_read_uint16(a)) - ((int)gldns_read_uint16(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcbparam_mandatory(const char* val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
size_t i, count, val_len;
|
||||||
|
char* next_key;
|
||||||
|
|
||||||
|
val_len = strlen(val);
|
||||||
|
|
||||||
|
for (i = 0, count = 1; val[i]; i++) {
|
||||||
|
if (val[i] == ',')
|
||||||
|
count += 1;
|
||||||
|
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sizeof(uint16_t) * (count + 2) > *rd_len)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_MANDATORY);
|
||||||
|
gldns_write_uint16(rd + 2, sizeof(uint16_t) * count);
|
||||||
|
*rd_len = 4;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int svcparamkey;
|
||||||
|
|
||||||
|
if (!(next_key = strchr(val, ','))) {
|
||||||
|
svcparamkey = gldns_str2wire_svcparam_key_lookup(val, val_len);
|
||||||
|
|
||||||
|
if (svcparamkey < 0) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
gldns_write_uint16(rd + *rd_len, svcparamkey);
|
||||||
|
*rd_len += 2;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
svcparamkey = gldns_str2wire_svcparam_key_lookup(val, next_key - val);
|
||||||
|
|
||||||
|
if (svcparamkey < 0) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
gldns_write_uint16(rd + *rd_len,
|
||||||
|
svcparamkey);
|
||||||
|
*rd_len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
val_len -= next_key - val + 1;
|
||||||
|
val = next_key + 1; /* skip the comma */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
|
||||||
|
*
|
||||||
|
* "In wire format, the keys are represented by their numeric
|
||||||
|
* values in network byte order, concatenated in ascending order."
|
||||||
|
*/
|
||||||
|
qsort((void *)(rd + 4), count, sizeof(uint16_t), gldns_network_uint16_cmp);
|
||||||
|
|
||||||
|
/* The code below revolves around semantic errors in the SVCParam set.
|
||||||
|
* So long as we do not distinguish between running Unbound as a primary
|
||||||
|
* or as a secondary, we default to secondary behavior and we ignore the
|
||||||
|
* semantic errors. */
|
||||||
|
#ifdef SVCB_SEMANTIC_ERRORS
|
||||||
|
/* In draft-ietf-dnsop-svcb-https-06 Section 8
|
||||||
|
* automatically mandatory MUST NOT appear in its own value-list
|
||||||
|
*/
|
||||||
|
if (gldns_read_uint16(rd + 4) == SVCB_KEY_MANDATORY)
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY;
|
||||||
|
|
||||||
|
/* Guarantee key uniqueness. After the sort we only need to
|
||||||
|
* compare neighbouring keys */
|
||||||
|
if (count > 1) {
|
||||||
|
for (i = 0; i < count - 1; i++) {
|
||||||
|
uint8_t* current_pos = (rd + 4 + (sizeof(uint16_t) * i));
|
||||||
|
uint16_t key = gldns_read_uint16(current_pos);
|
||||||
|
|
||||||
|
if (key == gldns_read_uint16(current_pos + 2)) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcbparam_ech_value(const char* val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
uint8_t buffer[GLDNS_MAX_RDFLEN];
|
||||||
|
int wire_len;
|
||||||
|
|
||||||
|
/* single 0 represents empty buffer */
|
||||||
|
if(strcmp(val, "0") == 0) {
|
||||||
|
if (*rd_len < 4)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_ECH);
|
||||||
|
gldns_write_uint16(rd + 2, 0);
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
wire_len = gldns_b64_pton(val, buffer, GLDNS_MAX_RDFLEN);
|
||||||
|
|
||||||
|
if (wire_len <= 0) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SYNTAX_B64;
|
||||||
|
} else if ((unsigned)wire_len + 4 > *rd_len) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
} else {
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_ECH);
|
||||||
|
gldns_write_uint16(rd + 2, wire_len);
|
||||||
|
memcpy(rd + 4, buffer, wire_len);
|
||||||
|
*rd_len = 4 + wire_len;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
gldns_str2wire_svcbparam_parse_next_unescaped_comma(const char *val)
|
||||||
|
{
|
||||||
|
while (*val) {
|
||||||
|
/* Only return when the comma is not escaped*/
|
||||||
|
if (*val == '\\'){
|
||||||
|
++val;
|
||||||
|
if (!*val)
|
||||||
|
break;
|
||||||
|
} else if (*val == ',')
|
||||||
|
return val;
|
||||||
|
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The source is already properly unescaped, this double unescaping is purely to allow for
|
||||||
|
* comma's in comma separated alpn lists.
|
||||||
|
*
|
||||||
|
* In draft-ietf-dnsop-svcb-https-06 Section 7:
|
||||||
|
* To enable simpler parsing, this SvcParamValue MUST NOT contain escape sequences.
|
||||||
|
*/
|
||||||
|
static size_t
|
||||||
|
gldns_str2wire_svcbparam_parse_copy_unescaped(uint8_t *dst,
|
||||||
|
const char *src, size_t len)
|
||||||
|
{
|
||||||
|
uint8_t *orig_dst = dst;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
if (*src == '\\') {
|
||||||
|
src++;
|
||||||
|
len--;
|
||||||
|
if (!len)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*dst++ = *src++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
return (size_t)(dst - orig_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcbparam_alpn_value(const char* val,
|
||||||
|
uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
uint8_t unescaped_dst[GLDNS_MAX_RDFLEN];
|
||||||
|
uint8_t *dst = unescaped_dst;
|
||||||
|
const char *next_str;
|
||||||
|
size_t str_len;
|
||||||
|
size_t dst_len;
|
||||||
|
size_t val_len;
|
||||||
|
|
||||||
|
val_len = strlen(val);
|
||||||
|
|
||||||
|
if (val_len > sizeof(unescaped_dst)) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
|
||||||
|
}
|
||||||
|
while (val_len) {
|
||||||
|
size_t key_len;
|
||||||
|
|
||||||
|
str_len = (next_str = gldns_str2wire_svcbparam_parse_next_unescaped_comma(val))
|
||||||
|
? (size_t)(next_str - val) : val_len;
|
||||||
|
|
||||||
|
if (str_len > 255) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_len = gldns_str2wire_svcbparam_parse_copy_unescaped(dst + 1, val, str_len);
|
||||||
|
*dst++ = key_len;
|
||||||
|
dst += key_len;
|
||||||
|
|
||||||
|
if (!next_str)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* skip the comma in the next iteration */
|
||||||
|
val_len -= next_str - val + 1;
|
||||||
|
val = next_str + 1;
|
||||||
|
}
|
||||||
|
dst_len = dst - unescaped_dst;
|
||||||
|
if (*rd_len < 4 + dst_len)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
gldns_write_uint16(rd, SVCB_KEY_ALPN);
|
||||||
|
gldns_write_uint16(rd + 2, dst_len);
|
||||||
|
memcpy(rd + 4, unescaped_dst, dst_len);
|
||||||
|
*rd_len = 4 + dst_len;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_str2wire_svcparam_value(const char *key, size_t key_len,
|
||||||
|
const char *val, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
size_t str_len;
|
||||||
|
int svcparamkey = gldns_str2wire_svcparam_key_lookup(key, key_len);
|
||||||
|
|
||||||
|
if (svcparamkey < 0) {
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* key without value */
|
||||||
|
if (val == NULL) {
|
||||||
|
switch (svcparamkey) {
|
||||||
|
#ifdef SVCB_SEMANTIC_ERRORS
|
||||||
|
case SVCB_KEY_MANDATORY:
|
||||||
|
case SVCB_KEY_ALPN:
|
||||||
|
case SVCB_KEY_PORT:
|
||||||
|
case SVCB_KEY_IPV4HINT:
|
||||||
|
case SVCB_KEY_IPV6HINT:
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
if (*rd_len < 4)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
gldns_write_uint16(rd, svcparamkey);
|
||||||
|
gldns_write_uint16(rd + 2, 0);
|
||||||
|
*rd_len = 4;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value is non-empty */
|
||||||
|
switch (svcparamkey) {
|
||||||
|
case SVCB_KEY_PORT:
|
||||||
|
return gldns_str2wire_svcparam_port(val, rd, rd_len);
|
||||||
|
case SVCB_KEY_IPV4HINT:
|
||||||
|
return gldns_str2wire_svcbparam_ipv4hint(val, rd, rd_len);
|
||||||
|
case SVCB_KEY_IPV6HINT:
|
||||||
|
return gldns_str2wire_svcbparam_ipv6hint(val, rd, rd_len);
|
||||||
|
case SVCB_KEY_MANDATORY:
|
||||||
|
return gldns_str2wire_svcbparam_mandatory(val, rd, rd_len);
|
||||||
|
#ifdef SVCB_SEMANTIC_ERRORS
|
||||||
|
case SVCB_KEY_NO_DEFAULT_ALPN:
|
||||||
|
return GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE;
|
||||||
|
#endif
|
||||||
|
case SVCB_KEY_ECH:
|
||||||
|
return gldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
|
||||||
|
case SVCB_KEY_ALPN:
|
||||||
|
return gldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
|
||||||
|
default:
|
||||||
|
str_len = strlen(val);
|
||||||
|
if (*rd_len < 4 + str_len)
|
||||||
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
gldns_write_uint16(rd, svcparamkey);
|
||||||
|
gldns_write_uint16(rd + 2, str_len);
|
||||||
|
memcpy(rd + 4, val, str_len);
|
||||||
|
*rd_len = 4 + str_len;
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLDNS_WIREPARSE_ERR_GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_str2wire_svcparam_buf(const char* str, uint8_t* rd, size_t* rd_len)
|
||||||
|
{
|
||||||
|
const char* eq_pos;
|
||||||
|
char unescaped_val[GLDNS_MAX_RDFLEN];
|
||||||
|
char* val_out = unescaped_val;
|
||||||
|
const char* val_in;
|
||||||
|
|
||||||
|
eq_pos = strchr(str, '=');
|
||||||
|
|
||||||
|
/* case: key=value */
|
||||||
|
if (eq_pos != NULL && eq_pos[1]) {
|
||||||
|
val_in = eq_pos + 1;
|
||||||
|
|
||||||
|
/* unescape characters and "" blocks */
|
||||||
|
if (*val_in == '"') {
|
||||||
|
val_in++;
|
||||||
|
while (*val_in != '"'
|
||||||
|
&& (size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
|
||||||
|
&& gldns_parse_char( (uint8_t*) val_out, &val_in)) {
|
||||||
|
val_out++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ((size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
|
||||||
|
&& gldns_parse_char( (uint8_t*) val_out, &val_in)) {
|
||||||
|
val_out++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*val_out = 0;
|
||||||
|
|
||||||
|
return gldns_str2wire_svcparam_value(str, eq_pos - str,
|
||||||
|
unescaped_val[0] ? unescaped_val : NULL, rd, rd_len);
|
||||||
|
}
|
||||||
|
/* case: key= */
|
||||||
|
else if (eq_pos != NULL && !(eq_pos[1])) {
|
||||||
|
return gldns_str2wire_svcparam_value(str, eq_pos - str, NULL, rd, rd_len);
|
||||||
|
}
|
||||||
|
/* case: key */
|
||||||
|
else {
|
||||||
|
return gldns_str2wire_svcparam_value(str, strlen(str), NULL, rd, rd_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
||||||
gldns_rdf_type rdftype)
|
gldns_rdf_type rdftype)
|
||||||
{
|
{
|
||||||
|
@ -1013,6 +1698,8 @@ int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
|
||||||
return gldns_str2wire_int16_data_buf(str, rd, len);
|
return gldns_str2wire_int16_data_buf(str, rd, len);
|
||||||
case GLDNS_RDF_TYPE_AMTRELAY:
|
case GLDNS_RDF_TYPE_AMTRELAY:
|
||||||
return gldns_str2wire_amtrelay_buf(str, rd, len);
|
return gldns_str2wire_amtrelay_buf(str, rd, len);
|
||||||
|
case GLDNS_RDF_TYPE_SVCPARAM:
|
||||||
|
return gldns_str2wire_svcparam_buf(str, rd, len);
|
||||||
case GLDNS_RDF_TYPE_UNKNOWN:
|
case GLDNS_RDF_TYPE_UNKNOWN:
|
||||||
case GLDNS_RDF_TYPE_SERVICE:
|
case GLDNS_RDF_TYPE_SERVICE:
|
||||||
return GLDNS_WIREPARSE_ERR_NOT_IMPL;
|
return GLDNS_WIREPARSE_ERR_NOT_IMPL;
|
||||||
|
@ -1483,9 +2170,13 @@ int gldns_str2wire_tsigtime_buf(const char* str, uint8_t* rd, size_t* len)
|
||||||
int gldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len)
|
int gldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len)
|
||||||
{
|
{
|
||||||
const char* end;
|
const char* end;
|
||||||
uint32_t p = gldns_str2period(str, &end);
|
int overflow;
|
||||||
|
uint32_t p = gldns_str2period(str, &end, &overflow);
|
||||||
if(*end != 0)
|
if(*end != 0)
|
||||||
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_PERIOD, end-str);
|
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_PERIOD, end-str);
|
||||||
|
if(overflow)
|
||||||
|
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
|
||||||
|
end-str);
|
||||||
if(*len < 4)
|
if(*len < 4)
|
||||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
gldns_write_uint32(rd, p);
|
gldns_write_uint32(rd, p);
|
||||||
|
|
|
@ -23,10 +23,27 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
struct gldns_struct_lookup_table;
|
struct gldns_struct_lookup_table;
|
||||||
|
|
||||||
|
#define GLDNS_IP4ADDRLEN (32/8)
|
||||||
|
#define GLDNS_IP6ADDRLEN (128/8)
|
||||||
|
|
||||||
/** buffer to read an RR, cannot be larger than 64K because of packet size */
|
/** buffer to read an RR, cannot be larger than 64K because of packet size */
|
||||||
#define GLDNS_RR_BUF_SIZE 65535 /* bytes */
|
#define GLDNS_RR_BUF_SIZE 65535 /* bytes */
|
||||||
#define GLDNS_DEFAULT_TTL 3600
|
#define GLDNS_DEFAULT_TTL 3600
|
||||||
|
|
||||||
|
/* SVCB keys currently defined in draft-ietf-dnsop-svcb-https */
|
||||||
|
#define SVCB_KEY_MANDATORY 0
|
||||||
|
#define SVCB_KEY_ALPN 1
|
||||||
|
#define SVCB_KEY_NO_DEFAULT_ALPN 2
|
||||||
|
#define SVCB_KEY_PORT 3
|
||||||
|
#define SVCB_KEY_IPV4HINT 4
|
||||||
|
#define SVCB_KEY_ECH 5
|
||||||
|
#define SVCB_KEY_IPV6HINT 6
|
||||||
|
#define SVCPARAMKEY_COUNT 7
|
||||||
|
|
||||||
|
#define MAX_NUMBER_OF_SVCPARAMS 64
|
||||||
|
|
||||||
|
#define SVCB_MAX_COMMA_SEPARATED_VALUES 1000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To convert class and type to string see
|
* To convert class and type to string see
|
||||||
* gldns_get_rr_class_by_name(str)
|
* gldns_get_rr_class_by_name(str)
|
||||||
|
@ -170,7 +187,7 @@ uint8_t* gldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
|
||||||
#define GLDNS_WIREPARSE_MASK 0x0fff
|
#define GLDNS_WIREPARSE_MASK 0x0fff
|
||||||
#define GLDNS_WIREPARSE_SHIFT 12
|
#define GLDNS_WIREPARSE_SHIFT 12
|
||||||
#define GLDNS_WIREPARSE_ERROR(e) ((e)&GLDNS_WIREPARSE_MASK)
|
#define GLDNS_WIREPARSE_ERROR(e) ((e)&GLDNS_WIREPARSE_MASK)
|
||||||
#define GLDNS_WIREPARSE_OFFSET(e) (((e)&~GLDNS_WIREPARSE_MASK)>>GLDNS_WIREPARSE_SHIFT)
|
#define GLDNS_WIREPARSE_OFFSET(e) ((((unsigned)(e))&~GLDNS_WIREPARSE_MASK)>>GLDNS_WIREPARSE_SHIFT)
|
||||||
/* use lookuptable to get error string, gldns_wireparse_errors */
|
/* use lookuptable to get error string, gldns_wireparse_errors */
|
||||||
#define GLDNS_WIREPARSE_ERR_OK 0
|
#define GLDNS_WIREPARSE_ERR_OK 0
|
||||||
#define GLDNS_WIREPARSE_ERR_GENERAL 342
|
#define GLDNS_WIREPARSE_ERR_GENERAL 342
|
||||||
|
@ -204,6 +221,20 @@ uint8_t* gldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
|
||||||
#define GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
|
#define GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
|
||||||
#define GLDNS_WIREPARSE_ERR_INCLUDE 371
|
#define GLDNS_WIREPARSE_ERR_INCLUDE 371
|
||||||
#define GLDNS_WIREPARSE_ERR_PARENTHESIS 372
|
#define GLDNS_WIREPARSE_ERR_PARENTHESIS 372
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY 373
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM 374
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS 375
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS 376
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS 377
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM 378
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY 379
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY 380
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX 381
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES 382
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES 383
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE 384
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
|
||||||
|
#define GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get reference to a constant string for the (parse) error.
|
* Get reference to a constant string for the (parse) error.
|
||||||
|
|
|
@ -151,6 +151,30 @@ static gldns_lookup_table gldns_wireparse_errors_data[] = {
|
||||||
{ GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" },
|
{ GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" },
|
||||||
{ GLDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" },
|
{ GLDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" },
|
||||||
{ GLDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" },
|
{ GLDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY, "Unknown SvcParamKey"},
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM, "SvcParam is missing a SvcParamValue"},
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS, "Duplicate SVCB key found"},
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS, "Too many keys in mandatory" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS,
|
||||||
|
"Too many SvcParams. Unbound only allows 63 entries" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM,
|
||||||
|
"Mandatory SvcParamKey is missing"},
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY,
|
||||||
|
"Keys in SvcParam mandatory MUST be unique" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY,
|
||||||
|
"mandatory MUST not be included as mandatory parameter" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX,
|
||||||
|
"Could not parse port SvcParamValue" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES,
|
||||||
|
"Too many IPv4 addresses in ipv4hint" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES,
|
||||||
|
"Too many IPv6 addresses in ipv6hint" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE,
|
||||||
|
"Alpn strings need to be smaller than 255 chars"},
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE,
|
||||||
|
"No-default-alpn should not have a value" },
|
||||||
|
{ GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA,
|
||||||
|
"General SVCParam error" },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
gldns_lookup_table* gldns_wireparse_errors = gldns_wireparse_errors_data;
|
gldns_lookup_table* gldns_wireparse_errors = gldns_wireparse_errors_data;
|
||||||
|
@ -172,6 +196,7 @@ static gldns_lookup_table gldns_edns_options_data[] = {
|
||||||
{ 8, "edns-client-subnet" },
|
{ 8, "edns-client-subnet" },
|
||||||
{ 11, "edns-tcp-keepalive"},
|
{ 11, "edns-tcp-keepalive"},
|
||||||
{ 12, "Padding" },
|
{ 12, "Padding" },
|
||||||
|
{ 15, "EDE"},
|
||||||
{ 0, NULL}
|
{ 0, NULL}
|
||||||
};
|
};
|
||||||
gldns_lookup_table* gldns_edns_options = gldns_edns_options_data;
|
gldns_lookup_table* gldns_edns_options = gldns_edns_options_data;
|
||||||
|
@ -198,6 +223,12 @@ static gldns_lookup_table gldns_tsig_errors_data[] = {
|
||||||
};
|
};
|
||||||
gldns_lookup_table* gldns_tsig_errors = gldns_tsig_errors_data;
|
gldns_lookup_table* gldns_tsig_errors = gldns_tsig_errors_data;
|
||||||
|
|
||||||
|
/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
|
||||||
|
const char *svcparamkey_strs[] = {
|
||||||
|
"mandatory", "alpn", "no-default-alpn", "port",
|
||||||
|
"ipv4hint", "ech", "ipv6hint"
|
||||||
|
};
|
||||||
|
|
||||||
char* gldns_wire2str_pkt(uint8_t* data, size_t len)
|
char* gldns_wire2str_pkt(uint8_t* data, size_t len)
|
||||||
{
|
{
|
||||||
size_t slen = (size_t)gldns_wire2str_pkt_buf(data, len, NULL, 0);
|
size_t slen = (size_t)gldns_wire2str_pkt_buf(data, len, NULL, 0);
|
||||||
|
@ -789,6 +820,7 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
||||||
unsigned i, counter=0;
|
unsigned i, counter=0;
|
||||||
unsigned maxcompr = 1000; /* loop detection, max compr ptrs */
|
unsigned maxcompr = 1000; /* loop detection, max compr ptrs */
|
||||||
int in_buf = 1;
|
int in_buf = 1;
|
||||||
|
size_t dname_len = 0;
|
||||||
if(comprloop) {
|
if(comprloop) {
|
||||||
if(*comprloop != 0)
|
if(*comprloop != 0)
|
||||||
maxcompr = 30; /* for like ipv6 reverse name, per label */
|
maxcompr = 30; /* for like ipv6 reverse name, per label */
|
||||||
|
@ -844,6 +876,16 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
||||||
labellen = (uint8_t)*dlen;
|
labellen = (uint8_t)*dlen;
|
||||||
else if(!in_buf && pos+(size_t)labellen > pkt+pktlen)
|
else if(!in_buf && pos+(size_t)labellen > pkt+pktlen)
|
||||||
labellen = (uint8_t)(pkt + pktlen - pos);
|
labellen = (uint8_t)(pkt + pktlen - pos);
|
||||||
|
dname_len += ((size_t)labellen)+1;
|
||||||
|
if(dname_len > GLDNS_MAX_DOMAINLEN) {
|
||||||
|
/* dname_len counts the uncompressed length we have
|
||||||
|
* seen so far, and the domain name has become too
|
||||||
|
* long, prevent the loop from printing overly long
|
||||||
|
* content. */
|
||||||
|
w += gldns_str_print(s, slen,
|
||||||
|
"ErrorDomainNameTooLong");
|
||||||
|
return w;
|
||||||
|
}
|
||||||
for(i=0; i<(unsigned)labellen; i++) {
|
for(i=0; i<(unsigned)labellen; i++) {
|
||||||
w += dname_char_print(s, slen, *pos++);
|
w += dname_char_print(s, slen, *pos++);
|
||||||
}
|
}
|
||||||
|
@ -942,6 +984,253 @@ int gldns_wire2str_ttl_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
|
||||||
return gldns_str_print(s, slen, "%u", (unsigned)ttl);
|
return gldns_str_print(s, slen, "%u", (unsigned)ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey)
|
||||||
|
{
|
||||||
|
if (svcparamkey < SVCPARAMKEY_COUNT) {
|
||||||
|
return gldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return gldns_str_print(s, slen, "key%d", (int)svcparamkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_port2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
if (data_len != 2)
|
||||||
|
return -1; /* wireformat error, a short is 2 bytes */
|
||||||
|
w = gldns_str_print(s, slen, "=%d", (int)gldns_read_uint16(data));
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_ipv4hint2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
char ip_str[INET_ADDRSTRLEN + 1];
|
||||||
|
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
assert(data_len > 0);
|
||||||
|
|
||||||
|
if ((data_len % GLDNS_IP4ADDRLEN) == 0) {
|
||||||
|
if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
|
||||||
|
return -1; /* wireformat error, incorrect size or inet family */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, "=%s", ip_str);
|
||||||
|
data += GLDNS_IP4ADDRLEN;
|
||||||
|
|
||||||
|
while ((data_len -= GLDNS_IP4ADDRLEN) > 0) {
|
||||||
|
if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
|
||||||
|
return -1; /* wireformat error, incorrect size or inet family */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, ",%s", ip_str);
|
||||||
|
data += GLDNS_IP4ADDRLEN;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_ipv6hint2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
char ip_str[INET6_ADDRSTRLEN + 1];
|
||||||
|
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
assert(data_len > 0);
|
||||||
|
|
||||||
|
if ((data_len % GLDNS_IP6ADDRLEN) == 0) {
|
||||||
|
if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
|
||||||
|
return -1; /* wireformat error, incorrect size or inet family */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, "=%s", ip_str);
|
||||||
|
data += GLDNS_IP6ADDRLEN;
|
||||||
|
|
||||||
|
while ((data_len -= GLDNS_IP6ADDRLEN) > 0) {
|
||||||
|
if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
|
||||||
|
return -1; /* wireformat error, incorrect size or inet family */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, ",%s", ip_str);
|
||||||
|
data += GLDNS_IP6ADDRLEN;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_mandatory2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
assert(data_len > 0);
|
||||||
|
|
||||||
|
if (data_len % sizeof(uint16_t))
|
||||||
|
return -1; /* wireformat error, data_len must be multiple of shorts */
|
||||||
|
w += gldns_str_print(s, slen, "=");
|
||||||
|
w += gldns_print_svcparamkey(s, slen, gldns_read_uint16(data));
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
while ((data_len -= sizeof(uint16_t))) {
|
||||||
|
w += gldns_str_print(s, slen, ",");
|
||||||
|
w += gldns_print_svcparamkey(s, slen, gldns_read_uint16(data));
|
||||||
|
data += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_alpn2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
uint8_t *dp = (void *)data;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
assert(data_len > 0); /* Guaranteed by gldns_wire2str_svcparam_scan */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, "=\"");
|
||||||
|
while (data_len) {
|
||||||
|
/* alpn is list of length byte (str_len) followed by a string of that size */
|
||||||
|
uint8_t i, str_len = *dp++;
|
||||||
|
|
||||||
|
if (str_len > --data_len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < str_len; i++) {
|
||||||
|
if (dp[i] == '"' || dp[i] == '\\')
|
||||||
|
w += gldns_str_print(s, slen, "\\\\\\%c", dp[i]);
|
||||||
|
|
||||||
|
else if (dp[i] == ',')
|
||||||
|
w += gldns_str_print(s, slen, "\\\\%c", dp[i]);
|
||||||
|
|
||||||
|
else if (!isprint(dp[i]))
|
||||||
|
w += gldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]);
|
||||||
|
|
||||||
|
else
|
||||||
|
w += gldns_str_print(s, slen, "%c", dp[i]);
|
||||||
|
}
|
||||||
|
dp += str_len;
|
||||||
|
if ((data_len -= str_len))
|
||||||
|
w += gldns_str_print(s, slen, "%s", ",");
|
||||||
|
}
|
||||||
|
w += gldns_str_print(s, slen, "\"");
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gldns_wire2str_svcparam_ech2str(char** s,
|
||||||
|
size_t* slen, uint16_t data_len, uint8_t* data)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
assert(data_len > 0); /* Guaranteed by gldns_wire2str_svcparam_scan */
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, "=\"");
|
||||||
|
|
||||||
|
if ((size = gldns_b64_ntop(data, data_len, *s, *slen)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
(*s) += size;
|
||||||
|
(*slen) -= size;
|
||||||
|
|
||||||
|
w += gldns_str_print(s, slen, "\"");
|
||||||
|
|
||||||
|
return w + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
|
||||||
|
{
|
||||||
|
uint8_t ch;
|
||||||
|
uint16_t svcparamkey, data_len;
|
||||||
|
int written_chars = 0;
|
||||||
|
int r, i;
|
||||||
|
|
||||||
|
/* verify that we have enough data to read svcparamkey and data_len */
|
||||||
|
if(*dlen < 4)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
svcparamkey = gldns_read_uint16(*d);
|
||||||
|
data_len = gldns_read_uint16(*d+2);
|
||||||
|
*d += 4;
|
||||||
|
*dlen -= 4;
|
||||||
|
|
||||||
|
/* verify that we have data_len data */
|
||||||
|
if (data_len > *dlen)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
written_chars += gldns_print_svcparamkey(s, slen, svcparamkey);
|
||||||
|
if (!data_len) {
|
||||||
|
|
||||||
|
/* Some SvcParams MUST have values */
|
||||||
|
switch (svcparamkey) {
|
||||||
|
case SVCB_KEY_ALPN:
|
||||||
|
case SVCB_KEY_PORT:
|
||||||
|
case SVCB_KEY_IPV4HINT:
|
||||||
|
case SVCB_KEY_IPV6HINT:
|
||||||
|
case SVCB_KEY_MANDATORY:
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
return written_chars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (svcparamkey) {
|
||||||
|
case SVCB_KEY_PORT:
|
||||||
|
r = gldns_wire2str_svcparam_port2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
case SVCB_KEY_IPV4HINT:
|
||||||
|
r = gldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
case SVCB_KEY_IPV6HINT:
|
||||||
|
r = gldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
case SVCB_KEY_MANDATORY:
|
||||||
|
r = gldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
case SVCB_KEY_NO_DEFAULT_ALPN:
|
||||||
|
return -1; /* wireformat error, should not have a value */
|
||||||
|
case SVCB_KEY_ALPN:
|
||||||
|
r = gldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
case SVCB_KEY_ECH:
|
||||||
|
r = gldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
r = gldns_str_print(s, slen, "=\"");
|
||||||
|
|
||||||
|
for (i = 0; i < data_len; i++) {
|
||||||
|
ch = (*d)[i];
|
||||||
|
|
||||||
|
if (ch == '"' || ch == '\\')
|
||||||
|
r += gldns_str_print(s, slen, "\\%c", ch);
|
||||||
|
|
||||||
|
else if (!isprint(ch))
|
||||||
|
r += gldns_str_print(s, slen, "\\%03u", (unsigned) ch);
|
||||||
|
|
||||||
|
else
|
||||||
|
r += gldns_str_print(s, slen, "%c", ch);
|
||||||
|
|
||||||
|
}
|
||||||
|
r += gldns_str_print(s, slen, "\"");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (r <= 0)
|
||||||
|
return -1; /* wireformat error */
|
||||||
|
|
||||||
|
written_chars += r;
|
||||||
|
*d += data_len;
|
||||||
|
*dlen -= data_len;
|
||||||
|
return written_chars;
|
||||||
|
}
|
||||||
|
|
||||||
int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
||||||
int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop)
|
int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop)
|
||||||
{
|
{
|
||||||
|
@ -1022,6 +1311,8 @@ int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
|
||||||
case GLDNS_RDF_TYPE_AMTRELAY:
|
case GLDNS_RDF_TYPE_AMTRELAY:
|
||||||
return gldns_wire2str_amtrelay_scan(d, dlen, s, slen, pkt,
|
return gldns_wire2str_amtrelay_scan(d, dlen, s, slen, pkt,
|
||||||
pktlen, comprloop);
|
pktlen, comprloop);
|
||||||
|
case GLDNS_RDF_TYPE_SVCPARAM:
|
||||||
|
return gldns_wire2str_svcparam_scan(d, dlen, s, slen);
|
||||||
case GLDNS_RDF_TYPE_TSIGERROR:
|
case GLDNS_RDF_TYPE_TSIGERROR:
|
||||||
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
|
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ char* gldns_wire2str_pkt(uint8_t* data, size_t len);
|
||||||
char* gldns_wire2str_rr(uint8_t* rr, size_t len);
|
char* gldns_wire2str_rr(uint8_t* rr, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conver wire dname to a string.
|
* Convert wire dname to a string.
|
||||||
* @param dname: the dname in uncompressed wireformat.
|
* @param dname: the dname in uncompressed wireformat.
|
||||||
* @param dname_len: length of the dname.
|
* @param dname_len: length of the dname.
|
||||||
* @return string or NULL on failure.
|
* @return string or NULL on failure.
|
||||||
|
@ -494,6 +494,18 @@ int gldns_wire2str_opcode_buf(int opcode, char* str, size_t len);
|
||||||
int gldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
|
int gldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert wire SVCB to a string with user buffer.
|
||||||
|
* @param d: the SVCB data in uncompressed wireformat.
|
||||||
|
* @param dlen: length of the SVCB data.
|
||||||
|
* @param s: the string to write to.
|
||||||
|
* @param slen: length of string.
|
||||||
|
* @return the number of characters for this element, excluding zerobyte.
|
||||||
|
* Is larger or equal than str_len if output was truncated.
|
||||||
|
*/
|
||||||
|
int gldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s,
|
||||||
|
size_t* slen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan wireformat rdf field to string, with user buffers.
|
* Scan wireformat rdf field to string, with user buffers.
|
||||||
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).
|
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).
|
||||||
|
|
|
@ -94,10 +94,4 @@ typedef struct _getdns_tls_x509
|
||||||
gnutls_datum_t tls;
|
gnutls_datum_t tls;
|
||||||
} _getdns_tls_x509;
|
} _getdns_tls_x509;
|
||||||
|
|
||||||
typedef struct _getdns_tls_hmac
|
|
||||||
{
|
|
||||||
gnutls_hmac_hd_t tls;
|
|
||||||
unsigned int md_len;
|
|
||||||
} _getdns_tls_hmac;
|
|
||||||
|
|
||||||
#endif /* _GETDNS_TLS_INTERNAL_H */
|
#endif /* _GETDNS_TLS_INTERNAL_H */
|
||||||
|
|
|
@ -393,6 +393,12 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
|
||||||
if (dane_state_init(&res->dane_state, DANE_F_IGNORE_DNSSEC) != DANE_E_SUCCESS)
|
if (dane_state_init(&res->dane_state, DANE_F_IGNORE_DNSSEC) != DANE_E_SUCCESS)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
gnutls_datum_t proto;
|
||||||
|
proto.data = (unsigned char *)"dot";
|
||||||
|
proto.size = 3;
|
||||||
|
if (gnutls_alpn_set_protocols(res->tls, &proto, 1, 0) != GNUTLS_E_SUCCESS)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
gnutls_transport_set_int(res->tls, fd);
|
gnutls_transport_set_int(res->tls, fd);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -869,55 +875,6 @@ unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size)
|
|
||||||
{
|
|
||||||
gnutls_mac_algorithm_t alg;
|
|
||||||
_getdns_tls_hmac* res;
|
|
||||||
|
|
||||||
if (get_gnu_mac_algorithm(algorithm, &alg) != GETDNS_RETURN_GOOD)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_hmac)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (gnutls_hmac_init(&res->tls, alg, key, key_size) < 0) {
|
|
||||||
GETDNS_FREE(*mfs, res);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
res->md_len = gnutls_hmac_get_len(alg);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size)
|
|
||||||
{
|
|
||||||
if (!h || !h->tls || !data)
|
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (gnutls_hmac(h->tls, data, data_size) < 0)
|
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
else
|
|
||||||
return GETDNS_RETURN_GOOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size)
|
|
||||||
{
|
|
||||||
unsigned char* res;
|
|
||||||
|
|
||||||
if (!h || !h->tls)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, h->md_len);
|
|
||||||
if (!res)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
gnutls_hmac_deinit(h->tls, res);
|
|
||||||
if (output_size)
|
|
||||||
*output_size = h->md_len;
|
|
||||||
|
|
||||||
GETDNS_FREE(*mfs, h);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
|
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
|
||||||
{
|
{
|
||||||
gnutls_hash_fast(GNUTLS_DIG_SHA1, data, data_size, buf);
|
gnutls_hash_fast(GNUTLS_DIG_SHA1, data, data_size, buf);
|
||||||
|
|
|
@ -29,8 +29,15 @@
|
||||||
#ifdef HAVE_OPENSSL_BN_H
|
#ifdef HAVE_OPENSSL_BN_H
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OPENSSL_RSA_H
|
#ifdef HAVE_OPENSSL_PARAM_BUILD_H
|
||||||
#include <openssl/rsa.h>
|
# include <openssl/param_build.h>
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_OPENSSL_RSA_H
|
||||||
|
# include <openssl/rsa.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_OPENSSL_DSA_H
|
||||||
|
# include <openssl/dsa.h>
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OPENSSL_DSA_H
|
#ifdef HAVE_OPENSSL_DSA_H
|
||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
|
@ -44,7 +51,7 @@
|
||||||
#ifdef USE_GOST
|
#ifdef USE_GOST
|
||||||
|
|
||||||
/** store GOST engine reference loaded into OpenSSL library */
|
/** store GOST engine reference loaded into OpenSSL library */
|
||||||
#ifdef OPENSSL_NO_ENGINE
|
#if defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER > 0x30000000
|
||||||
int
|
int
|
||||||
gldns_key_EVP_load_gost_id(void)
|
gldns_key_EVP_load_gost_id(void)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +84,7 @@ gldns_key_EVP_load_gost_id(void)
|
||||||
if(!e) {
|
if(!e) {
|
||||||
/* load it ourself, in case statically linked */
|
/* load it ourself, in case statically linked */
|
||||||
ENGINE_load_builtin_engines();
|
ENGINE_load_builtin_engines();
|
||||||
|
ENGINE_load_dynamic();
|
||||||
e = ENGINE_by_id("gost");
|
e = ENGINE_by_id("gost");
|
||||||
}
|
}
|
||||||
if(!e) {
|
if(!e) {
|
||||||
|
@ -115,49 +123,71 @@ void gldns_key_EVP_unload_gost(void)
|
||||||
#endif /* ifndef OPENSSL_NO_ENGINE */
|
#endif /* ifndef OPENSSL_NO_ENGINE */
|
||||||
#endif /* USE_GOST */
|
#endif /* USE_GOST */
|
||||||
|
|
||||||
DSA *
|
/* Retrieve params as BIGNUM from raw buffer */
|
||||||
gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
|
static int
|
||||||
|
gldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
|
||||||
|
BIGNUM** q, BIGNUM** g, BIGNUM** y)
|
||||||
{
|
{
|
||||||
uint8_t T;
|
uint8_t T;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
DSA *dsa;
|
|
||||||
BIGNUM *Q; BIGNUM *P;
|
|
||||||
BIGNUM *G; BIGNUM *Y;
|
|
||||||
|
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
return NULL;
|
return 0;
|
||||||
T = (uint8_t)key[0];
|
T = (uint8_t)key[0];
|
||||||
length = (64 + T * 8);
|
length = (64 + T * 8);
|
||||||
offset = 1;
|
offset = 1;
|
||||||
|
|
||||||
if (T > 8) {
|
if (T > 8) {
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
|
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
|
*q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
|
||||||
offset += SHA_DIGEST_LENGTH;
|
offset += SHA_DIGEST_LENGTH;
|
||||||
|
|
||||||
P = BN_bin2bn(key+offset, (int)length, NULL);
|
*p = BN_bin2bn(key+offset, (int)length, NULL);
|
||||||
offset += length;
|
offset += length;
|
||||||
|
|
||||||
G = BN_bin2bn(key+offset, (int)length, NULL);
|
*g = BN_bin2bn(key+offset, (int)length, NULL);
|
||||||
offset += length;
|
offset += length;
|
||||||
|
|
||||||
Y = BN_bin2bn(key+offset, (int)length, NULL);
|
*y = BN_bin2bn(key+offset, (int)length, NULL);
|
||||||
|
|
||||||
/* create the key and set its properties */
|
if(!*q || !*p || !*g || !*y) {
|
||||||
if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
|
BN_free(*q);
|
||||||
BN_free(Q);
|
BN_free(*p);
|
||||||
BN_free(P);
|
BN_free(*g);
|
||||||
BN_free(G);
|
BN_free(*y);
|
||||||
BN_free(Y);
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
DSA *
|
||||||
|
gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
|
||||||
|
{
|
||||||
|
DSA *dsa;
|
||||||
|
BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
|
||||||
|
if(!gldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* create the key and set its properties */
|
||||||
|
if(!(dsa = DSA_new())) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
|
||||||
|
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
|
||||||
|
#ifndef S_SPLINT_S
|
||||||
|
dsa->p = P;
|
||||||
|
dsa->q = Q;
|
||||||
|
dsa->g = G;
|
||||||
|
dsa->pub_key = Y;
|
||||||
|
#endif /* splint */
|
||||||
|
|
||||||
#if defined(HAVE_DSA_SET0_PQG) && defined(HAVE_DSA_SET0_KEY)
|
#else /* OPENSSL_VERSION_NUMBER */
|
||||||
if (!DSA_set0_pqg(dsa, P, Q, G)) {
|
if (!DSA_set0_pqg(dsa, P, Q, G)) {
|
||||||
/* QPG not yet attached, need to free */
|
/* QPG not yet attached, need to free */
|
||||||
BN_free(Q);
|
BN_free(Q);
|
||||||
|
@ -174,33 +204,115 @@ gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
|
||||||
BN_free(Y);
|
BN_free(Y);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
# ifndef S_SPLINT_S
|
|
||||||
dsa->p = P;
|
|
||||||
dsa->q = Q;
|
|
||||||
dsa->g = G;
|
|
||||||
dsa->pub_key = Y;
|
|
||||||
# endif /* splint */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return dsa;
|
return dsa;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
|
||||||
|
|
||||||
RSA *
|
EVP_PKEY *gldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
|
||||||
gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
|
{
|
||||||
|
#ifdef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
EVP_PKEY* evp_key = NULL;
|
||||||
|
EVP_PKEY_CTX* ctx;
|
||||||
|
BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
|
||||||
|
OSSL_PARAM_BLD* param_bld;
|
||||||
|
OSSL_PARAM* params = NULL;
|
||||||
|
if(!gldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
param_bld = OSSL_PARAM_BLD_new();
|
||||||
|
if(!param_bld) {
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
|
||||||
|
!OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
|
||||||
|
!OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
|
||||||
|
!OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
|
||||||
|
ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
|
||||||
|
if(!ctx) {
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(p);
|
||||||
|
BN_free(q);
|
||||||
|
BN_free(g);
|
||||||
|
BN_free(y);
|
||||||
|
return evp_key;
|
||||||
|
#else
|
||||||
|
DSA* dsa;
|
||||||
|
EVP_PKEY* evp_key = EVP_PKEY_new();
|
||||||
|
if(!evp_key) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dsa = gldns_key_buf2dsa_raw(key, len);
|
||||||
|
if(!dsa) {
|
||||||
|
EVP_PKEY_free(evp_key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
|
||||||
|
DSA_free(dsa);
|
||||||
|
EVP_PKEY_free(evp_key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return evp_key;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
|
||||||
|
static int
|
||||||
|
gldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
|
||||||
|
BIGNUM** e)
|
||||||
{
|
{
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
uint16_t exp;
|
uint16_t exp;
|
||||||
uint16_t int16;
|
uint16_t int16;
|
||||||
RSA *rsa;
|
|
||||||
BIGNUM *modulus;
|
|
||||||
BIGNUM *exponent;
|
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return NULL;
|
return 0;
|
||||||
if (key[0] == 0) {
|
if (key[0] == 0) {
|
||||||
if(len < 3)
|
if(len < 3)
|
||||||
return NULL;
|
return 0;
|
||||||
memmove(&int16, key+1, 2);
|
memmove(&int16, key+1, 2);
|
||||||
exp = ntohs(int16);
|
exp = ntohs(int16);
|
||||||
offset = 3;
|
offset = 3;
|
||||||
|
@ -211,46 +323,140 @@ gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
|
||||||
|
|
||||||
/* key length at least one */
|
/* key length at least one */
|
||||||
if(len < (size_t)offset + exp + 1)
|
if(len < (size_t)offset + exp + 1)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
/* Exponent */
|
/* Exponent */
|
||||||
exponent = BN_new();
|
*e = BN_new();
|
||||||
if(!exponent) return NULL;
|
if(!*e) return 0;
|
||||||
(void) BN_bin2bn(key+offset, (int)exp, exponent);
|
(void) BN_bin2bn(key+offset, (int)exp, *e);
|
||||||
offset += exp;
|
offset += exp;
|
||||||
|
|
||||||
/* Modulus */
|
/* Modulus */
|
||||||
modulus = BN_new();
|
*n = BN_new();
|
||||||
if(!modulus) {
|
if(!*n) {
|
||||||
BN_free(exponent);
|
BN_free(*e);
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
/* length of the buffer must match the key length! */
|
/* length of the buffer must match the key length! */
|
||||||
(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
|
(void) BN_bin2bn(key+offset, (int)(len - offset), *n);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
RSA *
|
||||||
|
gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
|
||||||
|
{
|
||||||
|
BIGNUM* modulus = NULL;
|
||||||
|
BIGNUM* exponent = NULL;
|
||||||
|
RSA *rsa;
|
||||||
|
if(!gldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
|
||||||
|
return NULL;
|
||||||
rsa = RSA_new();
|
rsa = RSA_new();
|
||||||
if(!rsa) {
|
if(!rsa) {
|
||||||
BN_free(exponent);
|
BN_free(exponent);
|
||||||
BN_free(modulus);
|
BN_free(modulus);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
|
||||||
|
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
|
||||||
|
#ifndef S_SPLINT_S
|
||||||
|
rsa->n = modulus;
|
||||||
|
rsa->e = exponent;
|
||||||
|
#endif /* splint */
|
||||||
|
|
||||||
#if defined(HAVE_RSA_SET0_KEY)
|
#else /* OPENSSL_VERSION_NUMBER */
|
||||||
if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
|
if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
|
||||||
BN_free(exponent);
|
BN_free(exponent);
|
||||||
BN_free(modulus);
|
BN_free(modulus);
|
||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
# ifndef S_SPLINT_S
|
|
||||||
rsa->n = modulus;
|
|
||||||
rsa->e = exponent;
|
|
||||||
# endif /* splint */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return rsa;
|
return rsa;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
|
||||||
|
|
||||||
|
EVP_PKEY* gldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
EVP_PKEY* evp_key = NULL;
|
||||||
|
EVP_PKEY_CTX* ctx;
|
||||||
|
BIGNUM *n=NULL, *e=NULL;
|
||||||
|
OSSL_PARAM_BLD* param_bld;
|
||||||
|
OSSL_PARAM* params = NULL;
|
||||||
|
|
||||||
|
if(!gldns_key_rsa_buf_bignum(key, len, &n, &e)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
param_bld = OSSL_PARAM_BLD_new();
|
||||||
|
if(!param_bld) {
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
|
||||||
|
ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||||||
|
if(!ctx) {
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
BN_free(n);
|
||||||
|
BN_free(e);
|
||||||
|
return evp_key;
|
||||||
|
#else
|
||||||
|
RSA* rsa;
|
||||||
|
EVP_PKEY *evp_key = EVP_PKEY_new();
|
||||||
|
if(!evp_key) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rsa = gldns_key_buf2rsa_raw(key, len);
|
||||||
|
if(!rsa) {
|
||||||
|
EVP_PKEY_free(evp_key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
|
||||||
|
RSA_free(rsa);
|
||||||
|
EVP_PKEY_free(evp_key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return evp_key;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_GOST
|
#ifdef USE_GOST
|
||||||
EVP_PKEY*
|
EVP_PKEY*
|
||||||
|
@ -281,6 +487,62 @@ gldns_gost2pkey_raw(unsigned char* key, size_t keylen)
|
||||||
EVP_PKEY*
|
EVP_PKEY*
|
||||||
gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
|
gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
|
||||||
|
EVP_PKEY *evp_key = NULL;
|
||||||
|
EVP_PKEY_CTX* ctx;
|
||||||
|
OSSL_PARAM_BLD* param_bld;
|
||||||
|
OSSL_PARAM* params = NULL;
|
||||||
|
char* group = NULL;
|
||||||
|
|
||||||
|
/* check length, which uncompressed must be 2 bignums */
|
||||||
|
if(algo == GLDNS_ECDSAP256SHA256) {
|
||||||
|
if(keylen != 2*256/8) return NULL;
|
||||||
|
group = "prime256v1";
|
||||||
|
} else if(algo == GLDNS_ECDSAP384SHA384) {
|
||||||
|
if(keylen != 2*384/8) return NULL;
|
||||||
|
group = "P-384";
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(keylen+1 > sizeof(buf)) { /* sanity check */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* prepend the 0x04 for uncompressed format */
|
||||||
|
buf[0] = POINT_CONVERSION_UNCOMPRESSED;
|
||||||
|
memmove(buf+1, key, keylen);
|
||||||
|
|
||||||
|
param_bld = OSSL_PARAM_BLD_new();
|
||||||
|
if(!param_bld) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
|
||||||
|
!OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
|
||||||
|
ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
|
||||||
|
if(!ctx) {
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
return evp_key;
|
||||||
|
#else
|
||||||
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
|
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
|
||||||
const unsigned char* pp = buf;
|
const unsigned char* pp = buf;
|
||||||
EVP_PKEY *evp_key;
|
EVP_PKEY *evp_key;
|
||||||
|
@ -317,6 +579,7 @@ gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return evp_key;
|
return evp_key;
|
||||||
|
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
|
||||||
}
|
}
|
||||||
#endif /* USE_ECDSA */
|
#endif /* USE_ECDSA */
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ int gldns_key_EVP_load_gost_id(void);
|
||||||
/** Release the engine reference held for the GOST engine. */
|
/** Release the engine reference held for the GOST engine. */
|
||||||
void gldns_key_EVP_unload_gost(void);
|
void gldns_key_EVP_unload_gost(void);
|
||||||
|
|
||||||
|
#ifndef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
/**
|
/**
|
||||||
* Like gldns_key_buf2dsa, but uses raw buffer.
|
* Like gldns_key_buf2dsa, but uses raw buffer.
|
||||||
* \param[in] key the uncompressed wireformat of the key.
|
* \param[in] key the uncompressed wireformat of the key.
|
||||||
|
@ -44,6 +45,15 @@ void gldns_key_EVP_unload_gost(void);
|
||||||
* \return a DSA * structure with the key material
|
* \return a DSA * structure with the key material
|
||||||
*/
|
*/
|
||||||
DSA *gldns_key_buf2dsa_raw(unsigned char* key, size_t len);
|
DSA *gldns_key_buf2dsa_raw(unsigned char* key, size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a holding buffer with DSA key material to EVP PKEY in openssl.
|
||||||
|
* \param[in] key the uncompressed wireformat of the key.
|
||||||
|
* \param[in] len length of key data
|
||||||
|
* \return the key or NULL on error.
|
||||||
|
*/
|
||||||
|
EVP_PKEY *gldns_key_dsa2pkey_raw(unsigned char* key, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||||
|
@ -64,6 +74,7 @@ EVP_PKEY* gldns_gost2pkey_raw(unsigned char* key, size_t keylen);
|
||||||
*/
|
*/
|
||||||
EVP_PKEY* gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
|
EVP_PKEY* gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
|
||||||
|
|
||||||
|
#ifndef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
/**
|
/**
|
||||||
* Like gldns_key_buf2rsa, but uses raw buffer.
|
* Like gldns_key_buf2rsa, but uses raw buffer.
|
||||||
* \param[in] key the uncompressed wireformat of the key.
|
* \param[in] key the uncompressed wireformat of the key.
|
||||||
|
@ -71,6 +82,15 @@ EVP_PKEY* gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
|
||||||
* \return a RSA * structure with the key material
|
* \return a RSA * structure with the key material
|
||||||
*/
|
*/
|
||||||
RSA *gldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
RSA *gldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a holding buffer with RSA key material to EVP PKEY in openssl.
|
||||||
|
* \param[in] key the uncompressed wireformat of the key.
|
||||||
|
* \param[in] len length of key data
|
||||||
|
* \return the key or NULL on error.
|
||||||
|
*/
|
||||||
|
EVP_PKEY* gldns_key_rsa2pkey_raw(unsigned char* key, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||||
|
|
|
@ -81,12 +81,4 @@ typedef struct _getdns_tls_x509
|
||||||
X509* ssl;
|
X509* ssl;
|
||||||
} _getdns_tls_x509;
|
} _getdns_tls_x509;
|
||||||
|
|
||||||
typedef struct _getdns_tls_hmac
|
|
||||||
{
|
|
||||||
HMAC_CTX *ctx;
|
|
||||||
#ifndef HAVE_HMAC_CTX_NEW
|
|
||||||
HMAC_CTX ctx_space;
|
|
||||||
#endif
|
|
||||||
} _getdns_tls_hmac;
|
|
||||||
|
|
||||||
#endif /* _GETDNS_TLS_INTERNAL_H */
|
#endif /* _GETDNS_TLS_INTERNAL_H */
|
||||||
|
|
|
@ -320,6 +320,10 @@ void _getdns_tls_init()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DOT_PROTO_ALPN_ID "dot"
|
||||||
|
#define DOT_PROTO_ALPN "\x3" DOT_PROTO_ALPN_ID
|
||||||
|
#define DOT_PROTO_ALPN_LEN (sizeof(DOT_PROTO_ALPN) - 1)
|
||||||
|
|
||||||
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log)
|
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log)
|
||||||
{
|
{
|
||||||
_getdns_tls_context* res;
|
_getdns_tls_context* res;
|
||||||
|
@ -348,6 +352,8 @@ _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns
|
||||||
GETDNS_FREE(*mfs, res);
|
GETDNS_FREE(*mfs, res);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
SSL_CTX_set_alpn_protos(res->ssl, (const uint8_t *)DOT_PROTO_ALPN,
|
||||||
|
DOT_PROTO_ALPN_LEN);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1191,70 +1197,6 @@ unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size)
|
|
||||||
{
|
|
||||||
const EVP_MD *digester = get_digester(algorithm);
|
|
||||||
_getdns_tls_hmac* res;
|
|
||||||
|
|
||||||
if (!digester)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_hmac)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#ifdef HAVE_HMAC_CTX_NEW
|
|
||||||
res->ctx = HMAC_CTX_new();
|
|
||||||
if (!res->ctx) {
|
|
||||||
GETDNS_FREE(*mfs, res);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
res->ctx = &res->ctx_space;
|
|
||||||
HMAC_CTX_init(res->ctx);
|
|
||||||
#endif
|
|
||||||
if (!HMAC_Init_ex(res->ctx, key, key_size, digester, NULL)) {
|
|
||||||
#ifdef HAVE_HMAC_CTX_NEW
|
|
||||||
HMAC_CTX_free(res->ctx);
|
|
||||||
#endif
|
|
||||||
GETDNS_FREE(*mfs, res);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size)
|
|
||||||
{
|
|
||||||
if (!h || !h->ctx || !data)
|
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (!HMAC_Update(h->ctx, data, data_size))
|
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
else
|
|
||||||
return GETDNS_RETURN_GOOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size)
|
|
||||||
{
|
|
||||||
unsigned char* res;
|
|
||||||
unsigned int md_len;
|
|
||||||
|
|
||||||
res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, GETDNS_TLS_MAX_DIGEST_LENGTH);
|
|
||||||
if (!res)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
(void) HMAC_Final(h->ctx, res, &md_len);
|
|
||||||
|
|
||||||
#ifdef HAVE_HMAC_CTX_NEW
|
|
||||||
HMAC_CTX_free(h->ctx);
|
|
||||||
#endif
|
|
||||||
GETDNS_FREE(*mfs, h);
|
|
||||||
|
|
||||||
if (output_size)
|
|
||||||
*output_size = md_len;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
|
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
|
||||||
{
|
{
|
||||||
SHA1(data, data_size, buf);
|
SHA1(data, data_size, buf);
|
||||||
|
|
|
@ -500,7 +500,9 @@ _getdns_network_validate_tsig(getdns_network_req *req)
|
||||||
unsigned char *result_mac;
|
unsigned char *result_mac;
|
||||||
size_t result_mac_len;
|
size_t result_mac_len;
|
||||||
uint16_t original_id;
|
uint16_t original_id;
|
||||||
_getdns_tls_hmac *hmac;
|
size_t data_size;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
|
||||||
DEBUG_STUB("%s %-35s: Validate TSIG\n", STUB_DEBUG_TSIG, __FUNC__);
|
DEBUG_STUB("%s %-35s: Validate TSIG\n", STUB_DEBUG_TSIG, __FUNC__);
|
||||||
for ( rr = _getdns_rr_iter_init(&rr_spc, req->query,
|
for ( rr = _getdns_rr_iter_init(&rr_spc, req->query,
|
||||||
|
@ -607,19 +609,33 @@ _getdns_network_validate_tsig(getdns_network_req *req)
|
||||||
gldns_read_uint16(req->response + 10) - 1);
|
gldns_read_uint16(req->response + 10) - 1);
|
||||||
gldns_write_uint16(req->response, original_id);
|
gldns_write_uint16(req->response, original_id);
|
||||||
|
|
||||||
hmac = _getdns_tls_hmac_new(&req->owner->my_mf, req->upstream->tsig_alg, req->upstream->tsig_key, req->upstream->tsig_size);
|
data_size = request_mac_len + 2
|
||||||
if (!hmac)
|
+ (size_t)(rr->pos - req->response)
|
||||||
|
+ gldns_buffer_position(&gbuf);
|
||||||
|
data = GETDNS_XMALLOC(req->owner->my_mf, uint8_t, data_size);
|
||||||
|
if (!data) {
|
||||||
|
DEBUG_STUB("%s %-35s: Error allocating %d bytes\n",
|
||||||
|
STUB_DEBUG_TSIG, __FUNC__, (int)(data_size));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
memcpy(data , request_mac - 2 , request_mac_len + 2);
|
||||||
|
memcpy(data + request_mac_len + 2, req->response, rr->pos - req->response);
|
||||||
|
memcpy(data + request_mac_len + 2 + (size_t)(rr->pos - req->response)
|
||||||
|
, tsig_vars, gldns_buffer_position(&gbuf));
|
||||||
|
|
||||||
_getdns_tls_hmac_add(hmac, request_mac - 2, request_mac_len + 2);
|
result_mac = _getdns_tls_hmac_hash(&req->owner->my_mf
|
||||||
_getdns_tls_hmac_add(hmac, req->response, rr->pos - req->response);
|
, req->upstream->tsig_alg
|
||||||
_getdns_tls_hmac_add(hmac, tsig_vars, gldns_buffer_position(&gbuf));
|
, req->upstream->tsig_key
|
||||||
result_mac = _getdns_tls_hmac_end(&req->owner->my_mf, hmac, &result_mac_len);
|
, req->upstream->tsig_size
|
||||||
if (!result_mac)
|
, data, data_size , &result_mac_len);
|
||||||
|
GETDNS_FREE(req->owner->my_mf, data);
|
||||||
|
if (!result_mac) {
|
||||||
|
DEBUG_STUB("%s %-35s: Error calculating TSIG digest\n",
|
||||||
|
STUB_DEBUG_TSIG, __FUNC__);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
DEBUG_STUB("%s %-35s: Result MAC length: %d\n",
|
DEBUG_STUB("%s %-35s: Result MAC length: %d for %d bytes of data\n",
|
||||||
STUB_DEBUG_TSIG, __FUNC__, (int)(result_mac_len));
|
STUB_DEBUG_TSIG, __FUNC__, (int)(result_mac_len), (int)data_size);
|
||||||
if (result_mac_len == response_mac_len &&
|
if (result_mac_len == response_mac_len &&
|
||||||
memcmp(result_mac, response_mac, result_mac_len) == 0)
|
memcmp(result_mac, response_mac, result_mac_len) == 0)
|
||||||
req->tsig_status = GETDNS_DNSSEC_SECURE;
|
req->tsig_status = GETDNS_DNSSEC_SECURE;
|
||||||
|
|
|
@ -1314,7 +1314,7 @@ _getdns_rr_buffer_write_cached_name(gldns_buffer *buf, getdns_bindata *name, nam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned name_offset = gldns_buffer_position(buf);
|
unsigned name_offset = gldns_buffer_position(buf);
|
||||||
if (name_offset < 0xc000) {
|
if (name_offset < 0x4000) {
|
||||||
/* Cache name */
|
/* Cache name */
|
||||||
entry_ptr = &name_cache->entry[count % NAME_CACHE_ENTRIES];
|
entry_ptr = &name_cache->entry[count % NAME_CACHE_ENTRIES];
|
||||||
entry_ptr->name = name;
|
entry_ptr->name = name;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit afd5b88687f05554513d9caf000f08904e32e6a4
|
Subproject commit 89ff45974cafa7e03f0503ed013fe3e680698c20
|
|
@ -709,6 +709,8 @@ static void
|
||||||
stub_timeout_cb(void *userarg)
|
stub_timeout_cb(void *userarg)
|
||||||
{
|
{
|
||||||
getdns_network_req *netreq = (getdns_network_req *)userarg;
|
getdns_network_req *netreq = (getdns_network_req *)userarg;
|
||||||
|
getdns_upstream *upstream = netreq? netreq->upstream: NULL;
|
||||||
|
getdns_upstreams *upstreams = upstream? upstream->upstreams: NULL;
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
|
@ -723,6 +725,8 @@ stub_timeout_cb(void *userarg)
|
||||||
"%-40s : Upstream : UDP - Resps=%6d, Timeouts =%6d (logged every 100 responses)\n",
|
"%-40s : Upstream : UDP - Resps=%6d, Timeouts =%6d (logged every 100 responses)\n",
|
||||||
netreq->upstream->addr_str,
|
netreq->upstream->addr_str,
|
||||||
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
|
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
|
||||||
|
/* Only choose next stream if the timeout is on current UDP stream */
|
||||||
|
if (upstreams && (upstream == &upstreams->upstreams[upstreams->current_udp]))
|
||||||
stub_next_upstream(netreq);
|
stub_next_upstream(netreq);
|
||||||
} else {
|
} else {
|
||||||
netreq->upstream->responses_timeouts++;
|
netreq->upstream->responses_timeouts++;
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
#if 0
|
||||||
START_TEST (getdns_context_destroy_7)
|
START_TEST (getdns_context_destroy_7)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -205,7 +206,6 @@
|
||||||
RUN_EVENT_LOOP;
|
RUN_EVENT_LOOP;
|
||||||
|
|
||||||
CONTEXT_DESTROY;
|
CONTEXT_DESTROY;
|
||||||
|
|
||||||
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
@ -229,10 +229,10 @@
|
||||||
&flag, &transaction_id, destroy_callbackfn),
|
&flag, &transaction_id, destroy_callbackfn),
|
||||||
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
|
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
|
||||||
getdns_cancel_callback(context, transaction_id);
|
getdns_cancel_callback(context, transaction_id);
|
||||||
|
|
||||||
RUN_EVENT_LOOP;
|
RUN_EVENT_LOOP;
|
||||||
|
|
||||||
CONTEXT_DESTROY;
|
CONTEXT_DESTROY;
|
||||||
|
|
||||||
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
@ -264,10 +264,10 @@
|
||||||
RUN_EVENT_LOOP;
|
RUN_EVENT_LOOP;
|
||||||
|
|
||||||
CONTEXT_DESTROY;
|
CONTEXT_DESTROY;
|
||||||
|
|
||||||
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
#endif
|
||||||
|
|
||||||
void verify_getdns_context_destroy(struct extracted_response *ex_response)
|
void verify_getdns_context_destroy(struct extracted_response *ex_response)
|
||||||
{
|
{
|
||||||
|
@ -301,10 +301,11 @@
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_4);
|
tcase_add_test(tc_pos, getdns_context_destroy_4);
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_5);
|
tcase_add_test(tc_pos, getdns_context_destroy_5);
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_6);
|
tcase_add_test(tc_pos, getdns_context_destroy_6);
|
||||||
// raise aborts via assertion failures
|
#if 0
|
||||||
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_7, SIGABRT);
|
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_7, SIGABRT);
|
||||||
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_8, SIGABRT);
|
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_8, SIGABRT);
|
||||||
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_9, SIGABRT);
|
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_9, SIGABRT);
|
||||||
|
#endif
|
||||||
suite_add_tcase(s, tc_pos);
|
suite_add_tcase(s, tc_pos);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -134,38 +134,39 @@ for (( ii = 0; ii < 1; ii++)); do
|
||||||
|
|
||||||
if [[ $HAVE_SSL_HN_AUTH = 1 ]]
|
if [[ $HAVE_SSL_HN_AUTH = 1 ]]
|
||||||
then
|
then
|
||||||
NUM_GOOD_QUERIES=8
|
NUM_GOOD_QUERIES=7
|
||||||
GOOD_QUERIES=(
|
GOOD_QUERIES=(
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
|
||||||
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP}" "L" "S"
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP}" "L" "S"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S")
|
||||||
"-s -G TXT large.getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
#"-s -A getdnsapi.net -l U @185.49.141.38 +edns_cookies" "U" "-"
|
||||||
|
#"-s -G TXT large.getdnsapi.net -l U @8.8.8.8 -b 512 -D" "U" "-"
|
||||||
else
|
else
|
||||||
NUM_GOOD_QUERIES=6
|
NUM_GOOD_QUERIES=6
|
||||||
GOOD_QUERIES=(
|
GOOD_QUERIES=(
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
|
||||||
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||||
"-s -G TXT large.getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-"
|
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_SS_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_SS_KEY}\"" "L" "S")
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_SS_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_SS_KEY}\"" "L" "S")
|
||||||
|
|
||||||
|
#"-s -A getdnsapi.net -l U @185.49.141.38 +edns_cookies" "U" "-"
|
||||||
|
# "-s -G TXT large.getdnsapi.net -l U @8.8.8.8 -b 512 -D" "U" "-"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
NUM_GOOD_FB_QUERIES=6
|
NUM_GOOD_FB_QUERIES=4
|
||||||
GOOD_FALLBACK_QUERIES=(
|
GOOD_FALLBACK_QUERIES=(
|
||||||
"-s -A getdnsapi.net -l LU @${SERVER_IP}" "U" "-"
|
|
||||||
"-s -A getdnsapi.net -l LT @${SERVER_IP}" "T" "-"
|
"-s -A getdnsapi.net -l LT @${SERVER_IP}" "T" "-"
|
||||||
"-s -A getdnsapi.net -l LT @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
"-s -A getdnsapi.net -l LT @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
"-s -A getdnsapi.net -l LT -m @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
"-s -A getdnsapi.net -l LT -m @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
"-s -A getdnsapi.net -l L @${SERVER_IP} @${TLS_SERVER_IP_NO_NAME}" "L" "-"
|
"-s -A getdnsapi.net -l L @${SERVER_IP} @${TLS_SERVER_IP_NO_NAME}" "L" "-")
|
||||||
"-s -G TXT large.getdnsapi.net -l UT @${SERVER_IP} -b 512 -D" "T" "-")
|
#"-s -A getdnsapi.net -l LU @${SERVER_IP}" "U" "-"
|
||||||
|
#"-s -G TXT large.getdnsapi.net -l UT @$8.8.8.8 -b 512 -D" "T" "-"
|
||||||
|
|
||||||
NOT_AVAILABLE_QUERIES=(
|
NOT_AVAILABLE_QUERIES=(
|
||||||
"-s -A getdnsapi.net -l L @${SERVER_IP}"
|
"-s -A getdnsapi.net -l L @${SERVER_IP}"
|
||||||
|
|
33
src/tls.h
33
src/tls.h
|
@ -408,39 +408,6 @@ getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
|
||||||
*/
|
*/
|
||||||
unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size);
|
unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new HMAC handle.
|
|
||||||
*
|
|
||||||
* @param mfs pointer to getdns memory functions.
|
|
||||||
* @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>).
|
|
||||||
* @param key the key.
|
|
||||||
* @param key_size the key size.
|
|
||||||
* @return HMAC handle or NULL on error.
|
|
||||||
*/
|
|
||||||
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add data to a HMAC.
|
|
||||||
*
|
|
||||||
* @param h the HMAC.
|
|
||||||
* @param data the data to add.
|
|
||||||
* @param data_size the size of data to add.
|
|
||||||
* @return GETDNS_RETURN_GOOD if added.
|
|
||||||
* @return GETDNS_RETURN_INVALID_PARAMETER if h is null or has no HMAC.
|
|
||||||
* @return GETDNS_RETURN_GENERIC_ERROR on error.
|
|
||||||
*/
|
|
||||||
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the HMAC digest and free the handle.
|
|
||||||
*
|
|
||||||
* @param mfs pointer to getdns memory functions.
|
|
||||||
* @param h the HMAC.
|
|
||||||
* @param output_size the output size will be written here if not NULL.
|
|
||||||
* @return output malloc'd buffer with output, NULL on error.
|
|
||||||
*/
|
|
||||||
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate a SHA1 hash.
|
* Calculate a SHA1 hash.
|
||||||
*
|
*
|
||||||
|
|
|
@ -514,29 +514,13 @@ static int
|
||||||
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||||
unsigned char* key, size_t keylen)
|
unsigned char* key, size_t keylen)
|
||||||
{
|
{
|
||||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
|
||||||
DSA* dsa;
|
|
||||||
#endif
|
|
||||||
RSA* rsa;
|
|
||||||
|
|
||||||
switch(algo) {
|
switch(algo) {
|
||||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||||
case LDNS_DSA:
|
case LDNS_DSA:
|
||||||
case LDNS_DSA_NSEC3:
|
case LDNS_DSA_NSEC3:
|
||||||
*evp_key = EVP_PKEY_new();
|
*evp_key = sldns_key_dsa2pkey_raw(key, keylen);
|
||||||
if(!*evp_key) {
|
if(!*evp_key) {
|
||||||
log_err("verify: malloc failure in crypto");
|
verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dsa = sldns_key_buf2dsa_raw(key, keylen);
|
|
||||||
if(!dsa) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"sldns_key_buf2dsa_raw failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"EVP_PKEY_assign_DSA failed");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_EVP_DSS1
|
#ifdef HAVE_EVP_DSS1
|
||||||
|
@ -559,20 +543,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||||
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
|
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
|
||||||
case LDNS_RSASHA512:
|
case LDNS_RSASHA512:
|
||||||
#endif
|
#endif
|
||||||
*evp_key = EVP_PKEY_new();
|
*evp_key = sldns_key_rsa2pkey_raw(key, keylen);
|
||||||
if(!*evp_key) {
|
if(!*evp_key) {
|
||||||
log_err("verify: malloc failure in crypto");
|
verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rsa = sldns_key_buf2rsa_raw(key, keylen);
|
|
||||||
if(!rsa) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"sldns_key_buf2rsa_raw SHA failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"EVP_PKEY_assign_RSA SHA failed");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,20 +569,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||||
#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
|
#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
|
||||||
|
|
||||||
case LDNS_RSAMD5:
|
case LDNS_RSAMD5:
|
||||||
*evp_key = EVP_PKEY_new();
|
*evp_key = sldns_key_rsa2pkey_raw(key, keylen);
|
||||||
if(!*evp_key) {
|
if(!*evp_key) {
|
||||||
log_err("verify: malloc failure in crypto");
|
verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rsa = sldns_key_buf2rsa_raw(key, keylen);
|
|
||||||
if(!rsa) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"sldns_key_buf2rsa_raw MD5 failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
|
|
||||||
verbose(VERB_QUERY, "verify: "
|
|
||||||
"EVP_PKEY_assign_RSA MD5 failed");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*digest_type = EVP_md5();
|
*digest_type = EVP_md5();
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#define sldns_ecdsa2pkey_raw gldns_ecdsa2pkey_raw
|
#define sldns_ecdsa2pkey_raw gldns_ecdsa2pkey_raw
|
||||||
#define sldns_buffer_begin gldns_buffer_begin
|
#define sldns_buffer_begin gldns_buffer_begin
|
||||||
#define sldns_buffer_limit gldns_buffer_limit
|
#define sldns_buffer_limit gldns_buffer_limit
|
||||||
|
#define sldns_key_dsa2pkey_raw gldns_key_dsa2pkey_raw
|
||||||
|
#define sldns_key_rsa2pkey_raw gldns_key_rsa2pkey_raw
|
||||||
|
|
||||||
#include "util/val_secalgo.h"
|
#include "util/val_secalgo.h"
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,11 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||||
#include <stdio.h> /* defines printf for tests */
|
#include <stdio.h> /* defines printf for tests */
|
||||||
#include <time.h> /* defines time_t for timings in the test */
|
#include <time.h> /* defines time_t for timings in the test */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If our build system provides endianness info, signalled by
|
||||||
|
* HAVE_TARGET_ENDIANNESS and the presence or absence of TARGET_IS_BIG_ENDIAN,
|
||||||
|
* use that. Otherwise try to work out the endianness.
|
||||||
|
*/
|
||||||
#if defined(HAVE_TARGET_ENDIANNESS)
|
#if defined(HAVE_TARGET_ENDIANNESS)
|
||||||
# if defined(TARGET_IS_BIG_ENDIAN)
|
# if defined(TARGET_IS_BIG_ENDIAN)
|
||||||
# define HASH_LITTLE_ENDIAN 0
|
# define HASH_LITTLE_ENDIAN 0
|
||||||
|
@ -63,9 +68,55 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||||
# define HASH_BIG_ENDIAN 0
|
# define HASH_BIG_ENDIAN 0
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# error "Target endianness required."
|
# include <sys/param.h> /* attempt to define endianness */
|
||||||
|
# ifdef HAVE_SYS_TYPES_H
|
||||||
|
# include <sys/types.h> /* attempt to define endianness (solaris) */
|
||||||
|
# endif
|
||||||
|
# if defined(linux) || defined(__OpenBSD__)
|
||||||
|
# ifdef HAVE_ENDIAN_H
|
||||||
|
# include <endian.h> /* attempt to define endianness */
|
||||||
|
# else
|
||||||
|
# include <machine/endian.h> /* on older OpenBSD */
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||||
|
# include <sys/endian.h> /* attempt to define endianness */
|
||||||
|
# endif
|
||||||
|
/*
|
||||||
|
* My best guess at if you are big-endian or little-endian. This may
|
||||||
|
* need adjustment.
|
||||||
|
*/
|
||||||
|
# if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
|
||||||
|
__BYTE_ORDER == __LITTLE_ENDIAN) || \
|
||||||
|
(defined(i386) || defined(__i386__) || defined(__i486__) || \
|
||||||
|
defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL) || defined(__x86))
|
||||||
|
# define HASH_LITTLE_ENDIAN 1
|
||||||
|
# define HASH_BIG_ENDIAN 0
|
||||||
|
# elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
|
||||||
|
__BYTE_ORDER == __BIG_ENDIAN) || \
|
||||||
|
(defined(sparc) || defined(__sparc) || defined(__sparc__) || defined(POWERPC) || defined(mc68000) || defined(sel))
|
||||||
|
# define HASH_LITTLE_ENDIAN 0
|
||||||
|
# define HASH_BIG_ENDIAN 1
|
||||||
|
# elif defined(_MACHINE_ENDIAN_H_)
|
||||||
|
/* test for machine_endian_h protects failure if some are empty strings */
|
||||||
|
# if defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
|
||||||
|
# define HASH_LITTLE_ENDIAN 0
|
||||||
|
# define HASH_BIG_ENDIAN 1
|
||||||
|
# endif
|
||||||
|
# if defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||||
|
# define HASH_LITTLE_ENDIAN 1
|
||||||
|
# define HASH_BIG_ENDIAN 0
|
||||||
|
# endif /* _MACHINE_ENDIAN_H_ */
|
||||||
|
# else
|
||||||
|
# define HASH_LITTLE_ENDIAN 0
|
||||||
|
# define HASH_BIG_ENDIAN 0
|
||||||
|
# endif
|
||||||
#endif /* defined(HAVE_TARGET_ENDIANNESS) */
|
#endif /* defined(HAVE_TARGET_ENDIANNESS) */
|
||||||
|
|
||||||
|
#define hashsize(n) ((uint32_t)1<<(n))
|
||||||
|
#define hashmask(n) (hashsize(n)-1)
|
||||||
|
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
||||||
|
|
||||||
/* random initial value */
|
/* random initial value */
|
||||||
static uint32_t raninit = (uint32_t)0xdeadbeef;
|
static uint32_t raninit = (uint32_t)0xdeadbeef;
|
||||||
|
|
||||||
|
@ -75,10 +126,6 @@ hash_set_raninit(uint32_t v)
|
||||||
raninit = v;
|
raninit = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define hashsize(n) ((uint32_t)1<<(n))
|
|
||||||
#define hashmask(n) (hashsize(n)-1)
|
|
||||||
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
mix -- mix 3 32-bit values reversibly.
|
mix -- mix 3 32-bit values reversibly.
|
||||||
|
|
2
stubby
2
stubby
|
@ -1 +1 @@
|
||||||
Subproject commit 40b6bf95391f639cc86e5d328e89011ef4c16437
|
Subproject commit b53867d1ec467822dbd9e1a0ad6598f84a9f5ed7
|
Loading…
Reference in New Issue