From 6cd86799aea2effe59b7c396c8b8caca7311300e Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 19 Sep 2014 13:01:53 -0700 Subject: [PATCH] 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