0

I am following this tutorial: https://www.gnu.org/software/libmicrohttpd/tutorial.html#Adding-a-layer-of-security

In the section about ssl, there's an example provided called tlsauthentication.c... here's a link with the source code...

https://github.com/ulion/libmicrohttpd/blob/master/doc/examples/tlsauthentication.c

Unfortunately I can't get this file to run. The daemon never starts. Instead it returns null right away. (This happens in int main() way near the bottom of the source.)

The required files are server.key and server.pem which I have created in the right place based on the tutorial's instructions.

I found a similar question and the answer was that the OP had compiled with a --no-https flag (or something like that), but I simply compiled under default settings (./configure& make& make install I think it was).

What am I missing? How can I get this file to serve https as it was intended?

In case it's relevant, I'm using the newest stable version of libmicrohttpd, I updated gnutls (in case that matters), and I'm on OSX El Capitan.

sudo rm -rf slash
  • 1,156
  • 2
  • 16
  • 27
  • - Have you tried to run it through dtruss? Maybe you could find some clues in dtruss output... – woytekm Oct 08 '16 at 08:11
  • Answered my own question. It was a compilation issue after all. I uninstalled everything related to this project, ran `sudo brew install libmicrohttpd --with-ssl` and then `sudo brew link --overwrite libmicrohttpd` and now it all works. Not sure if I should delete the question or answer it myself... – sudo rm -rf slash Oct 08 '16 at 14:10

2 Answers2

1

If anyone, stumbles across this in the future, I spent some time making this work, so I thought I would share my documentation here. All of the existing guides that I found no longer worked properly (at least not for me).

The basic problem is that the normally distributed windows binaries of libmicrohttpd don't include HTTPS (TLS) support, so you have to build it yourself to get that. (You can check by seeing if the libmicrohttpd-12.dll links against libgnutls-30.dll. If it does, you should have TLS support).

Get Prerequisites

These are the free open source tools I used to build it on Windows 10:

Codeblocks 20.03

A free opensource IDE and build system for c/c++

http://sourceforge.net/projects/codeblocks/files/Binaries/20.03/Windows/codeblocks-20.03mingw-nosetup.zip

Libmicrohttpd source

Tested with this one: https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.73.tar.gz

MinGW 32bit build chain

A free opensource c/c++ compiler for Windows provided by the MINGW-W64 project.

Make sure the options selected are: i686 (32bit), posix threads, dwarf exception handling

https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z

If you need Windows XP/2003 server compatability you will need this older version (I have not tested with this.):

https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/6.4.0/threads-posix/dwarf/i686-6.4.0-release-posix-dwarf-rt_v5-rev0.7z

(newer versions of pthreads link against GetTickCount64 rather than GetTickCount)

Dependencies

A program for examining the dependency tree of an exe or dll (replacement for old dependency walker.)

https://github.com/lucasg/Dependencies/releases/download/v1.11.1/Dependencies_x64_Release.zip

GNUTLS and Binary dependencies

TLS support in libmicrohttpd depends on a number of other binaries that are part of MSYS.

Download and install MSYS base:

https://github.com/msys2/msys2-installer/releases/download/2021-11-30/msys2-base-x86_64-20211130.sfx.exe

start msys2.exe (on the first run it will update its trust database. Then close and reopen.)

Download packages:

pacman -S mingw-w64-i686-gcc mingw-w64-i686-libgcrypt mingw-w64-i686-gnutls (infact, I actually got mingw-w64-i686-gcc, make, wget, tar, and mingw-w64-i686-curl also).

After executing this command, verify that the following files were downloaded:

Binaries in msys64\mingw32\bin:

  1. libffi-7.dll
  2. libhogweed-6.dll
  3. libnettle-8.dll
  4. libgmp-10.dll
  5. libidn2-0.dll
  6. libunistring-2.dll
  7. libp11-kit-0.dll
  8. libiconv-2.dll
  9. libintl-8.dll
  10. libtasn1-6.dll
  11. libssp-0.dll
  12. libwinpthread-1.dll
  13. libstdc++-6.dll
  14. libgcc_s_dw2-1.dll
  15. libgnutls-30.dll

Linker file: msys64\mingw32\mingw32\lib\libgnutls.dll.a

Header files: msys64\mingw32\include\gnutls\*.h

Installing tools

  • Install code blocks (just upzip it if using the nosetup one).

  • Unzip MinGW build chain and copy into c:\Program Files (x86). Your directory structure should be: "C:\Program Files (x86)\i686-8.1.0-release-posix-dwarf-rt_v6-rev0\mingw32..."

  • Set toolchain. In Codeblocks, set the compiler build chain to the above folder. Codeblocks->Settings->Compiler->Toolchain Executable

Create Project & Copy Files

  • Start Codeblocks and create a new "Dynamic Link Library" project. This will create a project folder [MHD-LIB-ROOT] and a [MHD-LIB-PROJ-NAME].cbp

  • Upzip libmicrohttpd-0.9.73 to a subdirectory of [MHD-LIB-ROOT].

  • Copy libgnutls.dll.a from msys64\mingw32\mingw32\lib\ into [MHD-LIB-ROOT]. Also copy all headers from msys64\mingw32\include\gnutls into [MHD-LIB-ROOT]\gnutls\gnutls (so the following file should exist: [MHD-LIB-ROOT]\gnutls\gnutls\gnutls.h).

  • Copy binaries to the [MHD-LIB-ROOT]\bin\Debug and [MHD-LIB-ROOT]\bin\Release folders.

    Copy all the dlls listed above in the GNUTLS and Binary dependencies section.

