aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tls/info.txt2
-rw-r--r--src/tls/tls_channel.cpp188
-rw-r--r--src/tls/tls_channel.h85
-rw-r--r--src/tls/tls_client.cpp190
-rw-r--r--src/tls/tls_client.h46
-rw-r--r--src/tls/tls_server.cpp235
-rw-r--r--src/tls/tls_server.h45
7 files changed, 308 insertions, 483 deletions
diff --git a/src/tls/info.txt b/src/tls/info.txt
index 1170fef45..f09309bd2 100644
--- a/src/tls/info.txt
+++ b/src/tls/info.txt
@@ -8,6 +8,7 @@ serious bugs or security issues.
uses_tr1 yes
<header:public>
+tls_channel.h
tls_client.h
tls_exceptn.h
tls_magic.h
@@ -36,6 +37,7 @@ hello.cpp
rec_read.cpp
rec_wri.cpp
s_kex.cpp
+tls_channel.cpp
tls_client.cpp
tls_policy.cpp
tls_server.cpp
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
new file mode 100644
index 000000000..580c1e5e5
--- /dev/null
+++ b/src/tls/tls_channel.cpp
@@ -0,0 +1,188 @@
+/*
+* TLS Channels
+* (C) 2011 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#include <botan/tls_channel.h>
+#include <botan/internal/tls_alerts.h>
+#include <botan/internal/tls_state.h>
+#include <botan/loadstor.h>
+
+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) :
+ proc_fn(proc_fn),
+ writer(socket_output_fn),
+ state(0),
+ active(false)
+ {
+ }
+
+TLS_Channel::~TLS_Channel()
+ {
+ close();
+ delete state;
+ state = 0;
+ }
+
+size_t TLS_Channel::received_data(const byte buf[], size_t buf_size)
+ {
+ try
+ {
+ reader.add_input(buf, buf_size);
+
+ byte rec_type = CONNECTION_CLOSED;
+ SecureVector<byte> record;
+
+ while(!reader.currently_empty())
+ {
+ const size_t bytes_needed = reader.get_record(rec_type, record);
+
+ if(bytes_needed > 0)
+ return bytes_needed;
+
+ if(rec_type == APPLICATION_DATA)
+ {
+ if(active)
+ {
+ proc_fn(&record[0], record.size(), NO_ALERT_TYPE);
+ }
+ else
+ {
+ throw Unexpected_Message("Application data before handshake done");
+ }
+ }
+ else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
+ {
+ read_handshake(rec_type, record);
+ }
+ else if(rec_type == ALERT)
+ {
+ Alert alert_msg(record);
+
+ proc_fn(0, 0, alert_msg.type());
+
+ if(alert_msg.is_fatal() || alert_msg.type() == CLOSE_NOTIFY)
+ {
+ if(alert_msg.type() == CLOSE_NOTIFY)
+ {
+ writer.alert(WARNING, CLOSE_NOTIFY);
+ }
+
+ alert(FATAL, NO_ALERT_TYPE);
+ }
+ }
+ else
+ throw Unexpected_Message("Unknown message type received");
+ }
+
+ return 0; // on a record boundary
+ }
+ catch(TLS_Exception& e)
+ {
+ alert(FATAL, e.type());
+ throw;
+ }
+ catch(std::exception& e)
+ {
+ alert(FATAL, INTERNAL_ERROR);
+ throw;
+ }
+ }
+
+/*
+* Split up and process handshake messages
+*/
+void TLS_Channel::read_handshake(byte rec_type,
+ const MemoryRegion<byte>& rec_buf)
+ {
+ if(rec_type == HANDSHAKE)
+ state->queue.write(&rec_buf[0], rec_buf.size());
+
+ while(true)
+ {
+ Handshake_Type type = HANDSHAKE_NONE;
+ SecureVector<byte> contents;
+
+ if(rec_type == HANDSHAKE)
+ {
+ if(state->queue.size() >= 4)
+ {
+ byte head[4] = { 0 };
+ state->queue.peek(head, 4);
+
+ const size_t length = make_u32bit(0, head[1], head[2], head[3]);
+
+ if(state->queue.size() >= length + 4)
+ {
+ type = static_cast<Handshake_Type>(head[0]);
+ contents.resize(length);
+ state->queue.read(head, 4);
+ state->queue.read(&contents[0], contents.size());
+ }
+ }
+ }
+ else if(rec_type == CHANGE_CIPHER_SPEC)
+ {
+ if(state->queue.size() == 0 && rec_buf.size() == 1 && rec_buf[0] == 1)
+ type = HANDSHAKE_CCS;
+ else
+ throw Decoding_Error("Malformed ChangeCipherSpec message");
+ }
+ else
+ throw Decoding_Error("Unknown message type in handshake processing");
+
+ if(type == HANDSHAKE_NONE)
+ break;
+
+ process_handshake_msg(type, contents);
+
+ if(type == HANDSHAKE_CCS || !state)
+ break;
+ }
+ }
+
+void TLS_Channel::queue_for_sending(const byte buf[], size_t buf_size)
+ {
+ if(active)
+ {
+ while(!pre_handshake_write_queue.end_of_data())
+ {
+ SecureVector<byte> q_buf(1024);
+ const size_t got = pre_handshake_write_queue.read(&q_buf[0], q_buf.size());
+ writer.send(APPLICATION_DATA, &q_buf[0], got);
+ }
+
+ writer.send(APPLICATION_DATA, buf, buf_size);
+ writer.flush();
+ }
+ else
+ pre_handshake_write_queue.write(buf, buf_size);
+ }
+
+void TLS_Channel::alert(Alert_Level level, Alert_Type alert_code)
+ {
+ if(active && alert_code != NO_ALERT_TYPE)
+ {
+ try
+ {
+ writer.alert(level, alert_code);
+ writer.flush();
+ }
+ catch(...) { /* swallow it */ }
+ }
+
+ if(active && level == FATAL)
+ {
+ reader.reset();
+ writer.reset();
+ delete state;
+ state = 0;
+ active = false;
+ }
+ }
+
+}
diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h
new file mode 100644
index 000000000..d74504ccd
--- /dev/null
+++ b/src/tls/tls_channel.h
@@ -0,0 +1,85 @@
+/*
+* TLS Channel
+* (C) 2011 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TLS_CHANNEL_H__
+#define BOTAN_TLS_CHANNEL_H__
+
+#include <botan/tls_policy.h>
+#include <botan/tls_record.h>
+#include <botan/x509cert.h>
+#include <vector>
+
+namespace Botan {
+
+/**
+* Generic interface for TLS endpoint
+*/
+class BOTAN_DLL TLS_Channel
+ {
+ public:
+ /**
+ * Inject TLS traffic received from counterparty
+
+ * @return a hint as the how many more bytes we need to process the
+ current record (this may be 0 if on a record boundary)
+ */
+ virtual size_t received_data(const byte buf[], size_t buf_size);
+
+ /**
+ * Inject plaintext intended for counterparty
+ */
+ virtual void queue_for_sending(const byte buf[], size_t buf_size);
+
+ /**
+ * Send a close notification alert
+ */
+ void close() { alert(WARNING, CLOSE_NOTIFY); }
+
+ /**
+ * Send a TLS alert message. If the alert is fatal, the
+ * internal state (keys, etc) will be reset
+ */
+ void alert(Alert_Level level, Alert_Type type);
+
+ /**
+ * Is the connection active?
+ */
+ bool is_active() const { return active; }
+
+ /**
+ * Return the certificates of the peer
+ */
+ 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);
+
+ virtual ~TLS_Channel();
+ protected:
+ virtual void read_handshake(byte rec_type,
+ const MemoryRegion<byte>& rec_buf);
+
+ virtual void process_handshake_msg(Handshake_Type type,
+ const MemoryRegion<byte>& contents) = 0;
+
+ std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn;
+
+ Record_Writer writer;
+ Record_Reader reader;
+
+ SecureQueue pre_handshake_write_queue;
+
+ std::vector<X509_Certificate> peer_certs;
+
+ class Handshake_State* state;
+
+ bool active;
+ };
+
+}
+
+#endif
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index cfa86881c..30c440d29 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -6,9 +6,7 @@
*/
#include <botan/tls_client.h>
-#include <botan/internal/tls_alerts.h>
#include <botan/internal/tls_state.h>
-#include <botan/loadstor.h>
#include <botan/rsa.h>
#include <botan/dsa.h>
#include <botan/dh.h>
@@ -17,7 +15,7 @@ namespace Botan {
namespace {
-/**
+/*
* Verify the state transition is allowed
* FIXME: checks are wrong for session reuse (add a flag for that)
*/
@@ -78,19 +76,16 @@ void client_check_state(Handshake_Type new_msg, Handshake_State* state)
}
-/**
+/*
* TLS Client Constructor
*/
-TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
- std::tr1::function<void (const byte[], size_t, u16bit)> process_fn,
+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,
const TLS_Policy& policy,
RandomNumberGenerator& rng) :
+ TLS_Channel(output_fn, proc_fn),
policy(policy),
- rng(rng),
- proc_fn(process_fn),
- writer(socket_output_fn),
- state(0),
- active(false)
+ rng(rng)
{
writer.set_version(policy.pref_version());
@@ -104,185 +99,16 @@ void TLS_Client::add_client_cert(const X509_Certificate& cert,
certs.push_back(std::make_pair(cert, cert_key));
}
-/**
+/*
* TLS Client Destructor
*/
TLS_Client::~TLS_Client()
{
- close();
for(size_t i = 0; i != certs.size(); i++)
delete certs[i].second;
- delete state;
- }
-
-size_t TLS_Client::received_data(const byte buf[], size_t buf_size)
- {
- try
- {
- reader.add_input(buf, buf_size);
-
- byte rec_type = CONNECTION_CLOSED;
- SecureVector<byte> record;
-
- while(!reader.currently_empty())
- {
- const size_t bytes_needed = reader.get_record(rec_type, record);
-
- if(bytes_needed > 0)
- return bytes_needed;
-
- if(rec_type == APPLICATION_DATA)
- {
- if(active)
- {
- proc_fn(&record[0], record.size(), NO_ALERT_TYPE);
- }
- else
- {
- throw Unexpected_Message("Application data before handshake done");
- }
- }
- else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
- {
- read_handshake(rec_type, record);
- }
- else if(rec_type == ALERT)
- {
- Alert alert(record);
-
- proc_fn(0, 0, alert.type());
-
- if(alert.is_fatal() || alert.type() == CLOSE_NOTIFY)
- {
- if(alert.type() == CLOSE_NOTIFY)
- {
- writer.alert(WARNING, CLOSE_NOTIFY);
- }
-
- close(FATAL, NO_ALERT_TYPE);
- }
- }
- else
- throw Unexpected_Message("Unknown message type received");
- }
-
- return 0; // on a record boundary
- }
- catch(TLS_Exception& e)
- {
- close(FATAL, e.type());
- throw;
- }
- catch(std::exception& e)
- {
- close(FATAL, INTERNAL_ERROR);
- throw;
- }
- }
-
-void TLS_Client::queue_for_sending(const byte buf[], size_t buf_size)
- {
- if(active)
- {
- while(!pre_handshake_write_queue.end_of_data())
- {
- SecureVector<byte> q_buf(1024);
- const size_t got = pre_handshake_write_queue.read(&q_buf[0], q_buf.size());
- writer.send(APPLICATION_DATA, &q_buf[0], got);
- }
-
- writer.send(APPLICATION_DATA, buf, buf_size);
- writer.flush();
- }
- else
- pre_handshake_write_queue.write(buf, buf_size);
- }
-
-/**
-* Close a TLS connection
-*/
-void TLS_Client::close()
- {
- close(WARNING, CLOSE_NOTIFY);
}
-/**
-* Close a TLS connection
-*/
-void TLS_Client::close(Alert_Level level, Alert_Type alert_code)
- {
- if(active)
- {
- active = false;
-
- if(alert_code != NO_ALERT_TYPE)
- {
- try
- {
- writer.alert(level, alert_code);
- writer.flush();
- }
- catch(...) { /* swallow it */ }
- }
-
- reader.reset();
- writer.reset();
- }
- }
-
-/**
-* Split up and process handshake messages
-*/
-void TLS_Client::read_handshake(byte rec_type,
- const MemoryRegion<byte>& rec_buf)
- {
- if(rec_type == HANDSHAKE)
- state->queue.write(&rec_buf[0], rec_buf.size());
-
- while(true)
- {
- Handshake_Type type = HANDSHAKE_NONE;
- SecureVector<byte> contents;
-
- if(rec_type == HANDSHAKE)
- {
- if(state->queue.size() >= 4)
- {
- byte head[4] = { 0 };
- state->queue.peek(head, 4);
-
- const size_t length = make_u32bit(0, head[1], head[2], head[3]);
-
- if(state->queue.size() >= length + 4)
- {
- type = static_cast<Handshake_Type>(head[0]);
- contents.resize(length);
- state->queue.read(head, 4);
- state->queue.read(&contents[0], contents.size());
- }
- }
- }
- else if(rec_type == CHANGE_CIPHER_SPEC)
- {
- if(state->queue.size() == 0 && rec_buf.size() == 1 && rec_buf[0] == 1)
- type = HANDSHAKE_CCS;
- else
- throw Decoding_Error("Malformed ChangeCipherSpec message");
- }
- else
- throw Decoding_Error("Unknown message type in handshake processing");
-
- if(type == HANDSHAKE_NONE)
- break;
-
- process_handshake_msg(type, contents);
-
- if(type == HANDSHAKE_CCS || !state)
- break;
- }
- }
-
-/**
+/*
* Process a handshake message
*/
void TLS_Client::process_handshake_msg(Handshake_Type type,
diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h
index 6d613be33..063323c8b 100644
--- a/src/tls/tls_client.h
+++ b/src/tls/tls_client.h
@@ -8,17 +8,15 @@
#ifndef BOTAN_TLS_CLIENT_H__
#define BOTAN_TLS_CLIENT_H__
-#include <botan/tls_policy.h>
-#include <botan/tls_record.h>
+#include <botan/tls_channel.h>
#include <vector>
-#include <string>
namespace Botan {
/**
* SSL/TLS Client
*/
-class BOTAN_DLL TLS_Client
+class BOTAN_DLL TLS_Client : public TLS_Channel
{
public:
/**
@@ -29,57 +27,17 @@ class BOTAN_DLL TLS_Client
const TLS_Policy& policy,
RandomNumberGenerator& rng);
- /**
- * Inject TLS traffic received from counterparty
-
- * @return a hint as the how many more bytes we need to process the
- current record (this may be 0 if on a record boundary)
- */
- size_t received_data(const byte buf[], size_t buf_size);
-
- /**
- * Inject plaintext intended for counterparty
- */
- void queue_for_sending(const byte buf[], size_t buf_size);
-
- void close();
-
- bool handshake_complete() const { return active; }
-
- std::vector<X509_Certificate> peer_cert_chain() const { return peer_certs; }
-
void add_client_cert(const X509_Certificate& cert,
Private_Key* cert_key);
~TLS_Client();
private:
- void close(Alert_Level, Alert_Type);
-
- size_t get_pending_socket_input(byte output[], size_t length);
-
- void initialize();
- void do_handshake();
-
- void state_machine();
- void read_handshake(byte, const MemoryRegion<byte>&);
void process_handshake_msg(Handshake_Type, const MemoryRegion<byte>&);
const TLS_Policy& policy;
RandomNumberGenerator& rng;
- std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn;
-
- Record_Writer writer;
- Record_Reader reader;
-
- SecureQueue pre_handshake_write_queue;
-
- std::vector<X509_Certificate> peer_certs;
std::vector<std::pair<X509_Certificate, Private_Key*> > certs;
-
- class Handshake_State* state;
- //SecureVector<byte> session_id;
- bool active;
};
}
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 8964be3d7..81ed2c48e 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -1,6 +1,6 @@
/*
* TLS Server
-* (C) 2004-2010 Jack Lloyd
+* (C) 2004-2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -85,40 +85,20 @@ void server_check_state(Handshake_Type new_msg, Handshake_State* state)
/*
* TLS Server Constructor
*/
-TLS_Server::TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn,
- std::tr1::function<void (const byte[], size_t)> output_fn,
+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,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
const X509_Certificate& cert,
const Private_Key& cert_key) :
- input_fn(input_fn),
+ TLS_Channel(output_fn, proc_fn),
policy(policy),
- rng(rng),
- writer(output_fn)
+ rng(rng)
{
- state = 0;
+ writer.set_version(TLS_V10);
cert_chain.push_back(cert);
private_key = PKCS8::copy_key(cert_key, rng);
-
- try {
- active = false;
- writer.set_version(TLS_V10);
- do_handshake();
- active = true;
- }
- catch(std::exception& e)
- {
- if(state)
- {
- delete state;
- state = 0;
- }
-
- writer.alert(FATAL, HANDSHAKE_FAILURE);
- throw Stream_IO_Error(std::string("TLS_Server: Handshake failed: ") +
- e.what());
- }
}
/*
@@ -126,143 +106,7 @@ TLS_Server::TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn,
*/
TLS_Server::~TLS_Server()
{
- close();
delete private_key;
- delete state;
- }
-
-/*
-* Return the peer's certificate chain
-*/
-std::vector<X509_Certificate> TLS_Server::peer_cert_chain() const
- {
- return peer_certs;
- }
-
-/*
-* Write to a TLS connection
-*/
-void TLS_Server::write(const byte buf[], size_t length)
- {
- if(!active)
- throw Internal_Error("TLS_Server::write called while closed");
-
- writer.send(APPLICATION_DATA, buf, length);
- }
-
-/*
-* Read from a TLS connection
-*/
-size_t TLS_Server::read(byte out[], size_t length)
- {
- if(!active)
- throw Internal_Error("TLS_Server::read called while closed");
-
- writer.flush();
-
- while(read_buf.size() == 0)
- {
- state_machine();
- if(active == false)
- break;
- }
-
- size_t got = std::min<size_t>(read_buf.size(), length);
- read_buf.read(out, got);
- return got;
- }
-
-/*
-* Check connection status
-*/
-bool TLS_Server::is_closed() const
- {
- if(!active)
- return true;
- return false;
- }
-
-/*
-* Close a TLS connection
-*/
-void TLS_Server::close()
- {
- close(WARNING, CLOSE_NOTIFY);
- }
-
-/*
-* Close a TLS connection
-*/
-void TLS_Server::close(Alert_Level level, Alert_Type alert_code)
- {
- if(active)
- {
- try {
- active = false;
- writer.alert(level, alert_code);
- writer.flush();
- }
- catch(...) {}
- }
- }
-
-/*
-* Iterate the TLS state machine
-*/
-void TLS_Server::state_machine()
- {
- byte rec_type = CONNECTION_CLOSED;
- SecureVector<byte> record(1024);
-
- size_t bytes_needed = reader.get_record(rec_type, record);
-
- while(bytes_needed)
- {
- size_t to_get = std::min<size_t>(record.size(), bytes_needed);
- size_t got = input_fn(&record[0], to_get);
-
- if(got == 0)
- {
- rec_type = CONNECTION_CLOSED;
- break;
- }
-
- reader.add_input(&record[0], got);
-
- bytes_needed = reader.get_record(rec_type, record);
- }
-
- if(rec_type == CONNECTION_CLOSED)
- {
- active = false;
- reader.reset();
- writer.reset();
- }
- else if(rec_type == APPLICATION_DATA)
- {
- if(active)
- read_buf.write(&record[0], record.size());
- else
- throw Unexpected_Message("Application data before handshake done");
- }
- else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
- read_handshake(rec_type, record);
- else if(rec_type == ALERT)
- {
- Alert alert(record);
-
- if(alert.is_fatal() || alert.type() == CLOSE_NOTIFY)
- {
- if(alert.type() == CLOSE_NOTIFY)
- writer.alert(WARNING, CLOSE_NOTIFY);
-
- reader.reset();
- writer.reset();
- active = false;
- }
- }
- else
- throw Unexpected_Message("Unknown message type received");
}
/*
@@ -271,54 +115,10 @@ void TLS_Server::state_machine()
void TLS_Server::read_handshake(byte rec_type,
const MemoryRegion<byte>& rec_buf)
{
- if(rec_type == HANDSHAKE)
- {
- if(!state)
- state = new Handshake_State;
- state->queue.write(&rec_buf[0], rec_buf.size());
- }
-
- while(true)
- {
- Handshake_Type type = HANDSHAKE_NONE;
- SecureVector<byte> contents;
-
- if(rec_type == HANDSHAKE)
- {
- if(state->queue.size() >= 4)
- {
- byte head[4] = { 0 };
- state->queue.peek(head, 4);
-
- const size_t length = make_u32bit(0, head[1], head[2], head[3]);
-
- if(state->queue.size() >= length + 4)
- {
- type = static_cast<Handshake_Type>(head[0]);
- contents.resize(length);
- state->queue.read(head, 4);
- state->queue.read(&contents[0], contents.size());
- }
- }
- }
- else if(rec_type == CHANGE_CIPHER_SPEC)
- {
- if(state->queue.size() == 0 && rec_buf.size() == 1 && rec_buf[0] == 1)
- type = HANDSHAKE_CCS;
- else
- throw Decoding_Error("Malformed ChangeCipherSpec message");
- }
- else
- throw Decoding_Error("Unknown message type in handshake processing");
+ if(rec_type == HANDSHAKE && !state)
+ state = new Handshake_State;
- if(type == HANDSHAKE_NONE)
- break;
-
- process_handshake_msg(type, contents);
-
- if(type == HANDSHAKE_CCS || !state)
- break;
- }
+ TLS_Channel::read_handshake(rec_type, rec_buf);
}
/*
@@ -474,21 +274,4 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
throw Unexpected_Message("Unknown handshake message received");
}
-/*
-* Perform a server-side TLS handshake
-*/
-void TLS_Server::do_handshake()
- {
- while(true)
- {
- if(active && !state)
- break;
-
- state_machine();
-
- if(!active && !state)
- throw TLS_Exception(HANDSHAKE_FAILURE, "TLS_Server: Handshake failed");
- }
- }
-
}
diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h
index 510ad15a7..e975071d2 100644
--- a/src/tls/tls_server.h
+++ b/src/tls/tls_server.h
@@ -8,8 +8,7 @@
#ifndef BOTAN_TLS_SERVER_H__
#define BOTAN_TLS_SERVER_H__
-#include <botan/tls_record.h>
-#include <botan/tls_policy.h>
+#include <botan/tls_channel.h>
#include <vector>
namespace Botan {
@@ -17,58 +16,42 @@ namespace Botan {
/**
* TLS Server
*/
-class BOTAN_DLL TLS_Server
+class BOTAN_DLL TLS_Server : public TLS_Channel
{
public:
- size_t read(byte buf[], size_t buf_len);
- void write(const byte buf[], size_t buf_len);
- std::vector<X509_Certificate> peer_cert_chain() const;
-
- std::string requested_hostname() const
- { return client_requested_hostname; }
-
- void close();
- bool is_closed() const;
-
- /*
+ /**
+ * TLS_Server initialization
+ *
* FIXME: support cert chains (!)
* FIXME: support anonymous servers
*/
- TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn,
- std::tr1::function<void (const byte[], size_t)> output_fn,
+ TLS_Server(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
+ std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
const X509_Certificate& cert,
const Private_Key& cert_key);
~TLS_Server();
- private:
- void close(Alert_Level, Alert_Type);
- void do_handshake();
- void state_machine();
+ /**
+ * Return the server name indicator, if set by the client
+ */
+ std::string server_name_indicator() const
+ { return client_requested_hostname; }
+ private:
void read_handshake(byte, const MemoryRegion<byte>&);
void process_handshake_msg(Handshake_Type, const MemoryRegion<byte>&);
- std::tr1::function<size_t (byte[], size_t)> input_fn;
-
const TLS_Policy& policy;
RandomNumberGenerator& rng;
- Record_Writer writer;
- Record_Reader reader;
-
- // FIXME: rename to match TLS_Client
- std::vector<X509_Certificate> cert_chain, peer_certs;
+ std::vector<X509_Certificate> cert_chain;
Private_Key* private_key;
- class Handshake_State* state;
- SecureVector<byte> session_id;
- SecureQueue read_buf;
std::string client_requested_hostname;
- bool active;
};
}