xtreemfs/cpp/test/rpc/client_ssl_test.cpp
2020-09-22 02:25:22 +02:00

1200 lines
45 KiB
C++

/*
* Copyright (c) 2014 by Robert Schmidtke, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
#ifdef HAS_OPENSSL
#include <gtest/gtest.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
#include <cerrno>
#include <fcntl.h>
#include <fstream>
#include <signal.h>
#include <stdio.h>
#include <stdexcept>
#include <string>
#include <openssl/opensslv.h>
#include "libxtreemfs/client.h"
#include "libxtreemfs/client_implementation.h"
#include "libxtreemfs/options.h"
#include "libxtreemfs/xtreemfs_exception.h"
#include "pbrpc/RPC.pb.h"
#include "util/logging.h"
/**
* The working directory is assumed to be cpp/build.
*/
using namespace xtreemfs::pbrpc;
using namespace xtreemfs::util;
namespace xtreemfs {
namespace rpc {
/**
* Represents a DIR, MRC or OSD started via command line. Not the stripped
* down test environment services.
*/
class ExternalService {
public:
ExternalService(
std::string service_class,
std::string config_file_name,
std::string log_file_name,
std::string startup_phrase)
: service_class_(service_class),
config_file_name_(config_file_name),
log_file_name_(log_file_name),
startup_phrase_(startup_phrase),
java_home_(""),
classpath_(""),
argv_(NULL),
service_pid_(-1) {
char *java_home = getenv("JAVA_HOME");
if (java_home == NULL || (java_home_ = java_home).empty()) {
if (Logging::log->loggingActive(LEVEL_WARN)) {
Logging::log->getLog(LEVEL_WARN) << "JAVA_HOME is empty."
<< std::endl;
}
}
if (!boost::algorithm::ends_with(java_home_, "/")) {
java_home_ += "/";
}
classpath_ = "../../java/servers/dist/XtreemFS.jar";
classpath_ += ":../../java/foundation/dist/Foundation.jar";
classpath_ += ":../../java/flease/dist/Flease.jar";
classpath_ += ":../../java/lib/*";
}
void cleanup() {
service_pid_ = -1;
if (argv_ != NULL) {
for (size_t i = 0; i < 6; ++i) {
free(argv_[i]);
}
delete[] argv_;
argv_ = NULL;
}
}
int JavaMajorVersion() {
// java -version prints to stderr
FILE *pipe = popen((java_home_ + "bin/java -version 2>&1").c_str(), "r");
char buf[256];
std::string output("");
while (!feof(pipe)) {
if (fgets(buf, 256, pipe) != NULL) {
output += buf;
}
}
pclose(pipe);
// Output starts with: java version "1.X.Y_Z"
size_t a = output.find('.', 0);
size_t b = output.find('.', a + 1);
return atoi(output.substr(a + 1, b - a - 1).c_str());
}
bool Start() {
argv_ = new char*[7];
argv_[0] = strdup((java_home_ + "bin/java").c_str());
argv_[1] = strdup("-ea");
argv_[2] = strdup("-cp");
argv_[3] = strdup(classpath_.c_str());
argv_[4] = strdup(service_class_.c_str());
argv_[5] = strdup(config_file_name_.c_str());
argv_[6] = NULL;
char *envp[] = { NULL };
service_pid_ = fork();
if (service_pid_ == 0) {
/* This block is executed by the child and is blocking. */
// Redirect stdout and stderr to file
int log_fd = open(log_file_name_.c_str(),
O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
dup2(log_fd, 1);
dup2(log_fd, 2);
close(log_fd);
// execve does not return control upon successful completion.
execve((java_home_ + "bin/java").c_str(), argv_, envp);
exit(errno);
} else {
/* This block is executed by the parent. */
// Wait until the child has created the log file.
int log_fd = -1;
while ((log_fd = open(log_file_name_.c_str(), O_RDONLY)) == -1)
;
// Listen to the log file until the startup phrase has occurred
// and the service process is still running.
std::string output("");
bool service_alive = true;
while (output.find(startup_phrase_) == std::string::npos && service_alive) {
char buffer[1024];
ssize_t n = read(log_fd, buffer, sizeof(buffer));
if (n > 0) {
output.append(buffer, n);
} else if (n == -1) {
throw std::runtime_error(
"Could not read log file '" + log_file_name_ + "'.");
}
// Read status of child process using wait because otherwise it would
// remain in the process table, even if exited to allow the parent to
// read the exit status using wait.
int status;
pid_t p = waitpid(service_pid_, &status, WNOHANG);
if (p == service_pid_) {
service_alive = !WIFEXITED(status);
}
}
close(log_fd);
if (!service_alive) {
std::cerr << service_class_ << " did not start properly: " << errno
<< std::endl;
cleanup();
return false;
}
}
return true;
}
void Shutdown() {
if (service_pid_ > 0) {
// This block is executed by the parent. Interrupt the child and wait
// for completion.
kill(service_pid_, 2);
waitpid(service_pid_, NULL, 0);
cleanup();
}
}
private:
std::string service_class_;
std::string config_file_name_;
std::string log_file_name_;
std::string startup_phrase_;
std::string java_home_;
std::string classpath_;
char **argv_;
pid_t service_pid_;
};
class ExternalDIR : public ExternalService {
public:
ExternalDIR(std::string config_file_name, std::string log_file_name)
: ExternalService("org.xtreemfs.dir.DIR", config_file_name, log_file_name,
"PBRPC Srv 48638 ready") {}
};
class ExternalMRC : public ExternalService {
public:
ExternalMRC(std::string config_file_name, std::string log_file_name)
: ExternalService("org.xtreemfs.mrc.MRC", config_file_name, log_file_name,
"PBRPC Srv 48636 ready") {}
};
class ExternalOSD : public ExternalService {
public:
ExternalOSD(std::string config_file_name, std::string log_file_name)
: ExternalService("org.xtreemfs.osd.OSD", config_file_name, log_file_name,
"PBRPC Srv 48640 ready") {}
};
enum TestCertificateType {
None, kPKCS12, kPEM
};
char g_ssl_tls_version_sslv3[] = "sslv3";
char g_ssl_tls_version_ssltls[] = "ssltls";
char g_ssl_tls_version_tlsv1[] = "tlsv1";
char g_ssl_tls_version_tlsv11[] = "tlsv11";
char g_ssl_tls_version_tlsv12[] = "tlsv12";
class ClientTest : public ::testing::Test {
protected:
ClientTest() {
char *xtreemfs_test_dir = getenv("XTREEMFS_TEST_DIR");
if (xtreemfs_test_dir == NULL ||
(xtreemfs_test_dir_ = xtreemfs_test_dir).empty()) {
xtreemfs_test_dir_ = "/tmp/";
} else {
if (!boost::algorithm::ends_with(xtreemfs_test_dir_, "/")) {
xtreemfs_test_dir_ += "/";
}
xtreemfs_test_dir_ += "log/";
}
}
virtual void SetUp() {
initialize_logger(options_.log_level_string,
options_.log_file_path,
LEVEL_WARN);
dir_log_file_name_ = options_.log_file_path + "_dir";
mrc_log_file_name_ = options_.log_file_path + "_mrc";
osd_log_file_name_ = options_.log_file_path + "_osd";
external_dir_.reset(new ExternalDIR(dir_config_file_, dir_log_file_name_));
ASSERT_TRUE(external_dir_->Start());
external_mrc_.reset(new ExternalMRC(mrc_config_file_, mrc_log_file_name_));
ASSERT_TRUE(external_mrc_->Start());
external_osd_.reset(new ExternalOSD(osd_config_file_, osd_log_file_name_));
ASSERT_TRUE(external_osd_->Start());
auth_.set_auth_type(AUTH_NONE);
user_credentials_.set_username("client_ssl_test");
user_credentials_.add_groups("client_ssl_test");
options_.retry_delay_s = 5;
mrc_url_.ParseURL(kMRC);
dir_url_.ParseURL(kDIR);
client_.reset(xtreemfs::Client::CreateClient(dir_url_.service_addresses,
user_credentials_,
options_.GenerateSSLOptions(),
options_));
client_->Start();
}
virtual void TearDown() {
if (client_.get() != NULL) {
client_->Shutdown();
}
if (external_osd_.get() != NULL) {
external_osd_->Shutdown();
}
if (external_mrc_.get() != NULL) {
external_mrc_->Shutdown();
}
if (external_dir_.get() != NULL) {
external_dir_->Shutdown();
}
if (!HasFailure()) {
unlink(options_.log_file_path.c_str());
unlink(dir_log_file_name_.c_str());
unlink(mrc_log_file_name_.c_str());
unlink(osd_log_file_name_.c_str());
}
}
void CreateOpenDeleteVolume(std::string volume_name) {
client_->CreateVolume(mrc_url_.service_addresses,
auth_,
user_credentials_,
volume_name);
client_->OpenVolume(volume_name,
options_.GenerateSSLOptions(),
options_);
client_->DeleteVolume(mrc_url_.service_addresses,
auth_,
user_credentials_,
volume_name);
}
size_t count_occurrences_in_file(std::string file_path, std::string s) {
std::ifstream in(file_path.c_str(), std::ios_base::in);
size_t occurences = 0;
while (!in.eof()) {
std::string line;
std::getline(in, line);
occurences += line.find(s) == std::string::npos ? 0 : 1;
}
in.close();
return occurences;
}
std::string cert_path(std::string cert) {
return "../../tests/certs/client_ssl_test/" + cert;
}
std::string config_path(std::string config) {
return "../../tests/configs/" + config;
}
std::string log_path(std::string log) {
return xtreemfs_test_dir_ + log;
}
boost::scoped_ptr<ExternalDIR> external_dir_;
boost::scoped_ptr<ExternalMRC> external_mrc_;
boost::scoped_ptr<ExternalOSD> external_osd_;
boost::scoped_ptr<xtreemfs::Client> client_;
xtreemfs::Options options_;
std::string dir_log_file_name_;
std::string mrc_log_file_name_;
std::string osd_log_file_name_;
xtreemfs::Options dir_url_;
xtreemfs::Options mrc_url_;
std::string dir_config_file_;
std::string mrc_config_file_;
std::string osd_config_file_;
std::string xtreemfs_test_dir_;
xtreemfs::pbrpc::Auth auth_;
xtreemfs::pbrpc::UserCredentials user_credentials_;
};
class ClientNoSSLTest : public ClientTest {
protected:
virtual void SetUp() {
dir_config_file_ = config_path("dirconfig_no_ssl.test");
mrc_config_file_ = config_path("mrcconfig_no_ssl.test");
osd_config_file_ = config_path("osdconfig_no_ssl.test");
dir_url_.xtreemfs_url = "pbrpc://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpc://localhost:48636/";
options_.log_level_string = "DEBUG";
options_.log_file_path = log_path("xtreemfs_client_ssl_test_no_ssl");
ClientTest::SetUp();
}
};
template<TestCertificateType t>
class ClientSSLTestShortChain : public ClientTest {
protected:
virtual void SetUp() {
// Root signed, root trusted
dir_config_file_ = config_path("dirconfig_ssl_short_chain.test");
mrc_config_file_ = config_path("mrcconfig_ssl_short_chain.test");
osd_config_file_ = config_path("osdconfig_ssl_short_chain.test");
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
// Root signed, only root as additional certificate.
switch (t) {
case kPKCS12:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_short_chain_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Root_Root.p12");
break;
case kPEM:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_short_chain_pem");
options_.ssl_pem_cert_path = cert_path("Client_Root.pem");
options_.ssl_pem_key_path = cert_path("Client_Root.key");
options_.ssl_pem_trusted_certs_path = cert_path("CA_Root.pem");
break;
case None:
break;
}
options_.ssl_verify_certificates = true;
ClientTest::SetUp();
}
void DoTest() {
CreateOpenDeleteVolume("test_ssl_short_chain");
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support activated"));
switch (t) {
case kPKCS12:
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support using PKCS#12 file "
"../../tests/certs/client_ssl_test/Client_Root_Root.p12"));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Writing 1 verification certificates to /tmp/ca"));
break;
case kPEM:
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support using PEM private key file "
"../../tests/certs/client_ssl_test/Client_Root.key"));
break;
case None:
break;
}
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=Root CA,O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
ASSERT_EQ(0, count_occurrences_in_file(
options_.log_file_path,
"CN=Intermediate CA,O=ZIB,L=Berlin,ST=Berlin,C=DE"));
ASSERT_EQ(0, count_occurrences_in_file(
options_.log_file_path,
"CN=Leaf CA,O=ZIB,L=Berlin,ST=Berlin,C=DE"));
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=MRC (Root),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful"));
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=DIR (Root),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
}
};
class ClientSSLTestShortChainPKCS12 : public ClientSSLTestShortChain<kPKCS12> {};
class ClientSSLTestShortChainPEM : public ClientSSLTestShortChain<kPEM> {};
template<TestCertificateType t>
class ClientSSLTestLongChain : public ClientTest {
protected:
virtual void SetUp() {
// All service certificates are signed with Leaf CA, which is signed with
// Intermediate CA, which is signed with Root CA. The keystore contains
// only the Leaf CA.
dir_config_file_ = config_path("dirconfig_ssl_long_chain.test");
mrc_config_file_ = config_path("mrcconfig_ssl_long_chain.test");
osd_config_file_ = config_path("osdconfig_ssl_long_chain.test");
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
// Client certificate is signed with Leaf CA. Contains the entire chain
// as additional certificates.
switch (t) {
case kPKCS12:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_long_chain_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Leaf_Chain.p12");
break;
case kPEM:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_long_chain_pem");
options_.ssl_pem_cert_path = cert_path("Client_Leaf.pem");
options_.ssl_pem_key_path = cert_path("Client_Leaf.key");
options_.ssl_pem_trusted_certs_path = cert_path("CA_Chain.pem");
break;
case None:
break;
}
options_.ssl_verify_certificates = true;
ClientTest::SetUp();
}
void DoTest() {
CreateOpenDeleteVolume("test_ssl_long_chain");
// Once for MRC and once for DIR.
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support activated"));
switch (t) {
case kPKCS12:
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support using PKCS#12 file "
"../../tests/certs/client_ssl_test/Client_Leaf_Chain.p12"));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Writing 3 verification certificates to /tmp/ca"));
break;
case kPEM:
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"SSL support using PEM private key file "
"../../tests/certs/client_ssl_test/Client_Leaf.key"));
break;
case None:
break;
}
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=Root CA,O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=Intermediate CA,O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=Leaf CA,O=ZIB,L=Berlin,ST=Berlin,C=DE' was "
"successful."));
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=MRC (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful"));
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=DIR (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
}
};
class ClientSSLTestLongChainPKCS12 : public ClientSSLTestLongChain<kPKCS12> {};
class ClientSSLTestLongChainPEM : public ClientSSLTestLongChain<kPEM> {};
template<TestCertificateType t>
class ClientSSLTestShortChainVerification : public ClientTest {
protected:
virtual void SetUp() {
dir_config_file_ = config_path("dirconfig_ssl_short_chain.test");
mrc_config_file_ = config_path("mrcconfig_ssl_short_chain.test");
osd_config_file_ = config_path("osdconfig_ssl_short_chain.test");
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
// Server does not know client's certificate, client does not know server's
// certificate.
switch (t) {
case kPKCS12:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_verification_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Leaf.p12");
break;
case kPEM:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_verification_pem");
options_.ssl_pem_cert_path = cert_path("Client_Leaf.pem");
options_.ssl_pem_key_path = cert_path("Client_Leaf.key");
break;
case None:
break;
}
options_.ssl_verify_certificates = true;
// Need this to avoid too many reconnects upon SSL errors.
options_.max_tries = 3;
ClientTest::SetUp();
}
void DoTest() {
// Server does not accept our certificate.
std::string exception_text;
try {
CreateOpenDeleteVolume("test_ssl_verification");
} catch (xtreemfs::IOException& e) {
exception_text = e.what();
}
// Depending on whether the error occurs on initial connect or reconnect,
// the error message varies. This depends on how quick the services start
// up, such that the first connect might happen before the services are
// operational.
ASSERT_TRUE(
exception_text.find("could not connect to host") != std::string::npos ||
exception_text.find("cannot connect to server") != std::string::npos);
// We do not accept the server's certificate.
ASSERT_TRUE(count_occurrences_in_file(
options_.log_file_path,
"OpenSSL verify error: 20") > 0); // Issuer certificate of untrusted
// certificate cannot be found.
ASSERT_TRUE(count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=MRC (Root),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was unsuccessful.") > 0);
}
};
class ClientSSLTestShortChainVerificationPKCS12 :
public ClientSSLTestShortChainVerification<kPKCS12> {};
class ClientSSLTestShortChainVerificationPEM :
public ClientSSLTestShortChainVerification<kPEM> {};
template<TestCertificateType t>
class ClientSSLTestLongChainVerificationIgnoreErrors : public ClientTest {
protected:
virtual void SetUp() {
dir_config_file_ = config_path("dirconfig_ssl_ignore_errors.test");
mrc_config_file_ = config_path("mrcconfig_ssl_ignore_errors.test");
osd_config_file_ = config_path("osdconfig_ssl_ignore_errors.test");
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
// Server knows client's certificate, client does not know server's
// certificate.
switch (t) {
case kPKCS12:
options_.log_file_path =
log_path("xtreemfs_client_ssl_test_verification_ignore_errors_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Leaf_Root.p12");
break;
case kPEM:
options_.log_file_path =
log_path("xtreemfs_client_ssl_test_verification_ignore_errors_pem");
options_.ssl_pem_cert_path = cert_path("Client_Leaf.pem");
options_.ssl_pem_key_path = cert_path("Client_Leaf.key");
options_.ssl_pem_trusted_certs_path = cert_path("CA_Root.pem");
break;
case None:
break;
}
options_.ssl_verify_certificates = true;
// The issuer certificate could not be found: this occurs if the issuer
// certificate of an untrusted certificate cannot be found.
options_.ssl_ignore_verify_errors.push_back(20);
// The root CA is not marked as trusted for the specified purpose.
options_.ssl_ignore_verify_errors.push_back(27);
// No signatures could be verified because the chain contains only one
// certificate and it is not self signed.
options_.ssl_ignore_verify_errors.push_back(21);
ClientTest::SetUp();
}
void DoTest() {
CreateOpenDeleteVolume("test_ssl_verification_ignore_errors");
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Ignoring OpenSSL verify error: 20 because of user settings."));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Ignoring OpenSSL verify error: 27 because of user settings."));
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Ignoring OpenSSL verify error: 21 because of user settings."));
ASSERT_EQ(3, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=MRC (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was unsuccessful. Overriding because of user settings."));
ASSERT_EQ(3, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=DIR (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was unsuccessful. Overriding because of user settings."));
}
};
class ClientSSLTestLongChainVerificationIgnoreErrorsPKCS12 :
public ClientSSLTestLongChainVerificationIgnoreErrors<kPKCS12> {};
class ClientSSLTestLongChainVerificationIgnoreErrorsPEM :
public ClientSSLTestLongChainVerificationIgnoreErrors<kPEM> {};
template<TestCertificateType t>
class ClientSSLTestLongChainNoVerification : public ClientTest {
protected:
virtual void SetUp() {
dir_config_file_ = config_path("dirconfig_ssl_no_verification.test");
mrc_config_file_ = config_path("mrcconfig_ssl_no_verification.test");
osd_config_file_ = config_path("osdconfig_ssl_no_verification.test");
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
// Server knows client's certificate, client does not know all of server's
// certificate.
switch (t) {
case kPKCS12:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_no_verification_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Leaf_Leaf.p12");
break;
case kPEM:
options_.log_file_path = log_path("xtreemfs_client_ssl_test_no_verification_pem");
options_.ssl_pem_cert_path = cert_path("Client_Leaf.pem");
options_.ssl_pem_key_path = cert_path("Client_Leaf.key");
options_.ssl_pem_trusted_certs_path = cert_path("CA_Leaf.pem");
break;
case None:
break;
}
ClientTest::SetUp();
}
void DoTest() {
CreateOpenDeleteVolume("test_ssl_no_verification");
// The issuer certificate of a looked up certificate could not be found.
// This normally means the list of trusted certificates is not complete.
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path,
"Ignoring OpenSSL verify error: 2 because of user settings."));
// Twice for MRC, twice for DIR.
ASSERT_EQ(4, count_occurrences_in_file(
options_.log_file_path,
"Ignoring OpenSSL verify error: 27 because of user settings."));
// Succeed because the client can verify the leaf certificates, but not their
// issuer certificates.
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=DIR (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
ASSERT_EQ(1, count_occurrences_in_file(
options_.log_file_path,
"Verification of subject 'CN=DIR (Leaf),O=ZIB,L=Berlin,ST=Berlin,C=DE' "
"was successful."));
}
};
class ClientSSLTestLongChainNoVerificationPKCS12 :
public ClientSSLTestLongChainNoVerification<kPKCS12> {};
class ClientSSLTestLongChainNoVerificationPEM :
public ClientSSLTestLongChainNoVerification<kPEM> {};
template<char const *client_ssl_method_string,
char const *server_ssl_method_string>
class ClientSSLTestSSLVersion : public ClientTest {
public:
ClientSSLTestSSLVersion() {
// Grab the Java version that all services run on so we know what TLS
// capabilities to expect.
java_major_version_ = ExternalService("", "", "", "").JavaMajorVersion();
}
protected:
virtual void SetUp() {
ASSERT_GE(java_major_version_, 6);
if (strcmp(server_ssl_method_string, "ssltls") == 0) {
dir_config_file_ = config_path("dirconfig_ssl_version.test");
mrc_config_file_ = config_path("mrcconfig_ssl_version.test");
osd_config_file_ = config_path("osdconfig_ssl_version.test");
} else if (strcmp(server_ssl_method_string, "sslv3") == 0) {
dir_config_file_ = config_path("dirconfig_ssl_version_sslv3.test");
mrc_config_file_ = config_path("mrcconfig_ssl_version_sslv3.test");
osd_config_file_ = config_path("osdconfig_ssl_version_sslv3.test");
} else if (strcmp(server_ssl_method_string, "tlsv1") == 0) {
dir_config_file_ = config_path("dirconfig_ssl_version_tlsv1.test");
mrc_config_file_ = config_path("mrcconfig_ssl_version_tlsv1.test");
osd_config_file_ = config_path("osdconfig_ssl_version_tlsv1.test");
} else if (strcmp(server_ssl_method_string, "tlsv11") == 0) {
dir_config_file_ = config_path("dirconfig_ssl_version_tlsv11.test");
mrc_config_file_ = config_path("mrcconfig_ssl_version_tlsv11.test");
osd_config_file_ = config_path("osdconfig_ssl_version_tlsv11.test");
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0) {
dir_config_file_ = config_path("dirconfig_ssl_version_tlsv12.test");
mrc_config_file_ = config_path("mrcconfig_ssl_version_tlsv12.test");
osd_config_file_ = config_path("osdconfig_ssl_version_tlsv12.test");
} else {
FAIL() << "Unsupported server SSL method.";
}
dir_url_.xtreemfs_url = "pbrpcs://localhost:48638/";
mrc_url_.xtreemfs_url = "pbrpcs://localhost:48636/";
options_.log_level_string = "DEBUG";
options_.log_file_path =
log_path("xtreemfs_client_ssl_test_version_pkcs12");
options_.ssl_pkcs12_path = cert_path("Client_Root_Root.p12");
options_.log_file_path.append("_").append(client_ssl_method_string);
options_.log_file_path.append("_").append(server_ssl_method_string);
options_.ssl_method_string = client_ssl_method_string;
options_.ssl_verify_certificates = true;
options_.max_tries = 3;
ClientTest::SetUp();
}
void assert_ssl_tls_in_log(std::string ssl_tls, std::string ex) {
ASSERT_EQ(2, count_occurrences_in_file(
options_.log_file_path, "Using SSL/TLS version '" + ssl_tls + "'."));
ASSERT_EQ(0, ex.size());
}
void assert_no_ssl_tls_in_log(std::string ex) {
// Different errors depending on boost version and client/server SSL/TLS
// versions.
size_t ssl_error = ex.find(
"could not connect to host 'localhost:48636': asio.ssl error");
size_t c_timeout = ex.find(
"connection to 'localhost:48636' timed out");
size_t r_timeout = ex.find("Request timed out");
size_t connect_error = ex.find(
"cannot connect to server 'localhost:48636'");
ASSERT_TRUE(ssl_error != std::string::npos ||
c_timeout != std::string::npos ||
r_timeout != std::string::npos ||
connect_error != std::string::npos);
}
void assert_ssl_tls_in_log_or_nothing(std::string ssl_tls, std::string ex) {
size_t c1 = count_occurrences_in_file(
options_.log_file_path, "Using SSL/TLS version '" + ssl_tls + "'.");
size_t ssl_error = ex.find(
"could not connect to host 'localhost:48636': asio.ssl error");
size_t c_timeout = ex.find(
"connection to 'localhost:48636' timed out");
size_t r_timeout = ex.find("Request timed out");
size_t connect_error = ex.find(
"cannot connect to server 'localhost:48636'");
ASSERT_TRUE(c1 == 2 ||
ssl_error != std::string::npos ||
c_timeout != std::string::npos ||
r_timeout != std::string::npos ||
connect_error != std::string::npos);
}
void assert_ssl_tls_in_log_or_other(std::string ssl_tls1, std::string ssl_tls2,
std::string ex) {
size_t c1 = count_occurrences_in_file(
options_.log_file_path, "Using SSL/TLS version '" + ssl_tls1 + "'.");
size_t c2 = count_occurrences_in_file(
options_.log_file_path, "Using SSL/TLS version '" + ssl_tls2 + "'.");
ASSERT_TRUE(c1 == 2 || c2 == 2);
ASSERT_EQ(0, ex.size());
}
void DoTest() {
std::string ex("");
try {
CreateOpenDeleteVolume("test_ssl_version");
} catch (xtreemfs::IOException& e) {
ex = e.what();
}
/* JDK 6 supports SSLv3, TLSv1 and possibly TLSv11. If it is set to TLSv11
* but does not support it, it will default to TLS which supports all
* other protocols. JDK 7 additionally supports TLSv11 and TLSv12.
*/
if (strcmp(client_ssl_method_string, "sslv3") == 0) {
if (strcmp(server_ssl_method_string, "sslv3") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log("SSLv3", ex);
} else {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "tlsv1") == 0) {
assert_no_ssl_tls_in_log(ex);
} else if (strcmp(server_ssl_method_string, "tlsv11") == 0) {
assert_ssl_tls_in_log_or_nothing("SSLv3", ex);
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_ssl_tls_in_log("SSLv3", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
} else {
if (strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_no_ssl_tls_in_log(ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
}
} else if (strcmp(client_ssl_method_string, "tlsv1") == 0) {
if (strcmp(server_ssl_method_string, "sslv3") == 0) {
assert_no_ssl_tls_in_log(ex);
} else if (strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log("TLSv1", ex);
} else {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "tlsv11") == 0) {
assert_ssl_tls_in_log_or_nothing("TLSv1", ex);
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_ssl_tls_in_log("TLSv1", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
} else {
if (strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_no_ssl_tls_in_log(ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
}
} else {
#if (OPENSSL_VERSION_NUMBER < 0x1000100fL)
/* OpenSSL < 1.0.1 supports SSLv3 and TLSv1 only. This implies a Boost
* version smaller than 1.54, in which case tlsv11 and tlsv12 default to
* ssltls behavior in the client.
*/
if (strcmp(client_ssl_method_string, "tlsv11") == 0 ||
strcmp(client_ssl_method_string, "tlsv12") == 0 ||
strcmp(client_ssl_method_string, "ssltls") == 0) {
if (strcmp(server_ssl_method_string, "sslv3") == 0) {
assert_ssl_tls_in_log("SSLv3", ex);
} else if (strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log("TLSv1", ex);
} else {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "tlsv11") == 0) {
assert_ssl_tls_in_log_or_nothing("TLSv1", ex);
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_ssl_tls_in_log("TLSv1", ex);
}
} else {
if (strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_no_ssl_tls_in_log(ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
}
} else {
FAIL() << "Unsupported client SSL method.";
}
#else // OPENSSL_VERSION_NUMBER < 0x1000100fL
/* The client is capable of all methods, now it depends on the Java version
* of the servers, see above. Boost >= 1.54 can enforce TLSv1.1 and TLSv1.2.
* Note that this does not imply a Boost version >= 1.54 here. For smaller
* Boost versions, tlsv11 and tlsv12 default to ssltls behavior in the client.
*/
bool ssltls_behavior;
#if (BOOST_VERSION >= 105400)
ssltls_behavior = false;
#else // BOOST_VERSION >= 105400
ssltls_behavior = true;
#endif // BOOST_VERSION >= 105400
if (strcmp(client_ssl_method_string, "tlsv11") == 0 &&
!ssltls_behavior) {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "sslv3") == 0 ||
strcmp(server_ssl_method_string, "tlsv1") == 0) {
assert_no_ssl_tls_in_log(ex);
} else if (strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log_or_nothing("TLSv1.1", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
} else {
if (strcmp(server_ssl_method_string, "sslv3") == 0 ||
strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0) {
assert_no_ssl_tls_in_log(ex);
} else if (strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log("TLSv1.1", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
} else if (strcmp(client_ssl_method_string, "tlsv12") == 0 &&
!ssltls_behavior) {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "sslv3") == 0 ||
strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_no_ssl_tls_in_log(ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
} else {
if (strcmp(server_ssl_method_string, "sslv3") == 0 ||
strcmp(server_ssl_method_string, "tlsv1") == 0 ||
strcmp(server_ssl_method_string, "tlsv11") == 0) {
assert_no_ssl_tls_in_log(ex);
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log("TLSv1.2", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
} else if (strcmp(client_ssl_method_string, "ssltls") == 0 ||
ssltls_behavior) {
if (strcmp(server_ssl_method_string, "sslv3") == 0) {
assert_ssl_tls_in_log("SSLv3", ex);
} else if (strcmp(server_ssl_method_string, "tlsv1") == 0) {
assert_ssl_tls_in_log("TLSv1", ex);
} else {
if (java_major_version_ == 6) {
if (strcmp(server_ssl_method_string, "tlsv11") == 0 ||
strcmp(server_ssl_method_string, "tlsv12") == 0 ||
strcmp(server_ssl_method_string, "ssltls") == 0) {
assert_ssl_tls_in_log_or_other("TLSv1", "TLSv1.1", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
} else {
if (strcmp(server_ssl_method_string, "tlsv11") == 0) {
assert_ssl_tls_in_log("TLSv1.1", ex);
} else if (strcmp(server_ssl_method_string, "tlsv12") == 0) {
// In Ubuntu 12.04 TLSv1.2 is disabled by default, so maybe
// expect a fail here.
assert_ssl_tls_in_log_or_nothing("TLSv1.2", ex);
} else if (strcmp(server_ssl_method_string, "ssltls") == 0) {
// Ubuntu 12.04 only goes up to TLSv1.1
assert_ssl_tls_in_log_or_other("TLSv1.2", "TLSv1.1", ex);
} else {
FAIL() << "Unsupported server SSL method.";
}
}
}
} else {
FAIL() << "Unsupported client SSL method.";
}
#endif // OPENSSL_VERSION_NUMBER < 0x1000100fL
}
}
private:
int java_major_version_;
};
class ClientSSLTestSSLVersionPKCS12_SSLv3_SSLv3 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_sslv3, g_ssl_tls_version_sslv3> {};
class ClientSSLTestSSLVersionPKCS12_SSLTLS_SSLv3 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_ssltls, g_ssl_tls_version_sslv3> {};
class ClientSSLTestSSLVersionPKCS12_TLSv1_SSLv3 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv1, g_ssl_tls_version_sslv3> {};
class ClientSSLTestSSLVersionPKCS12_TLSv11_SSLv3 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv11, g_ssl_tls_version_sslv3> {};
class ClientSSLTestSSLVersionPKCS12_TLSv12_SSLv3 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv12, g_ssl_tls_version_sslv3> {};
class ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv1 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_sslv3, g_ssl_tls_version_tlsv1> {};
class ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv1 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_ssltls, g_ssl_tls_version_tlsv1> {};
class ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv1 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv1, g_ssl_tls_version_tlsv1> {};
class ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv1 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv11, g_ssl_tls_version_tlsv1> {};
class ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv1 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv12, g_ssl_tls_version_tlsv1> {};
class ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv11 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_sslv3, g_ssl_tls_version_tlsv11> {};
class ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv11 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_ssltls, g_ssl_tls_version_tlsv11> {};
class ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv11 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv1, g_ssl_tls_version_tlsv11> {};
class ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv11 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv11, g_ssl_tls_version_tlsv11> {};
class ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv11 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv12, g_ssl_tls_version_tlsv11> {};
class ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv12 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_sslv3, g_ssl_tls_version_tlsv12> {};
class ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv12 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_ssltls, g_ssl_tls_version_tlsv12> {};
class ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv12 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv1, g_ssl_tls_version_tlsv12> {};
class ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv12 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv11, g_ssl_tls_version_tlsv12> {};
class ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv12 : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv12, g_ssl_tls_version_tlsv12> {};
class ClientSSLTestSSLVersionPKCS12_SSLv3_SSLTLS : public ClientSSLTestSSLVersion<
g_ssl_tls_version_sslv3, g_ssl_tls_version_ssltls> {};
class ClientSSLTestSSLVersionPKCS12_SSLTLS_SSLTLS : public ClientSSLTestSSLVersion<
g_ssl_tls_version_ssltls, g_ssl_tls_version_ssltls> {};
class ClientSSLTestSSLVersionPKCS12_TLSv1_SSLTLS : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv1, g_ssl_tls_version_ssltls> {};
class ClientSSLTestSSLVersionPKCS12_TLSv11_SSLTLS : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv11, g_ssl_tls_version_ssltls> {};
class ClientSSLTestSSLVersionPKCS12_TLSv12_SSLTLS : public ClientSSLTestSSLVersion<
g_ssl_tls_version_tlsv12, g_ssl_tls_version_ssltls> {};
TEST_F(ClientNoSSLTest, TestNoSSL) {
CreateOpenDeleteVolume("test_no_ssl");
ASSERT_EQ(0, count_occurrences_in_file(options_.log_file_path, "SSL"));
}
TEST_F(ClientSSLTestShortChainPKCS12, TestVerifyShortChain) { DoTest(); }
TEST_F(ClientSSLTestShortChainPEM, TestVerifyShortChain) { DoTest(); }
TEST_F(ClientSSLTestLongChainPKCS12, TestVerifyLongChain) { DoTest(); }
TEST_F(ClientSSLTestLongChainPEM, TestVerifyLongChain) { DoTest(); }
TEST_F(ClientSSLTestShortChainVerificationPKCS12, TestVerificationFail) {
DoTest();
}
TEST_F(ClientSSLTestShortChainVerificationPEM, TestVerificationFail) {
DoTest();
}
TEST_F(ClientSSLTestLongChainVerificationIgnoreErrorsPKCS12,
TestVerificationIgnoreErrors) {
DoTest();
}
TEST_F(ClientSSLTestLongChainVerificationIgnoreErrorsPEM,
TestVerificationIgnoreErrors) {
DoTest();
}
TEST_F(ClientSSLTestLongChainNoVerificationPKCS12, TestNoVerification) {
DoTest();
}
TEST_F(ClientSSLTestLongChainNoVerificationPEM, TestNoVerification) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLv3_SSLv3, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLTLS_SSLv3, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv1_SSLv3, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv11_SSLv3, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv12_SSLv3, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv1, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv1, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv1, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv1, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv1, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv11, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv11, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv11, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv11, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv11, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLv3_TLSv12, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLTLS_TLSv12, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv1_TLSv12, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv11_TLSv12, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv12_TLSv12, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLv3_SSLTLS, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_SSLTLS_SSLTLS, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv1_SSLTLS, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv11_SSLTLS, TestSSLVersion) { DoTest(); }
TEST_F(ClientSSLTestSSLVersionPKCS12_TLSv12_SSLTLS, TestSSLVersion) { DoTest(); }
} // namespace rpc
} // namespace xtreemfs
#endif // HAS_OPENSSL