diff options
author | Alexander Færøy <ahf@irssi.org> | 2013-06-23 23:50:14 +0000 |
---|---|---|
committer | ahf <ahf@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2013-06-23 23:50:14 +0000 |
commit | d826896f74925f2e77536d69a3d1a4b86b0cec61 (patch) | |
tree | 04b69aa66cddd1076bd1c691816ce16f88dfba32 /src | |
parent | 02aa2682dcd6de0defcdc88756dd92e25ae268a4 (diff) | |
download | irssi-d826896f74925f2e77536d69a3d1a4b86b0cec61.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/core/network-openssl.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 8aeb5a6e..f80083c8 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -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; } |