Configure Project

  • Add all .c and .h files to the project from [MHD-LIB-ROOT]\libmicrohttpd-0.9.73\src\microhttpd and [MHD-LIB-ROOT]\libmicrohttpd-0.9.73\src\include. Don't add files from [MHD-LIB-ROOT]\libmicrohttpd-0.9.73\src\lib or any of the examples.

  • In Project build options -> Search directories: Add the following paths to the compiler: "libmicrohttpd-0.9.73\src\include", "libmicrohttpd-0.9.73\w32\common", and "gnutls". (Recommend to use relative paths.)

  • In Project build options -> Linker settings: add ".\libgnutls.dll.a" to the link libraries. Add "-lws2_32" to the Other linker options.

Set MHD options

  • Edit w32/common/MHD_config.h:

    • Change: #define INLINE_FUNC 0
    • Add: #define HTTPS_SUPPORT 1

Fix for compile error

  • Edit mhd_str.c and remove the whole section with the INLINE_FUNC define block since this gives "error: multiple storage classes in declaration specifiers". (So you should only have the code that was within the !INLINE_FUNC block).

Note: there are likely better fixes, but I was just looking to make the build work.

Build the libmicrohttpd library

  • Invoke the "build" command in codeblocks. If everything is set up properly, the "libmicrohttpd-tls.dll" binary should be generated in the [MHD-LIB-ROOT]\bin\Debug and [MHD-LIB-ROOT]\bin\Release folders along with the 14 dlls that you should have already copied there.

Testing for missing libraries

Run the dependencies tool and load the "[MHD-LIB-PROJ-NAME].dll". Expand all the dependencies to verify that there are no missing dlls.

Create certificates:

Generate required certifications to make TLS encyption work without errors. Follow the steps outlined here: https://stackoverflow.com/a/27931596/2895480

Create certificate.ext

Put the following text in a file and save it as certificate.ext (for this example I called my domain SSPI-auth.local)

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = SSPI-auth.local

Generate Certificate authority (CA)

openssl req -x509 -nodes -new -sha256 -days 5000 -keyout c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.key -out c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.pem -subj "/C=US/CN=SSPI-Auth-Root-CA"

openssl x509 -outform pem -in c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.pem -out c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.crt

Generate Domain name certificate

openssl req -new -nodes -newkey rsa:2048 -keyout c:\Users\bruce.eng\Documents\SSPI-auth-domain.key -out c:\Users\bruce.eng\Documents\SSPI-auth-domain.csr -subj "/C=US/ST=Texas/L=Houston/O=SSPI-Auth-Certificates/CN=sspi-auth.local"

openssl x509 -req -sha256 -days 5000 -in c:\Users\bruce.eng\Documents\SSPI-auth-domain.csr -CA c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.pem -CAkey c:\Users\bruce.eng\Documents\SSPI-auth-RootCA.key -CAcreateserial -extfile c:\Users\bruce.eng\Documents\bruce-paging\certificate.ext -out c:\Users\bruce.eng\Documents\SSPI-auth-domain.crt

openssl x509 -in SSPI-auth-domain.crt -out SSPI-auth-domain.pem -outform PEM

Add entry to host file

Inlcude this line in the host file:

127.0.0.1           sspi-auth.local  

Add root CA to trusted certificates.

Add the SSPI-auth-RootCA to you Local Computer\Trusted Root Certification Authorities\Certificates

Building and testing example

Create a new console type project in codeblocks with a root directory of [TEST-PROJECT_ROOT]. Copy the tlsauthentication.c file from libmicrohttps-0.9.73/doc/examples into the [TEST-PROJECT_ROOT]. Rename it to tlsauthentication.cpp (might not be necessary, but this is what I had).

Add the following files to the project:

tlsauthentication.cpp

under Project build options->Linker settings, ADD ".\[MHD-LIB-PROJ-NAME].a" to the link libraries.

modify tlsauthentication.cpp so it loads the SSPI-auth-domain.pem and SSPI-auth-domain.key certificate files.

Build the project which should create bin\Debug[TEST-PROJECT_ROOT].exe. Copy libmicrohttpd-tls.dll (the version you just built, this was what I called it) as well as the 15 other dll dependencies to the same folder. Also copy your certificate files here.

Launch [TEST-PROJECT_ROOT].exe.

In the browser, go to https://SSPI-auth.local:8888 and fingers crossed, it will work without errors.

bruceceng
  • 1,844
  • 18
  • 23
0

If you are a Windows user and want to use libmicrohttpd with SSL, you must do the following steps:

  1. Add "#define HTTPS_SUPPORT 1" to MHD_config.h in w32\common\MHD_config.h
  2. Download libgnutls (the MinGW compiled version)
  3. Generate a LIB file for libgnutls by executing lib.exe from Visual Studio (open cmd.exe, browse into lib directory of libgnutls and then execute lib.exe like this: "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\lib.exe" /def:libgnutls-30.def /nologo /machine:x64)
  4. Copy the "include" directory of libgnutls beneath the libmicrohttpd Visual Studio project file and name it "gnutls"
  5. Copy the generated libgnutls-30.lib, libgnutls-30.exp as well as libgnutls-30.def into the folder with the libmicrohttpd Visual Studio project file.
  6. Compile libmicrohttpd using one of the configurations Debug-dll or Release-dll. Those with -static may not be used anymore, because this would violate the LGPL2.1 license (which is used when you use SSL).
  7. Link your application with the generated lib (i. e. libmicrohttpd-dll.lib) and copy libmicrohttpd-dll.dll as well as all libgnutls DLLs (libgnutls-30.dll, ...) to your exe file.
David Gausmann
  • 1,570
  • 16
  • 20