aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-12-28 16:08:42 +0000
committerlloyd <[email protected]>2011-12-28 16:08:42 +0000
commit5ee3046bc9b8517bb6de5eda34f03ee907f9ff16 (patch)
tree1ce7355bd7198ea195eb26078fe14891d975c4f8
parent19b985eae73839fdd7547f48b999377c4d1ff47e (diff)
Working though hacking client verify (server side only). Only supports
TLS 1.0/1.1, SSLv3 uses a different hash format. Only RSA certs tested so far.
-rw-r--r--doc/examples/tls_client.cpp3
-rw-r--r--doc/examples/tls_server.cpp8
-rw-r--r--src/tls/c_kex.cpp2
-rw-r--r--src/tls/cert_req.cpp4
-rw-r--r--src/tls/cert_ver.cpp8
-rw-r--r--src/tls/finished.cpp6
-rw-r--r--src/tls/hello.cpp12
-rw-r--r--src/tls/rec_read.cpp12
-rw-r--r--src/tls/rec_wri.cpp2
-rw-r--r--src/tls/s_kex.cpp5
-rw-r--r--src/tls/tls_alerts.h11
-rw-r--r--src/tls/tls_channel.cpp24
-rw-r--r--src/tls/tls_client.cpp2
-rw-r--r--src/tls/tls_handshake_hash.cpp18
-rw-r--r--src/tls/tls_handshake_hash.h12
-rw-r--r--src/tls/tls_magic.h5
-rw-r--r--src/tls/tls_messages.h28
-rw-r--r--src/tls/tls_server.cpp32
-rw-r--r--src/tls/tls_state.h2
19 files changed, 131 insertions, 65 deletions
diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp
index ee224e9eb..ad693c367 100644
--- a/doc/examples/tls_client.cpp
+++ b/doc/examples/tls_client.cpp
@@ -33,6 +33,7 @@ class HTTPS_Client
socket(host, port),
client(std::tr1::bind(&HTTPS_Client::socket_write, std::tr1::ref(*this), _1, _2),
std::tr1::bind(&HTTPS_Client::proc_data, std::tr1::ref(*this), _1, _2, _3),
+ sessions,
policy,
rng)
{
@@ -92,6 +93,8 @@ class HTTPS_Client
RandomNumberGenerator& rng;
Socket socket;
Client_TLS_Policy policy;
+ TLS_Session_Manager_In_Memory sessions;
+
TLS_Client client;
};
diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp
index 0f9b16871..a0e18b296 100644
--- a/doc/examples/tls_server.cpp
+++ b/doc/examples/tls_server.cpp
@@ -86,13 +86,13 @@ class Blocking_TLS_Server
void reader_fn(const byte buf[], size_t buf_len, u16bit alert_code)
{
- if(buf_len == 0 && alert_code != NO_ALERT_TYPE)
+ if(buf_len == 0 && alert_code != NULL_ALERT)
{
printf("Alert: %d, quitting\n", alert_code);
exit = true;
}
- printf("Got %d bytes: ", buf_len);
+ printf("Got %d bytes: ", (int)buf_len);
for(size_t i = 0; i != buf_len; ++i)
{
if(isprint(buf[i]))
@@ -114,6 +114,8 @@ class Blocking_TLS_Server
class Server_TLS_Policy : public TLS_Policy
{
public:
+ bool require_client_auth() const { return true; }
+
bool check_cert(const std::vector<X509_Certificate>& certs) const
{
for(size_t i = 0; i != certs.size(); ++i)
@@ -202,7 +204,7 @@ int main(int argc, char* argv[])
}
}
}
- catch(std::exception& e) { printf("%s\n", e.what()); }
+ catch(std::exception& e) { printf("Connection problem: %s\n", e.what()); }
}
}
catch(std::exception& e)
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp
index b55973ca3..ced31f870 100644
--- a/src/tls/c_kex.cpp
+++ b/src/tls/c_kex.cpp
@@ -21,7 +21,7 @@ namespace Botan {
*/
Client_Key_Exchange::Client_Key_Exchange(RandomNumberGenerator& rng,
Record_Writer& writer,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const Public_Key* pub_key,
Version_Code using_version,
Version_Code pref_version)
diff --git a/src/tls/cert_req.cpp b/src/tls/cert_req.cpp
index cc77509df..85c017fac 100644
--- a/src/tls/cert_req.cpp
+++ b/src/tls/cert_req.cpp
@@ -18,7 +18,7 @@ namespace Botan {
* Create a new Certificate Request message
*/
Certificate_Req::Certificate_Req(Record_Writer& writer,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const std::vector<X509_Certificate>& ca_certs,
const std::vector<Certificate_Type>& cert_types)
{
@@ -90,7 +90,7 @@ void Certificate_Req::deserialize(const MemoryRegion<byte>& buf)
*/
Certificate::Certificate(Record_Writer& writer,
const std::vector<X509_Certificate>& cert_list,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
certs = cert_list;
send(writer, hash);
diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp
index 0d8256e5e..4203e2542 100644
--- a/src/tls/cert_ver.cpp
+++ b/src/tls/cert_ver.cpp
@@ -1,6 +1,6 @@
/*
* Certificate Verify Message
-* (C) 2004-2010 Jack Lloyd
+* (C) 2004-2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -20,7 +20,7 @@ namespace Botan {
*/
Certificate_Verify::Certificate_Verify(RandomNumberGenerator& rng,
Record_Writer& writer,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const Private_Key* priv_key)
{
std::string padding = "";
@@ -71,7 +71,7 @@ void Certificate_Verify::deserialize(const MemoryRegion<byte>& buf)
* Verify a Certificate Verify message
*/
bool Certificate_Verify::verify(const X509_Certificate& cert,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
// FIXME: duplicate of Server_Key_Exchange::verify
@@ -92,7 +92,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert,
" is invalid/unknown for TLS signatures");
PK_Verifier verifier(*key, padding, format);
- return verifier.verify_message(hash.final(), signature);
+ return verifier.verify_message(hash.get_contents(), signature);
}
}
diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp
index dff977d31..bc072bc9d 100644
--- a/src/tls/finished.cpp
+++ b/src/tls/finished.cpp
@@ -16,7 +16,7 @@ namespace Botan {
Finished::Finished(Record_Writer& writer,
Version_Code version, Connection_Side side,
const MemoryRegion<byte>& master_secret,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
verification_data = compute_verify(master_secret, hash, side, version);
send(writer, hash);
@@ -42,7 +42,7 @@ void Finished::deserialize(const MemoryRegion<byte>& buf)
* Verify a Finished message
*/
bool Finished::verify(const MemoryRegion<byte>& secret, Version_Code version,
- const HandshakeHash& hash, Connection_Side side)
+ const TLS_Handshake_Hash& hash, Connection_Side side)
{
MemoryVector<byte> computed = compute_verify(secret, hash, side, version);
if(computed == verification_data)
@@ -54,7 +54,7 @@ bool Finished::verify(const MemoryRegion<byte>& secret, Version_Code version,
* Compute the verify_data
*/
MemoryVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret,
- HandshakeHash hash,
+ TLS_Handshake_Hash hash,
Connection_Side side,
Version_Code version)
{
diff --git a/src/tls/hello.cpp b/src/tls/hello.cpp
index 207c3d097..45eedbd76 100644
--- a/src/tls/hello.cpp
+++ b/src/tls/hello.cpp
@@ -15,7 +15,7 @@ namespace Botan {
/*
* Encode and send a Handshake message
*/
-void HandshakeMessage::send(Record_Writer& writer, HandshakeHash& hash) const
+void HandshakeMessage::send(Record_Writer& writer, TLS_Handshake_Hash& hash) const
{
MemoryVector<byte> buf = serialize();
MemoryVector<byte> send_buf(4);
@@ -40,7 +40,7 @@ void HandshakeMessage::send(Record_Writer& writer, HandshakeHash& hash) const
*/
Hello_Request::Hello_Request(Record_Writer& writer)
{
- HandshakeHash dummy; // FIXME: *UGLY*
+ TLS_Handshake_Hash dummy; // FIXME: *UGLY*
send(writer, dummy);
}
@@ -67,7 +67,7 @@ void Hello_Request::deserialize(const MemoryRegion<byte>& buf)
Client_Hello::Client_Hello(RandomNumberGenerator& rng,
Record_Writer& writer,
const TLS_Policy& policy,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
c_random = rng.random_vec(32);
@@ -229,7 +229,7 @@ Server_Hello::Server_Hello(RandomNumberGenerator& rng,
const Client_Hello& c_hello,
const MemoryRegion<byte>& session_id,
Version_Code ver,
- HandshakeHash& hash) :
+ TLS_Handshake_Hash& hash) :
s_version(ver),
sess_id(session_id),
s_random(rng.random_vec(32))
@@ -266,7 +266,7 @@ Server_Hello::Server_Hello(RandomNumberGenerator& rng,
u16bit ciphersuite,
byte compression,
Version_Code ver,
- HandshakeHash& hash) :
+ TLS_Handshake_Hash& hash) :
s_version(ver),
sess_id(session_id),
s_random(rng.random_vec(32)),
@@ -328,7 +328,7 @@ void Server_Hello::deserialize(const MemoryRegion<byte>& buf)
* Create a new Server Hello Done message
*/
Server_Hello_Done::Server_Hello_Done(Record_Writer& writer,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
send(writer, hash);
}
diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp
index 9b71bfec3..84a96f508 100644
--- a/src/tls/rec_read.cpp
+++ b/src/tls/rec_read.cpp
@@ -176,12 +176,16 @@ size_t Record_Reader::get_record(byte& msg_type,
input_queue.read(header, sizeof(header)); // pull off the header
input_queue.read(&buffer[0], buffer.size());
- /*
- * We are handshaking, no crypto to do so return as-is
- * TODO: Check msg_type to confirm a handshake?
- */
+ // We are handshaking, no crypto to do so return as-is
if(mac_size == 0)
{
+ if(header[0] != CHANGE_CIPHER_SPEC &&
+ header[0] != ALERT &&
+ header[0] != HANDSHAKE)
+ {
+ throw TLS_Exception(DECODE_ERROR, "Invalid msg type received during handshake");
+ }
+
msg_type = header[0];
output = buffer;
return 0; // got a full record
diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp
index b1edde64b..4803621f6 100644
--- a/src/tls/rec_wri.cpp
+++ b/src/tls/rec_wri.cpp
@@ -206,7 +206,7 @@ void Record_Writer::send_record(byte type, const byte buf[], size_t length)
SecureVector<byte> buf_mac = mac->final();
- // TODO: This could all use a single buffer
+ // FIXME: this could be done in place in a single buffer
cipher.start_msg();
if(iv_size)
diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp
index b11892923..bb2ed7c1d 100644
--- a/src/tls/s_kex.cpp
+++ b/src/tls/s_kex.cpp
@@ -25,7 +25,7 @@ Server_Key_Exchange::Server_Key_Exchange(RandomNumberGenerator& rng,
const Private_Key* priv_key,
const MemoryRegion<byte>& c_random,
const MemoryRegion<byte>& s_random,
- HandshakeHash& hash)
+ TLS_Handshake_Hash& hash)
{
const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(kex_key);
const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(kex_key);
@@ -44,7 +44,7 @@ Server_Key_Exchange::Server_Key_Exchange(RandomNumberGenerator& rng,
else
throw Invalid_Argument("Bad key for TLS key exchange: not DH or RSA");
-
+ // FIXME: cut and paste
std::string padding = "";
Signature_Format format = IEEE_1363;
@@ -153,6 +153,7 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert,
std::auto_ptr<Public_Key> key(cert.subject_public_key());
+ // FIXME: cut and paste
std::string padding = "";
Signature_Format format = IEEE_1363;
diff --git a/src/tls/tls_alerts.h b/src/tls/tls_alerts.h
index 241599aa8..c74361930 100644
--- a/src/tls/tls_alerts.h
+++ b/src/tls/tls_alerts.h
@@ -1,6 +1,6 @@
/*
* Alert Message
-* (C) 2004-2006 Jack Lloyd
+* (C) 2004-2006,2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -40,9 +40,14 @@ class Alert
if(buf[0] == 1) fatal = false;
else if(buf[0] == 2) fatal = true;
else
- throw Decoding_Error("Alert: Bad type code for alert level");
+ throw Decoding_Error("Alert: Bad code for alert level");
- type_code = static_cast<Alert_Type>(buf[1]);
+ const byte dc = buf[1];
+
+ if(dc == 255)
+ throw Decoding_Error("Alert: description code 255, rejecting");
+
+ type_code = static_cast<Alert_Type>(dc);
}
private:
bool fatal;
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index 399568a44..553f65836 100644
--- a/src/tls/tls_channel.cpp
+++ b/src/tls/tls_channel.cpp
@@ -54,7 +54,7 @@ size_t TLS_Channel::received_data(const byte buf[], size_t buf_size)
* following record. Avoid spurious callbacks.
*/
if(record.size() > 0)
- proc_fn(&record[0], record.size(), NO_ALERT_TYPE);
+ proc_fn(&record[0], record.size(), NULL_ALERT);
}
else
{
@@ -76,7 +76,7 @@ size_t TLS_Channel::received_data(const byte buf[], size_t buf_size)
if(alert_msg.type() == CLOSE_NOTIFY)
alert(FATAL, CLOSE_NOTIFY);
else
- alert(FATAL, NO_ALERT_TYPE);
+ alert(FATAL, NULL_ALERT);
}
}
else
@@ -90,6 +90,11 @@ size_t TLS_Channel::received_data(const byte buf[], size_t buf_size)
alert(FATAL, e.type());
throw;
}
+ catch(Decoding_Error& e)
+ {
+ alert(FATAL, DECODE_ERROR);
+ throw;
+ }
catch(std::exception& e)
{
alert(FATAL, INTERNAL_ERROR);
@@ -167,16 +172,19 @@ void TLS_Channel::queue_for_sending(const byte buf[], size_t buf_size)
pre_handshake_write_queue.write(buf, buf_size);
}
-void TLS_Channel::alert(Alert_Level level, Alert_Type alert_code)
+void TLS_Channel::alert(Alert_Level alert_level, Alert_Type alert_code)
{
- try
+ if(alert_code != NULL_ALERT)
{
- writer.alert(level, alert_code);
- writer.flush();
+ try
+ {
+ writer.alert(alert_level, alert_code);
+ writer.flush();
+ }
+ catch(...) { /* swallow it */ }
}
- catch(...) { /* swallow it */ }
- if(active && level == FATAL)
+ if(active && alert_level == FATAL)
{
reader.reset();
writer.reset();
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index dfa5c57df..d8861459c 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -55,8 +55,6 @@ TLS_Client::~TLS_Client()
void TLS_Client::process_handshake_msg(Handshake_Type type,
const MemoryRegion<byte>& contents)
{
- rng.add_entropy(&contents[0], contents.size());
-
if(type == HELLO_REQUEST)
{
if(state == 0)
diff --git a/src/tls/tls_handshake_hash.cpp b/src/tls/tls_handshake_hash.cpp
index 7c1e2e385..9621af535 100644
--- a/src/tls/tls_handshake_hash.cpp
+++ b/src/tls/tls_handshake_hash.cpp
@@ -1,6 +1,6 @@
/*
* TLS Handshake Hash
-* (C) 2004-2006 Jack Lloyd
+* (C) 2004-2006,2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -12,10 +12,22 @@
namespace Botan {
+void TLS_Handshake_Hash::update(Handshake_Type handshake_type,
+ const MemoryRegion<byte>& handshake_msg)
+ {
+ update(static_cast<byte>(handshake_type));
+
+ const size_t record_length = handshake_msg.size();
+ for(size_t i = 0; i != 3; i++)
+ update(get_byte<u32bit>(i+1, record_length));
+
+ update(handshake_msg);
+ }
+
/**
* Return a TLS Handshake Hash
*/
-SecureVector<byte> HandshakeHash::final()
+SecureVector<byte> TLS_Handshake_Hash::final()
{
MD5 md5;
SHA_160 sha1;
@@ -32,7 +44,7 @@ SecureVector<byte> HandshakeHash::final()
/**
* Return a SSLv3 Handshake Hash
*/
-SecureVector<byte> HandshakeHash::final_ssl3(const MemoryRegion<byte>& secret)
+SecureVector<byte> TLS_Handshake_Hash::final_ssl3(const MemoryRegion<byte>& secret)
{
const byte PAD_INNER = 0x36, PAD_OUTER = 0x5C;
diff --git a/src/tls/tls_handshake_hash.h b/src/tls/tls_handshake_hash.h
index cea612a71..4ee1fc1b9 100644
--- a/src/tls/tls_handshake_hash.h
+++ b/src/tls/tls_handshake_hash.h
@@ -1,6 +1,6 @@
/*
* TLS Handshake Hash
-* (C) 2004-2006 Jack Lloyd
+* (C) 2004-2006,2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -9,6 +9,7 @@
#define BOTAN_TLS_HANDSHAKE_HASH_H__
#include <botan/secmem.h>
+#include <botan/tls_magic.h>
namespace Botan {
@@ -17,7 +18,7 @@ using namespace Botan;
/**
* TLS Handshake Hash
*/
-class HandshakeHash
+class TLS_Handshake_Hash
{
public:
void update(const byte in[], size_t length)
@@ -29,8 +30,15 @@ class HandshakeHash
void update(byte in)
{ data.push_back(in); }
+ void update(Handshake_Type handshake_type,
+ const MemoryRegion<byte>& handshake_msg);
+
SecureVector<byte> final();
SecureVector<byte> final_ssl3(const MemoryRegion<byte>&);
+
+ const SecureVector<byte>& get_contents() const
+ { return data; }
+
private:
SecureVector<byte> data;
};
diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h
index 805519787..da6578c0a 100644
--- a/src/tls/tls_magic.h
+++ b/src/tls/tls_magic.h
@@ -84,9 +84,12 @@ enum Alert_Type {
USER_CANCELED = 90,
NO_RENEGOTIATION = 100,
+ UNSUPPORTED_EXTENSION = 110,
+ UNRECOGNIZED_NAME = 112,
+
UNKNOWN_PSK_IDENTITY = 115,
- NO_ALERT_TYPE = 0xFFFF
+ NULL_ALERT = 255
};
enum Certificate_Type {
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index c4920066e..880f77c98 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -28,7 +28,7 @@ class Record_Reader;
class HandshakeMessage
{
public:
- void send(Record_Writer&, HandshakeHash&) const;
+ void send(Record_Writer&, TLS_Handshake_Hash&) const;
virtual Handshake_Type type() const = 0;
@@ -68,7 +68,7 @@ class Client_Hello : public HandshakeMessage
bool offered_suite(u16bit) const;
Client_Hello(RandomNumberGenerator& rng,
- Record_Writer&, const TLS_Policy&, HandshakeHash&);
+ Record_Writer&, const TLS_Policy&, TLS_Handshake_Hash&);
Client_Hello(const MemoryRegion<byte>& buf,
Handshake_Type type)
@@ -108,7 +108,7 @@ class Client_Key_Exchange : public HandshakeMessage
Client_Key_Exchange(RandomNumberGenerator& rng,
Record_Writer& output,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const Public_Key* my_key,
Version_Code using_version,
Version_Code pref_version);
@@ -137,7 +137,7 @@ class Certificate : public HandshakeMessage
bool empty() const { return certs.empty(); }
Certificate(Record_Writer&, const std::vector<X509_Certificate>&,
- HandshakeHash&);
+ TLS_Handshake_Hash&);
Certificate(const MemoryRegion<byte>& buf) { deserialize(buf); }
private:
MemoryVector<byte> serialize() const;
@@ -157,7 +157,7 @@ class Certificate_Req : public HandshakeMessage
std::vector<X509_DN> acceptable_CAs() const { return names; }
Certificate_Req(Record_Writer& writer,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const std::vector<X509_Certificate>& allowed_cas,
const std::vector<Certificate_Type>& types =
std::vector<Certificate_Type>());
@@ -180,11 +180,11 @@ class Certificate_Verify : public HandshakeMessage
Handshake_Type type() const { return CERTIFICATE_VERIFY; }
bool verify(const X509_Certificate& cert,
- HandshakeHash& hash);
+ TLS_Handshake_Hash& hash);
Certificate_Verify(RandomNumberGenerator& rng,
Record_Writer& writer,
- HandshakeHash& hash,
+ TLS_Handshake_Hash& hash,
const Private_Key* key);
Certificate_Verify(const MemoryRegion<byte>& buf) { deserialize(buf); }
@@ -204,17 +204,17 @@ class Finished : public HandshakeMessage
Handshake_Type type() const { return FINISHED; }
bool verify(const MemoryRegion<byte>&, Version_Code,
- const HandshakeHash&, Connection_Side);
+ const TLS_Handshake_Hash&, Connection_Side);
Finished(Record_Writer&, Version_Code, Connection_Side,
- const MemoryRegion<byte>&, HandshakeHash&);
+ const MemoryRegion<byte>&, TLS_Handshake_Hash&);
Finished(const MemoryRegion<byte>& buf) { deserialize(buf); }
private:
MemoryVector<byte> serialize() const;
void deserialize(const MemoryRegion<byte>&);
MemoryVector<byte> compute_verify(const MemoryRegion<byte>&,
- HandshakeHash, Connection_Side,
+ TLS_Handshake_Hash, Connection_Side,
Version_Code);
Connection_Side side;
@@ -264,7 +264,7 @@ class Server_Hello : public HandshakeMessage
const Client_Hello& other,
const MemoryRegion<byte>& session_id,
Version_Code version,
- HandshakeHash& hash);
+ TLS_Handshake_Hash& hash);
Server_Hello(RandomNumberGenerator& rng,
Record_Writer& writer,
@@ -272,7 +272,7 @@ class Server_Hello : public HandshakeMessage
u16bit ciphersuite,
byte compression,
Version_Code ver,
- HandshakeHash& hash);
+ TLS_Handshake_Hash& hash);
Server_Hello(const MemoryRegion<byte>& buf) { deserialize(buf); }
private:
@@ -300,7 +300,7 @@ class Server_Key_Exchange : public HandshakeMessage
Server_Key_Exchange(RandomNumberGenerator& rng,
Record_Writer&, const Public_Key*,
const Private_Key*, const MemoryRegion<byte>&,
- const MemoryRegion<byte>&, HandshakeHash&);
+ const MemoryRegion<byte>&, TLS_Handshake_Hash&);
Server_Key_Exchange(const MemoryRegion<byte>& buf) { deserialize(buf); }
private:
@@ -320,7 +320,7 @@ class Server_Hello_Done : public HandshakeMessage
public:
Handshake_Type type() const { return SERVER_HELLO_DONE; }
- Server_Hello_Done(Record_Writer&, HandshakeHash&);
+ Server_Hello_Done(Record_Writer&, TLS_Handshake_Hash&);
Server_Hello_Done(const MemoryRegion<byte>& buf) { deserialize(buf); }
private:
MemoryVector<byte> serialize() const;
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index f9de0a2b6..581d562be 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -12,6 +12,8 @@
#include <botan/rsa.h>
#include <botan/dh.h>
+#include <stdio.h>
+
namespace Botan {
namespace {
@@ -126,14 +128,12 @@ void TLS_Server::read_handshake(byte rec_type,
void TLS_Server::process_handshake_msg(Handshake_Type type,
const MemoryRegion<byte>& contents)
{
- rng.add_entropy(&contents[0], contents.size());
-
if(state == 0)
throw Unexpected_Message("Unexpected handshake message");
state->confirm_transition_to(type);
- if(type != HANDSHAKE_CCS && type != FINISHED)
+ if(type != HANDSHAKE_CCS && type != FINISHED && type != CERTIFICATE_VERIFY)
{
if(type != CLIENT_HELLO_SSLV2)
{
@@ -252,7 +252,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
/*
* If the client doesn't have a cert they want to use they are
* allowed to send either an empty cert message or proceed
- * directly to the client key exchange.
+ * directly to the client key exchange, so allow either case.
*/
state->set_expected_next(CLIENT_KEX);
@@ -263,6 +263,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
{
state->client_certs = new Certificate(contents);
+ // Is this allowed by the protocol?
if(state->client_certs->count() > 1)
throw TLS_Exception(CERTIFICATE_UNKNOWN,
"Client sent more than one certificate");
@@ -293,7 +294,28 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
std::vector<X509_Certificate> client_certs = state->client_certs->cert_chain();
- //const bool ok = state->client_verify->verify(client_certs[0]);
+ const bool sig_valid = state->client_verify->verify(client_certs[0],
+ state->hash);
+
+ state->hash.update(static_cast<byte>(type));
+
+ const size_t record_length = contents.size();
+ for(size_t i = 0; i != 3; i++)
+ state->hash.update(get_byte<u32bit>(i+1, record_length));
+
+ state->hash.update(contents);
+
+ /*
+ * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for
+ * "A handshake cryptographic operation failed, including being
+ * unable to correctly verify a signature, ..."
+ */
+ if(!sig_valid && false)
+ throw TLS_Exception(DECRYPT_ERROR, "Client cert verify failed");
+
+ printf("Sig valid? %d\n", sig_valid);
+
+ // Check cert was issued by a CA we requested, signatures, etc.
state->set_expected_next(HANDSHAKE_CCS);
}
diff --git a/src/tls/tls_state.h b/src/tls/tls_state.h
index 63f89132d..4d1ae9d6d 100644
--- a/src/tls/tls_state.h
+++ b/src/tls/tls_state.h
@@ -46,7 +46,7 @@ class Handshake_State
CipherSuite suite;
SessionKeys keys;
- HandshakeHash hash;
+ TLS_Handshake_Hash hash;
SecureQueue queue;