Skip to content

Commit

Permalink
SSL securitylevel WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
qris authored and Chris Wilson committed May 1, 2019
1 parent 83238a9 commit cb3be2c
Show file tree
Hide file tree
Showing 75 changed files with 1,633 additions and 66 deletions.
17 changes: 16 additions & 1 deletion bin/bbackupd/bbackupd-config.in
Expand Up @@ -169,7 +169,7 @@ if(!-f $private_key)
if(!-f $certificate_request)
{
die "Couldn't run openssl for CSR generation" unless
open(CSR,"|openssl req -new -key $private_key -sha1 -out $certificate_request");
open(CSR,"|openssl req -new -key $private_key -sha256 -out $certificate_request");
print CSR <<__E;
.
.
Expand Down Expand Up @@ -317,6 +317,21 @@ NotifyScript = $notify_script

__E

if("@HAVE_SSL_CTX_SET_SECURITY_LEVEL@" eq "1")
{
print CONFIG <<__E;
# Box Backup compiled with support for SSLSecurityLevel
SSLSecurityLevel = 2
__E
}
else
{
print CONFIG <<__E;
# Box Backup compiled without support for SSLSecurityLevel
# SSLSecurityLevel = 2
__E
}

if($backup_mode eq 'lazy')
{
# lazy mode configuration
Expand Down
4 changes: 3 additions & 1 deletion bin/bbackupquery/bbackupquery.cpp
Expand Up @@ -364,7 +364,9 @@ int main(int argc, const char *argv[])
std::string certFile(conf.GetKeyValue("CertificateFile"));
std::string keyFile(conf.GetKeyValue("PrivateKeyFile"));
std::string caFile(conf.GetKeyValue("TrustedCAsFile"));
tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str());
int ssl_security_level(conf.GetKeyValueInt("SSLSecurityLevel"));
tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(),
caFile.c_str(), ssl_security_level);

// Initialise keys
BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str());
Expand Down
8 changes: 4 additions & 4 deletions bin/bbstored/bbstored-certs.in
Expand Up @@ -122,7 +122,7 @@ sub cmd_init_create_root

# make CSR
die "Couldn't run openssl for CSR generation" unless
open(CSR,"|openssl req -new -key $key -sha1 -out $csr");
open(CSR,"|openssl req -new -key $key -sha256 -out $csr");
print CSR <<__E;
.
.
Expand All @@ -140,7 +140,7 @@ __E
die "Certificate request wasn't created.\n" unless -f $csr;

# sign it to make a self-signed root CA key
if(system("openssl x509 -req -in $csr -sha1 -extensions v3_ca -signkey $key -out $cert -days $root_sign_period") != 0)
if(system("openssl x509 -req -in $csr -sha256 -extensions v3_ca -signkey $key -out $cert -days $root_sign_period") != 0)
{
die "Couldn't generate root certificate."
}
Expand Down Expand Up @@ -201,7 +201,7 @@ __E
my $out_cert = "$cert_dir/clients/$acc"."-cert.pem";

# sign it!
if(system("openssl x509 -req -in $csr -sha1 -extensions usr_crt -CA $cert_dir/roots/clientCA.pem -CAkey $cert_dir/keys/clientRootKey.pem -out $out_cert -days $sign_period") != 0)
if(system("openssl x509 -req -in $csr -sha256 -extensions usr_crt -CA $cert_dir/roots/clientCA.pem -CAkey $cert_dir/keys/clientRootKey.pem -out $out_cert -days $sign_period") != 0)
{
die "Signing failed"
}
Expand Down Expand Up @@ -257,7 +257,7 @@ __E
my $out_cert = "$cert_dir/servers/$common_name"."-cert.pem";

# sign it!
if(system("openssl x509 -req -in $csr -sha1 -extensions usr_crt -CA $cert_dir/roots/serverCA.pem -CAkey $cert_dir/keys/serverRootKey.pem -out $out_cert -days $sign_period") != 0)
if(system("openssl x509 -req -in $csr -sha256 -extensions usr_crt -CA $cert_dir/roots/serverCA.pem -CAkey $cert_dir/keys/serverRootKey.pem -out $out_cert -days $sign_period") != 0)
{
die "Signing failed"
}
Expand Down
17 changes: 15 additions & 2 deletions bin/bbstored/bbstored-config.in
Expand Up @@ -202,11 +202,24 @@ Server
CertificateFile = $certificate
PrivateKeyFile = $private_key
TrustedCAsFile = $ca_root_cert
}

