diff options
author | lloyd <[email protected]> | 2012-06-29 21:42:41 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-06-29 21:42:41 +0000 |
commit | 25208d3db9ebfb074a300191496f3668fa113cfc (patch) | |
tree | bb342a7c393cc9d882247fa26fb69eca528626c4 | |
parent | ae8535843aa24a5f5322f3c4bd9caf7604b400c2 (diff) |
Single basic TLS test using in-memory handshake.
Fix compile flags for the NIST tests
-rw-r--r-- | checks/check.cpp | 1 | ||||
-rw-r--r-- | checks/nist_tests/Makefile | 10 | ||||
-rw-r--r-- | checks/tls.cpp | 268 | ||||
-rw-r--r-- | checks/validate.h | 2 |
4 files changed, 276 insertions, 5 deletions
diff --git a/checks/check.cpp b/checks/check.cpp index e47cc543b..374eff964 100644 --- a/checks/check.cpp +++ b/checks/check.cpp @@ -229,6 +229,7 @@ int run_test_suite(RandomNumberGenerator& rng) errors += do_bigint_tests(BIGINT_VALIDATION_FILE, rng); errors += do_pk_validation_tests(PK_VALIDATION_FILE, rng); do_x509_tests(rng); + do_tls_tests(rng); //errors += do_cvc_tests(rng); } catch(std::exception& e) diff --git a/checks/nist_tests/Makefile b/checks/nist_tests/Makefile index 52dc340c9..19f8a462d 100644 --- a/checks/nist_tests/Makefile +++ b/checks/nist_tests/Makefile @@ -1,10 +1,10 @@ -BOTAN_CONFIG=../../build/botan-config-1.10 +BOTAN_CONFIG=../../build/botan-config-1.11 -CC=g++ -FLAGS=-g -Os -W -Wall -ansi -LDFLAGS=$(shell $(BOTAN_CONFIG) --libs) -L../.. -lbotan-1.10 -CFLAGS=$(shell $(BOTAN_CONFIG) --cflags) -I../../build/include +CC=g++-4.7.0 -std=c++11 +FLAGS=-g -Os -W -Wall +LDFLAGS=-L../.. -lbotan-1.11 +CFLAGS=-I../../build/include x509test: x509test.cpp $(CC) $(FLAGS) $(CFLAGS) x509test.cpp $(LDFLAGS) -o x509test diff --git a/checks/tls.cpp b/checks/tls.cpp new file mode 100644 index 000000000..db3c008e2 --- /dev/null +++ b/checks/tls.cpp @@ -0,0 +1,268 @@ +#include <botan/tls_server.h> +#include <botan/tls_client.h> +#include <botan/pkcs10.h> +#include <botan/x509self.h> +#include <botan/rsa.h> +#include <botan/x509_ca.h> +#include <botan/hex.h> + +#include "validate.h" +#include <iostream> +#include <vector> +#include <memory> + +using namespace Botan; + +namespace { + +class Credentials_Manager_Test : public Botan::Credentials_Manager + { + public: + Credentials_Manager_Test(const X509_Certificate& server_cert, + const X509_Certificate& ca_cert, + Private_Key* server_key) : + m_server_cert(server_cert), + m_ca_cert(ca_cert), + m_key(server_key) + { + } + + std::vector<X509_Certificate> + trusted_certificate_authorities(const std::string&, + const std::string&) override + { + std::vector<X509_Certificate> certs; + certs.push_back(m_ca_cert); + return certs; + } + + std::vector<X509_Certificate> cert_chain( + const std::vector<std::string>& cert_key_types, + const std::string& type, + const std::string&) override + { + std::vector<X509_Certificate> chain; + + if(type == "tls-server") + { + bool have_match = false; + for(size_t i = 0; i != cert_key_types.size(); ++i) + if(cert_key_types[i] == m_key->algo_name()) + have_match = true; + + if(have_match) + { + chain.push_back(m_server_cert); + chain.push_back(m_ca_cert); + } + } + + return chain; + } + + void verify_certificate_chain( + const std::string& type, + const std::string& purported_hostname, + const std::vector<Botan::X509_Certificate>& cert_chain) override + { + try + { + Credentials_Manager::verify_certificate_chain(type, + purported_hostname, + cert_chain); + } + catch(std::exception& e) + { + std::cout << "Certificate verification failed - " << e.what() << " - but will ignore\n"; + } + } + + Private_Key* private_key_for(const X509_Certificate&, + const std::string&, + const std::string&) override + { + return m_key; + } + public: + X509_Certificate m_server_cert, m_ca_cert; + Private_Key* m_key; + }; + +Credentials_Manager* create_creds(RandomNumberGenerator& rng) + { + std::auto_ptr<Private_Key> ca_key(new RSA_PrivateKey(rng, 1024)); + + X509_Cert_Options ca_opts; + ca_opts.common_name = "Test CA"; + ca_opts.country = "US"; + ca_opts.CA_key(1); + + X509_Certificate ca_cert = + X509::create_self_signed_cert(ca_opts, + *ca_key, + "SHA-256", + rng); + + Private_Key* server_key = new RSA_PrivateKey(rng, 1024); + + X509_Cert_Options server_opts; + server_opts.common_name = "localhost"; + server_opts.country = "US"; + + PKCS10_Request req = X509::create_cert_req(server_opts, + *server_key, + "SHA-256", + rng); + + X509_CA ca(ca_cert, *ca_key, "SHA-256"); + + auto now = std::chrono::system_clock::now(); + X509_Time start_time(now); + typedef std::chrono::duration<int, std::ratio<31556926>> years; + X509_Time end_time(now + years(1)); + + X509_Certificate server_cert = ca.sign_request(req, + rng, + start_time, + end_time); + + return new Credentials_Manager_Test(server_cert, ca_cert, server_key); + } + + +void test_handshake(RandomNumberGenerator& rng) + { + TLS::Policy default_policy; + + std::auto_ptr<Credentials_Manager> creds(create_creds(rng)); + + TLS::Session_Manager_In_Memory server_sessions; + TLS::Session_Manager_In_Memory client_sessions; + + std::vector<byte> c2s_q, s2c_q, c2s_data, s2c_data; + + auto handshake_complete = [](const TLS::Session& session) + { + std::cout << "Handshake complete, " << session.version().to_string() + << " using " << session.ciphersuite().to_string() << "\n"; + + if(!session.session_id().empty()) + std::cout << "Session ID " << hex_encode(session.session_id()) << "\n"; + + if(!session.session_ticket().empty()) + std::cout << "Session ticket " << hex_encode(session.session_ticket()) << "\n"; + + std::cout << "Secure renegotiation is" + << (session.secure_renegotiation() ? "" : " NOT") + << " supported\n"; + + return true; + }; + + auto save_server_data = [&](const byte buf[], size_t sz, TLS::Alert alert) + { + c2s_data.insert(c2s_data.end(), buf, buf+sz); + if(alert.is_valid()) + std::cout << "Server recvd alert " << alert.type_string() << "\n"; + }; + + auto save_client_data = [&](const byte buf[], size_t sz, TLS::Alert alert) + { + s2c_data.insert(s2c_data.end(), buf, buf+sz); + if(alert.is_valid()) + std::cout << "Client recvd alert " << alert.type_string() << "\n"; + }; + + TLS::Server server([&](const byte buf[], size_t sz) + { s2c_q.insert(s2c_q.end(), buf, buf+sz); }, + save_server_data, + handshake_complete, + server_sessions, + *creds, + default_policy, + rng); + + TLS::Client client([&](const byte buf[], size_t sz) + { c2s_q.insert(c2s_q.end(), buf, buf+sz); }, + save_client_data, + handshake_complete, + client_sessions, + *creds, + default_policy, + rng); + + while(true) + { + if(client.is_active()) + client.send("1"); + if(server.is_active()) + server.send("2"); + + /* + * 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_q, input); + + try + { + server.received_data(&input[0], input.size()); + } + catch(std::exception& e) + { + std::cout << "Server error - " << e.what() << "\n"; + break; + } + + input.clear(); + std::swap(s2c_q, input); + + try + { + client.received_data(&input[0], input.size()); + } + catch(std::exception& e) + { + std::cout << "Client error - " << e.what() << "\n"; + break; + } + + if(c2s_data.size()) + { + if(c2s_data[0] != '1') + { + std::cout << "Error\n"; + break; + } + } + + if(s2c_data.size()) + { + if(s2c_data[0] != '2') + { + std::cout << "Error\n"; + break; + } + } + + if(s2c_data.size() && c2s_data.size()) + break; + } + } + +} + +size_t do_tls_tests(RandomNumberGenerator& rng) + { + size_t errors = 0; + + std::cout << "TLS tests: "; + + test_handshake(rng); + + std::cout << std::endl; + + return errors; + } diff --git a/checks/validate.h b/checks/validate.h index 9e34d64fb..b88837d4b 100644 --- a/checks/validate.h +++ b/checks/validate.h @@ -28,4 +28,6 @@ u32bit do_cvc_tests(RandomNumberGenerator& rng); void do_x509_tests(RandomNumberGenerator&); +size_t do_tls_tests(RandomNumberGenerator& rng); + #endif |