From 7bd30fb1730d6bef8edcabefed47876e1b8856b0 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Jan 14 2015 19:07:13 +0000 Subject: backport fixes to make CA mode TLS certificate validation work OOTB --- diff --git a/0001-check-whether-trust-store-is-a-file-or-directory-in-.patch b/0001-check-whether-trust-store-is-a-file-or-directory-in-.patch new file mode 100644 index 0000000..8cb12b0 --- /dev/null +++ b/0001-check-whether-trust-store-is-a-file-or-directory-in-.patch @@ -0,0 +1,115 @@ +From 6cd86799aea2effe59b7c396c8b8caca7311300e Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Fri, 19 Sep 2014 13:01:53 -0700 +Subject: [PATCH 1/2] check whether trust store is a file or directory in + CHECK_CA + +The existing code only allows you to provide a set of trusted +CA certificates as an openssl 'CApath'-type directory. Fedora, +RHEL (and derived distros) and probably other distros provide +a system-wide database of trusted CA certs in various bundle +formats, but not as a CApath-type directory. This checks whether +check_store is a file or directory and loads it appropriately, +when initializing an SSL connection. + +Note that there is code elsewhere which assumes the trust store +will be a file, but that code is hit only in CHECK_BASIC mode. +This change applies only to CHECK_CA mode. +--- + bip.conf.5 | 5 +++++ + samples/bip.conf | 10 ++++++---- + src/connection.c | 29 ++++++++++++++++++++++++----- + 3 files changed, 35 insertions(+), 9 deletions(-) + +diff --git a/bip.conf.5 b/bip.conf.5 +index a4a59a2..e8030c2 100644 +--- a/bip.conf.5 ++++ b/bip.conf.5 +@@ -251,6 +251,11 @@ allows a "ssh-like" private key generation scheme. Note that in basic mode: + .TP + \fBssl_check_store\fP (default: \fBnot set\fP) + This repository is browsed by BIP when a SSL certificate or CA check is needed. ++In ssl_check_mode \fBbasic\fP it must be a file, to which certificates you ++choose to trust will be appended. In ssl_check_mode \fBca\fP it may be a ++single file containing one or more trusted certificates concatenated together ++between BEGIN CERTIFICATE and END CERTIFICATE lines, or a directory containing ++individual certificates in PEM format which has been processed by \fBc_rehash\fP. + + .TP + \fBssl_client_certfile\fP (default: \fBnot set\fP) +diff --git a/samples/bip.conf b/samples/bip.conf +index 6761688..59a0339 100644 +--- a/samples/bip.conf ++++ b/samples/bip.conf +@@ -117,13 +117,15 @@ user { + # using "basic" unless you're a crypto zealot... + ssl_check_mode = "none"; + +- # Location of the user's store for SSL certificate check ++ # Location of the user's store for server SSL certificate check + # In "basic" mode, that must point to a single file with all trusted + # certs concatenated together (the interactive "trust" appends to this + # file). +- # In "ca" mode, it's a directory of a standard openssl store; you must +- # put PEM objects (certificates, CRLs...) with .pem extension and run +- # `c_rehash .' in it ++ # In "ca" mode, it can be either: ++ # - a directory of a standard openssl store; you must put PEM objects ++ # (certificates, CRLs...) with .pem extension and run `c_rehash .' in it ++ # - a certificate bundle file containing one or more certificates in PEM ++ # format, enclosed in BEGIN CERTIFICATE / END CERTIFICATE lines + ssl_check_store = "/home/bip4ever/.bip/trustedcerts.txt"; + + # Some networks (OFTC at least) allow you to authenticate to nickserv +diff --git a/src/connection.c b/src/connection.c +index da23996..b534cd0 100644 +--- a/src/connection.c ++++ b/src/connection.c +@@ -1461,6 +1461,7 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport, + conn->ssl_check_mode = check_mode; + + switch (conn->ssl_check_mode) { ++ struct stat st_buf; + case SSL_CHECK_BASIC: + if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, check_store, + NULL)) { +@@ -1469,13 +1470,31 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport, + } + break; + case SSL_CHECK_CA: +- if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, NULL, +- check_store)) { +- mylog(LOG_ERROR, "Can't assign check store to " +- "SSL connection!"); ++ // Check if check_store is a file or directory ++ if (stat(check_store, &st_buf) == 0) { ++ if (st_buf.st_mode & S_IFDIR) { ++ if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, NULL, ++ check_store)) { ++ mylog(LOG_ERROR, "Can't assign check store to " ++ "SSL connection!"); ++ return conn; ++ } ++ break; ++ } ++ if (st_buf.st_mode & S_IFREG) { ++ if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, check_store, ++ NULL)) { ++ mylog(LOG_ERROR, "Can't assign check store to " ++ "SSL connection!"); ++ return conn; ++ } ++ break; ++ } ++ mylog(LOG_ERROR, "Check store is neither a file nor a directory."); + return conn; + } +- break; ++ mylog(LOG_ERROR, "Can't open check store! Make sure path is correct."); ++ return conn; + } + + switch (conn->ssl_check_mode) { +-- +2.1.0 + diff --git a/0002-allow-for-certificate-store-to-be-unspecified-in-CA-.patch b/0002-allow-for-certificate-store-to-be-unspecified-in-CA-.patch new file mode 100644 index 0000000..c635a48 --- /dev/null +++ b/0002-allow-for-certificate-store-to-be-unspecified-in-CA-.patch @@ -0,0 +1,80 @@ +From a54b6835493767c348b33381040506aee4629d19 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Fri, 19 Sep 2014 18:04:53 -0700 +Subject: [PATCH 2/2] allow for certificate store to be unspecified in CA mode + +In many cases, using OpenSSL's default certificate store is fine +and even preferred. If your OpenSSL provider (e.g. your +distribution) is competent, they will manage this database +better than you likely will. + +This could be refined to test in the NULL case whether the +certificate store is empty, and fail out if so. +--- + src/bip.c | 12 +++++++++--- + src/connection.c | 17 +++++++++++++++-- + 2 files changed, 24 insertions(+), 5 deletions(-) + +diff --git a/src/bip.c b/src/bip.c +index 37e72d9..f025c21 100644 +--- a/src/bip.c ++++ b/src/bip.c +@@ -1540,9 +1540,15 @@ noroom: + bip_notify(ic, "%s", buf); + + #ifdef HAVE_LIBSSL +- bip_notify(ic, "SSL check mode '%s', stored into '%s'", +- checkmode2text(u->ssl_check_mode), +- STRORNULL(u->ssl_check_store)); ++ if (u->ssl_check_store) { ++ bip_notify(ic, "SSL check mode '%s', stored into '%s'", ++ checkmode2text(u->ssl_check_mode), ++ u->ssl_check_store); ++ } ++ else { ++ bip_notify(ic, "SSL check mode '%s', default or no certificate store", ++ checkmode2text(u->ssl_check_mode)); ++ } + if (u->ssl_client_certfile) + bip_notify(ic, "SSL client certificate stored into '%s'", + u->ssl_client_certfile); +diff --git a/src/connection.c b/src/connection.c +index b534cd0..ab1516e 100644 +--- a/src/connection.c ++++ b/src/connection.c +@@ -1470,6 +1470,17 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport, + } + break; + case SSL_CHECK_CA: ++ if (!check_store) { ++ if (SSL_CTX_set_default_verify_paths(conn->ssl_ctx_h)) { ++ mylog(LOG_INFO, "No SSL certificate check store configured. " ++ "Default store will be used."); ++ break; ++ } else { ++ mylog(LOG_ERROR, "No SSL certificate check store configured " ++ "and cannot use default store!"); ++ return conn; ++ } ++ } + // Check if check_store is a file or directory + if (stat(check_store, &st_buf) == 0) { + if (st_buf.st_mode & S_IFDIR) { +@@ -1490,10 +1501,12 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport, + } + break; + } +- mylog(LOG_ERROR, "Check store is neither a file nor a directory."); ++ mylog(LOG_ERROR, "Specified SSL certificate check store is neither " ++ "a file nor a directory."); + return conn; + } +- mylog(LOG_ERROR, "Can't open check store! Make sure path is correct."); ++ mylog(LOG_ERROR, "Can't open SSL certificate check store! Check path " ++ "and permissions."); + return conn; + } + +-- +2.1.0 + diff --git a/bip.spec b/bip.spec index c3cd794..c213dc2 100644 --- a/bip.spec +++ b/bip.spec @@ -1,6 +1,6 @@ Name: bip Version: 0.8.9 -Release: 5%{?dist} +Release: 6%{?dist} Summary: IRC Bouncer Group: Applications/Internet License: GPLv2+ @@ -13,6 +13,12 @@ Source2: bip-tmpfs.conf Source3: bip.service Patch0: 0001-Setup-bip-for-Fedora-s-paths.patch Patch1: 0002-Throttle-joins-to-prevent-flooding.patch +# Backports of https://projects.duckcorp.org/issues/350: makes CA mode +# TLS work out of the box +# https://projects.duckcorp.org/projects/bip/repository/revisions/89295ca4b2b89f88b4ce52fd78f0033a34906d90 +# https://projects.duckcorp.org/projects/bip/repository/revisions/88242715f489850a1f7cad6064492668c84f5083 +Patch2: 0001-check-whether-trust-store-is-a-file-or-directory-in-.patch +Patch3: 0002-allow-for-certificate-store-to-be-unspecified-in-CA-.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -115,6 +121,9 @@ rm -rf $RPM_BUILD_ROOT %{_unitdir}/bip.service %changelog +* Wed Dec 10 2014 Adam Williamson - 0.8.9-6 +- backport a couple of patches that make CA mode TLS validation work OOTB + * Mon Oct 06 2014 Brian C. Lane 0.8.9-5 - Use network-online.target (#862610)