Skip to content

Instantly share code, notes, and snippets.

@nebulak
Last active June 8, 2017 08:08
Show Gist options
  • Save nebulak/f2d071ac21217d8b8ae9766ef5333dbe to your computer and use it in GitHub Desktop.
Save nebulak/f2d071ac21217d8b8ae9766ef5333dbe to your computer and use it in GitHub Desktop.
Build and use LibUnbound & LDNS for DNSSEC, DANE & HPKP

Setup development environment

Setup Development Environment for Windows

Follow the following guide to install msys2, gcc & make:

https://github.com/orlp/dev-on-windows/wiki/Installing-GCC--&-MSYS2

Install dependencies with pacman

Openssl-devel 1.0.2k

Be sure to install the 1.0.x version of openssl!

	pacman -S openssl-devel

libexpat

	pacman -S libexpat-devel

flex

Be sure to install a version lower or higher than 2.6.3 because of a bug in that version!

	wget http://repo.msys2.org/msys/x86_64/flex-2.6.1-1-x86_64.pkg.tar.xz
	
	pacman -U flex-2.6.1-1-x86_64.pkg.tar.xz

Build Libraries

Important Build Notes

Downloading PKGBUILD files

To get the PKGBUILD files you need you can download or clone the following repository:

https://github.com/Alexpux/MINGW-packages

After the download you should copy the directories for the needed packages to your msys home directory "home/your_username".

Fix PKGBUILD files

Most PKGBUILD files in the msys2 repository are out-of-date. Because of that you need fix the SHA256-sums inside these files using openssl and a text-editor:

	openssl dgst -sha256 ./the_file_to_hash

Build & install LDNS

Copy the mingw-w64-ldns directory to your home directory and enter it. After that Compile and install it with the following commands:

	MINGW_INSTALLS=mingw64 makepkg-mingw -sLf

	pacman -U mingw-w64-x86_64-ldns-1.6.17-4-any.pkg.tar.xz

	cd ..

Build and install LibUnbound

Copy the mingw-w64-unbound directory to your home directory and enter it. After that Compile and install it with the following commands:

	cd mingw-w64-unbound/

	MINGW_INSTALLS=mingw64 makepkg-mingw -sLf
	
	pacman -U mingw-w64-x86_64-unbound-1.5.10-1-any.pkg.tar.xz

Using LibUnbound and LDNS

Including the libraries and compiling own sources

Add the following headers to use the libraries:

	#include <stdio.h>	/* for printf */
	#include <ws2tcpip.h>
	#include <unbound.h>	/* unbound API - BSD-LICENSE*/
	#include <stdbool.h> /* bool */
	#include <ldns/ldns.h> /* BSD-LICENSE*/
	#include <ldns/rdata.h>
	#include <math.h>
	#include <string.h>

Compiling own sources under Windows:

	mkdir build
	cd ./build
	cmake -G "MSYS Makefiles" ..
	make

Compiling own sources under GNU/Linux:

  • Use a cmake script:

    • See CMakeLists.txt example file

    Build the project:

    mkdir build
    cd ./build
    cmake
    make
    

Common use cases:

DNS-server request and parsing the response

DNSSEC secured DNS request

Creating a TLSA-RR

  ldns_rr * own_tlsa_rr = malloc(sizeof(ldns_rr)*6);
  ldns_status status;

  status = ldns_dane_create_tlsa_rr(/*ldns_rr** */  &own_tlsa_rr,
	     /*ldns_tlsa_certificate_usage*/      tlsa_record->usage,
	     /*ldns_tlsa_selector*/               tlsa_record->selector,
	     /*ldns_tlsa_matching_type*/          tlsa_record->match_type,
	     /*X509* */                           cert);

DANE secured HTTPS request

https://gitlab.labs.nic.cz/labs/dnssec-validator/blob/master/plugin-source/TLSAValidatorPlugin/dane-plug.c

  • -> Line 1642: creating tlsa qname
  • -> Line 1891: TLSA request

https://www.cs.utah.edu/~swalton/listings/articles/ssl_client.c

  • -> fetch tls certificate
  • Changes needed: use TLSv1_1_client_method as ssl_method

http://fm4dd.com/openssl/certpubkey.htm

read public key:

http://openssl.6102.n7.nabble.com/difference-between-i2d-PUBKEY-and-i2d-PublicKey-td43869.html

  • convert evp_pkey to der.

https://stackoverflow.com/questions/2262386/generate-sha256-with-openssl-and-c

  • sha256 hash with openssl

Snippet: Conversion of uint8_to_hex-string:

void uint8_to_hex(uint8_t * bin, size_t size, char * result)
{
  char buffer [200];
  for(int i = 0; i < 32; i++) {
    sprintf(result,"%02x",bin[i]);
    printf("\n hex: %s \n", result);
  }
  printf("\n hex: %s \n", result);
}

Sending HTTPS request:

HPKP secured HTTPS request

cmake_minimum_required(VERSION 2.8.9)
project (ExampleProject)
MESSAGE(STATUS "Looking for libunbound")
FIND_PATH(UNBOUND_INCLUDE_DIR
NAMES unbound.h
PATH_SUFFIXES include/ include/unbound/
PATHS "${PROJECT_SOURCE_DIR}"
${UNBOUND_ROOT}
$ENV{UNBOUND_ROOT}
/usr/local/
/usr/
)
find_library(UNBOUND_LIBRARIES unbound)
MESSAGE(STATUS "Looking for libLDNS")
find_path (LDNS_INCLUDE_DIR NAMES ldns/ldns.h)
mark_as_advanced(LDNS_INCLUDE_DIR)
find_library(LDNS_LIBRARY NAMES
ldns
libldns
)
mark_as_advanced(LDNS_LIBRARY)
if(LDNS_INCLUDE_DIR)
foreach(_ldns_version_header util.h)
if(EXISTS "${LDNS_INCLUDE_DIR}/ldns/${_ldns_version_header}")
file(STRINGS "${LDNS_INCLUDE_DIR}/ldns/${_ldns_version_header}" ldns_version_str REGEX "^#define[\t ]+LDNS_VERSION[\t ]+\".*\"")
string(REGEX REPLACE "^#define[\t ]+LDNS_VERSION[\t ]+\"([^\"]*)\".*" "\\1" LDNS_VERSION_STRING "${ldns_version_str}")
unset(ldns_version_str)
break()
endif()
endforeach()
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LDNS
REQUIRED_VARS LDNS_LIBRARY LDNS_INCLUDE_DIR
VERSION_VAR LDNS_VERSION_STRING)
if(LDNS_FOUND)
set(LDNS_LIBRARIES ${LDNS_LIBRARY})
set(LDNS_INCLUDE_DIRS ${LDNS_INCLUDE_DIR})
endif()
# Set library directories:
set ( PROJECT_LINK_LIBS "${LDNS_LIBRARY}" "${UNBOUND_LIBRARIES}")
link_directories( ./lib/build usr/local/lib "${UNBOUND_LIBRARIES}" "${LDNS_LIBRARIES}" )
include_directories( ./lib usr/local/include "${UNBOUND_INCLUDE_DIR}" "${LDNS_INCLUDE_DIRS}" )
add_executable(ExampleProject ./example.c)
target_link_libraries( ExampleProject ${PROJECT_LINK_LIBS} )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment