diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/asio_tls_server.cpp | 44 | ||||
-rw-r--r-- | doc/examples/credentials.h | 108 | ||||
-rw-r--r-- | doc/examples/tls_client.cpp | 15 | ||||
-rw-r--r-- | doc/examples/tls_server.cpp | 66 | ||||
-rw-r--r-- | doc/log.txt | 3 | ||||
-rw-r--r-- | doc/tls.txt | 16 |
6 files changed, 215 insertions, 37 deletions
diff --git a/doc/examples/asio_tls_server.cpp b/doc/examples/asio_tls_server.cpp index 55f29b336..e721d0455 100644 --- a/doc/examples/asio_tls_server.cpp +++ b/doc/examples/asio_tls_server.cpp @@ -186,6 +186,46 @@ class tls_server_session : public boost::enable_shared_from_this<tls_server_sess std::vector<byte> m_outbox; }; +class Session_Manager_Locked : public Botan::TLS::Session_Manager + { + public: + bool load_from_session_id(const Botan::MemoryRegion<byte>& session_id, + Botan::TLS::Session& session) + { + boost::lock_guard<boost::mutex> lock(m_mutex); + return m_session_manager.load_from_session_id(session_id, session); + } + + bool load_from_host_info(const std::string& hostname, Botan::u16bit port, + Botan::TLS::Session& session) + { + boost::lock_guard<boost::mutex> lock(m_mutex); + return m_session_manager.load_from_host_info(hostname, port, session); + }; + + void remove_entry(const Botan::MemoryRegion<byte>& session_id) + { + boost::lock_guard<boost::mutex> lock(m_mutex); + m_session_manager.remove_entry(session_id); + } + + void save(const Botan::TLS::Session& session) + { + boost::lock_guard<boost::mutex> lock(m_mutex); + m_session_manager.save(session); + } + + Botan::u32bit session_lifetime() const + { + return m_session_manager.session_lifetime(); + } + + private: + boost::mutex m_mutex; + Botan::TLS::Session_Manager_In_Memory m_session_manager; + + }; + class tls_server { public: @@ -242,7 +282,7 @@ class tls_server tcp::acceptor m_acceptor; Botan::AutoSeeded_RNG m_rng; - Botan::TLS::Session_Manager_In_Memory m_session_manager; + Session_Manager_Locked m_session_manager; Botan::TLS::Policy m_policy; Credentials_Manager_Simple m_creds; }; @@ -271,7 +311,7 @@ int main() std::cout << "Using " << num_threads << " threads\n"; - std::vector<boost::shared_ptr<boost::thread>> threads; + std::vector<boost::shared_ptr<boost::thread> > threads; for(size_t i = 0; i != num_threads; ++i) { diff --git a/doc/examples/credentials.h b/doc/examples/credentials.h index 8a0d47911..65d34aeee 100644 --- a/doc/examples/credentials.h +++ b/doc/examples/credentials.h @@ -6,6 +6,8 @@ #include <botan/x509self.h> #include <botan/rsa.h> #include <botan/dsa.h> +#include <botan/srp6.h> +#include <botan/srp6_files.h> #include <botan/ecdsa.h> #include <iostream> #include <fstream> @@ -25,6 +27,104 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager public: Credentials_Manager_Simple(Botan::RandomNumberGenerator& rng) : rng(rng) {} + std::string srp_identifier(const std::string& type, + const std::string& hostname) + { + if(type == "tls-client" && hostname == "srp-host") + return "user"; + return ""; + } + + bool attempt_srp(const std::string& type, + const std::string& hostname) + { + if(hostname == "srp-host") + return true; + return false; + } + + std::vector<Botan::X509_Certificate> + trusted_certificate_authorities(const std::string& type, + const std::string& hostname) + { + + std::vector<Botan::X509_Certificate> certs; + + try + { + Botan::X509_Certificate testca("testCA.crt"); + certs.push_back(testca); + } + + if(type == "tls-client" && hostname == "twitter.com") + { + Botan::X509_Certificate verisign("/usr/share/ca-certificates/mozilla/VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.crt"); + certs.push_back(verisign); + } + + return certs; + } + + void verify_certificate_chain( + const std::string& type, + const std::string& purported_hostname, + const std::vector<Botan::X509_Certificate>& cert_chain) + { + try + { + Botan::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"; + } + } + + std::string srp_password(const std::string& type, + const std::string& hostname, + const std::string& identifier) + { + if(type == "tls-client" && hostname == "localhost" && identifier == "user") + return "password"; + + return ""; + } + + bool srp_verifier(const std::string& type, + const std::string& context, + const std::string& identifier, + std::string& group_id, + Botan::BigInt& verifier, + Botan::MemoryRegion<Botan::byte>& salt, + bool generate_fake_on_unknown) + { + + std::string pass = srp_password("tls-client", context, identifier); + if(pass == "") + { + if(!generate_fake_on_unknown) + return false; + + pass.resize(16); + Botan::global_state().global_rng().randomize((Botan::byte*)&pass[0], pass.size()); + } + + group_id = "modp/srp/2048"; + + salt.resize(16); + Botan::global_state().global_rng().randomize(&salt[0], salt.size()); + + verifier = Botan::generate_srp6_verifier(identifier, + pass, + salt, + group_id, + "SHA-1"); + + return true; + } + std::string psk_identity_hint(const std::string&, const std::string&) { @@ -34,6 +134,7 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager std::string psk_identity(const std::string&, const std::string&, const std::string& identity_hint) { + //return "lloyd"; return "Client_identity"; } @@ -49,6 +150,8 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager if(identity == "Client_identity") return Botan::SymmetricKey("b5a72e1387552e6dc10766dc0eda12961f5b21e17f98ef4c41e6572e53bd7527"); + if(identity == "lloyd") + return Botan::SymmetricKey("85b3c1b7dc62b507636ac767999c9630"); throw Botan::Internal_Error("No PSK set for " + identity); } @@ -86,7 +189,7 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager opts.email = "root@" + hostname; opts.dns = hostname; - std::unique_ptr<Private_Key> key; + std::auto_ptr<Private_Key> key; if(key_type == "rsa") key.reset(new RSA_PrivateKey(rng, 1024)); else if(key_type == "dsa") @@ -129,6 +232,9 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager { const std::string hostname = (context == "" ? "localhost" : context); + if(hostname == "nosuchname") + return std::vector<Botan::X509_Certificate>(); + std::string key_name = ""; if(value_exists(cert_key_types, "RSA")) diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp index 7c921ce53..a787af1fe 100644 --- a/doc/examples/tls_client.cpp +++ b/doc/examples/tls_client.cpp @@ -24,7 +24,7 @@ using namespace Botan; -using namespace std::placeholders; +using namespace std::tr1::placeholders; int connect_to_host(const std::string& host, u16bit port) { @@ -125,7 +125,7 @@ void doit(RandomNumberGenerator& rng, { int sockfd = connect_to_host(host, port); - TLS::Client client(std::bind(socket_write, sockfd, _1, _2), + TLS::Client client(std::tr1::bind(socket_write, sockfd, _1, _2), process_data, handshake_complete, session_manager, @@ -188,7 +188,16 @@ void doit(RandomNumberGenerator& rng, continue; } - client.send(buf, got); + if(got == 2 && (buf[0] == 'R' || buf[0] == 'r') && buf[1] == '\n') + { + std::cout << "Client initiated renegotiation\n"; + client.renegotiate((buf[0] == 'R')); + } + + if(buf[0] == 'H') + client.heartbeat(&buf[1], got-1); + else + client.send(buf, got); } } diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp index 6bbcfd8b5..334d8f1fc 100644 --- a/doc/examples/tls_server.cpp +++ b/doc/examples/tls_server.cpp @@ -19,22 +19,11 @@ using namespace std::placeholders; #include <iostream> #include <memory> -bool handshake_complete(const TLS::Session& session) - { - printf("Handshake complete, protocol=%04X ciphersuite=%s compression=%d\n", - session.version(), session.ciphersuite().to_string().c_str(), - session.compression_method()); - - printf("Session id = %s\n", hex_encode(session.session_id()).c_str()); - printf("Master secret = %s\n", hex_encode(session.master_secret()).c_str()); - return true; - } - class Blocking_TLS_Server { public: - Blocking_TLS_Server(std::function<void (const byte[], size_t)> output_fn, - std::function<size_t (byte[], size_t)> input_fn, + Blocking_TLS_Server(std::tr1::function<void (const byte[], size_t)> output_fn, + std::tr1::function<size_t (byte[], size_t)> input_fn, std::vector<std::string>& protocols, TLS::Session_Manager& sessions, Credentials_Manager& creds, @@ -43,24 +32,47 @@ class Blocking_TLS_Server input_fn(input_fn), server( output_fn, - std::bind(&Blocking_TLS_Server::reader_fn, std::ref(*this), _1, _2, _3), - handshake_complete, + std::tr1::bind(&Blocking_TLS_Server::reader_fn, std::tr1::ref(*this), _1, _2, _3), + std::tr1::bind(&Blocking_TLS_Server::handshake_complete, std::tr1::ref(*this), _1), sessions, creds, policy, - rng), + rng, + protocols), exit(false) { read_loop(); } + bool handshake_complete(const TLS::Session& session) + { + std::cout << "Handshake complete: " + << session.version().to_string() << " " + << session.ciphersuite().to_string() << " " + << "SessionID: " << hex_encode(session.session_id()) << "\n"; + + if(session.srp_identifier() != "") + std::cout << "SRP identifier: " << session.srp_identifier() << "\n"; + + if(server.next_protocol() != "") + std::cout << "Next protocol: " << server.next_protocol() << "\n"; + + /* + std::vector<X509_Certificate> peer_certs = session.peer_certs(); + if(peer_certs.size()) + std::cout << peer_certs[0].to_string(); + */ + + return true; + } + size_t read(byte buf[], size_t buf_len) { size_t got = read_queue.read(buf, buf_len); while(!exit && !got) { - read_loop(5); // header size + read_loop(TLS::TLS_HEADER_SIZE); got = read_queue.read(buf, buf_len); } @@ -119,7 +131,7 @@ class Blocking_TLS_Server read_queue.write(buf, buf_len); } - std::function<size_t (byte[], size_t)> input_fn; + std::tr1::function<size_t (byte[], size_t)> input_fn; TLS::Server server; SecureQueue read_queue; bool exit; @@ -148,8 +160,14 @@ int main(int argc, char* argv[]) Credentials_Manager_Simple creds(rng); std::vector<std::string> protocols; - protocols.push_back("spdy/2"); - protocols.push_back("http/1.0"); + + /* + * These are the protocols we advertise to the client, but the + * client will send back whatever it actually plans on talking, + * which may or may not take into account what we advertise. + */ + protocols.push_back("echo/1.0"); + protocols.push_back("echo/1.1"); while(true) { @@ -161,8 +179,8 @@ int main(int argc, char* argv[]) printf("Got new connection\n"); Blocking_TLS_Server tls( - std::bind(&Socket::write, std::ref(sock), _1, _2), - std::bind(&Socket::read, std::ref(sock), _1, _2, true), + std::tr1::bind(&Socket::write, std::tr1::ref(sock), _1, _2), + std::tr1::bind(&Socket::read, std::tr1::ref(sock), _1, _2, true), protocols, sessions, creds, @@ -196,7 +214,9 @@ int main(int argc, char* argv[]) } if(line == "reneg\n") - tls.underlying().renegotiate(); + tls.underlying().renegotiate(false); + else if(line == "RENEG\n") + tls.underlying().renegotiate(true); line.clear(); } diff --git a/doc/log.txt b/doc/log.txt index 478b27a94..b1206637a 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -34,6 +34,9 @@ Version 1.10.2, Not Yet Released * Add Google's Native Client as an compile target +* The Qt mutex wrapper was broken and would not compile with any recent + version of Qt. It has been removed. + * If targetting GCC on a Windows system, configure.py will warn that likely you wanted to configure for either MinGW or Cygwin, not the generic Windows target which is oriented to Win32 plus the Visual diff --git a/doc/tls.txt b/doc/tls.txt index dd4fb1270..267fb6e62 100644 --- a/doc/tls.txt +++ b/doc/tls.txt @@ -7,14 +7,14 @@ SSL and TLS .. versionadded:: 1.10.2 Botan supports both client and server implementations of the SSL/TLS -protocols, including SSL v3, TLS v1.0, and TLS v1.1 (the insecure and -obsolete SSL v2 protocol is not supported, beyond processing SSL v2 -client hellos which some implementations send for backwards -compatability). - -The implementation uses ``std::tr1::function``, so it may not have -been compiled into the version you are using; you can test for the -feature macro ``BOTAN_HAS_TLS`` to check. +protocols, including SSL v3, TLS v1.0, TLS v1.1, and TLS v1.2 (the +insecure and obsolete SSL v2 protocol is not supported, beyond +processing SSL v2 client hellos which some clients still send for +backwards compatability with ancient servers). + +The implementation uses ``std::tr1::function`` for callbacks, so it +may not have been compiled into the version you are using; you can +test for the feature macro ``BOTAN_HAS_TLS`` to check. General TLS Interface ---------------------------------------- |