aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Gierlings <[email protected]>2016-05-24 20:17:42 +0200
committerMatthias Gierlings <[email protected]>2016-06-19 18:28:39 +0200
commitd73460df43b2d4d14b62a98e9bc66dfea02ab63d (patch)
tree426fd474e3d71629f34cbb2f487032c7e4e34e60
parent490d538512b7f732268358b3a3a6fcbfd2bb67c6 (diff)
Extended TLS Unit Tests
- Modified TLS & DTLS tests to use both, legacy constructor and new virtual callback interface based constructors.
-rw-r--r--src/tests/unit_tls.cpp577
1 files changed, 326 insertions, 251 deletions
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index 621a803c8..919c3c950 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -219,24 +219,27 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
-
- Botan::TLS::Server server(Botan::TLS::Callbacks(
- queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
+ // TLS::Server object constructed by new constructor using virtual callback interface.
+ std::unique_ptr<Botan::TLS::Server> server(
+ new Botan::TLS::Server(Botan::TLS::Callbacks(
+ queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete),
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ false));
+
+ // TLS::Client object constructed by new constructor using virtual callback interface.
+ std::unique_ptr<Botan::TLS::Client> client(
+ new Botan::TLS::Client(Botan::TLS::Callbacks(
+ queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
print_alert,
handshake_complete),
- server_sessions,
- creds,
- policy,
- rng,
- next_protocol_chooser,
- false);
-
- Botan::TLS::Callbacks client_callbacks(queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete);
- Botan::TLS::Client client(client_callbacks,
client_sessions,
creds,
policy,
@@ -244,143 +247,177 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
Botan::TLS::Client::Properties(
Botan::TLS::Server_Information("server.example.com"),
offer_version,
- protocols_offered));
+ protocols_offered)));
size_t rounds = 0;
- while(true)
+ // Test TLS using both new and legacy constructors.
+ for(size_t ctor_sel = 0; ctor_sel < 2; ctor_sel++)
{
- ++rounds;
-
- if(rounds > 25)
+ if(ctor_sel == 1)
{
- if(r <= 2)
- result.test_failure("Still here after many rounds, deadlock?");
- break;
+ // TLS::Server object constructed by legacy constructor.
+ server = std::unique_ptr<Botan::TLS::Server>(
+ new Botan::TLS::Server(queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete,
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ false));
+
+ // TLS::Client object constructed by legacy constructor.
+ std::unique_ptr<Botan::TLS::Client> client(
+ new Botan::TLS::Client(queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ print_alert,
+ handshake_complete,
+ client_sessions,
+ creds,
+ policy,
+ rng,
+ Botan::TLS::Server_Information("server.example.com"),
+ offer_version,
+ protocols_offered));
}
- if(handshake_done && (client.is_closed() || server.is_closed()))
- break;
-
- if(client.is_active() && client_sent.empty())
+ while(true)
{
- // Choose a len between 1 and 511
- const size_t c_len = 1 + rng.next_byte() + rng.next_byte();
- client_sent = unlock(rng.random_vec(c_len));
+ ++rounds;
- // TODO send in several records
- client.send(client_sent);
- }
+ if(rounds > 25)
+ {
+ if(r <= 2)
+ result.test_failure("Still here after many rounds, deadlock?");
+ break;
+ }
- if(server.is_active() && server_sent.empty())
- {
- result.test_eq("server protocol", server.next_protocol(), "test/3");
+ if(handshake_done && (client->is_closed() || server->is_closed()))
+ break;
- const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
- server_sent = unlock(rng.random_vec(s_len));
- server.send(server_sent);
- }
+ if(client->is_active() && client_sent.empty())
+ {
+ // Choose a len between 1 and 511
+ const size_t c_len = 1 + rng.next_byte() + rng.next_byte();
+ client_sent = unlock(rng.random_vec(c_len));
- const bool corrupt_client_data = (r == 3);
- const bool corrupt_server_data = (r == 4);
+ // TODO send in several records
+ client->send(client_sent);
+ }
- if(c2s_traffic.size() > 0)
- {
- /*
- * Use this as a temp value to hold the queues as otherwise they
- * might end up appending more in response to messages during the
- * handshake.
- */
- std::vector<byte> input;
- std::swap(c2s_traffic, input);
-
- if(corrupt_server_data)
+ if(server->is_active() && server_sent.empty())
{
- input = Test::mutate_vec(input, true);
- size_t needed = server.received_data(input.data(), input.size());
-
- size_t total_consumed = needed;
+ result.test_eq("server->protocol", server->next_protocol(), "test/3");
- while(needed > 0 &&
- result.test_lt("Never requesting more than max protocol len", needed, 18*1024) &&
- result.test_lt("Total requested is readonable", total_consumed, 128*1024))
- {
- input.resize(needed);
- Test::rng().randomize(input.data(), input.size());
- needed = server.received_data(input.data(), input.size());
- total_consumed += needed;
- }
+ const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
+ server_sent = unlock(rng.random_vec(s_len));
+ server->send(server_sent);
}
- else
+
+ const bool corrupt_client_data = (r == 3);
+ const bool corrupt_server_data = (r == 4);
+
+ if(c2s_traffic.size() > 0)
{
- size_t needed = server.received_data(input.data(), input.size());
- result.test_eq("full packet received", needed, 0);
- }
+ /*
+ * Use this as a temp value to hold the queues as otherwise they
+ * might end up appending more in response to messages during the
+ * handshake.
+ */
+ std::vector<byte> input;
+ std::swap(c2s_traffic, input);
+
+ if(corrupt_server_data)
+ {
+ input = Test::mutate_vec(input, true);
+ size_t needed = server->received_data(input.data(), input.size());
- continue;
- }
+ size_t total_consumed = needed;
- if(s2c_traffic.size() > 0)
- {
- std::vector<byte> input;
- std::swap(s2c_traffic, input);
+ while(needed > 0 &&
+ result.test_lt("Never requesting more than max protocol len", needed, 18*1024) &&
+ result.test_lt("Total requested is readonable", total_consumed, 128*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = server->received_data(input.data(), input.size());
+ total_consumed += needed;
+ }
+ }
+ else
+ {
+ size_t needed = server->received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+
+ continue;
+ }
- if(corrupt_client_data)
+ if(s2c_traffic.size() > 0)
{
- input = Test::mutate_vec(input, true);
- size_t needed = client.received_data(input.data(), input.size());
+ std::vector<byte> input;
+ std::swap(s2c_traffic, input);
- size_t total_consumed = 0;
+ if(corrupt_client_data)
+ {
+ input = Test::mutate_vec(input, true);
+ size_t needed = client->received_data(input.data(), input.size());
- while(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ size_t total_consumed = 0;
+
+ while(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ needed = client->received_data(input.data(), input.size());
+ total_consumed += needed;
+ }
+ }
+ else
{
- input.resize(needed);
- Test::rng().randomize(input.data(), input.size());
- needed = client.received_data(input.data(), input.size());
- total_consumed += needed;
+ size_t needed = client->received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
}
+
+ continue;
}
- else
+
+ if(client_recv.size())
{
- size_t needed = client.received_data(input.data(), input.size());
- result.test_eq("full packet received", needed, 0);
+ result.test_eq("client recv", client_recv, server_sent);
}
- continue;
- }
-
- if(client_recv.size())
- {
- result.test_eq("client recv", client_recv, server_sent);
- }
-
- if(server_recv.size())
- {
- result.test_eq("server recv", server_recv, client_sent);
- }
+ if(server_recv.size())
+ {
+ result.test_eq("server->recv", server_recv, client_sent);
+ }
- if(r > 2)
- {
- if(client_recv.size() && server_recv.size())
+ if(r > 2)
{
- result.test_failure("Negotiated in the face of data corruption " + std::to_string(r));
+ if(client_recv.size() && server_recv.size())
+ {
+ result.test_failure("Negotiated in the face of data corruption " + std::to_string(r));
+ }
}
- }
- if(client.is_closed() && server.is_closed())
- break;
+ if(client->is_closed() && server->is_closed())
+ break;
- if(server_recv.size() && client_recv.size())
- {
- Botan::SymmetricKey client_key = client.key_material_export("label", "context", 32);
- Botan::SymmetricKey server_key = server.key_material_export("label", "context", 32);
+ if(server_recv.size() && client_recv.size())
+ {
+ Botan::SymmetricKey client_key = client->key_material_export("label", "context", 32);
+ Botan::SymmetricKey server_key = server->key_material_export("label", "context", 32);
- result.test_eq("TLS key material export", client_key.bits_of(), server_key.bits_of());
+ result.test_eq("TLS key material export", client_key.bits_of(), server_key.bits_of());
- if(r % 2 == 0)
- client.close();
- else
- server.close();
+ if(r % 2 == 0)
+ client->close();
+ else
+ server->close();
+ }
}
}
}
@@ -449,23 +486,27 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
- Botan::TLS::Callbacks server_callbacks(queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
- print_alert,
- handshake_complete);
- Botan::TLS::Server server(server_callbacks,
- server_sessions,
- creds,
- policy,
- rng,
- next_protocol_chooser,
- true);
-
- Botan::TLS::Callbacks client_callbacks(queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete);
- Botan::TLS::Client client(client_callbacks,
+ // TLS::Server object constructed by new constructor using virtual callback interface.
+ std::unique_ptr<Botan::TLS::Server> server(
+ new Botan::TLS::Server(Botan::TLS::Callbacks(
+ queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete),
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ true));
+
+ // TLS::Client object constructed by new constructor using virtual callback interface.
+ std::unique_ptr<Botan::TLS::Client> client(
+ new Botan::TLS::Client(Botan::TLS::Callbacks(
+ queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ print_alert,
+ handshake_complete),
client_sessions,
creds,
policy,
@@ -473,162 +514,196 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
Botan::TLS::Client::Properties(
Botan::TLS::Server_Information("server.example.com"),
offer_version,
- protocols_offered));
+ protocols_offered)));
size_t rounds = 0;
- while(true)
+ // Test DTLS using both new and legacy constructors.
+ for(size_t ctor_sel = 0; ctor_sel < 2; ctor_sel++)
{
- // TODO: client and server should be in different threads
- std::this_thread::sleep_for(std::chrono::milliseconds(rng.next_byte() % 2));
- ++rounds;
-
- if(rounds > 100)
+ if(ctor_sel == 1)
{
- result.test_failure("Still here after many rounds");
- break;
+ // TLS::Server object constructed by legacy constructor.
+ server = std::unique_ptr<Botan::TLS::Server>(
+ new Botan::TLS::Server(queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ print_alert,
+ handshake_complete,
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ true));
+
+ // TLS::Client object constructed by legacy constructor.
+ std::unique_ptr<Botan::TLS::Client> client(
+ new Botan::TLS::Client(queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ print_alert,
+ handshake_complete,
+ client_sessions,
+ creds,
+ policy,
+ rng,
+ Botan::TLS::Server_Information("server.example.com"),
+ offer_version,
+ protocols_offered));
}
- if(handshake_done && (client.is_closed() || server.is_closed()))
- break;
-
- if(client.is_active() && client_sent.empty())
+ while(true)
{
- // Choose a len between 1 and 511 and send random chunks:
- const size_t c_len = 1 + rng.next_byte() + rng.next_byte();
- client_sent = unlock(rng.random_vec(c_len));
+ // TODO: client and server should be in different threads
+ std::this_thread::sleep_for(std::chrono::milliseconds(rng.next_byte() % 2));
+ ++rounds;
- // TODO send multiple parts
- client.send(client_sent);
- }
-
- if(server.is_active() && server_sent.empty())
- {
- result.test_eq("server ALPN", server.next_protocol(), "test/3");
-
- const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
- server_sent = unlock(rng.random_vec(s_len));
- server.send(server_sent);
- }
+ if(rounds > 100)
+ {
+ result.test_failure("Still here after many rounds");
+ break;
+ }
- const bool corrupt_client_data = (r == 3 && rng.next_byte() % 3 <= 1 && rounds < 10);
- const bool corrupt_server_data = (r == 4 && rng.next_byte() % 3 <= 1 && rounds < 10);
+ if(handshake_done && (client->is_closed() || server->is_closed()))
+ break;
- if(c2s_traffic.size() > 0)
- {
- /*
- * Use this as a temp value to hold the queues as otherwise they
- * might end up appending more in response to messages during the
- * handshake.
- */
- std::vector<byte> input;
- std::swap(c2s_traffic, input);
-
- if(corrupt_server_data)
+ if(client->is_active() && client_sent.empty())
{
- try
- {
- input = Test::mutate_vec(input, true);
- size_t needed = server.received_data(input.data(), input.size());
+ // Choose a len between 1 and 511 and send random chunks:
+ const size_t c_len = 1 + rng.next_byte() + rng.next_byte();
+ client_sent = unlock(rng.random_vec(c_len));
- if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
- {
- input.resize(needed);
- Test::rng().randomize(input.data(), input.size());
- client.received_data(input.data(), input.size());
- }
- }
- catch(std::exception&)
- {
- result.test_note("corruption caused server exception");
- }
+ // TODO send multiple parts
+ client->send(client_sent);
}
- else
+
+ if(server->is_active() && server_sent.empty())
{
- try
- {
- size_t needed = server.received_data(input.data(), input.size());
- result.test_eq("full packet received", needed, 0);
- }
- catch(std::exception& e)
- {
- result.test_failure("server error", e.what());
- }
- }
+ result.test_eq("server ALPN", server->next_protocol(), "test/3");
- continue;
- }
+ const size_t s_len = 1 + rng.next_byte() + rng.next_byte();
+ server_sent = unlock(rng.random_vec(s_len));
+ server->send(server_sent);
+ }
- if(s2c_traffic.size() > 0)
- {
- std::vector<byte> input;
- std::swap(s2c_traffic, input);
+ const bool corrupt_client_data = (r == 3 && rng.next_byte() % 3 <= 1 && rounds < 10);
+ const bool corrupt_server_data = (r == 4 && rng.next_byte() % 3 <= 1 && rounds < 10);
- if(corrupt_client_data)
+ if(c2s_traffic.size() > 0)
{
- try
+ /*
+ * Use this as a temp value to hold the queues as otherwise they
+ * might end up appending more in response to messages during the
+ * handshake.
+ */
+ std::vector<byte> input;
+ std::swap(c2s_traffic, input);
+
+ if(corrupt_server_data)
{
- input = Test::mutate_vec(input, true);
- size_t needed = client.received_data(input.data(), input.size());
-
- if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ try
{
- input.resize(needed);
- Test::rng().randomize(input.data(), input.size());
- client.received_data(input.data(), input.size());
+ input = Test::mutate_vec(input, true);
+ size_t needed = server->received_data(input.data(), input.size());
+
+ if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ client->received_data(input.data(), input.size());
+ }
+ }
+ catch(std::exception&)
+ {
+ result.test_note("corruption caused server exception");
}
}
- catch(std::exception&)
+ else
{
- result.test_note("corruption caused client exception");
+ try
+ {
+ size_t needed = server->received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("server error", e.what());
+ }
}
+
+ continue;
}
- else
+
+ if(s2c_traffic.size() > 0)
{
- try
+ std::vector<byte> input;
+ std::swap(s2c_traffic, input);
+
+ if(corrupt_client_data)
{
- size_t needed = client.received_data(input.data(), input.size());
- result.test_eq("full packet received", needed, 0);
+ try
+ {
+ input = Test::mutate_vec(input, true);
+ size_t needed = client->received_data(input.data(), input.size());
+
+ if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, 18*1024))
+ {
+ input.resize(needed);
+ Test::rng().randomize(input.data(), input.size());
+ client->received_data(input.data(), input.size());
+ }
+ }
+ catch(std::exception&)
+ {
+ result.test_note("corruption caused client exception");
+ }
}
- catch(std::exception& e)
+ else
{
- result.test_failure("client error", e.what());
+ try
+ {
+ size_t needed = client->received_data(input.data(), input.size());
+ result.test_eq("full packet received", needed, 0);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure("client error", e.what());
+ }
}
- }
- continue;
- }
+ continue;
+ }
- // If we corrupted a DTLS application message, resend it:
- if(client.is_active() && corrupt_client_data && server_recv.empty())
- client.send(client_sent);
- if(server.is_active() && corrupt_server_data && client_recv.empty())
- server.send(server_sent);
+ // If we corrupted a DTLS application message, resend it:
+ if(client->is_active() && corrupt_client_data && server_recv.empty())
+ client->send(client_sent);
+ if(server->is_active() && corrupt_server_data && client_recv.empty())
+ server->send(server_sent);
- if(client_recv.size())
- {
- result.test_eq("client recv", client_recv, server_sent);
- }
+ if(client_recv.size())
+ {
+ result.test_eq("client recv", client_recv, server_sent);
+ }
- if(server_recv.size())
- {
- result.test_eq("server recv", server_recv, client_sent);
- }
+ if(server_recv.size())
+ {
+ result.test_eq("server recv", server_recv, client_sent);
+ }
- if(client.is_closed() && server.is_closed())
- break;
+ if(client->is_closed() && server->is_closed())
+ break;
- if(server_recv.size() && client_recv.size())
- {
- Botan::SymmetricKey client_key = client.key_material_export("label", "context", 32);
- Botan::SymmetricKey server_key = server.key_material_export("label", "context", 32);
+ if(server_recv.size() && client_recv.size())
+ {
+ Botan::SymmetricKey client_key = client->key_material_export("label", "context", 32);
+ Botan::SymmetricKey server_key = server->key_material_export("label", "context", 32);
- result.test_eq("key material export", client_key.bits_of(), server_key.bits_of());
+ result.test_eq("key material export", client_key.bits_of(), server_key.bits_of());
- if(r % 2 == 0)
- client.close();
- else
- server.close();
+ if(r % 2 == 0)
+ client->close();
+ else
+ server->close();
+ }
}
}
}