__E

if("@HAVE_SSL_CTX_SET_SECURITY_LEVEL@" eq "1")
{
print CONFIG <<__E;
# Box Backup compiled with support for SSLSecurityLevel
SSLSecurityLevel = 2
__E
}
else
{
print CONFIG <<__E;
# Box Backup compiled without support for SSLSecurityLevel
# SSLSecurityLevel = 2
__E
}

print CONFIG "}\n";
close CONFIG;

# explain to the user what they need to do next
Expand Down
4 changes: 4 additions & 0 deletions infrastructure/cmake/CMakeLists.txt
Expand Up @@ -430,6 +430,7 @@ else()
endif()
include_directories(${OPENSSL_INCLUDE_DIR})
target_link_libraries(lib_crypto PUBLIC ${OPENSSL_LIBRARIES})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})

# Link to PCRE
if (WIN32)
Expand Down Expand Up @@ -613,6 +614,9 @@ foreach(function_name ${detect_functions})
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_${platform_var_name}\n")
endforeach()

check_function_exists(SSL_CTX_set_security_level HAVE_SSL_CTX_SET_SECURITY_LEVEL)
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_SSL_CTX_SET_SECURITY_LEVEL\n")

check_symbol_exists(dirfd "dirent.h" HAVE_DECL_DIRFD)
file(APPEND "${boxconfig_h_file}" "#cmakedefine01 HAVE_DECL_DIRFD\n")

Expand Down
4 changes: 3 additions & 1 deletion infrastructure/m4/boxbackup_tests.m4
Expand Up @@ -128,6 +128,7 @@ AC_CHECK_FUNCS([dlsym dladdr])
AC_SEARCH_LIBS([gethostbyname], [nsl socket resolv])
AC_SEARCH_LIBS([shutdown], [nsl socket resolv])
AX_CHECK_SSL(, [AC_MSG_ERROR([[OpenSSL is not installed but is required]])])
AC_CHECK_DECLS([SSL_R_EE_KEY_TOO_SMALL],,, [[#include <openssl/sslerr.h>]])
AC_ARG_ENABLE(
[old-ssl],
[AC_HELP_STRING([--enable-old-ssl],
Expand All @@ -142,7 +143,8 @@ AC_SEARCH_LIBS(
Upgrade or read the documentation for alternatives]])
fi
])

AC_CHECK_FUNCS([SSL_CTX_set_security_level], [HAVE_SSL_CTX_SET_SECURITY_LEVEL=1])
AC_SUBST([HAVE_SSL_CTX_SET_SECURITY_LEVEL])

### Checks for header files.

Expand Down
9 changes: 6 additions & 3 deletions lib/backupclient/BackupDaemonConfigVerify.cpp
Expand Up @@ -8,10 +8,11 @@
// --------------------------------------------------------------------------

#include "Box.h"

#include "BackupConstants.h"
#include "BackupDaemonConfigVerify.h"
#include "Daemon.h"
#include "BoxPortsAndFiles.h"
#include "BackupConstants.h"
#include "Daemon.h"

#include "MemLeakFindOn.h"

Expand Down Expand Up @@ -148,7 +149,9 @@ static const ConfigurationVerifyKey verifyrootkeys[] =
ConfigTest_IsUint32),
ConfigurationVerifyKey("CertificateFile", 0),
ConfigurationVerifyKey("PrivateKeyFile", 0),
ConfigurationVerifyKey("TrustedCAsFile", ConfigTest_LastEntry),
ConfigurationVerifyKey("TrustedCAsFile", 0),
ConfigurationVerifyKey("SSLSecurityLevel", ConfigTest_IsInt | ConfigTest_LastEntry,
BOX_DEFAULT_SSL_SECURITY_LEVEL),
};

const ConfigurationVerify BackupDaemonConfigVerify =
Expand Down
3 changes: 2 additions & 1 deletion lib/bbackupd/BackupDaemon.cpp
Expand Up @@ -579,8 +579,9 @@ void BackupDaemon::InitCrypto()
std::string certFile(conf.GetKeyValue("CertificateFile"));
std::string keyFile(conf.GetKeyValue("PrivateKeyFile"));
std::string caFile(conf.GetKeyValue("TrustedCAsFile"));
int ssl_security_level(conf.GetKeyValueInt("SSLSecurityLevel"));
mTlsContext.Initialise(false /* as client */, certFile.c_str(),
keyFile.c_str(), caFile.c_str());
keyFile.c_str(), caFile.c_str(), ssl_security_level);

