aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/examples/tls_client.cpp16
-rw-r--r--doc/examples/tls_server.cpp18
-rw-r--r--src/tls/c_kex.cpp2
-rw-r--r--src/tls/rec_read.cpp12
-rw-r--r--src/tls/rec_wri.cpp15
-rw-r--r--src/tls/tls_channel.cpp11
-rw-r--r--src/tls/tls_channel.h10
-rw-r--r--src/tls/tls_client.cpp11
-rw-r--r--src/tls/tls_client.h2
-rw-r--r--src/tls/tls_extensions.cpp1
-rw-r--r--src/tls/tls_messages.h2
-rw-r--r--src/tls/tls_record.h8
-rw-r--r--src/tls/tls_server.cpp23
-rw-r--r--src/tls/tls_server.h1
-rw-r--r--src/tls/tls_session_key.cpp2
-rw-r--r--src/tls/tls_session_key.h2
-rw-r--r--src/tls/tls_suites.cpp10
-rw-r--r--src/tls/tls_suites.h12
18 files changed, 118 insertions, 40 deletions
diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp
index 3fb7f10c6..be72a65e7 100644
--- a/doc/examples/tls_client.cpp
+++ b/doc/examples/tls_client.cpp
@@ -66,6 +66,16 @@ int connect_to_host(const std::string& host, u16bit port)
return fd;
}
+void handshake_complete(const TLS_Session_Params& session)
+ {
+ printf("Handshake complete, protocol=%04X ciphersuite=%04X compression=%d\n",
+ session.version(), session.ciphersuite(),
+ 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());
+ }
+
void socket_write(int sockfd, const byte buf[], size_t length)
{
size_t offset = 0;
@@ -123,6 +133,7 @@ int main(int argc, char* argv[])
TLS_Client client(std::tr1::bind(socket_write, sockfd, _1, _2),
process_data,
+ handshake_complete,
session_manager,
policy,
rng,
@@ -130,6 +141,8 @@ int main(int argc, char* argv[])
fd_set readfds;
+ bool version_reported = false;
+
while(true)
{
FD_ZERO(&readfds);
@@ -141,6 +154,9 @@ int main(int argc, char* argv[])
if(client.is_closed())
break;
+ if(client.is_active() && !version_reported)
+ printf("Negotiated version %04X\n", client.protocol_version());
+
if(FD_ISSET(sockfd, &readfds))
{
byte buf[1024] = { 0 };
diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp
index f43af1dcf..0710c35f9 100644
--- a/doc/examples/tls_server.cpp
+++ b/doc/examples/tls_server.cpp
@@ -15,6 +15,16 @@ using namespace Botan;
#include <iostream>
#include <memory>
+void handshake_complete(const TLS_Session_Params& session)
+ {
+ printf("Handshake complete, protocol=%04X ciphersuite=%04X compression=%d\n",
+ session.version(), session.ciphersuite(),
+ 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());
+ }
+
class Blocking_TLS_Server
{
public:
@@ -29,6 +39,7 @@ class Blocking_TLS_Server
server(
output_fn,
std::tr1::bind(&Blocking_TLS_Server::reader_fn, std::tr1::ref(*this), _1, _2, _3),
+ handshake_complete,
sessions,
policy,
rng,
@@ -146,7 +157,7 @@ int main(int argc, char* argv[])
//DSA_PrivateKey key(rng, DL_Group("dsa/jce/1024"));
X509_Cert_Options options(
- "localhost/US/Syn Ack Labs/Mathematical Munitions Dept");
+ "localhost/US/Botan Library/Test Server");
X509_Certificate cert =
X509::create_self_signed_cert(options, key, "SHA-1", rng);
@@ -199,9 +210,14 @@ int main(int argc, char* argv[])
break;
}
+ if(line == "reneg\n")
+ tls.underlying().renegotiate();
+
line.clear();
}
}
+
+ delete sock;
}
catch(std::exception& e) { printf("Connection problem: %s\n", e.what()); }
}
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp
index 341ae1e14..48d76d1e6 100644
--- a/src/tls/c_kex.cpp
+++ b/src/tls/c_kex.cpp
@@ -61,7 +61,7 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer,
* Read a Client Key Exchange message
*/
Client_Key_Exchange::Client_Key_Exchange(const MemoryRegion<byte>& contents,
- const CipherSuite& suite,
+ const TLS_Cipher_Suite& suite,
Version_Code using_version)
{
include_length = true;
diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp
index 63c08cad5..f6cc1057d 100644
--- a/src/tls/rec_read.cpp
+++ b/src/tls/rec_read.cpp
@@ -42,9 +42,19 @@ void Record_Reader::set_version(Version_Code version)
}
/*
+* Get the version in use
+*/
+Version_Code Record_Reader::get_version() const
+ {
+ return static_cast<Version_Code>(
+ (static_cast<u16bit>(major) << 8) | minor);
+ }
+
+/*
* Set the keys for reading
*/
-void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys,
+void Record_Reader::activate(const TLS_Cipher_Suite& suite,
+ const SessionKeys& keys,
Connection_Side side)
{
cipher.reset();
diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp
index a9a5b4549..9af48b4ee 100644
--- a/src/tls/rec_wri.cpp
+++ b/src/tls/rec_wri.cpp
@@ -14,8 +14,6 @@
#include <botan/loadstor.h>
#include <botan/libstate.h>
-#include <stdio.h>
-
namespace Botan {
/*
@@ -34,8 +32,6 @@ void Record_Writer::set_maximum_fragment_size(size_t max_fragment)
m_max_fragment = MAX_PLAINTEXT_SIZE;
else
m_max_fragment = clamp(max_fragment, 128, MAX_PLAINTEXT_SIZE);
-
- printf("Setting max fragment size to %d\n", m_max_fragment);
}
/*
@@ -70,9 +66,18 @@ void Record_Writer::set_version(Version_Code version)
}
/*
+* Get the version in use
+*/
+Version_Code Record_Writer::get_version() const
+ {
+ return static_cast<Version_Code>(
+ (static_cast<u16bit>(m_major) << 8) | m_minor);
+ }
+
+/*
* Set the keys for writing
*/
-void Record_Writer::set_keys(const CipherSuite& suite,
+void Record_Writer::activate(const TLS_Cipher_Suite& suite,
const SessionKeys& keys,
Connection_Side side)
{
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index 3831a6792..0e119c2a3 100644
--- a/src/tls/tls_channel.cpp
+++ b/src/tls/tls_channel.cpp
@@ -13,8 +13,10 @@
namespace Botan {
TLS_Channel::TLS_Channel(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
- std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn) :
+ std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_complete) :
proc_fn(proc_fn),
+ handshake_fn(handshake_complete),
writer(socket_output_fn),
state(0),
handshake_completed(false),
@@ -29,6 +31,13 @@ TLS_Channel::~TLS_Channel()
state = 0;
}
+Version_Code TLS_Channel::protocol_version() const
+ {
+ if(!handshake_completed)
+ throw std::logic_error("Version not known until handshake complete");
+ return writer.get_version();
+ }
+
size_t TLS_Channel::received_data(const byte buf[], size_t buf_size)
{
try
diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h
index 52036c78d..4b5a91a65 100644
--- a/src/tls/tls_channel.h
+++ b/src/tls/tls_channel.h
@@ -10,6 +10,7 @@
#include <botan/tls_policy.h>
#include <botan/tls_record.h>
+#include <botan/tls_session_state.h>
#include <botan/x509cert.h>
#include <vector>
@@ -56,6 +57,11 @@ class BOTAN_DLL TLS_Channel
bool is_closed() const { return connection_closed; }
/**
+ * Return the negotiated version (if session is currently active)
+ */
+ Version_Code protocol_version() const;
+
+ /**
* Attempt to renegotiate the session
*/
virtual void renegotiate() = 0;
@@ -66,7 +72,8 @@ class BOTAN_DLL TLS_Channel
std::vector<X509_Certificate> peer_cert_chain() const { return peer_certs; }
TLS_Channel(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
- std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn);
+ std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_complete);
virtual ~TLS_Channel();
protected:
@@ -77,6 +84,7 @@ class BOTAN_DLL TLS_Channel
const MemoryRegion<byte>& contents) = 0;
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn;
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_fn;
Record_Writer writer;
Record_Reader reader;
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index bd6b66ba0..5dbf9dc9c 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -19,17 +19,18 @@ namespace Botan {
*/
TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_fn,
TLS_Session_Manager& session_manager,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
const std::string& hostname,
const std::string& srp_username) :
- TLS_Channel(output_fn, proc_fn),
+ TLS_Channel(output_fn, proc_fn, handshake_fn),
policy(policy),
rng(rng),
session_manager(session_manager)
{
- writer.set_version(policy.pref_version());
+ writer.set_version(SSL_V3);
state = new Handshake_State;
state->set_expected_next(SERVER_HELLO);
@@ -146,7 +147,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
secure_renegotiation.update(state->server_hello);
- state->suite = CipherSuite(state->server_hello->ciphersuite());
+ state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite());
// if resuming, next is HANDSHAKE_CCS
@@ -284,7 +285,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
writer.send(CHANGE_CIPHER_SPEC, 1);
- writer.set_keys(state->suite, state->keys, CLIENT);
+ writer.activate(state->suite, state->keys, CLIENT);
state->client_finished = new Finished(writer, state->hash,
state->version, CLIENT,
@@ -294,7 +295,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
{
state->set_expected_next(FINISHED);
- reader.set_keys(state->suite, state->keys, CLIENT);
+ reader.activate(state->suite, state->keys, CLIENT);
}
else if(type == FINISHED)
{
diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h
index 279f4bc16..e2623015a 100644
--- a/src/tls/tls_client.h
+++ b/src/tls/tls_client.h
@@ -24,6 +24,7 @@ class BOTAN_DLL TLS_Client : public TLS_Channel
* Set up a new TLS client session
* @param socket_output_fn is called with data for the outbound socket
* @param proc_fn is called when new data (application or alerts) is received
+ * @param handshake_complete is called when a handshake is completed
* @param session_manager manages session resumption
* @param policy specifies other connection policy information
* @param rng a random number generator
@@ -32,6 +33,7 @@ class BOTAN_DLL TLS_Client : public TLS_Channel
*/
TLS_Client(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_complete,
TLS_Session_Manager& session_manager,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp
index b793971c5..a08597d21 100644
--- a/src/tls/tls_extensions.cpp
+++ b/src/tls/tls_extensions.cpp
@@ -7,6 +7,7 @@
#include <botan/internal/tls_extensions.h>
#include <botan/internal/tls_reader.h>
+#include <botan/tls_exceptn.h>
namespace Botan {
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 8f9195412..2d66dfa11 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -196,7 +196,7 @@ class Client_Key_Exchange : public HandshakeMessage
Version_Code pref_version);
Client_Key_Exchange(const MemoryRegion<byte>& buf,
- const CipherSuite& suite,
+ const TLS_Cipher_Suite& suite,
Version_Code using_version);
private:
MemoryVector<byte> serialize() const;
diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h
index 55cb66034..be9fe6e73 100644
--- a/src/tls/tls_record.h
+++ b/src/tls/tls_record.h
@@ -45,12 +45,14 @@ class BOTAN_DLL Record_Writer
void alert(Alert_Level level, Alert_Type type);
- void set_keys(const CipherSuite& suite,
+ void activate(const TLS_Cipher_Suite& suite,
const SessionKeys& keys,
Connection_Side side);
void set_version(Version_Code version);
+ Version_Code get_version() const;
+
void reset();
void set_maximum_fragment_size(size_t max_fragment);
@@ -90,12 +92,14 @@ class BOTAN_DLL Record_Reader
SecureVector<byte> get_record(byte& msg_type);
- void set_keys(const CipherSuite& suite,
+ void activate(const TLS_Cipher_Suite& suite,
const SessionKeys& keys,
Connection_Side side);
void set_version(Version_Code version);
+ Version_Code get_version() const;
+
void reset();
bool currently_empty() const { return input_queue.size() == 0; }
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 3077476e3..f5efa10e4 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -39,7 +39,7 @@ bool check_for_resume(TLS_Session_Params& session_info,
if(client_session_id.empty()) // not resuming
return false;
- // wrong side
+ // not found
if(!session_manager.find(client_session_id, session_info))
return false;
@@ -81,18 +81,17 @@ bool check_for_resume(TLS_Session_Params& session_info,
*/
TLS_Server::TLS_Server(std::tr1::function<void (const byte[], size_t)> output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_fn,
TLS_Session_Manager& session_manager,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
const X509_Certificate& cert,
const Private_Key& cert_key) :
- TLS_Channel(output_fn, proc_fn),
+ TLS_Channel(output_fn, proc_fn, handshake_fn),
policy(policy),
rng(rng),
session_manager(session_manager)
{
- writer.set_version(TLS_V10);
-
cert_chain.push_back(cert);
private_key = PKCS8::copy_key(cert_key, rng);
}
@@ -196,7 +195,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
if(session_info.fragment_size())
writer.set_maximum_fragment_size(session_info.fragment_size());
- state->suite = CipherSuite(state->server_hello->ciphersuite());
+ state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite());
state->keys = SessionKeys(state->suite, state->version,
session_info.master_secret(),
@@ -206,12 +205,15 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
writer.send(CHANGE_CIPHER_SPEC, 1);
- writer.set_keys(state->suite, state->keys, SERVER);
+ writer.activate(state->suite, state->keys, SERVER);
state->server_finished = new Finished(writer, state->hash,
state->version, SERVER,
state->keys.master_secret());
+ if(handshake_fn)
+ handshake_fn(session_info);
+
state->set_expected_next(HANDSHAKE_CCS);
}
else // new session
@@ -231,7 +233,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
if(state->client_hello->fragment_size())
writer.set_maximum_fragment_size(state->client_hello->fragment_size());
- state->suite = CipherSuite(state->server_hello->ciphersuite());
+ state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite());
if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON)
{
@@ -345,7 +347,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
{
state->set_expected_next(FINISHED);
- reader.set_keys(state->suite, state->keys, SERVER);
+ reader.activate(state->suite, state->keys, SERVER);
}
else if(type == FINISHED)
{
@@ -365,7 +367,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
writer.send(CHANGE_CIPHER_SPEC, 1);
- writer.set_keys(state->suite, state->keys, SERVER);
+ writer.activate(state->suite, state->keys, SERVER);
state->server_finished = new Finished(writer, state->hash,
state->version, SERVER,
@@ -391,6 +393,9 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
);
session_manager.save(session_info);
+
+ if(handshake_fn)
+ handshake_fn(session_info);
}
secure_renegotiation.update(state->client_finished,
diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h
index 45e25f0f9..16c6f8e3e 100644
--- a/src/tls/tls_server.h
+++ b/src/tls/tls_server.h
@@ -29,6 +29,7 @@ class BOTAN_DLL TLS_Server : public TLS_Channel
*/
TLS_Server(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
+ std::tr1::function<void (const TLS_Session_Params&)> handshake_complete,
TLS_Session_Manager& session_manager,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp
index 43118d921..f0ddc4493 100644
--- a/src/tls/tls_session_key.cpp
+++ b/src/tls/tls_session_key.cpp
@@ -28,7 +28,7 @@ std::string lookup_prf_name(Version_Code version)
/**
* SessionKeys Constructor
*/
-SessionKeys::SessionKeys(const CipherSuite& suite,
+SessionKeys::SessionKeys(const TLS_Cipher_Suite& suite,
Version_Code version,
const MemoryRegion<byte>& pre_master_secret,
const MemoryRegion<byte>& client_random,
diff --git a/src/tls/tls_session_key.h b/src/tls/tls_session_key.h
index 76cb7e3e1..a698dfcfc 100644
--- a/src/tls/tls_session_key.h
+++ b/src/tls/tls_session_key.h
@@ -33,7 +33,7 @@ class SessionKeys
SessionKeys() {}
- SessionKeys(const CipherSuite& suite,
+ SessionKeys(const TLS_Cipher_Suite& suite,
Version_Code version,
const MemoryRegion<byte>& pre_master,
const MemoryRegion<byte>& client_random,
diff --git a/src/tls/tls_suites.cpp b/src/tls/tls_suites.cpp
index 8dbd74e4e..aff15d68f 100644
--- a/src/tls/tls_suites.cpp
+++ b/src/tls/tls_suites.cpp
@@ -13,7 +13,7 @@ namespace Botan {
/**
* Convert an SSL/TLS ciphersuite to algorithm fields
*/
-TLS_Ciphersuite_Algos CipherSuite::lookup_ciphersuite(u16bit suite)
+TLS_Ciphersuite_Algos TLS_Cipher_Suite::lookup_ciphersuite(u16bit suite)
{
if(suite == TLS_RSA_WITH_RC4_128_MD5)
return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
@@ -274,7 +274,7 @@ std::pair<std::string, size_t> cipher_code_to_name(TLS_Ciphersuite_Algos algo)
return std::make_pair("SEED", 16);
throw TLS_Exception(INTERNAL_ERROR,
- "CipherSuite: Unknown cipher type " + to_string(algo));
+ "TLS_Cipher_Suite: Unknown cipher type " + to_string(algo));
}
std::string mac_code_to_name(TLS_Ciphersuite_Algos algo)
@@ -292,15 +292,15 @@ std::string mac_code_to_name(TLS_Ciphersuite_Algos algo)
return "SHA-384";
throw TLS_Exception(INTERNAL_ERROR,
- "CipherSuite: Unknown MAC type " + to_string(algo));
+ "TLS_Cipher_Suite: Unknown MAC type " + to_string(algo));
}
}
/**
-* CipherSuite Constructor
+* TLS_Cipher_Suite Constructor
*/
-CipherSuite::CipherSuite(u16bit suite_code)
+TLS_Cipher_Suite::TLS_Cipher_Suite(u16bit suite_code)
{
if(suite_code == 0)
return;
diff --git a/src/tls/tls_suites.h b/src/tls/tls_suites.h
index 8d6db0e8b..3256dc198 100644
--- a/src/tls/tls_suites.h
+++ b/src/tls/tls_suites.h
@@ -1,12 +1,12 @@
/*
-* Cipher Suites
-* (C) 2004-2010 Jack Lloyd
+* TLS Cipher Suites
+* (C) 2004-2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
-#ifndef BOTAN_TLS_CIPHERSUITES_H__
-#define BOTAN_TLS_CIPHERSUITES_H__
+#ifndef BOTAN_TLS_CIPHER_SUITES_H__
+#define BOTAN_TLS_CIPHER_SUITES_H__
#include <botan/types.h>
#include <botan/tls_magic.h>
@@ -17,7 +17,7 @@ namespace Botan {
/**
* Ciphersuite Information
*/
-class BOTAN_DLL CipherSuite
+class BOTAN_DLL TLS_Cipher_Suite
{
public:
static TLS_Ciphersuite_Algos lookup_ciphersuite(u16bit suite);
@@ -30,7 +30,7 @@ class BOTAN_DLL CipherSuite
TLS_Ciphersuite_Algos kex_type() const { return kex_algo; }
TLS_Ciphersuite_Algos sig_type() const { return sig_algo; }
- CipherSuite(u16bit = 0);
+ TLS_Cipher_Suite(u16bit ciphersuite_code = 0);
private:
TLS_Ciphersuite_Algos kex_algo, sig_algo;
std::string cipher, mac;