#include <RCF/test/TestMinimal.hpp>
#include <RCF/FilterService.hpp>
#include <RCF/Idl.hpp>
#include <RCF/OpenSslEncryptionFilter.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/TcpEndpoint.hpp>
#include <RCF/test/TransportFactories.hpp>
#include <RCF/util/PortNumbers.hpp>
namespace Test_OpenSslFilter {
class Echo
{
public:
std::string echo(const std::string &s)
{
return s;
}
};
RCF_BEGIN(I_Echo, "I_Echo")
RCF_METHOD_R1(std::string, echo, const std::string &)
RCF_END(I_Echo)
bool cbVerify(RCF::OpenSslEncryptionFilter &filter, bool ret)
{
SSL *ssl = filter.getSSL();
SSL_CTX *ssl_ctx = filter.getCTX();
BOOST_CHECK(ssl);
BOOST_CHECK(ssl_ctx);
return ret;
}
}
int RCF_TEST_MAIN(int argc, char **argv)
{
printTestHeader(__FILE__);
using namespace Test_OpenSslFilter;
util::CommandLine::getSingleton().parse(argc, argv);
{
// test involves:
// 1. server using CA cert to verify client cert occasionally
// 1. server using CA cert to verify client cert on demand (via session)
// 2. client using CA cert to verify server always
// 3. callback to client code for unverified server certs
// 4. customizing cipher list
// 5. DONE: using password encrypted certificates
std::string s0 = "sample text";
std::string certA = TEMP_DIR "certA.pem";
std::string certPassA = "";
std::string certB = TEMP_DIR "certB.pem";
std::string certPassB = "";
std::string caCertA = TEMP_DIR "caCertA.pem";
std::string caCertB = TEMP_DIR "caCertB.pem";
std::string ssCert1 = TEMP_DIR "ssCert1.pem";
std::string ssCertPass1 = "mt2316";
std::string ssCert2 = TEMP_DIR "ssCert2.pem";
std::string ssCertPass2 = "mt2316";
std::string ciphers = "";
int port = util::PortNumbers::getSingleton().getNext();
RCF::FilterServicePtr filterServicePtr(new RCF::FilterService());
Echo echo;
RCF::TcpEndpoint endpoint(port);
RCF::RcfServer server(endpoint);
server.bind( (I_Echo*) 0, echo);
server.addService( RCF::ServicePtr(filterServicePtr));
server.start();
RcfClient<I_Echo> client(endpoint);
client.getClientStub().setRemoteCallTimeoutMs(1000*3600);
typedef boost::shared_ptr<RCF::OpenSslEncryptionFilter> OpenSslEncryptionFilterPtr;
OpenSslEncryptionFilterPtr filterPtr;
// not encrypted
BOOST_CHECK(client.echo(s0) == s0);
// encrypted
//--------------------------
// client verifies server certificate
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certA,
certPassA,
"",
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
"",
"",
caCertA,
ciphers));
client.getClientStub().requestTransportFilters(filterPtr);
BOOST_CHECK(client.echo(s0) == s0);
//--------------------------
// client fails to verify server certificate (wrong CA)
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certB,
certPassB,
"",
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
"",
"",
caCertA,
ciphers));
client.getClientStub().requestTransportFilters(filterPtr);
try
{
client.echo(s0);
BOOST_CHECK(1==0);
}
catch(const RCF::Exception &e)
{
BOOST_CHECK(1==1);
BOOST_CHECK(e.getError() == RCF::RcfError_SslCertVerification);
client.getClientStub().clearTransportFilters();
}
//--------------------------
// client overrides verification of server certificate (wrong CA) (accepting)
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certB,
certPassB,
"",
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
"",
"",
caCertA,
ciphers,
boost::bind(cbVerify, _1, true)));
client.getClientStub().requestTransportFilters(filterPtr);
BOOST_CHECK(client.echo(s0) == s0);
//--------------------------
// client overrides verification of server certificate (wrong CA) (not accepting)
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certB,
certPassB,
"",
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
"",
"",
caCertA,
ciphers,
boost::bind(cbVerify, _1, false)));
client.getClientStub().requestTransportFilters(filterPtr);
try
{
client.echo(s0);
BOOST_CHECK(1==0);
}
catch(const RCF::Exception &e)
{
BOOST_CHECK(1==1);
BOOST_CHECK(e.getError() == RCF::RcfError_SslCertVerification);
client.getClientStub().clearTransportFilters();
}
//--------------------------
// client fails to verify server certificate (self-signed)
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
ssCert1,
ssCertPass1,
"",
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
"",
"",
caCertA,
ciphers));
client.getClientStub().requestTransportFilters(filterPtr);
try
{
client.echo(s0);
BOOST_CHECK(1==0);
}
catch(const RCF::Exception &e)
{
BOOST_CHECK(1==1);
BOOST_CHECK(e.getError() == RCF::RcfError_SslCertVerification);
client.getClientStub().clearTransportFilters();
}
//--------------------------
// server and client verify each others certificate
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certA,
certPassA,
caCertB,
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
certB,
certPassB,
caCertA,
ciphers));
client.getClientStub().requestTransportFilters(filterPtr);
BOOST_CHECK(client.echo(s0) == s0);
//--------------------------
// server fails to verify client certificate (self-signed)
filterServicePtr->addFilterFactory(
RCF::FilterFactoryPtr( new RCF::OpenSslEncryptionFilterFactory(
certA,
certPassA,
caCertB,
ciphers)));
filterPtr.reset( new RCF::OpenSslEncryptionFilter(
ssCert2,
ssCertPass2,
caCertA,
ciphers));
client.getClientStub().requestTransportFilters(filterPtr);
try
{
client.echo(s0);
BOOST_CHECK(1==0);
}
catch(const RCF::Exception &e)
{
BOOST_CHECK(1==1);
client.getClientStub().clearTransportFilters();
}
}
return boost::exit_success;
}