aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/filters/threaded_fork.cpp5
-rw-r--r--src/lib/hash/hash.cpp2
-rw-r--r--src/lib/misc/tss/info.txt1
-rw-r--r--src/lib/misc/tss/tss.cpp1
-rw-r--r--src/lib/rng/hmac_drbg/hmac_drbg.cpp54
-rw-r--r--src/lib/rng/hmac_drbg/hmac_drbg.h53
-rw-r--r--src/lib/tls/msg_client_hello.cpp18
-rw-r--r--src/lib/tls/tls_callbacks.h30
-rw-r--r--src/lib/tls/tls_client.cpp29
9 files changed, 139 insertions, 54 deletions
diff --git a/src/lib/filters/threaded_fork.cpp b/src/lib/filters/threaded_fork.cpp
index f558ac9c2..ff54bcbc6 100644
--- a/src/lib/filters/threaded_fork.cpp
+++ b/src/lib/filters/threaded_fork.cpp
@@ -136,6 +136,11 @@ void Threaded_Fork::thread_entry(Filter* filter)
{
while(true)
{
+ /*
+ * This is plain wrong: a single thread can get the semaphore
+ * more than one time, meaning it will process the input twice
+ * and some other thread/filter will not see this input.
+ */
m_thread_data->m_input_ready_semaphore.acquire();
if(!m_thread_data->m_input)
diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp
index 7a32ccede..ede2f8c99 100644
--- a/src/lib/hash/hash.cpp
+++ b/src/lib/hash/hash.cpp
@@ -269,7 +269,7 @@ std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
#endif
#if defined(BOTAN_HAS_COMB4P)
- if(req.algo_name() == "Comb4p" && req.arg_count() == 2)
+ if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
{
std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0)));
std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1)));
diff --git a/src/lib/misc/tss/info.txt b/src/lib/misc/tss/info.txt
index 5d0615170..5aaca6707 100644
--- a/src/lib/misc/tss/info.txt
+++ b/src/lib/misc/tss/info.txt
@@ -2,7 +2,6 @@ define THRESHOLD_SECRET_SHARING 20131128
<requires>
rng
-filters
hex
sha1
sha2_32
diff --git a/src/lib/misc/tss/tss.cpp b/src/lib/misc/tss/tss.cpp
index e1727dc33..b77e6c2b9 100644
--- a/src/lib/misc/tss/tss.cpp
+++ b/src/lib/misc/tss/tss.cpp
@@ -7,7 +7,6 @@
#include <botan/tss.h>
#include <botan/loadstor.h>
-#include <botan/pipe.h>
#include <botan/hex.h>
#include <botan/sha2_32.h>
#include <botan/sha160.h>
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp
index 6ea66aa2e..2e056e726 100644
--- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp
+++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp
@@ -12,38 +12,63 @@ namespace Botan {
HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
RandomNumberGenerator& underlying_rng,
- size_t reseed_interval) :
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request) :
Stateful_RNG(underlying_rng, reseed_interval),
- m_mac(std::move(prf))
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
{
BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
clear();
}
HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
RandomNumberGenerator& underlying_rng,
Entropy_Sources& entropy_sources,
- size_t reseed_interval) :
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request ) :
Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
- m_mac(std::move(prf))
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
{
BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
clear();
}
HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
Entropy_Sources& entropy_sources,
- size_t reseed_interval) :
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request) :
Stateful_RNG(entropy_sources, reseed_interval),
- m_mac(std::move(prf))
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
{
BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
clear();
}
HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf) :
Stateful_RNG(),
- m_mac(std::move(prf))
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(64*1024)
{
BOTAN_ASSERT_NONNULL(m_mac);
clear();
@@ -76,22 +101,9 @@ void HMAC_DRBG::randomize(byte output[], size_t output_len)
void HMAC_DRBG::randomize_with_input(byte output[], size_t output_len,
const byte input[], size_t input_len)
{
- /**
- * SP 800-90A requires we reject any request for a DRBG output
- * longer than max_number_of_bits_per_request. This is an
- * implementation-dependent value, but NIST requires for HMAC_DRBG
- * that every implementation set a value no more than 2**19 bits
- * (or 64 KiB).
- *
- * To avoid inconveniencing the caller who wants a large output for
- * whatever reason, instead treat very long output requests as
- * if multiple maximum-length requests had been made.
- */
- const size_t max_number_of_bytes_per_request = 64*1024;
-
while(output_len > 0)
{
- size_t this_req = std::min(max_number_of_bytes_per_request, output_len);
+ size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len);
output_len -= this_req;
reseed_check();
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h
index 11d355d70..189edbcdf 100644
--- a/src/lib/rng/hmac_drbg/hmac_drbg.h
+++ b/src/lib/rng/hmac_drbg/hmac_drbg.h
@@ -24,7 +24,7 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
/**
* Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
*
- * Automatic reseeding is disabled completely, as it as no access to
+ * Automatic reseeding is disabled completely, as it has no access to
* any source for seed material.
*
* If a fork is detected, the RNG will be unable to reseed itself
@@ -44,10 +44,22 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
* to perform the periodic reseeding
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
*/
HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
RandomNumberGenerator& underlying_rng,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
/**
* Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
@@ -59,10 +71,22 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed.
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
*/
HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
Entropy_Sources& entropy_sources,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
/**
* Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
@@ -77,20 +101,32 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
* @param entropy_sources will be polled to perform reseeding periodically
* @param reseed_interval specifies a limit of how many times
* the RNG will be called before automatic reseeding is performed.
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
*/
HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
RandomNumberGenerator& underlying_rng,
Entropy_Sources& entropy_sources,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
/**
* Constructor taking a string for the hash
*/
- HMAC_DRBG(const std::string& hmac_hash) : Stateful_RNG()
+ HMAC_DRBG(const std::string& hmac_hash) :
+ Stateful_RNG(),
+ m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")),
+ m_max_number_of_bytes_per_request(64 * 1024)
{
- m_mac = MessageAuthenticationCode::create("HMAC(" + hmac_hash + ")");
- if(!m_mac)
- throw Algorithm_Not_Found(hmac_hash);
clear();
}
@@ -112,6 +148,7 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
std::unique_ptr<MessageAuthenticationCode> m_mac;
secure_vector<byte> m_V;
+ const size_t m_max_number_of_bytes_per_request;
};
}
diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp
index 36335e7ce..50c83c10c 100644
--- a/src/lib/tls/msg_client_hello.cpp
+++ b/src/lib/tls/msg_client_hello.cpp
@@ -84,7 +84,7 @@ Client_Hello::Client_Hello(Handshake_IO& io,
"Our policy accepts the version we are offering");
/*
- * Place all empty extensions in front to avoid a bug in some sytems
+ * Place all empty extensions in front to avoid a bug in some systems
* which reject hellos when the last extension in the list is empty.
*/
m_extensions.add(new Extended_Master_Secret);
@@ -170,14 +170,7 @@ Client_Hello::Client_Hello(Handshake_IO& io,
m_extensions.add(new Supported_Point_Formats());
}
- if(m_version.supports_negotiable_signature_algorithms())
- m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
- policy.allowed_signature_methods()));
-
- if(reneg_info.empty() && !next_protocols.empty())
- m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
-
- if(policy.negotiate_encrypt_then_mac())
+ if(session.supports_encrypt_then_mac())
m_extensions.add(new Encrypt_then_MAC);
#if defined(BOTAN_HAS_SRP6)
@@ -189,6 +182,13 @@ Client_Hello::Client_Hello(Handshake_IO& io,
}
#endif
+ if(m_version.supports_negotiable_signature_algorithms())
+ m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
+ policy.allowed_signature_methods()));
+
+ if(reneg_info.empty() && !next_protocols.empty())
+ m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
+
hash.update(io.send(*this));
}
diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h
index 17cd19b81..4a14055f9 100644
--- a/src/lib/tls/tls_callbacks.h
+++ b/src/lib/tls/tls_callbacks.h
@@ -99,9 +99,35 @@ class BOTAN_DLL Callbacks
virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos);
/**
- * Optional callback: debug logging. (not currently used)
+ * Optional callback: error logging. (not currently called)
+ * @param err An error message related to this connection.
*/
- virtual bool tls_log_debug(const char*) { return false; }
+ virtual void tls_log_error(const char* err)
+ {
+ BOTAN_UNUSED(err);
+ }
+
+ /**
+ * Optional callback: debug logging. (not currently called)
+ * @param what Some hopefully informative string
+ */
+ virtual void tls_log_debug(const char* what)
+ {
+ BOTAN_UNUSED(what);
+ }
+
+ /**
+ * Optional callback: debug logging taking a buffer. (not currently called)
+ * @param descr What this buffer is
+ * @param val the bytes
+ * @param val_len length of val
+ */
+ virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len)
+ {
+ BOTAN_UNUSED(descr);
+ BOTAN_UNUSED(val);
+ BOTAN_UNUSED(val_len);
+ }
};
/**
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index 0e72b9a28..183886c66 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -149,18 +149,25 @@ void Client::send_client_hello(Handshake_State& state_base,
Session session_info;
if(session_manager().load_from_server_info(m_info, session_info))
{
- if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier)
+ /*
+ Ensure that the session protocol type matches what we want to use
+ If not skip the resume and establish a new session
+ */
+ if(version == session_info.version())
{
- state.client_hello(new Client_Hello(
- state.handshake_io(),
- state.hash(),
- policy(),
- rng(),
- secure_renegotiation_data_for_client_hello(),
- session_info,
- next_protocols));
-
- state.resume_master_secret = session_info.master_secret();
+ if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier)
+ {
+ state.client_hello(
+ new Client_Hello(state.handshake_io(),
+ state.hash(),
+ policy(),
+ rng(),
+ secure_renegotiation_data_for_client_hello(),
+ session_info,
+ next_protocols));
+
+ state.resume_master_secret = session_info.master_secret();
+ }
}
}
}