1
0
mirror of https://github.com/irssi/irssi.git synced 2025-02-02 15:08:01 -05:00

Implement experimental DNSSEC DANE support

This patch adds experimental support for the DNSSEC DANE verification
protocol using the libval library from the DNSSEC-Tools package.

Thanks to Thomas Steen Ramussen for creating a test setup and suggesting
the idea of experimenting with DANE support in Irssi :-)

git-svn-id: file:///var/www/svn.irssi.org/SVN/irssi/trunk@5218 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Alexander Færøy 2013-06-23 23:50:14 +00:00 committed by ahf
parent 02aa2682dc
commit d826896f74
2 changed files with 65 additions and 4 deletions

View File

@ -156,6 +156,15 @@ AC_ARG_ENABLE(ipv6,
fi,
want_ipv6=yes)
AC_ARG_ENABLE(dane,
[ --enable-dane Enable DANE support],
if test x$enableval = xno ; then
want_dane=no
else
want_dane=yes
fi,
want_dane=no)
dnl **
dnl ** SSL Library checks (OpenSSL)
dnl **
@ -616,6 +625,17 @@ if test "x$want_ipv6" = "xyes"; then
AC_MSG_RESULT($have_ipv6)
fi
have_dane=no
if test "x$want_dane" = "xyes"; then
AC_MSG_CHECKING([for DANE])
AC_CHECK_LIB(val-threads, val_getdaneinfo,
[
LIBS="$LIBS -lval-threads -lsres"
AC_DEFINE([HAVE_DANE], [], [DANE support])
have_dane=yes
])
fi
AC_CONFIG_FILES([
Makefile
src/Makefile
@ -733,6 +753,7 @@ echo "Building with IPv6 support ....... : $have_ipv6"
echo "Building with SSL support ........ : $have_openssl"
echo "Building with 64bit DCC support .. : $offt_64bit"
echo "Building with garbage collector .. : $have_gc"
echo "Building with DANE support ....... : $have_dane"
echo
echo "If there are any problems, read the INSTALL file."

View File

@ -31,6 +31,11 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
#ifdef HAVE_DANE
#include <validator/validator.h>
#include <validator/val_dane.h>
#endif
/* ssl i/o channel object */
typedef struct
{
@ -41,6 +46,7 @@ typedef struct
SSL_CTX *ctx;
unsigned int verify:1;
const char *hostname;
int port;
} GIOSSLChannel;
static int ssl_inited = FALSE;
@ -196,9 +202,42 @@ static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname)
return matched;
}
static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, X509 *cert)
static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, int port, X509 *cert)
{
long result;
#ifdef HAVE_DANE
int dane_ret;
struct val_daneparams daneparams;
struct val_danestatus *danestatus = NULL;
// Check if a TLSA record is available.
daneparams.port = port;
daneparams.proto = DANE_PARAM_PROTO_TCP;
dane_ret = val_getdaneinfo(NULL, hostname, &daneparams, &danestatus);
if (dane_ret == VAL_DANE_NOERROR) {
g_warning("DANE: TLSA record for hostname %s exists", hostname);
} else if (dane_ret != VAL_DANE_IGNORE_TLSA) {
g_warning("DANE: TLSA record for hostname %s could not be verified", hostname);
}
if (danestatus != NULL) {
int do_certificate_check = 1;
if (val_dane_check(NULL, ssl, danestatus, &do_certificate_check) != VAL_DANE_NOERROR) {
g_warning("DANE: Failed to verify hostname %s", hostname);
return FALSE;
}
g_warning("DANE: SSL certificate verified using DANE");
if (do_certificate_check == 0) {
g_warning("DANE: Skipping additional checks");
return TRUE;
}
}
#endif
result = SSL_get_verify_result(ssl);
if (result != X509_V_OK) {
@ -389,7 +428,7 @@ static gboolean irssi_ssl_init(void)
}
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, int port, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
{
GIOSSLChannel *chan;
GIOChannel *gchan;
@ -474,6 +513,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostn
chan->ctx = ctx;
chan->verify = verify;
chan->hostname = hostname;
chan->port = port;
gchan = (GIOChannel *)chan;
gchan->funcs = &irssi_ssl_channel_funcs;
@ -491,7 +531,7 @@ GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADD
handle = net_connect_ip(ip, port, my_ip);
if (handle == NULL)
return NULL;
ssl_handle = irssi_ssl_get_iochannel(handle, hostname, cert, pkey, cafile, capath, verify);
ssl_handle = irssi_ssl_get_iochannel(handle, hostname, port, cert, pkey, cafile, capath, verify);
if (ssl_handle == NULL)
g_io_channel_unref(handle);
return ssl_handle;
@ -533,7 +573,7 @@ int irssi_ssl_handshake(GIOChannel *handle)
g_warning("SSL server supplied no certificate");
return -1;
}
ret = !chan->verify || irssi_ssl_verify(chan->ssl, chan->ctx, chan->hostname, cert);
ret = !chan->verify || irssi_ssl_verify(chan->ssl, chan->ctx, chan->hostname, chan->port, cert);
X509_free(cert);
return ret ? 0 : -1;
}