// Set up the keys for various things
BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile"));
Expand Down
4 changes: 4 additions & 0 deletions lib/common/BoxPortsAndFiles.h.in
Expand Up @@ -20,6 +20,10 @@
// directory within the RAIDFILE root for the backup store daemon
#define BOX_RAIDFILE_ROOT_BBSTORED "backup"

// default security level if SSLSecurityLevel is not specified: see
// https://www.boxbackup.org/wiki/ReplacingCertificates
const int BOX_DEFAULT_SSL_SECURITY_LEVEL = -1;

// configuration file paths
#ifdef WIN32
// no default config file path, use these macros to call
Expand Down
15 changes: 11 additions & 4 deletions lib/common/Configuration.cpp
Expand Up @@ -470,6 +470,16 @@ int Configuration::GetKeyValueInt(const std::string& rKeyName) const
}


int Configuration::GetKeyValueInt(const std::string& rKeyName, int default_value) const
{
if(!KeyExists(rKeyName))
{
return default_value;
}
return GetKeyValueInt(rKeyName);
}


// --------------------------------------------------------------------------
//
// Function
Expand Down Expand Up @@ -778,8 +788,7 @@ bool Configuration::Verify(const ConfigurationVerify &rVerify,
}
else if(pvkey->HasDefaultValue())
{
mKeys[pvkey->Name()] =
pvkey->DefaultValue();
mKeys[pvkey->Name()] = pvkey->DefaultValue();
}
}

Expand Down Expand Up @@ -922,5 +931,3 @@ bool Configuration::Verify(const ConfigurationVerify &rVerify,

return ok;
}


1 change: 1 addition & 0 deletions lib/common/Configuration.h
Expand Up @@ -122,6 +122,7 @@ class Configuration
bool KeyExists(const std::string& rKeyName) const;
const std::string &GetKeyValue(const std::string& rKeyName) const;
int GetKeyValueInt(const std::string& rKeyName) const;
int GetKeyValueInt(const std::string& rKeyName, int default_value) const;
uint32_t GetKeyValueUint32(const std::string& rKeyName) const;
bool GetKeyValueBool(const std::string& rKeyName) const;
std::vector<std::string> GetKeyNames() const;
Expand Down
4 changes: 3 additions & 1 deletion lib/common/Test.cpp
Expand Up @@ -28,7 +28,7 @@

int num_tests_selected = 0;
int num_failures = 0;
int old_failure_count = 0;
static int old_failure_count = 0; // do not expose!
int first_fail_line;
std::string original_working_dir;
std::string first_fail_file;
Expand Down Expand Up @@ -98,6 +98,8 @@ bool setUp(const char* function_name)
StartsWith("0_", filename) ||
filename == "accounts.txt" ||
filename == "bbackupd-data" ||
filename == "bbackupquery.log" ||
filename == "bbstored.log" ||
filename == "ca" ||
StartsWith("file", filename) ||
StartsWith("notifyran", filename) ||
Expand Down
1 change: 0 additions & 1 deletion lib/common/Test.h
Expand Up @@ -39,7 +39,6 @@
extern int num_failures;
extern int first_fail_line;
extern int num_tests_selected;
extern int old_failure_count;
extern std::string first_fail_file;
extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
extern std::list<std::string> run_only_named_tests;
Expand Down
1 change: 1 addition & 0 deletions lib/server/ConnectionException.txt
Expand Up @@ -15,6 +15,7 @@ TLSNoPeerCertificate 36
TLSPeerCertificateInvalid 37 Check certification process
TLSClosedWhenWriting 38
TLSHandshakeTimedOut 39
TLSPeerWeakCertificate 40 The peer's RSA key is too short and no longer considered secure, see https://www.boxbackup.org/wiki/ReplacingCertificates for details
Protocol_Timeout 41 Probably a network issue between client and server.
Protocol_ObjTooBig 42
Protocol_BadCommandRecieved 44
Expand Down
4 changes: 4 additions & 0 deletions lib/server/Daemon.cpp
Expand Up @@ -42,6 +42,7 @@

