In one of my projects, we are using MHD and need to support SSL encrypted 
private keys, with passwords. I ended up modifying the MHD code to support 
propagating, in addition to an SSL certificate and key, an SSL key password 
through to GnuTLS. With some relatively simple changes in place, the option 
MHD_OPTION_HTTPS_KEY_PASSWORD can be used when calling MHD_start_daemon() to 
specify a const char * password string. Also, another debug message is added in 
order to report the code returned by GnuTLS in the event the SSL 
certificate/key cannot be processed.

Following are my code diffs, relative to the 0.9.39 release. Hopefully they can 
be vetted by the primary author(s) of this codebase and incorporated into a 
future MHD release. Thank you.

$ diff src/include/microhttpd.h.orig src/include/microhttpd.h
865a866,873
> 
>   /**
>    * Memory pointer for a password that decrypts the private key (key.pem)
>    * to be used by the HTTPS daemon. This option should be followed by a
>    * `const char *` argument.
>    * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.
>    */
>   MHD_OPTION_HTTPS_KEY_PASSWORD = 26,
$ diff src/microhttpd/internal.h.orig src/microhttpd/internal.h
1202a1203,1208
>    * Pointer to a string containing a password (in ASCII) that de-crypts
>    * our SSL/TLS key.
>    */
>   const char *https_key_password;
>   
>   /**
$ diff src/microhttpd/daemon.c.orig src/microhttpd/daemon.c
547,549c547,560
<       return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
<                                                 &cert, &key,
<                                                 GNUTLS_X509_FMT_PEM);
---
>       int r;
>       if (NULL != daemon->https_key_password)
>       r = gnutls_certificate_set_x509_key_mem2(daemon->x509_cred, &cert,
>                                                &key, GNUTLS_X509_FMT_PEM,
>                                                daemon->https_key_password,0);
>       else
>       r = gnutls_certificate_set_x509_key_mem(daemon->x509_cred, &cert, &key,
>                                               GNUTLS_X509_FMT_PEM);
> #if HAVE_MESSAGES
>       if (r != 0)
>       MHD_DLOG(daemon, "GnuTLS could not set up SSL certificate/key; " \
>                "GnuTLS code %d was returned\n", r);
> #endif        
>       return r;
2997a3009,3018
>       case MHD_OPTION_HTTPS_KEY_PASSWORD:
>         if (0 != (daemon->options & MHD_USE_SSL))
>           daemon->https_key_password = va_arg (ap, const char *);
> #if HAVE_MESSAGES
>         else
>           MHD_DLOG (daemon,
>                     "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not 
> set\n",
>                     opt);
> #endif
>           break;
3178a3200
>               case MHD_OPTION_HTTPS_KEY_PASSWORD:
3228c3250,3252
<               (opt <= MHD_OPTION_HTTPS_PRIORITIES)) || (opt == 
MHD_OPTION_HTTPS_MEM_TRUST))
---
>               (opt <= MHD_OPTION_HTTPS_PRIORITIES)) ||
>             (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
>             (opt == MHD_OPTION_HTTPS_KEY_PASSWORD))


Andrew Basile
Basile Enterprises <http://basileenterprises.com/>

Reply via email to