diff options
Diffstat (limited to 'src/core/tsi')
-rw-r--r-- | src/core/tsi/fake_transport_security_test.cc | 151 | ||||
-rw-r--r-- | src/core/tsi/ssl_transport_security.h | 11 | ||||
-rw-r--r-- | src/core/tsi/ssl_transport_security_test.cc | 534 | ||||
-rw-r--r-- | src/core/tsi/transport_security_interface.h | 17 | ||||
-rw-r--r-- | src/core/tsi/transport_security_test_lib.cc | 363 | ||||
-rw-r--r-- | src/core/tsi/transport_security_test_lib.h | 154 |
6 files changed, 11 insertions, 1219 deletions
diff --git a/src/core/tsi/fake_transport_security_test.cc b/src/core/tsi/fake_transport_security_test.cc deleted file mode 100644 index 0ae88e0c9a..0000000000 --- a/src/core/tsi/fake_transport_security_test.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * Copyright 2014, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/tsi/fake_transport_security.h" - -#include "src/core/tsi/transport_security_test_lib.h" -#include <gtest/gtest.h> -#include "util/random/permute-inl.h" - -namespace { - -void CheckStringPeerProperty(const tsi_peer& peer, int property_index, - const char* expected_name, - const char* expected_value) { - EXPECT_LT(property_index, peer.property_count); - const tsi_peer_property* property = &peer.properties[property_index]; - EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, property->type); - EXPECT_EQ(string(expected_name), string(property->name)); - EXPECT_EQ(string(expected_value), - string(property->value.string.data, property->value.string.length)); -} - -class FakeTransportSecurityTest : public tsi::test::TransportSecurityTest { - protected: - void SetupHandshakers() override { - client_handshaker_.reset(tsi_create_fake_handshaker(1)); - server_handshaker_.reset(tsi_create_fake_handshaker(0)); - } - - void CheckPeer(tsi_handshaker* handshaker) { - tsi_peer peer; - EXPECT_EQ(TSI_OK, tsi_handshaker_extract_peer(handshaker, &peer)); - EXPECT_EQ(1, peer.property_count); - CheckStringPeerProperty(peer, 0, TSI_CERTIFICATE_TYPE_PEER_PROPERTY, - TSI_FAKE_CERTIFICATE_TYPE); - tsi_peer_destruct(&peer); - } - - void CheckHandshakeResults() override { - CheckPeer(client_handshaker_.get()); - CheckPeer(server_handshaker_.get()); - } - - const tsi::test::TestConfig* config() { - return &config_; - } - - tsi::test::TestConfig config_; -}; - -TEST_F(FakeTransportSecurityTest, Handshake) { - PerformHandshake(); -} - -TEST_F(FakeTransportSecurityTest, HandshakeSmallBuffer) { - config_.handshake_buffer_size = 3; - PerformHandshake(); -} -TEST_F(FakeTransportSecurityTest, PingPong) { - PingPong(); -} - -TEST_F(FakeTransportSecurityTest, RoundTrip) { - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripSmallMessageBuffer) { - config_.message_buffer_allocated_size = 42; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripSmallProtectedBufferSize) { - config_.protected_buffer_size = 37; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripSmallReadBufferSize) { - config_.read_buffer_allocated_size = 41; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripSmallClientFrames) { - config_.set_client_max_output_protected_frame_size(39); - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripSmallServerFrames) { - config_.set_server_max_output_protected_frame_size(43); - config_.client_message = small_message_; - config_.server_message = big_message_; - DoRoundTrip(); -} - -TEST_F(FakeTransportSecurityTest, RoundTripOddBufferSizes) { - int odd_sizes[] = {33, 67, 135, 271, 523}; - RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes), - random_.get()); - permute.Permute(); - LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2] - << "\t" << odd_sizes[3] << "\t" << odd_sizes[4]; - config_.message_buffer_allocated_size = odd_sizes[0]; - config_.protected_buffer_size = odd_sizes[1]; - config_.read_buffer_allocated_size = odd_sizes[2]; - config_.set_client_max_output_protected_frame_size(odd_sizes[3]); - config_.set_server_max_output_protected_frame_size(odd_sizes[4]); - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -} // namespace diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 2ed3ed861b..56f50a5dde 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -43,6 +43,17 @@ extern "C" { /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ #define TSI_X509_CERTIFICATE_TYPE "X509" +/* This property is of type TSI_PEER_PROPERTY_STRING. */ +#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name" + +/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain + unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */ +#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \ + "x509_subject_alternative_names" + +/* This property is of type TSI_PEER_PROPERTY_STRING. */ +#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" + /* --- tsi_ssl_handshaker_factory object --- This object creates tsi_handshaker objects implemented in terms of the diff --git a/src/core/tsi/ssl_transport_security_test.cc b/src/core/tsi/ssl_transport_security_test.cc deleted file mode 100644 index a759403126..0000000000 --- a/src/core/tsi/ssl_transport_security_test.cc +++ /dev/null @@ -1,534 +0,0 @@ -/* - * - * Copyright 2014, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <memory> - -#include "base/commandlineflags.h" -#include "file/base/helpers.h" -#include "file/base/options.pb.h" -#include "file/base/path.h" -#include "src/core/tsi/transport_security_test_lib.h" -#include "src/core/tsi/ssl_transport_security.h" -#include "util/random/permute-inl.h" - -namespace { - -const char kTestCredsDir[] = - "/internal/tsi/test_creds/"; - -enum AlpnMode { - NO_ALPN, - ALPN_CLIENT_NO_SERVER, - ALPN_SERVER_NO_CLIENT, - ALPN_CLIENT_SERVER_OK, - ALPN_CLIENT_SERVER_MISMATCH -}; - -class SslTestConfig : public tsi::test::TestConfig { - public: - SslTestConfig() - : do_client_authentication(false), - subject_name_indication(nullptr), - use_bad_client_cert(false), - use_bad_server_cert(false), - alpn_mode(NO_ALPN) {} - bool do_client_authentication; - const char* subject_name_indication; - bool use_bad_client_cert; - bool use_bad_server_cert; - AlpnMode alpn_mode; -}; - -struct TsiSslHandshakerFactoryDeleter { - inline void operator()(tsi_ssl_handshaker_factory* ptr) { - tsi_ssl_handshaker_factory_destroy(ptr); - } -}; -typedef std::unique_ptr<tsi_ssl_handshaker_factory, - TsiSslHandshakerFactoryDeleter> - TsiSslHandshakerFactoryUniquePtr; - -class SslTransportSecurityTest : public tsi::test::TransportSecurityTest { - protected: - void CheckSubjectAltName(const tsi_peer_property& property, - const string& expected_subject_alt_name) { - EXPECT_EQ(property.type, TSI_PEER_PROPERTY_TYPE_STRING); - EXPECT_EQ(property.name, nullptr); - EXPECT_EQ( - string(property.value.string.data, property.value.string.length), - expected_subject_alt_name); - } - - const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName( - const tsi_peer* peer) { - const tsi_peer_property* property = - tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); - EXPECT_NE(property, nullptr); - EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING); - EXPECT_EQ( - string(property->value.string.data, property->value.string.length), - string(TSI_X509_CERTIFICATE_TYPE)); - property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING); - return property; - } - - void CheckServer0Peer(tsi_peer* peer) { - const tsi_peer_property* property = - CheckBasicAuthenticatedPeerAndGetCommonName(peer); - EXPECT_EQ( - string(property->value.string.data, property->value.string.length), - string("*.test.google.com.au")); - property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY); - EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST); - EXPECT_EQ(property->value.list.child_count, 0); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au")); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.test.google.blah")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.com.au")); - tsi_peer_destruct(peer); - } - - void CheckServer1Peer(tsi_peer* peer) { - const tsi_peer_property* property = - CheckBasicAuthenticatedPeerAndGetCommonName(peer); - EXPECT_EQ( - string(property->value.string.data, property->value.string.length), - string("*.test.google.com")); - property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY); - EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST); - EXPECT_EQ(property->value.list.child_count, 3); - CheckSubjectAltName(property->value.list.children[0], "*.test.google.fr"); - CheckSubjectAltName(property->value.list.children[1], - "waterzooi.test.google.be"); - CheckSubjectAltName(property->value.list.children[2], "*.test.youtube.com"); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com")); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.fr")); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be")); - EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.fr")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.test.google.be")); - EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.youtube.com")); - tsi_peer_destruct(peer); - } - - void CheckClientPeer(tsi_peer* peer, bool is_authenticated) { - if (!is_authenticated) { - EXPECT_EQ(peer->property_count, - config_.alpn_mode == ALPN_CLIENT_SERVER_OK ? 1 : 0); - } else { - const tsi_peer_property* property = - CheckBasicAuthenticatedPeerAndGetCommonName(peer); - EXPECT_EQ( - string(property->value.string.data, property->value.string.length), - string("testclient")); - } - tsi_peer_destruct(peer); - } - - void SetupHandshakers() override { - tsi_ssl_handshaker_factory* client_handshaker_factory; - const unsigned char* client_cert = NULL; - unsigned int client_cert_size = 0; - const unsigned char* client_key = NULL; - unsigned int client_key_size = 0; - if (config_.do_client_authentication) { - if (config_.use_bad_client_cert) { - client_cert = - reinterpret_cast<const unsigned char*>(badclient_cert_.data()); - client_cert_size = badclient_cert_.size(); - client_key = - reinterpret_cast<const unsigned char*>(badclient_key_.data()); - client_key_size = badclient_key_.size(); - } else { - client_cert = - reinterpret_cast<const unsigned char*>(client_cert_.data()); - client_cert_size = client_cert_.size(); - client_key = reinterpret_cast<const unsigned char*>(client_key_.data()); - client_key_size = client_key_.size(); - } - } - const unsigned char** client_alpn_protocols(nullptr); - const unsigned char* client_alpn_protocols_lengths(nullptr); - uint16_t num_client_alpn_protocols = 0; - if (config_.alpn_mode == ALPN_CLIENT_NO_SERVER || - config_.alpn_mode == ALPN_CLIENT_SERVER_OK || - config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - client_alpn_protocols = - reinterpret_cast<const unsigned char**>(&client_alpn_protocols_[0]); - client_alpn_protocols_lengths = &client_alpn_protocols_lengths_[0]; - num_client_alpn_protocols = client_alpn_protocols_.size(); - } - - EXPECT_EQ(tsi_create_ssl_client_handshaker_factory( - client_key, client_key_size, client_cert, client_cert_size, - reinterpret_cast<const unsigned char*>(root_certs_.data()), - root_certs_.size(), NULL, client_alpn_protocols, - client_alpn_protocols_lengths, num_client_alpn_protocols, - &client_handshaker_factory), - TSI_OK); - client_handshaker_factory_.reset(client_handshaker_factory); - - const unsigned char** server_alpn_protocols(nullptr); - const unsigned char* server_alpn_protocols_lengths(nullptr); - uint16_t num_server_alpn_protocols = 0; - if (config_.alpn_mode == ALPN_SERVER_NO_CLIENT || - config_.alpn_mode == ALPN_CLIENT_SERVER_OK || - config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_alpn_protocols = - reinterpret_cast<const unsigned char**>(&server_alpn_protocols_[0]); - server_alpn_protocols_lengths = &server_alpn_protocols_lengths_[0]; - num_server_alpn_protocols = server_alpn_protocols_.size(); - if (config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - // Remove the last element that is common. - num_server_alpn_protocols--; - } - } - tsi_ssl_handshaker_factory* server_handshaker_factory; - EXPECT_EQ( - tsi_create_ssl_server_handshaker_factory( - config_.use_bad_server_cert ? &badserver_keys_[0] - : &server_keys_[0], - config_.use_bad_server_cert ? &badserver_keys_sizes_[0] - : &server_keys_sizes_[0], - config_.use_bad_server_cert ? &badserver_certs_[0] - : &server_certs_[0], - config_.use_bad_server_cert ? &badserver_certs_sizes_[0] - : &server_certs_sizes_[0], - config_.use_bad_server_cert ? badserver_keys_.size() - : server_keys_.size(), - config_.do_client_authentication - ? reinterpret_cast<const unsigned char*>(root_certs_.data()) - : NULL, - config_.do_client_authentication ? root_certs_.size() : 0, NULL, - server_alpn_protocols, server_alpn_protocols_lengths, - num_server_alpn_protocols, &server_handshaker_factory), - TSI_OK); - server_handshaker_factory_.reset(server_handshaker_factory); - - tsi_handshaker* client_handshaker; - EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker( - client_handshaker_factory, config_.subject_name_indication, - &client_handshaker), - TSI_OK); - client_handshaker_.reset(client_handshaker); - - tsi_handshaker* server_handshaker; - EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker( - server_handshaker_factory, NULL, &server_handshaker), - TSI_OK); - server_handshaker_.reset(server_handshaker); - } - - void CheckAlpn(const tsi_peer* peer) { - const tsi_peer_property* alpn_property = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (config_.alpn_mode != ALPN_CLIENT_SERVER_OK) { - EXPECT_EQ(nullptr, alpn_property); - } else { - EXPECT_NE(nullptr, alpn_property); - EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, alpn_property->type); - string expected_match("baz"); - EXPECT_EQ(expected_match, string(alpn_property->value.string.data, - alpn_property->value.string.length)); - } - } - - void CheckHandshakeResults() override { - tsi_peer peer; - - bool expect_success = - !(config_.use_bad_server_cert || - (config_.use_bad_client_cert && config_.do_client_authentication)); - tsi_result result = tsi_handshaker_get_result(client_handshaker_.get()); - EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS); - if (expect_success) { - EXPECT_EQ(result, TSI_OK); - EXPECT_EQ(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer), - TSI_OK); - CheckAlpn(&peer); - // TODO(jboeuf): This is a bit fragile. Maybe revisit. - if (config_.subject_name_indication != nullptr) { - CheckServer1Peer(&peer); - } else { - CheckServer0Peer(&peer); - } - } else { - EXPECT_NE(result, TSI_OK); - EXPECT_NE(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer), - TSI_OK); - } - - result = tsi_handshaker_get_result(server_handshaker_.get()); - EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS); - if (expect_success) { - EXPECT_EQ(result, TSI_OK); - EXPECT_EQ(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer), - TSI_OK); - CheckAlpn(&peer); - CheckClientPeer(&peer, config_.do_client_authentication); - } else { - EXPECT_NE(result, TSI_OK); - EXPECT_NE(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer), - TSI_OK); - } - } - - const tsi::test::TestConfig* config() override { - return &config_; - } - - SslTransportSecurityTest() - : client_alpn_protocols_({"foo", "toto", "baz"}), - server_alpn_protocols_({"boooo", "far", "baz"}), - client_alpn_protocols_lengths_({3, 4, 3}), - server_alpn_protocols_lengths_({5, 3, 3}) { - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.key"), - &badserver_key_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.pem"), - &badserver_cert_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.key"), - &badclient_key_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.pem"), - &badclient_cert_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.key"), - &server0_key_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.pem"), - &server0_cert_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.key"), - &server1_key_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.pem"), - &server1_cert_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.key"), - &client_key_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.pem"), - &client_cert_, file::Options())); - CHECK_OK(file::GetContents( - file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "ca.pem"), - &root_certs_, file::Options())); - badserver_keys_.push_back( - reinterpret_cast<const unsigned char*>(badserver_key_.data())); - badserver_certs_.push_back( - reinterpret_cast<const unsigned char*>(badserver_cert_.data())); - server_keys_.push_back( - reinterpret_cast<const unsigned char*>(server0_key_.data())); - server_keys_.push_back( - reinterpret_cast<const unsigned char*>(server1_key_.data())); - server_certs_.push_back( - reinterpret_cast<const unsigned char*>(server0_cert_.data())); - server_certs_.push_back( - reinterpret_cast<const unsigned char*>(server1_cert_.data())); - badserver_keys_sizes_.push_back(badserver_key_.size()); - badserver_certs_sizes_.push_back(badserver_cert_.size()); - server_keys_sizes_.push_back(server0_key_.size()); - server_keys_sizes_.push_back(server1_key_.size()); - server_certs_sizes_.push_back(server0_cert_.size()); - server_certs_sizes_.push_back(server1_cert_.size()); - } - - string badserver_key_; - string badserver_cert_; - string badclient_key_; - string badclient_cert_; - string server0_key_; - string server0_cert_; - string server1_key_; - string server1_cert_; - string client_key_; - string client_cert_; - string root_certs_; - std::vector<const unsigned char*> badserver_keys_; - std::vector<const unsigned char*> badserver_certs_; - std::vector<const unsigned char*> server_keys_; - std::vector<const unsigned char*> server_certs_; - std::vector<unsigned int> badserver_keys_sizes_; - std::vector<unsigned int> badserver_certs_sizes_; - std::vector<unsigned int> server_keys_sizes_; - std::vector<unsigned int> server_certs_sizes_; - TsiSslHandshakerFactoryUniquePtr client_handshaker_factory_; - TsiSslHandshakerFactoryUniquePtr server_handshaker_factory_; - std::vector<const char*> client_alpn_protocols_; - std::vector<const char*> server_alpn_protocols_; - std::vector<unsigned char> client_alpn_protocols_lengths_; - std::vector<unsigned char> server_alpn_protocols_lengths_; - string matched_alpn_; - SslTestConfig config_; -}; - - -TEST_F(SslTransportSecurityTest, LoadInvalidRoots) { - tsi_ssl_handshaker_factory* client_handshaker_factory; - string invalid_roots("Invalid roots!"); - EXPECT_EQ( - TSI_INVALID_ARGUMENT, - tsi_create_ssl_client_handshaker_factory( - NULL, 0, NULL, 0, - reinterpret_cast<const unsigned char*>(invalid_roots.data()), - invalid_roots.size(), NULL, NULL, 0, 0, &client_handshaker_factory)); -} - -TEST_F(SslTransportSecurityTest, Handshake) { - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, HandshakeClientAuthentication) { - config_.do_client_authentication = true; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, HandshakeSmallBuffer) { - config_.handshake_buffer_size = 128; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, HandshakeSNIExactDomain) { - // server1 cert contains waterzooi.test.google.be in SAN. - config_.subject_name_indication = "waterzooi.test.google.be"; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, HandshakeSNIWildstarDomain) { - // server1 cert contains *.test.google.fr in SAN. - config_.subject_name_indication = "juju.test.google.fr"; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, BadServerCertFailure) { - config_.use_bad_server_cert = true; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, BadClientCertFailure) { - config_.use_bad_client_cert = true; - config_.do_client_authentication = true; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, AlpnClientNoServer) { - config_.alpn_mode = ALPN_CLIENT_NO_SERVER; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, AlpnServerNoClient) { - config_.alpn_mode = ALPN_SERVER_NO_CLIENT; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, AlpnClientServeMismatch) { - config_.alpn_mode = ALPN_CLIENT_SERVER_MISMATCH; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, AlpnClientServerOk) { - config_.alpn_mode = ALPN_CLIENT_SERVER_OK; - PerformHandshake(); -} - -TEST_F(SslTransportSecurityTest, PingPong) { - PingPong(); -} - -TEST_F(SslTransportSecurityTest, RoundTrip) { - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripSmallMessageBuffer) { - config_.message_buffer_allocated_size = 42; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripSmallProtectedBufferSize) { - config_.protected_buffer_size = 37; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripSmallReadBufferSize) { - config_.read_buffer_allocated_size = 41; - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripSmallClientFrames) { - config_.set_client_max_output_protected_frame_size(39); - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripSmallServerFrames) { - config_.set_server_max_output_protected_frame_size(43); - config_.client_message = small_message_; - config_.server_message = big_message_; - DoRoundTrip(); -} - -TEST_F(SslTransportSecurityTest, RoundTripOddBufferSizes) { - int odd_sizes[] = {33, 67, 135, 271, 523}; - RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes), - random_.get()); - permute.Permute(); - LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2] - << "\t" << odd_sizes[3] << "\t" << odd_sizes[4]; - config_.message_buffer_allocated_size = odd_sizes[0]; - config_.protected_buffer_size = odd_sizes[1]; - config_.read_buffer_allocated_size = odd_sizes[2]; - config_.set_client_max_output_protected_frame_size(odd_sizes[3]); - config_.set_server_max_output_protected_frame_size(odd_sizes[4]); - config_.client_message = big_message_; - config_.server_message = small_message_; - DoRoundTrip(); -} - -} // namespace diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h index 6be72c753a..18545b4253 100644 --- a/src/core/tsi/transport_security_interface.h +++ b/src/core/tsi/transport_security_interface.h @@ -180,23 +180,6 @@ void tsi_frame_protector_destroy(tsi_frame_protector* self); /* This property is of type TSI_PEER_PROPERTY_STRING. */ #define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type" -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name" - -/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain - unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \ - "x509_subject_alternative_names" - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_MDB_USER_NAME_PEER_PROPERTY "mdb_user_name" - -/* This property is of type TSI_PEER_PROPERTY_SIGNED_INTEGER. */ -#define TSI_MDB_GAIA_ID_PEER_PROPERTY "mdb_gaia_id" - /* Properties of type TSI_PEER_PROPERTY_TYPE_STRING may contain NULL characters just like C++ strings. The length field gives the length of the string. */ typedef enum { diff --git a/src/core/tsi/transport_security_test_lib.cc b/src/core/tsi/transport_security_test_lib.cc deleted file mode 100644 index 1b630c9578..0000000000 --- a/src/core/tsi/transport_security_test_lib.cc +++ /dev/null @@ -1,363 +0,0 @@ -/* - * - * Copyright 2014, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/tsi/transport_security_test_lib.h" - -#include <memory> - -#include "base/commandlineflags.h" -#include "src/core/tsi/transport_security_interface.h" -#include "strings/escaping.h" -#include "strings/strcat.h" -#include <gtest/gtest.h> -#include "util/random/mt_random.h" - -namespace { - -const char kPingRequest[] = "Ping"; -const char kPongResponse[] = "Pong"; -const int kBigMessageSize = 17000; - -} // namespace - -namespace tsi { -namespace test { - -TransportSecurityTest::TransportSecurityTest() : random_(new MTRandom()) { - small_message_ = "Chapi Chapo"; - big_message_ = RandomString(kBigMessageSize); -} - -string TransportSecurityTest::RandomString(int size) { - std::unique_ptr<char[]> buffer(new char[size]); - for (int i = 0; i < size; i++) { - buffer[i] = random_->Rand8(); - } - return string(buffer.get(), size); -} - -void TransportSecurityTest::SendBytesToPeer(bool is_client, unsigned char* buf, - unsigned int buf_size) { - string& channel = is_client ? to_server_channel_ : to_client_channel_; - LOG(INFO) << (is_client ? "Client:" : "Server") << " sending " << buf_size - << " bytes to peer."; - channel.append(reinterpret_cast<const char*>(buf), buf_size); -} - -void TransportSecurityTest::ReadBytesFromPeer(bool is_client, - unsigned char* buf, - unsigned int* buf_size) { - string& channel = is_client ? to_client_channel_ : to_server_channel_; - unsigned int to_read = - *buf_size < channel.size() ? *buf_size : channel.size(); - memcpy(buf, channel.data(), to_read); - *buf_size = to_read; - channel.erase(0, to_read); - LOG(INFO) << (is_client ? "Client:" : "Server") << " read " << to_read - << " bytes from peer."; -} - -void TransportSecurityTest::DoHandshakeStep(bool is_client, - unsigned int buf_allocated_size, - tsi_handshaker* handshaker, - string* remaining_bytes) { - tsi_result result = TSI_OK; - std::unique_ptr<unsigned char[]> buf(new unsigned char[buf_allocated_size]); - unsigned int buf_offset; - unsigned int buf_size; - // See if we need to send some bytes to the peer. - do { - unsigned int buf_size_to_send = buf_allocated_size; - result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf.get(), - &buf_size_to_send); - if (buf_size_to_send > 0) { - SendBytesToPeer(is_client, buf.get(), buf_size_to_send); - } - } while (result == TSI_INCOMPLETE_DATA); - if (!tsi_handshaker_is_in_progress(handshaker)) return; - - do { - // Read bytes from the peer. - buf_size = buf_allocated_size; - buf_offset = 0; - ReadBytesFromPeer(is_client, buf.get(), &buf_size); - if (buf_size == 0) break; - - // Process the bytes from the peer. We have to be careful as these bytes - // may contain non-handshake data (protected data). If this is the case, - // we will exit from the loop with buf_size > 0. - unsigned int consumed_by_handshaker = buf_size; - result = tsi_handshaker_process_bytes_from_peer(handshaker, buf.get(), - &consumed_by_handshaker); - buf_size -= consumed_by_handshaker; - buf_offset += consumed_by_handshaker; - } while (result == TSI_INCOMPLETE_DATA); - - if (!tsi_handshaker_is_in_progress(handshaker)) { - remaining_bytes->assign( - reinterpret_cast<const char*>(buf.get()) + buf_offset, buf_size); - } -} - -void TransportSecurityTest::PerformHandshake() { - SetupHandshakers(); - string remaining_bytes; - do { - DoHandshakeStep(true, config()->handshake_buffer_size, - client_handshaker_.get(), &remaining_bytes); - EXPECT_EQ(0, remaining_bytes.size()); - DoHandshakeStep(false, config()->handshake_buffer_size, - server_handshaker_.get(), &remaining_bytes); - EXPECT_EQ(0, remaining_bytes.size()); - } while (tsi_handshaker_is_in_progress(client_handshaker_.get()) || - tsi_handshaker_is_in_progress(server_handshaker_.get())); - CheckHandshakeResults(); -} - -void TransportSecurityTest::SendMessageToPeer( - bool is_client, tsi_frame_protector* protector, const string& message, - unsigned int protected_buffer_size) { - std::unique_ptr<unsigned char[]> protected_buffer( - new unsigned char[protected_buffer_size]); - unsigned int message_size = message.size(); - const unsigned char* message_bytes = - reinterpret_cast<const unsigned char*>(message.data()); - tsi_result result = TSI_OK; - while (message_size > 0 && result == TSI_OK) { - unsigned int protected_buffer_size_to_send = protected_buffer_size; - unsigned int processed_message_size = message_size; - result = tsi_frame_protector_protect( - protector, message_bytes, &processed_message_size, - protected_buffer.get(), &protected_buffer_size_to_send); - EXPECT_EQ(TSI_OK, result); - SendBytesToPeer(is_client, protected_buffer.get(), - protected_buffer_size_to_send); - message_bytes += processed_message_size; - message_size -= processed_message_size; - - // Flush if we're done. - if (message_size == 0) { - unsigned int still_pending_size; - do { - protected_buffer_size_to_send = protected_buffer_size; - result = tsi_frame_protector_protect_flush( - protector, protected_buffer.get(), &protected_buffer_size_to_send, - &still_pending_size); - EXPECT_EQ(TSI_OK, result); - SendBytesToPeer(is_client, protected_buffer.get(), - protected_buffer_size_to_send); - } while (still_pending_size > 0 && result == TSI_OK); - EXPECT_EQ(TSI_OK, result); - } - } - EXPECT_EQ(TSI_OK, result); -} - -void TransportSecurityTest::ReceiveMessageFromPeer( - bool is_client, tsi_frame_protector* protector, - unsigned int read_buf_allocated_size, - unsigned int message_buf_allocated_size, string* message) { - std::unique_ptr<unsigned char[]> read_buffer( - new unsigned char[read_buf_allocated_size]); - unsigned int read_offset = 0; - unsigned int read_from_peer_size = 0; - std::unique_ptr<unsigned char[]> message_buffer( - new unsigned char[message_buf_allocated_size]); - tsi_result result = TSI_OK; - bool done = false; - while (!done && result == TSI_OK) { - if (read_from_peer_size == 0) { - read_from_peer_size = read_buf_allocated_size; - ReadBytesFromPeer(is_client, read_buffer.get(), &read_from_peer_size); - read_offset = 0; - } - if (read_from_peer_size == 0) done = true; - unsigned int message_buffer_size; - do { - message_buffer_size = message_buf_allocated_size; - unsigned int processed_size = read_from_peer_size; - result = tsi_frame_protector_unprotect( - protector, read_buffer.get() + read_offset, &processed_size, - message_buffer.get(), &message_buffer_size); - EXPECT_EQ(TSI_OK, result); - if (message_buffer_size > 0) { - LOG(INFO) << "Wrote " << message_buffer_size << " bytes to message."; - message->append(reinterpret_cast<const char*>(message_buffer.get()), - message_buffer_size); - } - read_offset += processed_size; - read_from_peer_size -= processed_size; - } while ((read_from_peer_size > 0 || message_buffer_size > 0) && - result == TSI_OK); - EXPECT_EQ(TSI_OK, result); - } - EXPECT_EQ(TSI_OK, result); -} - -void TransportSecurityTest::DoRoundTrip(const string& request, - const string& response) { - PerformHandshake(); - - tsi_frame_protector* client_frame_protector; - tsi_frame_protector* server_frame_protector; - unsigned int client_max_output_protected_frame_size = - config()->client_max_output_protected_frame_size(); - EXPECT_EQ(TSI_OK, - tsi_handshaker_create_frame_protector( - client_handshaker_.get(), - config()->use_client_default_max_output_protected_frame_size() - ? nullptr - : &client_max_output_protected_frame_size, - &client_frame_protector)); - - unsigned int server_max_output_protected_frame_size = - config()->server_max_output_protected_frame_size(); - EXPECT_EQ(TSI_OK, - tsi_handshaker_create_frame_protector( - server_handshaker_.get(), - config()->use_server_default_max_output_protected_frame_size() - ? nullptr - : &server_max_output_protected_frame_size, - &server_frame_protector)); - - SendMessageToPeer(true, client_frame_protector, request, - config()->protected_buffer_size); - string retrieved_request; - ReceiveMessageFromPeer( - false, server_frame_protector, config()->read_buffer_allocated_size, - config()->message_buffer_allocated_size, &retrieved_request); - EXPECT_EQ(request.size(), retrieved_request.size()); - EXPECT_EQ(strings::b2a_hex(request), strings::b2a_hex(retrieved_request)); - - SendMessageToPeer(false, server_frame_protector, response, - config()->protected_buffer_size); - string retrieved_response; - ReceiveMessageFromPeer( - true, client_frame_protector, config()->read_buffer_allocated_size, - config()->message_buffer_allocated_size, &retrieved_response); - EXPECT_EQ(response.size(), retrieved_response.size()); - EXPECT_EQ(strings::b2a_hex(response), strings::b2a_hex(retrieved_response)); - - tsi_frame_protector_destroy(client_frame_protector); - tsi_frame_protector_destroy(server_frame_protector); -} - -void TransportSecurityTest::DoRoundTrip() { - DoRoundTrip(config()->client_message, config()->server_message); -} -void TransportSecurityTest::PingPong() { - PerformHandshake(); - - unsigned char to_server[4096]; - unsigned char to_client[4096]; - unsigned int max_frame_size = sizeof(to_client); - tsi_frame_protector* client_frame_protector; - tsi_frame_protector* server_frame_protector; - EXPECT_EQ( - tsi_handshaker_create_frame_protector( - client_handshaker_.get(), &max_frame_size, &client_frame_protector), - TSI_OK); - EXPECT_EQ(max_frame_size, sizeof(to_client)); - EXPECT_EQ( - tsi_handshaker_create_frame_protector( - server_handshaker_.get(), &max_frame_size, &server_frame_protector), - TSI_OK); - EXPECT_EQ(max_frame_size, sizeof(to_client)); - - // Send Ping. - unsigned int ping_length = strlen(kPingRequest); - unsigned int protected_size = sizeof(to_server); - EXPECT_EQ(tsi_frame_protector_protect( - client_frame_protector, - reinterpret_cast<const unsigned char*>(kPingRequest), - &ping_length, to_server, &protected_size), - TSI_OK); - EXPECT_EQ(ping_length, strlen(kPingRequest)); - EXPECT_EQ(protected_size, 0); - protected_size = sizeof(to_server); - unsigned int still_pending_size; - EXPECT_EQ( - tsi_frame_protector_protect_flush(client_frame_protector, to_server, - &protected_size, &still_pending_size), - TSI_OK); - EXPECT_EQ(still_pending_size, 0); - EXPECT_GT(protected_size, strlen(kPingRequest)); - - // Receive Ping. - unsigned int unprotected_size = sizeof(to_server); - unsigned int saved_protected_size = protected_size; - EXPECT_EQ(tsi_frame_protector_unprotect(server_frame_protector, to_server, - &protected_size, to_server, - &unprotected_size), - TSI_OK); - EXPECT_EQ(saved_protected_size, protected_size); - EXPECT_EQ(ping_length, unprotected_size); - EXPECT_EQ(string(kPingRequest), - string(reinterpret_cast<const char*>(to_server), unprotected_size)); - - // Send back Pong. - unsigned int pong_length = strlen(kPongResponse); - protected_size = sizeof(to_client); - EXPECT_EQ(tsi_frame_protector_protect( - server_frame_protector, - reinterpret_cast<const unsigned char*>(kPongResponse), - &pong_length, to_client, &protected_size), - TSI_OK); - EXPECT_EQ(pong_length, strlen(kPongResponse)); - EXPECT_EQ(protected_size, 0); - protected_size = sizeof(to_client); - EXPECT_EQ( - tsi_frame_protector_protect_flush(server_frame_protector, to_client, - &protected_size, &still_pending_size), - TSI_OK); - EXPECT_EQ(still_pending_size, 0); - EXPECT_GT(protected_size, strlen(kPongResponse)); - - // Receive Pong. - unprotected_size = sizeof(to_server); - saved_protected_size = protected_size; - EXPECT_EQ(tsi_frame_protector_unprotect(client_frame_protector, to_client, - &protected_size, to_client, - &unprotected_size), - TSI_OK); - EXPECT_EQ(saved_protected_size, protected_size); - EXPECT_EQ(pong_length, unprotected_size); - EXPECT_EQ(string(kPongResponse), - string(reinterpret_cast<const char*>(to_client), unprotected_size)); - - tsi_frame_protector_destroy(client_frame_protector); - tsi_frame_protector_destroy(server_frame_protector); -} - -} // namespace test -} // namespace tsi diff --git a/src/core/tsi/transport_security_test_lib.h b/src/core/tsi/transport_security_test_lib.h deleted file mode 100644 index 8c9c764c91..0000000000 --- a/src/core/tsi/transport_security_test_lib.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * - * Copyright 2014, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef __TRANSPORT_SECURITY_TEST_LIB_H_ -#define __TRANSPORT_SECURITY_TEST_LIB_H_ - -#include <memory> - -#include "base/commandlineflags.h" -#include "src/core/tsi/transport_security_interface.h" -#include "strings/strcat.h" -#include <gtest/gtest.h> -#include "util/random/mt_random.h" - -namespace tsi { -namespace test { - -class TestConfig { - public: - TestConfig() - : client_message("Chapi Chapo"), - server_message("Chapi Chapo"), - handshake_buffer_size(4096), - read_buffer_allocated_size(4096), - message_buffer_allocated_size(4096), - protected_buffer_size(16384), - use_client_default_max_output_protected_frame_size_(true), - use_server_default_max_output_protected_frame_size_(true), - client_max_output_protected_frame_size_(0), - server_max_output_protected_frame_size_(0) {} - - void set_client_max_output_protected_frame_size(unsigned int size) { - use_client_default_max_output_protected_frame_size_ = false; - client_max_output_protected_frame_size_ = size; - } - void set_server_max_output_protected_frame_size(unsigned int size) { - use_server_default_max_output_protected_frame_size_ = false; - server_max_output_protected_frame_size_ = size; - } - bool use_client_default_max_output_protected_frame_size() const { - return use_client_default_max_output_protected_frame_size_; - } - bool use_server_default_max_output_protected_frame_size() const { - return use_server_default_max_output_protected_frame_size_; - } - unsigned int client_max_output_protected_frame_size() const { - return client_max_output_protected_frame_size_; - } - unsigned int server_max_output_protected_frame_size() const { - return server_max_output_protected_frame_size_; - } - - string client_message; - string server_message; - unsigned int handshake_buffer_size; - unsigned int read_buffer_allocated_size; - unsigned int message_buffer_allocated_size; - unsigned int protected_buffer_size; - - private: - bool use_client_default_max_output_protected_frame_size_; - bool use_server_default_max_output_protected_frame_size_; - unsigned int client_max_output_protected_frame_size_; - unsigned int server_max_output_protected_frame_size_; -}; - - -struct TsiHandshakerDeleter { - inline void operator()(tsi_handshaker* ptr) { tsi_handshaker_destroy(ptr); } -}; -typedef std::unique_ptr<tsi_handshaker, TsiHandshakerDeleter> - TsiHandshakerUniquePtr; - -class TransportSecurityTest : public ::testing::Test { - protected: - TransportSecurityTest(); - virtual ~TransportSecurityTest() {} - virtual const TestConfig* config() = 0; - string RandomString(int size); - virtual void SetupHandshakers() = 0; - // An implementation-specific verification of the validity of the handshake. - virtual void CheckHandshakeResults() = 0; - // Do a full handshake. - void PerformHandshake(); - // Send a protected message between the client and server. - void SendMessageToPeer(bool is_client, tsi_frame_protector* protector, - const string& message, - unsigned int protected_buffer_size); - void ReceiveMessageFromPeer(bool is_client, tsi_frame_protector* protector, - unsigned int read_buf_allocated_size, - unsigned int message_buf_allocated_size, - string* message); - - // A simple test that does a handshake and sends a message back and forth - void PingPong(); - // A complicated test that can be configured by modifying config(). - void DoRoundTrip(); - - TsiHandshakerUniquePtr client_handshaker_; - TsiHandshakerUniquePtr server_handshaker_; - - string small_message_; - string big_message_; - std::unique_ptr<RandomBase> random_; - - private: - // Functions to send raw bytes between the client and server. - void SendBytesToPeer(bool is_client, unsigned char* buf, - unsigned int buf_size); - void ReadBytesFromPeer(bool is_client, unsigned char* buf, - unsigned int* buf_size); - // Do a single step of the handshake. - void DoHandshakeStep(bool is_client, unsigned int buf_allocated_size, - tsi_handshaker* handshaker, string* remaining_bytes); - void DoRoundTrip(const string& request, const string& response); - - string to_server_channel_; - string to_client_channel_; -}; - -} // namespace test -} // namespace tsi - -#endif // __TRANSPORT_SECURITY_TEST_LIB_H_ |