#include "autogen_ConnectionException.h"
#include "autogen_ServerException.h"
#include "BoxPortsAndFiles.h"
#include "Configuration.h"
#include "Daemon.h"
#include "FileModificationTime.h"
Expand All @@ -52,6 +53,9 @@

#include "MemLeakFindOn.h"

const ConfigurationVerifyKey ssl_security_level_key("SSLSecurityLevel",
ConfigTest_IsInt | ConfigTest_LastEntry, BOX_DEFAULT_SSL_SECURITY_LEVEL);

Daemon *Daemon::spDaemon = 0;


Expand Down
2 changes: 2 additions & 0 deletions lib/server/Daemon.h
Expand Up @@ -121,5 +121,7 @@ class Daemon
ConfigurationVerifyKey("LogFacility", 0), \
ConfigurationVerifyKey("User", ConfigTest_LastEntry)

extern const ConfigurationVerifyKey ssl_security_level_key;

#endif // DAEMON__H

1 change: 1 addition & 0 deletions lib/server/ServerException.txt
Expand Up @@ -29,6 +29,7 @@ TLSSetCiphersFailed 28
SSLLibraryInitialisationError 29
TLSNoSSLObject 31
TLSAlreadyHandshaked 35
TLSServerWeakCertificate 36 Our RSA key is too short and no longer considered secure, see https://www.boxbackup.org/wiki/ReplacingCertificates for details
SocketSetNonBlockingFailed 40
Protocol_BadUsage 43
Protocol_UnsuitableStreamTypeForSending 51
Expand Down
10 changes: 9 additions & 1 deletion lib/server/ServerTLS.h
Expand Up @@ -10,6 +10,7 @@
#ifndef SERVERTLS__H
#define SERVERTLS__H

#include "BoxPortsAndFiles.h"
#include "ServerStream.h"
#include "SocketStreamTLS.h"
#include "SSLLib.h"
Expand Down Expand Up @@ -52,8 +53,14 @@ class ServerTLS : public ServerStream<SocketStreamTLS, Port, ListenBacklog, Fork
std::string certFile(serverconf.GetKeyValue("CertificateFile"));
std::string keyFile(serverconf.GetKeyValue("PrivateKeyFile"));
std::string caFile(serverconf.GetKeyValue("TrustedCAsFile"));

// -1 is the default security level, especially for daemons with no
// ConfigurationVerify to override it:
int ssl_security_level(conf.GetKeyValueInt("SSLSecurityLevel",
BOX_DEFAULT_SSL_SECURITY_LEVEL));

mContext.Initialise(true /* as server */, certFile.c_str(),
keyFile.c_str(), caFile.c_str());
keyFile.c_str(), caFile.c_str(), ssl_security_level);

// Then do normal stream server stuff
ServerStream<SocketStreamTLS, Port, ListenBacklog,
Expand All @@ -75,6 +82,7 @@ class ServerTLS : public ServerStream<SocketStreamTLS, Port, ListenBacklog, Fork
ConfigurationVerifyKey("CertificateFile", ConfigTest_Exists), \
ConfigurationVerifyKey("PrivateKeyFile", ConfigTest_Exists), \
ConfigurationVerifyKey("TrustedCAsFile", ConfigTest_Exists), \
ConfigurationVerifyKey("SSLSecurityLevel", ConfigTest_IsInt, -1), \
SERVERSTREAM_VERIFY_SERVER_KEYS(DEFAULT_ADDRESSES)

#endif // SERVERTLS__H
Expand Down
4 changes: 4 additions & 0 deletions lib/server/SocketStream.cpp
Expand Up @@ -171,6 +171,10 @@ void SocketStream::Open(Socket::Type Type, const std::string& rName, int Port)
Socket::NameLookupToSockAddr(addr, sockDomain, Type, rName, Port,
addrLen);

std::ostringstream oss;
oss << rName << ":" << Port;
mPeerSocketDesc = oss.str();

// Create the socket
mSocketHandle = ::socket(sockDomain, SOCK_STREAM,
0 /* let OS choose protocol */);
Expand Down
1 change: 1 addition & 0 deletions lib/server/SocketStream.h
Expand Up @@ -114,6 +114,7 @@ class SocketStream : public IOStream
protected:
off_t mBytesRead;
off_t mBytesWritten;
std::string mPeerSocketDesc;

public:
off_t GetBytesRead() const {return mBytesRead;}
Expand Down

0 comments on commit cb3be2c

Please sign in to comment.