aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/tls')
-rw-r--r--src/lib/tls/credentials_manager.cpp13
-rw-r--r--src/lib/tls/msg_client_kex.cpp5
-rw-r--r--src/lib/tls/msg_server_kex.cpp54
-rw-r--r--src/lib/tls/sessions_sql/tls_session_manager_sql.cpp56
-rw-r--r--src/lib/tls/sessions_sql/tls_session_manager_sql.h4
-rw-r--r--src/lib/tls/tls_policy.cpp7
-rw-r--r--src/lib/tls/tls_reader.h2
-rw-r--r--src/lib/tls/tls_session.cpp19
-rw-r--r--src/lib/tls/tls_session_manager.h11
-rw-r--r--src/lib/tls/tls_session_manager_memory.cpp11
-rw-r--r--src/lib/tls/tls_suite_info.cpp7
11 files changed, 89 insertions, 100 deletions
diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp
index 43ba7650a..3762dc149 100644
--- a/src/lib/tls/credentials_manager.cpp
+++ b/src/lib/tls/credentials_manager.cpp
@@ -129,11 +129,14 @@ void Credentials_Manager::verify_certificate_chain(
Path_Validation_Restrictions restrictions;
- auto result = x509_path_validate(cert_chain,
- restrictions,
- trusted_CAs,
- purported_hostname,
- choose_leaf_usage(type));
+ Path_Validation_Result result = x509_path_validate(cert_chain,
+ restrictions,
+ trusted_CAs,
+ purported_hostname,
+ choose_leaf_usage(type));
+
+ if(!result.successful_validation())
+ throw std::runtime_error("Certificate validation failure: " + result.result_string());
if(!cert_in_some_store(trusted_CAs, result.trust_root()))
throw std::runtime_error("Certificate chain roots in unknown/untrusted CA");
diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp
index c5b9305c7..7ce9b9df2 100644
--- a/src/lib/tls/msg_client_kex.cpp
+++ b/src/lib/tls/msg_client_kex.cpp
@@ -106,8 +106,9 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
DL_Group group(p, g);
- if(!group.verify_group(rng, true))
- throw Internal_Error("DH group failed validation, possible attack");
+ if(!group.verify_group(rng, false))
+ throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
+ "DH group validation failed");
DH_PublicKey counterparty_key(group, Y);
diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp
index 3fcdb5ab2..0c3b5c704 100644
--- a/src/lib/tls/msg_server_kex.cpp
+++ b/src/lib/tls/msg_server_kex.cpp
@@ -1,6 +1,6 @@
/*
* Server Key Exchange Message
-* (C) 2004-2010,2012 Jack Lloyd
+* (C) 2004-2010,2012,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -145,21 +145,17 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf,
Protocol_Version version) :
m_kex_key(nullptr), m_srp_params(nullptr)
{
- if(buf.size() < 6)
- throw Decoding_Error("Server_Key_Exchange: Packet corrupted");
-
TLS_Data_Reader reader("ServerKeyExchange", buf);
/*
- * We really are just serializing things back to what they were
- * before, but unfortunately to know where the signature is we need
- * to be able to parse the whole thing anyway.
+ * Here we are deserializing enough to find out what offset the
+ * signature is at. All processing is done when the Client Key Exchange
+ * is prepared.
*/
if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
{
- const std::string identity_hint = reader.get_string(2, 0, 65535);
- append_tls_length_value(m_params, identity_hint, 2);
+ reader.get_string(2, 0, 65535); // identity hint
}
if(kex_algo == "DH" || kex_algo == "DHE_PSK")
@@ -168,49 +164,29 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf,
for(size_t i = 0; i != 3; ++i)
{
- BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- append_tls_length_value(m_params, BigInt::encode(v), 2);
+ reader.get_range<byte>(2, 1, 65535);
}
}
else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
{
- const byte curve_type = reader.get_byte();
-
- if(curve_type != 3)
- throw Decoding_Error("Server_Key_Exchange: Server sent non-named ECC curve");
-
- const u16bit curve_id = reader.get_u16bit();
-
- const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);
-
- std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);
-
- if(name == "")
- throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " +
- std::to_string(curve_id));
-
- m_params.push_back(curve_type);
- m_params.push_back(get_byte(0, curve_id));
- m_params.push_back(get_byte(1, curve_id));
- append_tls_length_value(m_params, ecdh_key, 1);
+ reader.get_byte(); // curve type
+ reader.get_u16bit(); // curve id
+ reader.get_range<byte>(1, 1, 255); // public key
}
else if(kex_algo == "SRP_SHA")
{
// 2 bigints (N,g) then salt, then server B
- const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
- std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
- const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
-
- append_tls_length_value(m_params, BigInt::encode(N), 2);
- append_tls_length_value(m_params, BigInt::encode(g), 2);
- append_tls_length_value(m_params, salt, 1);
- append_tls_length_value(m_params, BigInt::encode(B), 2);
+ reader.get_range<byte>(2, 1, 65535);
+ reader.get_range<byte>(2, 1, 65535);
+ reader.get_range<byte>(1, 1, 255);
+ reader.get_range<byte>(2, 1, 65535);
}
else if(kex_algo != "PSK")
throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo);
+ m_params.assign(buf.data(), buf.data() + reader.read_so_far());
+
if(sig_algo != "")
{
if(version.supports_negotiable_signature_algorithms())
diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
index ed207972e..9f025374e 100644
--- a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
+++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp
@@ -16,27 +16,6 @@ namespace Botan {
namespace TLS {
-namespace {
-
-SymmetricKey derive_key(const std::string& passphrase,
- const byte salt[],
- size_t salt_len,
- size_t iterations,
- size_t& check_val)
- {
- std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)"));
-
- secure_vector<byte> x = pbkdf->derive_key(32 + 2,
- passphrase,
- salt, salt_len,
- iterations).bits_of();
-
- check_val = make_u16bit(x[0], x[1]);
- return SymmetricKey(&x[2], x.size() - 2);
- }
-
-}
-
Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const std::string& passphrase,
RandomNumberGenerator& rng,
@@ -67,6 +46,8 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const size_t salts = m_db->row_count("tls_sessions_metadata");
+ std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)"));
+
if(salts == 1)
{
// existing db
@@ -78,12 +59,13 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
const size_t iterations = stmt->get_size_t(1);
const size_t check_val_db = stmt->get_size_t(2);
- size_t check_val_created;
- m_session_key = derive_key(passphrase,
- salt.first,
- salt.second,
- iterations,
- check_val_created);
+ secure_vector<byte> x = pbkdf->pbkdf_iterations(32 + 2,
+ passphrase,
+ salt.first, salt.second,
+ iterations);
+
+ const size_t check_val_created = make_u16bit(x[0], x[1]);
+ m_session_key.assign(x.begin() + 2, x.end());
if(check_val_created != check_val_db)
throw std::runtime_error("Session database password not valid");
@@ -98,11 +80,17 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db,
// new database case
std::vector<byte> salt = unlock(rng.random_vec(16));
- const size_t iterations = 256 * 1024;
- size_t check_val = 0;
+ size_t iterations = 0;
- m_session_key = derive_key(passphrase, salt.data(), salt.size(),
- iterations, check_val);
+ secure_vector<byte> x = pbkdf->pbkdf_timed(32 + 2,
+ passphrase,
+ salt.data(), salt.size(),
+ std::chrono::milliseconds(100),
+ iterations);
+
+ printf("pbkdf iter %d\n", iterations);
+ size_t check_val = make_u16bit(x[0], x[1]);
+ m_session_key.assign(x.begin() + 2, x.end());
auto stmt = m_db->new_statement("insert into tls_sessions_metadata values(?1, ?2, ?3)");
@@ -174,6 +162,12 @@ void Session_Manager_SQL::remove_entry(const std::vector<byte>& session_id)
stmt->spin();
}
+size_t Session_Manager_SQL::remove_all()
+ {
+ auto stmt = m_db->new_statement("delete from tls_sessions");
+ return stmt->spin();
+ }
+
void Session_Manager_SQL::save(const Session& session)
{
auto stmt = m_db->new_statement("insert or replace into tls_sessions"
diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.h b/src/lib/tls/sessions_sql/tls_session_manager_sql.h
index 081c42e74..24e2be7c3 100644
--- a/src/lib/tls/sessions_sql/tls_session_manager_sql.h
+++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.h
@@ -56,6 +56,8 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager
void remove_entry(const std::vector<byte>& session_id) override;
+ size_t remove_all() override;
+
void save(const Session& session_data) override;
std::chrono::seconds session_lifetime() const override
@@ -65,7 +67,7 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager
void prune_session_cache();
std::shared_ptr<SQL_Database> m_db;
- SymmetricKey m_session_key;
+ secure_vector<byte> m_session_key;
RandomNumberGenerator& m_rng;
size_t m_max_sessions;
std::chrono::seconds m_session_lifetime;
diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp
index d8dd2c828..7d1af71ef 100644
--- a/src/lib/tls/tls_policy.cpp
+++ b/src/lib/tls/tls_policy.cpp
@@ -1,6 +1,6 @@
/*
* Policies for TLS
-* (C) 2004-2010,2012 Jack Lloyd
+* (C) 2004-2010,2012,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -44,7 +44,7 @@ std::vector<std::string> Policy::allowed_signature_hashes() const
"SHA-512",
"SHA-384",
"SHA-256",
- "SHA-224",
+ //"SHA-224",
//"SHA-1",
//"MD5",
};
@@ -282,9 +282,6 @@ std::vector<u16bit> Policy::ciphersuite_list(Protocol_Version version,
if(!have_srp && suite.kex_algo() == "SRP_SHA")
continue;
- if(version.is_datagram_protocol() && suite.cipher_algo() == "RC4")
- continue;
-
if(!version.supports_aead_modes() && suite.mac_algo() == "AEAD")
continue;
diff --git a/src/lib/tls/tls_reader.h b/src/lib/tls/tls_reader.h
index c2aef3163..63a59625f 100644
--- a/src/lib/tls/tls_reader.h
+++ b/src/lib/tls/tls_reader.h
@@ -34,6 +34,8 @@ class TLS_Data_Reader
throw decode_error("Extra bytes at end of message");
}
+ size_t read_so_far() const { return m_offset; }
+
size_t remaining_bytes() const { return m_buf.size() - m_offset; }
bool has_remaining() const { return (remaining_bytes() > 0); }
diff --git a/src/lib/tls/tls_session.cpp b/src/lib/tls/tls_session.cpp
index 8cb1a2aa7..7089a70f0 100644
--- a/src/lib/tls/tls_session.cpp
+++ b/src/lib/tls/tls_session.cpp
@@ -11,8 +11,7 @@
#include <botan/asn1_str.h>
#include <botan/pem.h>
#include <botan/aead.h>
-#include <botan/sha2_32.h>
-#include <botan/hmac.h>
+#include <botan/mac.h>
namespace Botan {
@@ -162,10 +161,10 @@ Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const
const secure_vector<byte> bits = this->DER_encode();
// Support any length key for input
- HMAC hmac(new SHA_256);
- hmac.set_key(key);
- hmac.update(nonce);
- aead->set_key(hmac.final());
+ std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
+ hmac->set_key(key);
+ hmac->update(nonce);
+ aead->set_key(hmac->final());
secure_vector<byte> buf = nonce;
buf += bits;
@@ -185,10 +184,10 @@ Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key
throw Decoding_Error("Encrypted session too short to be valid");
// Support any length key for input
- HMAC hmac(new SHA_256);
- hmac.set_key(key);
- hmac.update(in, nonce_len); // nonce bytes
- aead->set_key(hmac.final());
+ std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
+ hmac->set_key(key);
+ hmac->update(in, nonce_len); // nonce bytes
+ aead->set_key(hmac->final());
aead->start(in, nonce_len);
secure_vector<byte> buf(in + nonce_len, in + in_len);
diff --git a/src/lib/tls/tls_session_manager.h b/src/lib/tls/tls_session_manager.h
index c7aa1960b..5ab151c26 100644
--- a/src/lib/tls/tls_session_manager.h
+++ b/src/lib/tls/tls_session_manager.h
@@ -55,6 +55,11 @@ class BOTAN_DLL Session_Manager
virtual void remove_entry(const std::vector<byte>& session_id) = 0;
/**
+ * Remove all sessions from the cache, return number of sessions deleted
+ */
+ virtual size_t remove_all() = 0;
+
+ /**
* Save a session on a best effort basis; the manager may not in
* fact be able to save the session for whatever reason; this is
* not an error. Caller cannot assume that calling save followed
@@ -89,6 +94,8 @@ class BOTAN_DLL Session_Manager_Noop : public Session_Manager
void remove_entry(const std::vector<byte>&) override {}
+ size_t remove_all() override { return 0; }
+
void save(const Session&) override {}
std::chrono::seconds session_lifetime() const override
@@ -120,6 +127,8 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager
void remove_entry(const std::vector<byte>& session_id) override;
+ size_t remove_all();
+
void save(const Session& session_data) override;
std::chrono::seconds session_lifetime() const override
@@ -136,7 +145,7 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager
std::chrono::seconds m_session_lifetime;
RandomNumberGenerator& m_rng;
- SymmetricKey m_session_key;
+ secure_vector<byte> m_session_key;
std::map<std::string, std::vector<byte>> m_sessions; // hex(session_id) -> session
std::map<Server_Information, std::string> m_info_sessions;
diff --git a/src/lib/tls/tls_session_manager_memory.cpp b/src/lib/tls/tls_session_manager_memory.cpp
index 2c836290b..37019c943 100644
--- a/src/lib/tls/tls_session_manager_memory.cpp
+++ b/src/lib/tls/tls_session_manager_memory.cpp
@@ -20,7 +20,7 @@ Session_Manager_In_Memory::Session_Manager_In_Memory(
m_max_sessions(max_sessions),
m_session_lifetime(session_lifetime),
m_rng(rng),
- m_session_key(m_rng, 32)
+ m_session_key(m_rng.random_vec(32))
{}
bool Session_Manager_In_Memory::load_from_session_str(
@@ -95,6 +95,15 @@ void Session_Manager_In_Memory::remove_entry(
m_sessions.erase(i);
}
+size_t Session_Manager_In_Memory::remove_all()
+ {
+ const size_t removed = m_sessions.size();
+ m_info_sessions.clear();
+ m_sessions.clear();
+ m_session_key = m_rng.random_vec(32);
+ return removed;
+ }
+
void Session_Manager_In_Memory::save(const Session& session)
{
std::lock_guard<std::mutex> lock(m_mutex);
diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp
index cb5c1d4c5..5aff035b9 100644
--- a/src/lib/tls/tls_suite_info.cpp
+++ b/src/lib/tls/tls_suite_info.cpp
@@ -2,8 +2,8 @@
* TLS cipher suite information
*
* This file was automatically generated from the IANA assignments
-* (tls-parameters.txt hash 4bc98b6f75ad5b63952b5f457fa7adbfef60f095)
-* by ./src/scripts/tls_suite_info.py on 2015-05-11
+* (tls-parameters.txt hash 6a934405ed41aa4d6113dad17f815867741430ac)
+* by ./src/scripts/tls_suite_info.py on 2015-11-13
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -57,9 +57,6 @@ Ciphersuite Ciphersuite::by_id(u16bit suite)
case 0xC081: // DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384
return Ciphersuite(0xC081, "DSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384");
- case 0x0066: // DHE_DSS_WITH_RC4_128_SHA
- return Ciphersuite(0x0066, "DSA", "DH", "RC4", 16, 0, 0, "SHA-1", 20);
-
case 0x0099: // DHE_DSS_WITH_SEED_CBC_SHA
return Ciphersuite(0x0099, "DSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20);