mirror of https://github.com/getdnsapi/getdns.git
Added a wincrypt adapter to read CA trust certs from Windows CA store and feed them into openssl for TLS hostname authentication
This commit is contained in:
parent
b39ddf01d0
commit
7e9563faed
|
@ -32,12 +32,12 @@ dnl see if on windows
|
||||||
if test "$ac_cv_header_windows_h" = "yes"; then
|
if test "$ac_cv_header_windows_h" = "yes"; then
|
||||||
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
||||||
USE_WINSOCK="1"
|
USE_WINSOCK="1"
|
||||||
LIBS="$LIBS -lws2_32"
|
LIBS="$LIBS -lws2_32 -lcrypt32"
|
||||||
fi
|
fi
|
||||||
],
|
],
|
||||||
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
|
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
|
||||||
ORIGLIBS="$LIBS"
|
ORIGLIBS="$LIBS"
|
||||||
LIBS="$LIBS -lws2_32"
|
LIBS="$LIBS -lws2_32 -lcrypt32"
|
||||||
AC_LINK_IFELSE(
|
AC_LINK_IFELSE(
|
||||||
[AC_LANG_PROGRAM(
|
[AC_LANG_PROGRAM(
|
||||||
[
|
[
|
||||||
|
@ -62,7 +62,7 @@ AC_LINK_IFELSE(
|
||||||
)],
|
)],
|
||||||
[
|
[
|
||||||
ac_cv_func_getaddrinfo="yes"
|
ac_cv_func_getaddrinfo="yes"
|
||||||
dnl already: LIBS="$LIBS -lws2_32"
|
dnl already: LIBS="$LIBS -lws2_32 -lcrypt32"
|
||||||
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
||||||
USE_WINSOCK="1"
|
USE_WINSOCK="1"
|
||||||
],
|
],
|
||||||
|
|
|
@ -44,6 +44,14 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
typedef unsigned short in_port_t;
|
typedef unsigned short in_port_t;
|
||||||
|
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <Wincrypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -130,6 +138,66 @@ static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*,
|
||||||
/* Stuff to make it compile pedantically */
|
/* Stuff to make it compile pedantically */
|
||||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
// For windows, the CA trust store is not read by openssl.
|
||||||
|
// Add code to open the trust store using wincrypt API and add
|
||||||
|
// the root certs into openssl trust store
|
||||||
|
X509_STORE *store;
|
||||||
|
X509_STORE_CTX *sslctx = NULL;
|
||||||
|
void add_cacerts_to_openssl_store(struct getdns_context *context)
|
||||||
|
{
|
||||||
|
HCERTSTORE hSystemStore;
|
||||||
|
PCCERT_CONTEXT pTargetCert = NULL;
|
||||||
|
|
||||||
|
// Call wincrypt's CertOpenStore to open the CA root store.
|
||||||
|
|
||||||
|
if ((hSystemStore = CertOpenStore(
|
||||||
|
CERT_STORE_PROV_SYSTEM,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
// mingw does not have this const: replace with 1 << 16 from code
|
||||||
|
// CERT_SYSTEM_STORE_CURRENT_USER,
|
||||||
|
1 << 16,
|
||||||
|
L"root")) == 0)
|
||||||
|
{
|
||||||
|
DEBUG_STUB("*** %s(CertOpenStore failed)\n", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store = SSL_CTX_get_cert_store(context->tls_ctx);
|
||||||
|
|
||||||
|
// iterate over the windows cert store and add to openssl store
|
||||||
|
while (pTargetCert = CertEnumCertificatesInStore(
|
||||||
|
hSystemStore,
|
||||||
|
pTargetCert))
|
||||||
|
{
|
||||||
|
BYTE* cert = pTargetCert->pbCertEncoded;
|
||||||
|
X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded);
|
||||||
|
if (!cert1) {
|
||||||
|
DEBUG_STUB("*** %s(%s)\n", __FUNCTION__,
|
||||||
|
"unable to parse certificate in memory");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (X509_STORE_add_cert(store, cert1) == 0)
|
||||||
|
DEBUG_STUB("*** %s(%s)\n", __FUNCTION__,
|
||||||
|
"error adding certificate");
|
||||||
|
X509_free(cert1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clean up memory and quit.
|
||||||
|
|
||||||
|
if (pTargetCert)
|
||||||
|
CertFreeCertificateContext(pTargetCert);
|
||||||
|
if (hSystemStore)
|
||||||
|
{
|
||||||
|
if (!CertCloseStore(
|
||||||
|
hSystemStore, 0))
|
||||||
|
DEBUG_STUB("*** %s(%s)\n", __FUNCTION__, "CertCloseStore failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void destroy_local_host(_getdns_rbnode_t * node, void *arg)
|
static void destroy_local_host(_getdns_rbnode_t * node, void *arg)
|
||||||
{
|
{
|
||||||
getdns_context *context = (getdns_context *)arg;
|
getdns_context *context = (getdns_context *)arg;
|
||||||
|
@ -2631,7 +2699,8 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
#else
|
#else
|
||||||
printf("Warning! Bad TLS context, check openssl version on Windows!\n");;
|
printf("Warning! Bad TLS context, check openssl version on Windows!\n");
|
||||||
|
add_cacerts_to_openssl_store(context);
|
||||||
#endif
|
#endif
|
||||||
/* Be strict and only use the cipher suites recommended in RFC7525
|
/* Be strict and only use the cipher suites recommended in RFC7525
|
||||||
Unless we later fallback to opportunistic. */
|
Unless we later fallback to opportunistic. */
|
||||||
|
|
Loading…
Reference in New Issue